Files
lodash/_createFlow.js
2017-01-09 16:03:54 -08:00

80 lines
2.2 KiB
JavaScript

import LodashWrapper from './_LodashWrapper.js';
import getData from './_getData.js';
import getFuncName from './_getFuncName.js';
import isArray from './isArray.js';
import isLaziable from './_isLaziable.js';
/** Error message constants. */
const FUNC_ERROR_TEXT = 'Expected a function';
/** Used to compose bitmasks for function metadata. */
const WRAP_CURRY_FLAG = 8;
const WRAP_PARTIAL_FLAG = 32;
const WRAP_ARY_FLAG = 128;
const WRAP_REARG_FLAG = 256;
/**
* Creates a `_.flow` or `_.flowRight` function.
*
* @private
* @param {boolean} [fromRight] Specify iterating from right to left.
* @returns {Function} Returns the new flow function.
*/
function createFlow(fromRight) {
return (...funcs) => {
const length = funcs.length;
const prereq = LodashWrapper.prototype.thru;
let func;
let wrapper;
let index = length;
if (fromRight) {
funcs.reverse();
}
while (index--) {
func = funcs[index];
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
wrapper = new LodashWrapper([], true);
}
}
index = wrapper ? index : length;
while (++index < length) {
func = funcs[index];
const funcName = getFuncName(func);
const data = funcName == 'wrapper' ? getData(func) : undefined;
if (data && isLaziable(data[0]) &&
data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&
!data[4].length && data[9] == 1
) {
wrapper = wrapper[getFuncName(data[0])](...data[3]);
} else {
wrapper = (func.length == 1 && isLaziable(func))
? wrapper[funcName]()
: wrapper.thru(func);
}
}
return function() {
const args = arguments;
const value = args[0];
if (wrapper && args.length == 1 && isArray(value)) {
return wrapper.plant(value).value();
}
let index = 0, result = length ? funcs[index].apply(this, args) : value;
while (++index < length) {
result = funcs[index].call(this, result);
}
return result;
};
};
}
export default createFlow;