83 lines
2.0 KiB
JavaScript
83 lines
2.0 KiB
JavaScript
import R from 'remeda';
|
|
|
|
const composeMw = (mws) => (api) => (original_next) =>
|
|
mws.reduceRight((next, mw) => mw(api)(next), original_next);
|
|
|
|
export function augmentMiddlewareApi(api, actions, selectors) {
|
|
const getState = () => api.getState();
|
|
const dispatch = (action) => api.dispatch(action);
|
|
|
|
Object.assign(
|
|
getState,
|
|
R.mapValues(selectors, (selector) => {
|
|
return (...args) => {
|
|
let result = selector(api.getState());
|
|
|
|
if (typeof result === 'function') return result(...args);
|
|
|
|
return result;
|
|
};
|
|
}),
|
|
);
|
|
|
|
Object.assign(
|
|
dispatch,
|
|
R.mapValues(actions, (action) => {
|
|
return (...args) => api.dispatch(action(...args));
|
|
}),
|
|
);
|
|
|
|
return {
|
|
...api,
|
|
getState,
|
|
dispatch,
|
|
actions,
|
|
selectors,
|
|
};
|
|
}
|
|
|
|
const sliceMw = (slice, mw) => (api) => {
|
|
const getSliceState = () => get(api.getState(), slice);
|
|
return mw({ ...api, getState: getSliceState });
|
|
};
|
|
|
|
const middlewareFor = (type, middleware) => (api) => (next) => (action) => {
|
|
if (type !== '*' && action.type !== type) return next(action);
|
|
|
|
return middleware(api)(next)(action);
|
|
};
|
|
|
|
export const effectToMiddleware = (effect, actions, selectors) => {
|
|
let mw = effect;
|
|
let action = '*';
|
|
|
|
if (Array.isArray(effect)) {
|
|
action = effect[0];
|
|
mw = effect[1];
|
|
mw = middlewareFor(action, mw);
|
|
}
|
|
|
|
return (api) => mw(augmentMiddlewareApi(api, actions, selectors));
|
|
};
|
|
|
|
export function buildMiddleware(
|
|
effects = [],
|
|
actions = {},
|
|
selectors = {},
|
|
subduxes = {},
|
|
) {
|
|
let inner = R.compact(
|
|
Object.entries(subduxes).map((slice, [{ middleware }]) =>
|
|
slice !== '*' && middleware ? sliceMw(slice, middleware) : null,
|
|
),
|
|
);
|
|
|
|
const local = effects.map((effect) =>
|
|
effectToMiddleware(effect, actions, selectors),
|
|
);
|
|
|
|
let mws = [...local, ...inner];
|
|
|
|
return composeMw(mws);
|
|
}
|