60 lines
1.7 KiB
TypeScript
60 lines
1.7 KiB
TypeScript
import { AnyAction } from '@reduxjs/toolkit';
|
|
import { MiddlewareAPI } from '@reduxjs/toolkit';
|
|
import { Dispatch } from '@reduxjs/toolkit';
|
|
|
|
export interface EffectMiddleware<S = any, D extends Dispatch = Dispatch> {
|
|
(api: MiddlewareAPI<D, S>): (
|
|
next: Dispatch<AnyAction>,
|
|
) => (action: AnyAction) => any;
|
|
}
|
|
|
|
const composeMw = (mws) => (api) => (originalNext) =>
|
|
mws.reduceRight((next, mw) => mw(api)(next), originalNext);
|
|
|
|
export const augmentGetState = (originalGetState, selectors) => {
|
|
const getState = () => originalGetState();
|
|
for (const s in selectors) {
|
|
getState[s] = (...args) => {
|
|
let result = selectors[s](originalGetState());
|
|
if (typeof result === 'function') return result(...args);
|
|
return result;
|
|
};
|
|
}
|
|
return getState;
|
|
};
|
|
|
|
const augmentDispatch = (originalDispatch, actions) => {
|
|
const dispatch = (action) => originalDispatch(action);
|
|
|
|
for (const a in actions) {
|
|
dispatch[a] = (...args) => dispatch(actions[a](...args));
|
|
}
|
|
return dispatch;
|
|
};
|
|
|
|
export const augmentMiddlewareApi = (api, actions, selectors) => {
|
|
return {
|
|
...api,
|
|
getState: augmentGetState(api.getState, selectors),
|
|
dispatch: augmentDispatch(api.dispatch, actions),
|
|
actions,
|
|
selectors,
|
|
};
|
|
};
|
|
|
|
export function buildEffectsMiddleware(
|
|
effects = [],
|
|
actions = {},
|
|
selectors = {},
|
|
) {
|
|
return (api) => {
|
|
const newApi = augmentMiddlewareApi(api, actions, selectors);
|
|
|
|
let mws = effects.map((e) => e(newApi));
|
|
|
|
return (originalNext) => {
|
|
return mws.reduceRight((next, mw) => mw(next), originalNext);
|
|
};
|
|
};
|
|
}
|