UNPKG

4.17 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.default = reducerHash;
7
8var _lodash = require('lodash.identity');
9
10var _lodash2 = _interopRequireDefault(_lodash);
11
12var _lodash3 = require('lodash.isfunction');
13
14var _lodash4 = _interopRequireDefault(_lodash3);
15
16var _verify = require('../util/verify');
17
18var _verify2 = _interopRequireDefault(_verify);
19
20function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
22/**
23 * Create a higher-order reducer by combining a set of sub-reducer
24 * functions that are indexed by the standard action.type. When no
25 * action.type is acted on, the original state is merely
26 * passed-through (using the [identity
27 * function](https://lodash.com/docs#identity)).
28 *
29 * This is one of the more prevalent composition reducers, and
30 * provides an alternative to the switch statement (commonly used to
31 * provide this control mechanism).
32 *
33 * The {{book.guide.devGuide}} discusses reducerHash() in more detail (see
34 * {{book.guide.conceptHash}}), and additional examples can be found in
35 * {{book.guide.conceptJoin}} and {{book.guide.fullExample}}.
36 *
37 * **SideBar**: Because reducerHash is so central to the rudimentary
38 * aspect of reduction, it is a common practice to extend it,
39 * promoting a
40 * [`centralized reducer-based logging capability`](/extending/logExt.md),
41 * with an ability to correlate logging levels to state changes
42 * *(providing a means to filter logs at a high level with minimal
43 * output)*.
44 *
45 * @param {ActionReducerHash} actionHandlers - a hash of reducer functions,
46 * indexed by the standard redux action.type.
47 *
48 * @param {InitialState} [initialState] - the optional fall-back state
49 * value used during the state initialization boot-strap process.
50 *
51 * @returns {reducerFn} a newly created reducer function (described above).
52 */
53function reducerHash(actionHandlers, initialState) {
54
55 // validate params
56 var check = _verify2.default.prefix('AstxReduxUtil.reducerHash() parameter violation: ');
57
58 check(actionHandlers, 'actionHandlers is required');
59
60 // ... AI: this check may be too intrusive if the client's actionHandlers object is used for OTHER things?
61 var invalidHashEntry = Object.getOwnPropertyNames(actionHandlers).reduce(function (firstBadEntry, type) {
62 return firstBadEntry || (0, _lodash4.default)(actionHandlers[type]) ? null : type;
63 }, null);
64 check(!invalidHashEntry, 'actionHandlers[\'' + invalidHashEntry + '\'] is NOT a function ... expecting reducer function indexed by action type');
65
66 check(!actionHandlers['undefined'], "actionHandlers contains an 'undefined' entry ... suspect a misspelled constant");
67
68 // internal function: locate handler from actionHandlers action.type hash lookup
69 // ... default: identity pass-through
70 var locateHandler = function locateHandler(action) {
71 return actionHandlers[action.type] || _lodash2.default;
72 };
73
74 // expose the new reducer fn, which resolves according the the supplied actionHandlers
75 return function () {
76 var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;
77 var action = arguments[1];
78 var originalReducerState = arguments[2];
79
80
81 // maintain the originalReducerState as the immutable state
82 // at the time of the start of the reduction process
83 // ... in support of joinReducers()
84 // ... for more info, refer to the Dev Guide {{book.guide.originalReducerState}}
85 if (originalReducerState === undefined) {
86 originalReducerState = state;
87 }
88
89 // execute the handler indexed by the action.type (or the identity pass-through)
90 return locateHandler(action)(state, action, originalReducerState);
91 };
92}
93
94//***
95//*** Specification: ActionReducerHash
96//***
97
98/**
99 * @typedef {Object} ActionReducerHash
100 *
101 * A hash of reducer functions, indexed by the standard redux
102 * action.type.
103 *
104 * @property {reducerFn} actionType1 - The reducer function servicing: 'actionType1'.
105 * @property {reducerFn} actionType2 - The reducer function servicing: 'actionType2'.
106 * @property {reducerFn} ...more - ...etc.
107 */
\No newline at end of file