_createFlow.js 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. var LodashWrapper = require('./_LodashWrapper'),
  2. flatRest = require('./_flatRest'),
  3. getData = require('./_getData'),
  4. getFuncName = require('./_getFuncName'),
  5. isArray = require('./isArray'),
  6. isLaziable = require('./_isLaziable');
  7. /** Error message constants. */
  8. var FUNC_ERROR_TEXT = 'Expected a function';
  9. /** Used to compose bitmasks for function metadata. */
  10. var WRAP_CURRY_FLAG = 8,
  11. WRAP_PARTIAL_FLAG = 32,
  12. WRAP_ARY_FLAG = 128,
  13. WRAP_REARG_FLAG = 256;
  14. /**
  15. * Creates a `_.flow` or `_.flowRight` function.
  16. *
  17. * @private
  18. * @param {boolean} [fromRight] Specify iterating from right to left.
  19. * @returns {Function} Returns the new flow function.
  20. */
  21. function createFlow(fromRight) {
  22. return flatRest(function(funcs) {
  23. var length = funcs.length,
  24. index = length,
  25. prereq = LodashWrapper.prototype.thru;
  26. if (fromRight) {
  27. funcs.reverse();
  28. }
  29. while (index--) {
  30. var func = funcs[index];
  31. if (typeof func != 'function') {
  32. throw new TypeError(FUNC_ERROR_TEXT);
  33. }
  34. if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
  35. var wrapper = new LodashWrapper([], true);
  36. }
  37. }
  38. index = wrapper ? index : length;
  39. while (++index < length) {
  40. func = funcs[index];
  41. var funcName = getFuncName(func),
  42. data = funcName == 'wrapper' ? getData(func) : undefined;
  43. if (data && isLaziable(data[0]) &&
  44. data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&
  45. !data[4].length && data[9] == 1
  46. ) {
  47. wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
  48. } else {
  49. wrapper = (func.length == 1 && isLaziable(func))
  50. ? wrapper[funcName]()
  51. : wrapper.thru(func);
  52. }
  53. }
  54. return function() {
  55. var args = arguments,
  56. value = args[0];
  57. if (wrapper && args.length == 1 && isArray(value)) {
  58. return wrapper.plant(value).value();
  59. }
  60. var index = 0,
  61. result = length ? funcs[index].apply(this, args) : value;
  62. while (++index < length) {
  63. result = funcs[index].call(this, result);
  64. }
  65. return result;
  66. };
  67. });
  68. }
  69. module.exports = createFlow;