UNPKG

2.42 kBJavaScriptView Raw
1import LodashWrapper from './_LodashWrapper';
2import baseFlatten from './_baseFlatten';
3import getData from './_getData';
4import getFuncName from './_getFuncName';
5import isArray from './isArray';
6import isLaziable from './_isLaziable';
7import rest from './rest';
8
9/** Used as the size to enable large array optimizations. */
10var LARGE_ARRAY_SIZE = 200;
11
12/** Used as the `TypeError` message for "Functions" methods. */
13var FUNC_ERROR_TEXT = 'Expected a function';
14
15/** Used to compose bitmasks for wrapper metadata. */
16var CURRY_FLAG = 8,
17 PARTIAL_FLAG = 32,
18 ARY_FLAG = 128,
19 REARG_FLAG = 256;
20
21/**
22 * Creates a `_.flow` or `_.flowRight` function.
23 *
24 * @private
25 * @param {boolean} [fromRight] Specify iterating from right to left.
26 * @returns {Function} Returns the new flow function.
27 */
28function createFlow(fromRight) {
29 return rest(function(funcs) {
30 funcs = baseFlatten(funcs, 1);
31
32 var length = funcs.length,
33 index = length,
34 prereq = LodashWrapper.prototype.thru;
35
36 if (fromRight) {
37 funcs.reverse();
38 }
39 while (index--) {
40 var func = funcs[index];
41 if (typeof func != 'function') {
42 throw new TypeError(FUNC_ERROR_TEXT);
43 }
44 if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
45 var wrapper = new LodashWrapper([], true);
46 }
47 }
48 index = wrapper ? index : length;
49 while (++index < length) {
50 func = funcs[index];
51
52 var funcName = getFuncName(func),
53 data = funcName == 'wrapper' ? getData(func) : undefined;
54
55 if (data && isLaziable(data[0]) &&
56 data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) &&
57 !data[4].length && data[9] == 1
58 ) {
59 wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
60 } else {
61 wrapper = (func.length == 1 && isLaziable(func))
62 ? wrapper[funcName]()
63 : wrapper.thru(func);
64 }
65 }
66 return function() {
67 var args = arguments,
68 value = args[0];
69
70 if (wrapper && args.length == 1 &&
71 isArray(value) && value.length >= LARGE_ARRAY_SIZE) {
72 return wrapper.plant(value).value();
73 }
74 var index = 0,
75 result = length ? funcs[index].apply(this, args) : value;
76
77 while (++index < length) {
78 result = funcs[index].call(this, result);
79 }
80 return result;
81 };
82 });
83}
84
85export default createFlow;