UNPKG

astx-redux-util

Version:

Several redux reducer composition utilities.

105 lines (85 loc) 4.13 kB
'use strict'; exports.__esModule = true; exports.default = reducerHash; var _lodash = require('lodash.identity'); var _lodash2 = _interopRequireDefault(_lodash); var _lodash3 = require('lodash.isfunction'); var _lodash4 = _interopRequireDefault(_lodash3); var _verify = require('../util/verify'); var _verify2 = _interopRequireDefault(_verify); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Create a higher-order reducer by combining a set of sub-reducer * functions that are indexed by the standard action.type. When no * action.type is acted on, the original state is merely * passed-through (using the [identity * function](https://lodash.com/docs#identity)). * * This is one of the more prevalent composition reducers, and * provides an alternative to the switch statement (commonly used to * provide this control mechanism). * * The {{book.guide.devGuide}} discusses reducerHash() in more detail (see * {{book.guide.conceptHash}}), and additional examples can be found in * {{book.guide.conceptJoin}} and {{book.guide.fullExample}}. * * **SideBar**: Because reducerHash is so central to the rudimentary * aspect of reduction, it is a common practice to extend it, * promoting a * [`centralized reducer-based logging capability`](/extending/logExt.md), * with an ability to correlate logging levels to state changes * *(providing a means to filter logs at a high level with minimal * output)*. * * @param {ActionReducerHash} actionHandlers - a hash of reducer functions, * indexed by the standard redux action.type. * * @param {InitialState} [initialState] - the optional fall-back state * value used during the state initialization boot-strap process. * * @returns {reducerFn} a newly created reducer function (described above). */ function reducerHash(actionHandlers, initialState) { // validate params var check = _verify2.default.prefix('AstxReduxUtil.reducerHash() parameter violation: '); check(actionHandlers, 'actionHandlers is required'); // ... AI: this check may be too intrusive if the client's actionHandlers object is used for OTHER things? var invalidHashEntry = Object.getOwnPropertyNames(actionHandlers).reduce(function (firstBadEntry, type) { return firstBadEntry || (0, _lodash4.default)(actionHandlers[type]) ? null : type; }, null); check(!invalidHashEntry, 'actionHandlers[\'' + invalidHashEntry + '\'] is NOT a function ... expecting reducer function indexed by action type'); check(!actionHandlers['undefined'], "actionHandlers contains an 'undefined' entry ... suspect a misspelled constant"); // internal function: locate handler from actionHandlers action.type hash lookup // ... default: identity pass-through var locateHandler = function locateHandler(action) { return actionHandlers[action.type] || _lodash2.default; }; // expose the new reducer fn, which resolves according the the supplied actionHandlers return function () { var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; var action = arguments[1]; var originalReducerState = arguments[2]; // maintain the originalReducerState as the immutable state // at the time of the start of the reduction process // ... in support of joinReducers() // ... for more info, refer to the Dev Guide {{book.guide.originalReducerState}} if (originalReducerState === undefined) { originalReducerState = state; } // execute the handler indexed by the action.type (or the identity pass-through) return locateHandler(action)(state, action, originalReducerState); }; } //*** //*** Specification: ActionReducerHash //*** /** * @typedef {Object} ActionReducerHash * * A hash of reducer functions, indexed by the standard redux * action.type. * * @property {reducerFn} actionType1 - The reducer function servicing: 'actionType1'. * @property {reducerFn} actionType2 - The reducer function servicing: 'actionType2'. * @property {reducerFn} ...more - ...etc. */