@@ -35,16 +35,19 @@ import {
3535} from './actions/index.js' ;
3636import ensurePojo from './ensurePojo.js' ;
3737import type { EndpointUpdateFunction } from './types.js' ;
38+ import { ReduxMiddlewareAPI } from '../manager/applyManager.js' ;
3839import type { GCInterface } from '../state/GCPolicy.js' ;
3940import { ImmortalGCPolicy } from '../state/GCPolicy.js' ;
4041import { initialState } from '../state/reducer/createReducer.js' ;
4142import selectMeta from '../state/selectMeta.js' ;
42- import type { ActionTypes , State } from '../types.js' ;
43+ import type { ActionTypes , Dispatch , State } from '../types.js' ;
4344
4445export type GenericDispatch = ( value : any ) => Promise < void > ;
4546export type DataClientDispatch = ( value : ActionTypes ) => Promise < void > ;
4647
47- interface ConstructorProps < D extends GenericDispatch = DataClientDispatch > {
48+ export interface ControllerConstructorProps <
49+ D extends GenericDispatch = DataClientDispatch ,
50+ > {
4851 dispatch ?: D ;
4952 getState ?: ( ) => State < unknown > ;
5053 memo ?: Pick < MemoCache , 'denormalize' | 'query' | 'buildQueryKey' > ;
@@ -68,22 +71,23 @@ const unsetState = (): State<unknown> => {
6871 * @see https://dataclient.io/docs/api/Controller
6972 */
7073export default class Controller <
74+ // NOTE: We template on entire dispatch, so we can be contravariant on ActionTypes
7175 D extends GenericDispatch = DataClientDispatch ,
7276> {
7377 /**
7478 * Dispatches an action to Reactive Data Client reducer.
7579 *
7680 * @see https://dataclient.io/docs/api/Controller#dispatch
7781 */
78- declare readonly dispatch : D ;
82+ declare protected _dispatch : D ;
7983 /**
8084 * Gets the latest state snapshot that is fully committed.
8185 *
8286 * This can be useful for imperative use-cases like event handlers.
8387 * This should *not* be used to render; instead useSuspense() or useCache()
8488 * @see https://dataclient.io/docs/api/Controller#getState
8589 */
86- declare readonly getState : ( ) => State < unknown > ;
90+ declare getState : ( ) => State < unknown > ;
8791 /**
8892 * Singleton to maintain referential equality between calls
8993 */
@@ -102,13 +106,35 @@ export default class Controller<
102106 getState = unsetState ,
103107 memo = new MemoCache ( ) ,
104108 gcPolicy = new ImmortalGCPolicy ( ) ,
105- } : ConstructorProps < D > = { } ) {
106- this . dispatch = dispatch ;
109+ } : ControllerConstructorProps < D > = { } ) {
110+ this . _dispatch = dispatch ;
107111 this . getState = getState ;
108112 this . memo = memo ;
109113 this . gcPolicy = gcPolicy ;
110114 }
111115
116+ // TODO: drop when drop support for destructuring (0.14 and below)
117+ set dispatch ( dispatch : D ) {
118+ /* istanbul ignore next */
119+ this . _dispatch = dispatch ;
120+ }
121+
122+ // TODO: drop when drop support for destructuring (0.14 and below)
123+ get dispatch ( ) : D {
124+ return this . _dispatch ;
125+ }
126+
127+ bindMiddleware ( {
128+ dispatch,
129+ getState,
130+ } : {
131+ dispatch : D ;
132+ getState : ReduxMiddlewareAPI [ 'getState' ] ;
133+ } ) {
134+ this . _dispatch = dispatch ;
135+ this . getState = getState ;
136+ }
137+
112138 /*************** Action Dispatchers ***************/
113139
114140 /**
0 commit comments