UNPKG

redux-conditional

Version:

Make sharing reducers easy by conditionally applying actions to shared Redux reducers.

78 lines (59 loc) 2.24 kB
const conditionalDefaultSubKey = '__redux_conditional_default_subkey__'; // Symbol('SUB KEY IN CONDITIONAL KEY'); const conditionalKeyReader = (paths, subKey = conditionalDefaultSubKey) => action => { let fullPath = []; if (Array.isArray(paths)) { fullPath = paths; } let val = action; try { fullPath.reduce((prev, cur) => (val = prev[cur]), action); } catch (err) { // just don't report error } finally { return val && val[subKey]; } }; const conditionalKeyWriter = (paths, subKey = conditionalDefaultSubKey) => data => action => { let target = action; if (Array.isArray(paths)) { target = paths.reduce((prev, cur) => { if (prev[cur] === undefined || prev[cur] === null) { prev[cur] = {}; } return prev[cur]; }, action); } target[subKey] = data; return action; }; const simpleConditionMaker = (reader) => data => (state, action) => reader(action) === data; const simpleConditionalActionCreator = paths => actionCreator => data => (...actionCreatorArgs) => { let dataWithKey = data; if (typeof data !== 'object') { dataWithKey = { [conditionalDefaultSubKey]: data }; } const initValue = typeof actionCreator === 'function' ? actionCreator(...actionCreatorArgs) : Object.assign({}, actionCreator); return (Object.keys(dataWithKey).concat(Object.getOwnPropertySymbols(dataWithKey))).reduce((action, subKey) => conditionalKeyWriter(paths, subKey)(dataWithKey[subKey])(action), initValue); }; const simpleConditional = ({ paths, switches } = {})=> { // don't use "actionCreator" const conditions = { actionCreator: simpleConditionalActionCreator(paths) }; const subKeys = (switches || []).concat([conditionalDefaultSubKey]); subKeys.forEach(subKey => { const keyWriter = conditionalKeyWriter(paths, subKey); const keyReader = conditionalKeyReader(paths, subKey); const exportKey = subKey === conditionalDefaultSubKey ? 'default' : subKey; conditions[exportKey] = { conditionMaker: simpleConditionMaker(keyReader), conditionalKeyWriter: keyWriter, conditionalKeyReader: keyReader, }; }); return conditions; }; export { conditionalDefaultSubKey, simpleConditional, };