UNPKG

@snipsonian/observable-state

Version:

Observable-state snippets (redux-like)

63 lines (62 loc) 2.58 kB
import isFunction from '@snipsonian/core/es/is/isFunction'; import isObservableStateAction from './isObservableStateAction'; const WARN_MESSAGE = { FILTER_MAY_NOT_RETURN_OTHER_ACTION_TYPE: 'Observable state action: returning another action type from a filter hook is not supported!!!', }; export default function createObservableStateActionMiddleware({ store, extraProcessInput = {}, }) { const middleware = ({ getState }) => (next) => (action) => { if (isObservableStateAction(action)) { const filterHookResultingAction = executeFilterHook(action); if (filterHookResultingAction === false) { return; } const resultNextMiddleware = next(filterHookResultingAction); executeProcessHook(filterHookResultingAction); return resultNextMiddleware; } return next(action); function executeFilterHook(incomingAction) { if (incomingAction.filter) { const filterResultingAction = incomingAction.filter({ action: incomingAction, getState, }); if (filterResultingAction && filterResultingAction.type !== incomingAction.type) { if (process.env.NODE_ENV !== 'test') { console.warn(WARN_MESSAGE.FILTER_MAY_NOT_RETURN_OTHER_ACTION_TYPE); } } else { return filterResultingAction; } } return incomingAction; } function executeProcessHook(filteredAction) { if (filteredAction.process) { filteredAction.process(Object.assign({ action: filteredAction, getState, setState: ({ newState, notificationsToTrigger, context = getDefaultContext(filteredAction) }) => { store.setState({ newState, notificationsToTrigger, context, }); }, dispatch: store.dispatch }, extraProcessInput)); } } }; return middleware; } function getDefaultContext(action) { const actionWithoutFunctions = Object.keys(action) .reduce((accumulator, propKey) => { const propVal = action[propKey]; if (!isFunction(propVal)) { accumulator[propKey] = propVal; } return accumulator; }, {}); return { title: action.type, info: actionWithoutFunctions, }; }