import NetworkManager from './NetworkManager.js'; import type Controller from '../controller/Controller.js'; import { Manager } from '../types.js'; export default function applyManager( managers: Manager[], controller: Controller, ): ReduxMiddleware[] { /* istanbul ignore next */ if ( process.env.NODE_ENV !== 'production' && !managers.find(mgr => mgr instanceof NetworkManager) ) { console.warn('NetworkManager not found; this is a required manager.'); console.warn( 'See https://dataclient.io/docs/guides/redux for hooking up redux', ); } return managers.map((manager, i) => { if (!manager.middleware) manager.middleware = manager.getMiddleware?.(); return (api: ReduxMiddlewareAPI) => { if (i === 0) { controller.bindMiddleware(api); } // controller is a superset of the middleware API return (manager as Manager & { middleware: ReduxMiddleware }).middleware( controller as any, ); }; }); } /* These should be compatible with redux */ export interface ReduxMiddlewareAPI< R extends Reducer = Reducer, > { getState: () => ReducerState; dispatch: ReactDispatch; } export type ReduxMiddleware = >({ dispatch, }: ReduxMiddlewareAPI) => (next: ReactDispatch) => ReactDispatch; /* The next are types from React; but we don't want dependencies on it */ export type ReactDispatch> = ( action: ReducerAction, ) => Promise; export type Reducer = (prevState: S, action: A) => S; export type ReducerState> = R extends Reducer ? S : never; export type ReducerAction> = R extends Reducer ? A : never;