import { State, Manager, Controller, ActionTypes, createReducer, applyManager, GCInterface, } from '@data-client/core'; import { combineReducers } from './combineReducers.js'; import { default as mapMiddleware } from './mapMiddleware.js'; import { default as PromiseifyMiddleware } from './PromiseifyMiddleware.js'; import { createStore, applyMiddleware } from './redux.js'; import type { Reducer, Middleware, Store } from './redux.js'; import GCPolicy from '../../state/GCPolicy.js'; export function prepareStore< R extends ReducersMapObject = {}, >( initialState: DeepPartialWithUnknown>, managers: Manager[], Ctrl: new (props: { gcPolicy: GCInterface }) => Controller, reducers: R = {} as any, middlewares: Middleware[] = [] as any, gcPolicy: GCInterface = new GCPolicy(), ) { const selector = (s: { dataclient: State }) => s.dataclient; const controller = new Ctrl({ gcPolicy }); const reducer = createReducer(controller); const store: Store< StateFromReducersMapObject & { dataclient: State } > = createStore( combineReducers({ ...reducers, dataclient: reducer }), { dataclient: initialState } as any, applyMiddleware( ...mapMiddleware(selector)( ...(applyManager(managers, controller) as any), ), PromiseifyMiddleware as any, ...middlewares, ), ) as any; return { selector, store, controller }; } // Extension of the DeepPartial type defined by Redux which handles unknown export type DeepPartialWithUnknown = { [K in keyof T]?: T[K] extends unknown ? any : T[K] extends object ? DeepPartialWithUnknown : T[K]; }; /* From redux@5 - we extract to maintain compatibility with v4 */ type StateFromReducersMapObject = M[keyof M] extends Reducer | undefined ? { [P in keyof M]: M[P] extends Reducer ? S : never; } : never; type ReducersMapObject< S = any, A extends { type: string } = any, PreloadedState = S, > = keyof PreloadedState extends keyof S ? { [K in keyof S]: Reducer< S[K], A, K extends keyof PreloadedState ? PreloadedState[K] : never >; } : never;