UNPKG

bdn-pocket

Version:

pocket tools for managing redux and redux-saga

65 lines (57 loc) 2.03 kB
import stampit from '@stamp/it' import equals from 'ramda/src/equals' import pathOr from 'ramda/src/pathOr' import propOr from 'ramda/src/propOr' import MakeReqMessenger from '../messenger/make_req_messenger' import SelectorDef, { makeIsCacheValid } from './selector_def' const Selector = stampit(SelectorDef) .methods({ getPag(pags, id) { const { defaultState } = MakeReqMessenger.compose.deepProperties if (pags === undefined) { throw new Error(` pags parameter is undefined - expected an object indexed by id `) } const getter = Array.isArray(id) ? pathOr : propOr return getter(defaultState, id, pags) } }) .init(({ reducer }, { stamp, instance }) => { const { PropTypes } = stamp.compose.staticProperties const { getSubState, } = instance const isPropsCacheValid = makeIsCacheValid(equals) const boundReducer = reducer.bind(instance) const isSubStateCacheValid = makeIsCacheValid((r, l) => r === l) let lastResult let lastPartialReducer /** * propsReducer generate a partial reducer function * that is memoized (lastPartialReducer) * if props is sent, propsReducer execute the partial reducer * else it return the partial reducer */ return function propsReducer(state, props) { const subStates = getSubState(state) // memoize partial reducer // this partial reducer will be reused in next call if args remains equal if (!isSubStateCacheValid(subStates)) { // invalidate props cache to ensure reducer to run next time isPropsCacheValid(undefined) lastPartialReducer = (props = {}) => { PropTypes(props) if ( !isPropsCacheValid(props) ) { lastResult = boundReducer(subStates, props, { instance }) } return lastResult } } return props === undefined ? lastPartialReducer : lastPartialReducer(props) } }) export default Selector