comp.js 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. 'use strict';
  2. const {Final, Many} = require('../index');
  3. const next = async (value, fns, index) => {
  4. for (let i = index; i <= fns.length; ++i) {
  5. if (value && typeof value.then == 'function') {
  6. // thenable
  7. value = await value;
  8. }
  9. if (value instanceof Final) {
  10. return value.value;
  11. }
  12. if (value instanceof Many) {
  13. if (i == fns.length) return value;
  14. const results = [],
  15. values = value.values;
  16. for (let j = 0; j < values.length; ++j) {
  17. const result = await next(values[j], fns, i);
  18. if (result instanceof Many) {
  19. results.push(...result.values);
  20. } else {
  21. results.push(result);
  22. }
  23. }
  24. return new Many(results);
  25. }
  26. if (value && typeof value.next == 'function') {
  27. // generator
  28. const results = [];
  29. for (;;) {
  30. let data = value.next();
  31. if (data && typeof data.then == 'function') {
  32. data = await data;
  33. }
  34. if (data.done) break;
  35. const result = await next(data.value, fns, i);
  36. if (result instanceof Many) {
  37. results.push(...result.values);
  38. } else {
  39. results.push(result);
  40. }
  41. }
  42. return new Many(results);
  43. }
  44. const fn = fns[i];
  45. if (!fn) break;
  46. value = fn(value);
  47. }
  48. return value;
  49. };
  50. const comp = (...fns) => {
  51. fns = fns.filter(fn => fn);
  52. if (!fns.length) return null;
  53. return async value => next(value, fns, 0);
  54. };
  55. module.exports = comp;