asFun.js 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. 'use strict';
  2. const {none, Final, Many} = require('../defs');
  3. const next = async (value, fns, index, push) => {
  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 === none) break;
  10. if (value instanceof Final) {
  11. value !== none && push(value.value);
  12. break;
  13. }
  14. if (value instanceof Many) {
  15. const values = value.values;
  16. if (i == fns.length) {
  17. values.forEach(val => push(val));
  18. } else {
  19. for (let j = 0; j < values.length; ++j) {
  20. await next(values[j], fns, i, push);
  21. }
  22. }
  23. break;
  24. }
  25. if (value && typeof value.next == 'function') {
  26. // generator
  27. for (;;) {
  28. let data = value.next();
  29. if (data && typeof data.then == 'function') {
  30. data = await data;
  31. }
  32. if (data.done) break;
  33. if (i == fns.length) {
  34. push(data.value);
  35. } else {
  36. await next(data.value, fns, i, push);
  37. }
  38. }
  39. break;
  40. }
  41. if (i == fns.length) {
  42. push(value);
  43. break;
  44. }
  45. value = fns[i](value);
  46. }
  47. };
  48. const nop = () => {};
  49. const asFun = (...fns) => {
  50. fns = fns.filter(fn => fn);
  51. if (!fns.length) return nop;
  52. return async value => {
  53. const results = [];
  54. await next(value, fns, 0, value => results.push(value));
  55. switch (results.length) {
  56. case 0:
  57. return none;
  58. case 1:
  59. return results[0];
  60. }
  61. return new Many(results);
  62. };
  63. };
  64. asFun.next = next;
  65. asFun.none = none;
  66. asFun.Final = Final;
  67. asFun.Many = Many;
  68. module.exports = asFun;