to-fun
Version:
Advanced Left-To-Right Function Composer
78 lines (66 loc) • 2.59 kB
JavaScript
;
exports.__esModule = true;
var identity = function identity(x) {
return x;
};
var always = function always(x) {
return function () {
return x;
};
};
var isFunction = function isFunction(f) {
return !!(f && f.constructor && f.call && f.apply);
};
var isThenable = function isThenable(p) {
return typeof p.then === 'function';
};
var isSimple = function isSimple(x) {
return x === null || typeof x === 'string' || typeof x === 'number' || typeof x === 'boolean';
};
/**
* toFun: Universal Function Composer
*
* @param {...Function} A list of functionables
* @returns {Function} A composite function
*/
var toFun = function toFun() {
for (var _len = arguments.length, functionableList = Array(_len), _key = 0; _key < _len; _key++) {
functionableList[_key] = arguments[_key];
}
return composeList(functionableList);
};
var functionize = exports.functionize = function functionize(functionable) {
if (functionable === undefined) return identity;
if (isFunction(functionable)) return functionable;
if (Array.isArray(functionable)) return composeList(functionable);
if (isSimple(functionable)) return always(functionable);
return composeMap(functionable);
};
var composeMap = exports.composeMap = function composeMap() {
var functionableMap = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
return function () {
for (var _len2 = arguments.length, rest = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
rest[_key2 - 1] = arguments[_key2];
}
var input = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
return Object.keys(functionableMap).map(function (key) {
var _ref;
return _ref = {}, _ref[key] = functionize(functionableMap[key]).apply(undefined, [input[key]].concat(rest)), _ref;
}).reduce(function (fused, shard) {
return Object.assign(fused, shard);
}, Object.assign({}, input));
};
};
var composeList = exports.composeList = function composeList(functionableList) {
var first = functionableList[0],
rest = functionableList.slice(1);
return function () {
return rest.reduce(reducer, functionize(first).apply(undefined, arguments));
};
};
var reducer = exports.reducer = function reducer(previousResult, functionable) {
var f = functionize(functionable);
if (isThenable(previousResult)) return previousResult.then(f);
return f(previousResult);
};
exports['default'] = toFun;