attadux
Version:
Implementation of the redux-modular-ducks, forked from the extensible-duck implementation and extended to include spected validators, state machines, helpers, web workers, effect handling, action multipliers, action enhancers, action throttling/debouncing
128 lines (118 loc) • 7.18 kB
JavaScript
import _default9 from 'ramda/src/path';
import _default8 from 'ramda/src/identity';
import _default7 from 'ramda/src/defaultTo';
import _default6 from 'ramda/src/compose';
import _default5 from 'ramda/src/converge';
import _default4 from 'ramda/src/assocPath';
import _default3 from 'ramda/src/curry';
import _default2 from 'ramda/src/prop';
import _default from 'ramda/src/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; };
import { addTransitionsToState, getNextState } from '../machines';
var initialIfNil = function initialIfNil(state, duck) {
return _default(state) ? _default2('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.
*/
export var makeReducer = _default3(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.
*/
export var makeTransitionsPostReducer = _default3(function (reducer, dux, state, action) {
var stateWithTransitions = addTransitionsToState(initialIfNil(state, dux), dux);
var updatedStates = _default4(dux.stateMachinesPropName, 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.
*/
export var makeExtendedReducer = _default3(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
*/
export var createReducer = _default5(makeReducer, [_default6(_default7(_default8), _default9(['options', 'reducer'])), _default8]);
/**
* 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
*/
export var createTransitionsPostReducer = _default5(makeTransitionsPostReducer, [_default6(_default7(_default8), _default9(['options', 'reducer'])), _default8]);