redux-conditional
Version:
Make sharing reducers easy by conditionally applying actions to shared Redux reducers.
78 lines (59 loc) • 2.24 kB
JavaScript
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,
};