asGen.js 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. 'use strict';
  2. const {none, Final, Many} = 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 (value instanceof Final) {
  11. if (value !== none) yield value;
  12. break;
  13. }
  14. if (value instanceof Many) {
  15. const values = value.values;
  16. if (i == fns.length) {
  17. for (let j = 0; j < values.length; ++j) {
  18. yield values[j];
  19. }
  20. } else {
  21. for (let j = 0; j < values.length; ++j) {
  22. yield* next(values[j], fns, i);
  23. }
  24. }
  25. break;
  26. }
  27. if (value && typeof value.next == 'function') {
  28. // generator
  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. if (i == fns.length) {
  36. yield data.value;
  37. } else {
  38. yield* next(data.value, fns, i);
  39. }
  40. }
  41. break;
  42. }
  43. if (i == fns.length) {
  44. yield value;
  45. break;
  46. }
  47. value = fns[i](value);
  48. }
  49. };
  50. const nop = async function*() {};
  51. const asGen = (...fns) => {
  52. fns = fns.filter(fn => fn);
  53. if (!fns.length) return nop;
  54. return async function*(value) {
  55. yield* next(value, fns, 0);
  56. };
  57. };
  58. asGen.next = next;
  59. asGen.none = none;
  60. asGen.Final = Final;
  61. asGen.Many = Many;
  62. module.exports = asGen;