asGen.js 1.7 KB

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