ruddy
Version:
Modularized state-management tools for modern front-end applications. Manage dispatched messages in a clean and predictable way for either small or large scale projects
161 lines (131 loc) • 8.28 kB
JavaScript
'use strict';
exports.__esModule = true;
exports.createTransitionsPostReducer = exports.createReducer = exports.makeExtendedReducer = exports.makeTransitionsPostReducer = exports.makeReducer = undefined;
var _path = require('ramda/src/path');
var _path2 = _interopRequireDefault(_path);
var _identity = require('ramda/src/identity');
var _identity2 = _interopRequireDefault(_identity);
var _defaultTo = require('ramda/src/defaultTo');
var _defaultTo2 = _interopRequireDefault(_defaultTo);
var _compose = require('ramda/src/compose');
var _compose2 = _interopRequireDefault(_compose);
var _converge = require('ramda/src/converge');
var _converge2 = _interopRequireDefault(_converge);
var _assocPath = require('ramda/src/assocPath');
var _assocPath2 = _interopRequireDefault(_assocPath);
var _curry = require('ramda/src/curry');
var _curry2 = _interopRequireDefault(_curry);
var _prop = require('ramda/src/prop');
var _prop2 = _interopRequireDefault(_prop);
var _isNil = require('ramda/src/isNil');
var _isNil2 = _interopRequireDefault(_isNil);
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _machines = require('../machines');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var initialIfNil = function initialIfNil(state, duck) {
return (0, _isNil2.default)(state) ? (0, _prop2.default)('initialState', duck) : state;
};
/**
* Creates a standard ducks reducer, where the duck is the context object,
* passed as the third param (standard redux reducers are two params, first for
* the current state of the store and the second is the dispatched redux
* action).
* This function is then applied to the state along with a dispatched action
* that may induce a change in state.
*
* @func ((a, b, c) -> a) -> c -> a -> b -> a
* @param {Function} reducer A function which processes state, action, and duck params
* to validate the action and (potentially) apply a change to state.
* @param {Object} duck A duck, containing types, consts, validators and other
* helpers that are used to carry out the reducer's logic
* @param {Object} state The current state of a certain portion of the store
* @param {Object} action A dispatched redux action, with (at minimum) a 'type' prop
* @returns {Object} Returns a clone of the state, potentially different than
* the original state if the action object caused a change. Because this is a
* curried function, you can omit the final two params (state and action) to set
* this partially curried function as a redux reducer in the combineReducers() setup.
*/
var makeReducer = exports.makeReducer = (0, _curry2.default)(function (reducer, duck, state, action) {
return reducer(initialIfNil(state, duck), action, duck);
});
/**
* Creates a standard ducks reducer, where the duck is the context object,
* passed as the third param (standard redux reducers are two params, first for
* the current state of the store and the second is the dispatched redux
* action).
* This function is then applied to the state along with a dispatched action
* that may induce a change in state.
*
* Appended to this reducer is an automatic validation of the action to see if
* it is registered as an accepted input to one or more of the state machines
* (inside the duck), and if so, the corresponding state transition is then applied
* to the store (at the prop/path which the user specified when they setup their duck).
*
* @func
* @sig ((a, b, c) -> a) -> c -> a -> b -> a
* @param {Function} reducer A function which processes state, action, and duck params
* to validate the action and (potentially) apply a change to state.
* @param {Object} duck A duck, containing types, consts, validators and other
* helpers that are used to carry out the reducer's logic
* @param {Object} state The current state of a certain portion of the store
* @param {Object} action A dispatched redux action, with (at minimum) a 'type' prop
* @returns {Object} Returns a clone of the state, potentially different than
* the original state if the action object caused a change. Because this is a
* curried function, you can omit the final two params (state and action) to set
* this partially curried function as a redux reducer in the combineReducers() setup.
*/
var makeTransitionsPostReducer = exports.makeTransitionsPostReducer = (0, _curry2.default)(function (reducer, dux, state, action) {
var stateWithTransitions = (0, _machines.addTransitionsToState)(initialIfNil(state, dux), dux);
var updatedStates = (0, _assocPath2.default)(dux.stateMachinesPropName, (0, _machines.getNextState)(stateWithTransitions, action, dux), {});
return _extends({}, reducer(_extends({}, stateWithTransitions, updatedStates), action, dux), updatedStates);
});
/**
* Creates a layered reducer which invokes one and then the other, passing in
* the result of the first reducer as the 'state' param to the second reducer.
*
* @func
* @sig {k: v} -> {k: v} -> {k: v} -> {k: v} -> {k: v}
* @param {Object} parentOptions An options object for a duck being extended, containing
* types, consts, validators and other helpers that are used to carry out the reducer's logic
* @param {Object} childOptions An options object for a duck that has yet to be created
* but which are being extened from an existing duck to validate the action and (potentially)
* apply a change to state.
* @param {Object} state The current state of a certain portion of the store
* @param {Object} action A dispatched redux action, with (at minimum) a 'type' prop
* @param {Object} duck A duck, containing types, consts, validators and other
* helpers that are used to carry out the reducer's logic
* @returns {Object} Returns a clone of the state, potentially different than
* the original state if the action object caused a change. Because this is a
* curried function, you can omit the final two params (state and action) to set
* this partially curried function as a redux reducer in the combineReducers() setup.
*/
var makeExtendedReducer = exports.makeExtendedReducer = (0, _curry2.default)(function (parentOptions, childOptions, state, action, duck) {
return childOptions.reducer(parentOptions.reducer(initialIfNil(state), action, duck), action, duck);
});
/**
* Parses the reducer from a duck (inside the 'options' prop),
* wraps it with the duck (as context) so that the reducer code will be able to execute
* (as it likely parses the types or other items from the duck to carry out its logic on the action payload).
* The resulting function is then ready to be passed state and a dispatched action.
*
* @func
* @sig {k: v} -> ((a, b) -> a)
* @param {Object} duck A duck, containing a reducer prop inside of its options prop
* @returns {Function} A wrapped reducer, ready to be invoked with state and action params
*/
var createReducer = exports.createReducer = (0, _converge2.default)(makeReducer, [(0, _compose2.default)((0, _defaultTo2.default)(_identity2.default), (0, _path2.default)(['options', 'reducer'])), _identity2.default]);
/**
* Parses the reducer from a duck (inside the 'options' prop),
* wraps it with the duck (as context) so that the reducer code will be able to execute
* (as it likely parses the types or other items from the duck to carry out its logic on the action payload),
* and finally a state machine transitions validation is appended to the
* reducer, so that the portion of the store that tracks state transitions will
* be updated.
* The resulting function is then ready to be passed state and a dispatched action.
*
* @func
* @sig {k: v} -> ((a, b) -> a)
* @param {Object} duck A duck, containing a reducer prop inside of its options prop
* @returns {Function} A wrapped reducer, ready to be invoked with state and action params
*/
var createTransitionsPostReducer = exports.createTransitionsPostReducer = (0, _converge2.default)(makeTransitionsPostReducer, [(0, _compose2.default)((0, _defaultTo2.default)(_identity2.default), (0, _path2.default)(['options', 'reducer'])), _identity2.default]);