core/flow.js

  1. import { flatten } from 'util/array'
  2. import { isFunction } from 'util/lang'
  3. /**
  4. * A function successively calling a list of functions.
  5. * @callback flowFunction
  6. * @memberof core
  7. * @param {*} arg The starting value
  8. * @returns {*} The resulting value
  9. * @since 1.0.0
  10. */
  11. /**
  12. * Creates a function that will successively call all functions contained in <code>args</code>.<br/>
  13. * Each function is called with the result of the previous one.<br/>
  14. * Non functions <code>args</code> are tolerated and will be ignored.
  15. * @memberof core
  16. * @param {...(function|Array<function>)} args The functions to apply
  17. * @returns {core.flowFunction} A function successively calling function <code>args</code>
  18. * @since 1.0.0
  19. */
  20. function flow(...args) {
  21. const fns = flatten(args)
  22. .filter(fn => isFunction(fn))
  23. .map(fn => fn.applier === undefined ? (
  24. ([obj, appliedPaths]) => [fn(obj), appliedPaths]
  25. ) : (
  26. ([obj, appliedPaths]) => [
  27. fn.applier(obj, appliedPaths),
  28. [...appliedPaths, fn.applier.path],
  29. ]
  30. ))
  31. return obj => {
  32. const [result] = fns.reduce(
  33. (acc, fn) => fn(acc),
  34. [obj, []],
  35. )
  36. return result
  37. }
  38. }
  39. export { flow }