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
149 lines (142 loc) • 8.28 kB
JavaScript
import _default31 from 'ramda/src/uniq';
import _default30 from 'ramda/src/path';
import _default29 from 'ramda/src/__';
import _default28 from 'ramda/src/when';
import _default27 from 'ramda/src/mapAccum';
import _default26 from 'ramda/src/mergeAll';
import _default25 from 'ramda/src/applyTo';
import _default24 from 'ramda/src/concat';
import _default23 from 'ramda/src/reduce';
import _default22 from 'ramda/src/objOf';
import _default21 from 'ramda/src/mergeDeepRight';
import _default20 from 'ramda/src/of';
import _default19 from 'ramda/src/find';
import _default18 from 'ramda/src/last';
import _default17 from 'ramda/src/has';
import _default16 from 'ramda/src/all';
import _default15 from 'ramda/src/ifElse';
import _default14 from 'ramda/src/T';
import _default13 from 'ramda/src/isNil';
import _default12 from 'ramda/src/identity';
import _default11 from 'ramda/src/mergeDeepWith';
import _default10 from 'ramda/src/converge';
import _default9 from 'ramda/src/always';
import _default8 from 'ramda/src/pair';
import _default7 from 'ramda/src/prop';
import _default6 from 'ramda/src/map';
import _default5 from 'ramda/src/is';
import _default4 from 'ramda/src/any';
import _default3 from 'ramda/src/compose';
import _default2 from 'ramda/src/cond';
import _default from 'ramda/src/curry';
import { makeExtendedReducer } from '../reducers';
import { duxDefaults } from './schema';
import { concatOrReplace } from '../types';
import { coerceToFn, simpleMergeStrategy } from '../util';
/**
* A function that creates an "extender" function which will merges
* a portion of two duck together at a specified prop
*
* @func
* @sig {k: v} -> {k: v} -> String -> *
* @param {Object} childDuckOptions A set of options from which a duck can be built
* @param {Object} parentDuck A duck that has already been built and whose original constructor options will be re-invoked
* @param {String} key A key name from which to match child options to parent (same prop for both)
* @returns {Function} A function that takes the name of a prop on a duck, and
* will merge the parent and child together for that prop
*/
export var createOptionsExtender = _default(function (childDuckOptions, _ref, key) {
var parentOptions = _ref.options;
return _default2([
/* If the key at the child or parent is a function */
[_default3(_default4(_default5(Function)), _default6(_default7(key)), _default8(parentOptions)),
/**
* then they both need to be invoked
* (coerced to fn, if not already)
* and then their results are merged
*/
_default9(_default10(_default11(simpleMergeStrategy), [coerceToFn(parentOptions[key]), _default10(coerceToFn(childDuckOptions[key]), [_default12, coerceToFn(parentOptions[key])])]))],
/* If the child doesn't have anything at that key, just return from the parent */
[_default3(_default13, _default7(key)), _default9(parentOptions[key])],
/* Otherwise, simply merge the parent and child together at that key */
[_default14, _default3(_default11(simpleMergeStrategy, parentOptions[key]), _default7(key))]])(childDuckOptions);
});
/**
* Merges the reducer from an existing duck with a reducer inside of a set of configuration options (for a new duck).
* If a reducer doesn't exist in both sources, no merging is needed, otherwise the merged reducer
* will always invoke the parent's reducer and feed that result into the child's reducer as its 'state' argument.
* This way a chain of reducers will always be executed.
*
* @func
* @sig {k: v} -> {k: v} -> {k: v}
* @param {Object} duck An existing duck, which contains its original
* configuration options at its 'options' prop.
* @param {Object} options A set of configuration options for a new duck
* @returns {Object} A reducer function which is either a chain of reducers (parent first, then child)
* or one of the reducers (if a reducer wasn't present in both sets of config options)
*/
export var extendReducer = function extendReducer(_ref2) {
var parentOptions = _ref2.options;
return _default3(_default15(_default16(_default17('reducer')), _default3(makeExtendedReducer(parentOptions), _default18), _default3(_default19(_default17('reducer')), _default8(parentOptions))), _default8(parentOptions));
};
/**
* Merges a set of configuration options (for a new duck) with those of an
* existing duck (along with defaults for any unsupplied, but required values).
*
* @func
* @sig {k: v} -> {k: v} -> {k: v}
* @param {Object} duck An existing duck, which contains its original
* configuration options at its 'options' prop.
* @param {Object} options A set of configuration options for a new duck
* @returns {Object} A set of configuration options where schema defaults are
* merged with the existing duck's configuration options and the new
* (to-be-built) duck's configuration options
*/
export var extendOptionsForDuck = function extendOptionsForDuck(duck) {
return _default3(_default10(_default21, [_default12, _default3(_default22('reducer'), extendReducer(duck))]), _default23(_default21, {}), _default24([duxDefaults, duck.options]), _default20, _default25(duck), coerceToFn);
};
/**
* Applies a set of evolvers, which are just transformations that are run against a given prop inside of an object.
* In this case the config options for a new duck are transformed and then
* those are merged with the same prop(s) inside of the config 'options' of the existing duck.
*
* @func
* @sig [[k: (a -> b)] -> {k: v} -> {k: v} -> {k: v}
* @param {Array} evolvers An array of arrays (which are key/value pairs whose
* key is a prop name on an options object and whose value is a function to
* execute against the corresponding value on the options object)
* @param {Object} duck An existing duck, which contains its original
* configuration options at its 'options' prop.
* @param {Object} options A set of configuration options for a new duck
* @returns {Object} The options from the original duck extended with the
* configuration options for a new (to-be-built) duck, according to the
* transformations defined in the evolvers.
*/
export var createExtendedOptions = _default(function (evolvers, duck, options) {
return _default3(_default21(options), _default26, _default18, _default27(function (mergedDuck, _ref3) {
var key = _ref3[0],
builder = _ref3[1];
var option = _default3(_default22(key), _default28(_default5(Function), _default25(key)), builder)(mergedDuck);
return [_default21(mergedDuck, option), option];
}, duck))(evolvers);
});
/**
* Takes an already built duck and the options for building a new one and
* extends the new options onto the options and simple props of the already built duck.
* The combined object can be passed as options when creating a new duck.
*
* @func
* @sig {k: v} -> {k: v} -> {k: v}
* @param {Object} duck An existing duck from which a new duck will be based
* @param {Object} options A set of options to be merged with those of an
* existing duck (to be used together whenn creating a new duck)
* @returns {Object} a merged set of options to be fed into a new duck
*/
export var createDuckExtender = function createDuckExtender(duck) {
var extendOptions = extendOptionsForDuck(duck);
return function (options) {
var childOptions = extendOptions(options);
var optionBuilders = [['consts', _default3(_default11(concatOrReplace, _default29, childOptions.consts), _default30(['options', 'consts']))], ['types', _default3(_default31, _default24(childOptions.types), _default30(['options', 'types']))], ['initialState', createOptionsExtender(childOptions)], ['machines', createOptionsExtender(childOptions)], ['creators', createOptionsExtender(childOptions)], ['selectors', createOptionsExtender(childOptions)], ['queries', createOptionsExtender(childOptions)], ['enhancers', createOptionsExtender(childOptions)], ['multipliers', createOptionsExtender(childOptions)], ['throttling', createOptionsExtender(childOptions)], ['debouncing', createOptionsExtender(childOptions)], ['effects', createOptionsExtender(childOptions)], ['validators', createOptionsExtender(childOptions)], ['workers', createOptionsExtender(childOptions)]];
return createExtendedOptions(optionBuilders, duck, childOptions);
};
};