UNPKG

redux-reorder

Version:

Higher-order reducer that tracks order fluctuation within iterable state

49 lines (46 loc) 1.84 kB
import isEqual from 'lodash/isEqual' import { isIterable } from 'iterall' import { INITIALIZE_REORDERS } from './actions' // @TODO: create a better abstraction / heuristic than `step` and do away with // need for explicit reorderType... export default function grokReorders(reducer, { step = 1, reorderType } = {}) { const initialState = { iterable: reducer(undefined, {}), fluctuationMap: [] } let calls = 0 let fluctuationMap = [] let prevIterableAsArray = Array.from(initialState.iterable) return (state = initialState, action) => { const nextIterable = reducer(state.iterable, action) // @TODO: obviate by 'putting everything on hold' until we get iterable state? if (!isIterable(nextIterable)) { throw new TypeError( `grokReorders expects a reducer that returns iterable state. Instead the reducer returned a ${typeof nextIterable}. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#iterable` ) } const nextIterableAsArray = Array.from(nextIterable) switch (action.type) { case INITIALIZE_REORDERS: calls = 0 return { iterable: nextIterable, fluctuationMap: [] } case reorderType: // If enough fluctuation has 'accumulated', represent this fluctuation // and store the new iterable state. // @TODO: prove you will never need >= here if (++calls === step) { fluctuationMap = nextIterableAsArray.map((x, i) => { const prevIndex = prevIterableAsArray.findIndex(y => isEqual(y, x)) return prevIndex !== -1 ? prevIndex - i : 0 }) calls = 0 prevIterableAsArray = nextIterableAsArray } return { iterable: nextIterable, fluctuationMap } default: return state } } }