chain-able
Version:
interfaces that describe their intentions.
94 lines (86 loc) • 8.03 kB
JavaScript
var isUndefined = require('../deps/is/undefined')
var Chainable = require('../Chainable')
var ChainedMap = require('../ChainedMap')
var Observe = require('./Observe')
var Shorthands = require('./Shorthands')
var Transform = require('./Transform')
var DotProp = require('./DotProp')
var ComposableExtensions = [Observe, Shorthands, Transform, DotProp]
/**
* @desc compose chains all the way up from Chainable
* @since 3.0.0
*
* @param {Class | Function | undefined} [target=ChainedMap] class or function to extend
* @param {Array | undefined} [extensions=[Observe, Shorthands, Transform, DotProp]] Array of extensions to compose together left ro right
* @return {Class | Function} composed
*
* @tutorial examples/playground/compose
* @tutorial examples/babel/decorators
*
* @func compose
* @member compose
* @tests compose
* @types compose
* @symb 🎼
*
* @see https://formidable.com/blog/2017/infinite-state-composition-with-freactal/
* @see https://blog.javascripting.com/2016/02/02/encapsulation-in-redux/
* @see https://www.barbarianmeetscoding.com/blog/2016/01/04/safer-javascript-object-composition-with-traits-and-traits-dot-js/
* @see https://medium.com/javascript-scene/why-learn-functional-programming-in-javascript-composing-software-ea13afc7a257
* @see https://hackernoon.com/javascript-functional-composition-for-every-day-use-22421ef65a10
* @see https://github.com/stoeffel/awesome-fp-js
*
* @example
*
* class Eh extends compose() {}
* new Eh() instanceof Chainable
* //=> true
*
* @example
*
* class Target {}
* class Eh extends compose(Target) {}
* new Eh() instanceof Target
* //=> true
*
* @example
*
* class Target {}
* const mixin = SuperClass => class extends SuperClass {}
* class Eh extends compose(Target, ) {}
* new Eh() instanceof Chainable
* //=> true
*
* @example
*
* class Winning {}
* class Yes extends compose(Winning) {
* get winning() {
* return true
* }
* }
* const yes = new Yes()
* yes instanceof Winning && yes.winning
* //=> true
*
*/
function compose(target, extensions) {
var extend = isUndefined(extensions) ? ComposableExtensions : extensions
var composed = target
if (target && target instanceof Object) {
composed = ChainedMap.compose(Chainable.compose(target))
}
else {
composed = ChainedMap
}
for (var index = 0; index < extend.length; index++) {
composed = extend[index](composed) || composed || ChainedMap
}
return composed
}
compose.Observe = Observe
compose.Shorthands = Shorthands
compose.Transform = Transform
compose.DotProp = DotProp
module.exports = compose
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9zZS5qcyIsInNvdXJjZXMiOlsiY29tcG9zZS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBpc1VuZGVmaW5lZCA9IHJlcXVpcmUoJy4uL2RlcHMvaXMvdW5kZWZpbmVkJylcbmNvbnN0IENoYWluYWJsZSA9IHJlcXVpcmUoJy4uL0NoYWluYWJsZScpXG5jb25zdCBDaGFpbmVkTWFwID0gcmVxdWlyZSgnLi4vQ2hhaW5lZE1hcCcpXG5jb25zdCBPYnNlcnZlID0gcmVxdWlyZSgnLi9PYnNlcnZlJylcbmNvbnN0IFNob3J0aGFuZHMgPSByZXF1aXJlKCcuL1Nob3J0aGFuZHMnKVxuY29uc3QgVHJhbnNmb3JtID0gcmVxdWlyZSgnLi9UcmFuc2Zvcm0nKVxuY29uc3QgRG90UHJvcCA9IHJlcXVpcmUoJy4vRG90UHJvcCcpXG5cbmNvbnN0IENvbXBvc2FibGVFeHRlbnNpb25zID0gW09ic2VydmUsIFNob3J0aGFuZHMsIFRyYW5zZm9ybSwgRG90UHJvcF1cblxuLyoqXG4gKiBAZGVzYyBjb21wb3NlIGNoYWlucyBhbGwgdGhlIHdheSB1cCBmcm9tIENoYWluYWJsZVxuICogQHNpbmNlIDMuMC4wXG4gKlxuICogQHBhcmFtICB7Q2xhc3MgfCBGdW5jdGlvbiB8IHVuZGVmaW5lZH0gW3RhcmdldD1DaGFpbmVkTWFwXSBjbGFzcyBvciBmdW5jdGlvbiB0byBleHRlbmRcbiAqIEBwYXJhbSAge0FycmF5IHwgdW5kZWZpbmVkfSBbZXh0ZW5zaW9ucz1bT2JzZXJ2ZSwgU2hvcnRoYW5kcywgVHJhbnNmb3JtLCBEb3RQcm9wXV0gQXJyYXkgb2YgZXh0ZW5zaW9ucyB0byBjb21wb3NlIHRvZ2V0aGVyIGxlZnQgcm8gcmlnaHRcbiAqIEByZXR1cm4ge0NsYXNzIHwgRnVuY3Rpb259IGNvbXBvc2VkXG4gKlxuICogQHR1dG9yaWFsIGV4YW1wbGVzL3BsYXlncm91bmQvY29tcG9zZVxuICogQHR1dG9yaWFsIGV4YW1wbGVzL2JhYmVsL2RlY29yYXRvcnNcbiAqXG4gKiBAZnVuYyBjb21wb3NlXG4gKiBAbWVtYmVyIGNvbXBvc2VcbiAqIEB0ZXN0cyBjb21wb3NlXG4gKiBAdHlwZXMgY29tcG9zZVxuICogQHN5bWIg8J+OvFxuICpcbiAqIEBzZWUgaHR0cHM6Ly9mb3JtaWRhYmxlLmNvbS9ibG9nLzIwMTcvaW5maW5pdGUtc3RhdGUtY29tcG9zaXRpb24td2l0aC1mcmVhY3RhbC9cbiAqIEBzZWUgaHR0cHM6Ly9ibG9nLmphdmFzY3JpcHRpbmcuY29tLzIwMTYvMDIvMDIvZW5jYXBzdWxhdGlvbi1pbi1yZWR1eC9cbiAqIEBzZWUgaHR0cHM6Ly93d3cuYmFyYmFyaWFubWVldHNjb2RpbmcuY29tL2Jsb2cvMjAxNi8wMS8wNC9zYWZlci1qYXZhc2NyaXB0LW9iamVjdC1jb21wb3NpdGlvbi13aXRoLXRyYWl0cy1hbmQtdHJhaXRzLWRvdC1qcy9cbiAqIEBzZWUgaHR0cHM6Ly9tZWRpdW0uY29tL2phdmFzY3JpcHQtc2NlbmUvd2h5LWxlYXJuLWZ1bmN0aW9uYWwtcHJvZ3JhbW1pbmctaW4tamF2YXNjcmlwdC1jb21wb3Npbmctc29mdHdhcmUtZWExM2FmYzdhMjU3XG4gKiBAc2VlIGh0dHBzOi8vaGFja2Vybm9vbi5jb20vamF2YXNjcmlwdC1mdW5jdGlvbmFsLWNvbXBvc2l0aW9uLWZvci1ldmVyeS1kYXktdXNlLTIyNDIxZWY2NWExMFxuICogQHNlZSBodHRwczovL2dpdGh1Yi5jb20vc3RvZWZmZWwvYXdlc29tZS1mcC1qc1xuICpcbiAqIEBleGFtcGxlXG4gKlxuICogIGNsYXNzIEVoIGV4dGVuZHMgY29tcG9zZSgpIHt9XG4gKiAgbmV3IEVoKCkgaW5zdGFuY2VvZiBDaGFpbmFibGVcbiAqICAvLz0+IHRydWVcbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqICBjbGFzcyBUYXJnZXQge31cbiAqICBjbGFzcyBFaCBleHRlbmRzIGNvbXBvc2UoVGFyZ2V0KSB7fVxuICogIG5ldyBFaCgpIGluc3RhbmNlb2YgVGFyZ2V0XG4gKiAgLy89PiB0cnVlXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiAgY2xhc3MgVGFyZ2V0IHt9XG4gKiAgY29uc3QgbWl4aW4gPSBTdXBlckNsYXNzID0+IGNsYXNzIGV4dGVuZHMgU3VwZXJDbGFzcyB7fVxuICogIGNsYXNzIEVoIGV4dGVuZHMgY29tcG9zZShUYXJnZXQsICkge31cbiAqICBuZXcgRWgoKSBpbnN0YW5jZW9mIENoYWluYWJsZVxuICogIC8vPT4gdHJ1ZVxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogICAgY2xhc3MgV2lubmluZyB7fVxuICogICAgY2xhc3MgWWVzIGV4dGVuZHMgY29tcG9zZShXaW5uaW5nKSB7XG4gKiAgICAgIGdldCB3aW5uaW5nKCkge1xuICogICAgICAgIHJldHVybiB0cnVlXG4gKiAgICAgIH1cbiAqICAgIH1cbiAqICAgIGNvbnN0IHllcyA9IG5ldyBZZXMoKVxuICogICAgeWVzIGluc3RhbmNlb2YgV2lubmluZyAmJiB5ZXMud2lubmluZ1xuICogICAgLy89PiB0cnVlXG4gKlxuICovXG5mdW5jdGlvbiBjb21wb3NlKHRhcmdldCwgZXh0ZW5zaW9ucykge1xuICBsZXQgZXh0ZW5kID0gaXNVbmRlZmluZWQoZXh0ZW5zaW9ucykgPyBDb21wb3NhYmxlRXh0ZW5zaW9ucyA6IGV4dGVuc2lvbnNcbiAgbGV0IGNvbXBvc2VkID0gdGFyZ2V0XG5cbiAgaWYgKHRhcmdldCAmJiB0YXJnZXQgaW5zdGFuY2VvZiBPYmplY3QpIHtcbiAgICBjb21wb3NlZCA9IENoYWluZWRNYXAuY29tcG9zZShDaGFpbmFibGUuY29tcG9zZSh0YXJnZXQpKVxuICB9XG4gIGVsc2Uge1xuICAgIGNvbXBvc2VkID0gQ2hhaW5lZE1hcFxuICB9XG5cbiAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGV4dGVuZC5sZW5ndGg7IGluZGV4KyspIHtcbiAgICBjb21wb3NlZCA9IGV4dGVuZFtpbmRleF0oY29tcG9zZWQpIHx8IGNvbXBvc2VkIHx8IENoYWluZWRNYXBcbiAgfVxuXG4gIHJldHVybiBjb21wb3NlZFxufVxuXG5jb21wb3NlLk9ic2VydmUgPSBPYnNlcnZlXG5jb21wb3NlLlNob3J0aGFuZHMgPSBTaG9ydGhhbmRzXG5jb21wb3NlLlRyYW5zZm9ybSA9IFRyYW5zZm9ybVxuY29tcG9zZS5Eb3RQcm9wID0gRG90UHJvcFxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbXBvc2VcbiJdLCJuYW1lcyI6WyJjb25zdCIsImxldCJdLCJtYXBwaW5ncyI6IkFBQUFBLEdBQUssQ0FBQyxXQUFXLEdBQUcsT0FBTyxDQUFDLHNCQUFzQixDQUFDO0FBQ25EQSxHQUFLLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQyxjQUFjLENBQUM7QUFDekNBLEdBQUssQ0FBQyxVQUFVLEdBQUcsT0FBTyxDQUFDLGVBQWUsQ0FBQztBQUMzQ0EsR0FBSyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDO0FBQ3BDQSxHQUFLLENBQUMsVUFBVSxHQUFHLE9BQU8sQ0FBQyxjQUFjLENBQUM7QUFDMUNBLEdBQUssQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQztBQUN4Q0EsR0FBSyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDOztBQUVwQ0EsR0FBSyxDQUFDLG9CQUFvQixHQUFHLENBQUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsT0FBTyxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUE0RHRFLFNBQVMsT0FBTyxDQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUU7RUFDbkNDLEdBQUcsQ0FBQyxNQUFNLEdBQUcsV0FBVyxDQUFDLFVBQVUsQ0FBQyxHQUFHLG9CQUFvQixHQUFHLFVBQVU7RUFDeEVBLEdBQUcsQ0FBQyxRQUFRLEdBQUcsTUFBTTs7RUFFckIsSUFBSSxNQUFNLElBQUksTUFBTSxZQUFZLE1BQU0sRUFBRTtJQUN0QyxRQUFRLEdBQUcsVUFBVSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0dBQ3pEO09BQ0k7SUFDSCxRQUFRLEdBQUcsVUFBVTtHQUN0Qjs7RUFFRCxLQUFLQSxHQUFHLENBQUMsS0FBSyxHQUFHLENBQUMsRUFBRSxLQUFLLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsRUFBRTtJQUNsRCxRQUFRLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLFFBQVEsSUFBSSxVQUFVO0dBQzdEOztFQUVELE9BQU8sUUFBUTtDQUNoQjs7QUFFRCxPQUFPLENBQUMsT0FBTyxHQUFHLE9BQU87QUFDekIsT0FBTyxDQUFDLFVBQVUsR0FBRyxVQUFVO0FBQy9CLE9BQU8sQ0FBQyxTQUFTLEdBQUcsU0FBUztBQUM3QixPQUFPLENBQUMsT0FBTyxHQUFHLE9BQU87O0FBRXpCLE1BQU0sQ0FBQyxPQUFPLEdBQUcsT0FBTzsifQ==