| var LodashWrapper = require('./_LodashWrapper'), |
| flatRest = require('./_flatRest'), |
| getData = require('./_getData'), |
| getFuncName = require('./_getFuncName'), |
| isArray = require('./isArray'), |
| isLaziable = require('./_isLaziable'); |
| |
| /** Error message constants. */ |
| var FUNC_ERROR_TEXT = 'Expected a function'; |
| |
| /** Used to compose bitmasks for function metadata. */ |
| var WRAP_CURRY_FLAG = 8, |
| WRAP_PARTIAL_FLAG = 32, |
| WRAP_ARY_FLAG = 128, |
| 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 flatRest(function(funcs) { |
| var length = funcs.length, |
| index = length, |
| prereq = LodashWrapper.prototype.thru; |
| |
| if (fromRight) { |
| funcs.reverse(); |
| } |
| while (index--) { |
| var func = funcs[index]; |
| if (typeof func != 'function') { |
| throw new TypeError(FUNC_ERROR_TEXT); |
| } |
| if (prereq && !wrapper && getFuncName(func) == 'wrapper') { |
| var wrapper = new LodashWrapper([], true); |
| } |
| } |
| index = wrapper ? index : length; |
| while (++index < length) { |
| func = funcs[index]; |
| |
| var funcName = getFuncName(func), |
| 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])].apply(wrapper, data[3]); |
| } else { |
| wrapper = (func.length == 1 && isLaziable(func)) |
| ? wrapper[funcName]() |
| : wrapper.thru(func); |
| } |
| } |
| return function() { |
| var args = arguments, |
| value = args[0]; |
| |
| if (wrapper && args.length == 1 && isArray(value)) { |
| return wrapper.plant(value).value(); |
| } |
| var index = 0, |
| result = length ? funcs[index].apply(this, args) : value; |
| |
| while (++index < length) { |
| result = funcs[index].call(this, result); |
| } |
| return result; |
| }; |
| }); |
| } |
| |
| module.exports = createFlow; |