asGen.js 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  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. if (value !== none) yield getFinalValue(value);
  12. break;
  13. }
  14. if (isMany(value)) {
  15. const values = getManyValues(value);
  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.isFinal = isFinal;
  62. asGen.getFinalValue = getFinalValue;
  63. asGen.many = many;
  64. asGen.isMany = isMany;
  65. asGen.getManyValues = getManyValues;
  66. module.exports = asGen;