|
| 1 | +import { Multicast } from './generators.js'; |
1 | 2 |
|
2 | 3 | export function use(asyncSource, ...args) {
|
3 |
| - const [transforms, options] = processArguments(args); |
| 4 | + const [channels, options] = getArguments(args); |
4 | 5 | const type = typeof asyncSource;
|
5 | 6 |
|
6 | 7 | switch(true) {
|
7 | 8 | case asyncSource instanceof Promise:
|
8 |
| - return transforms.length < 2 |
9 |
| - ? [fromPromise(asyncSource, transforms[0], options)] |
10 |
| - : branchPromise(asyncSource, transforms, options); |
| 9 | + return channels.length < 2 |
| 10 | + ? [fromPromise(asyncSource, channels[0], options)] |
| 11 | + : branchPromise(asyncSource, channels, options); |
| 12 | + case !!asyncSource[Symbol.asyncIterator]: |
| 13 | + return channels.length < 2 |
| 14 | + ? [fromAsyncIterator(asyncSource, channels[0], options)] |
| 15 | + : branchAsyncIterator(asyncSource, channels, options); |
11 | 16 | default:
|
12 | 17 | throwAsyncSourceTypeError(type);
|
13 | 18 | }
|
14 | 19 | }
|
15 | 20 |
|
16 |
| -function fromPromise(promise, transform, options) { |
| 21 | +function getArguments(channels) { |
| 22 | + let options = null; |
| 23 | + if(channels.length) { |
| 24 | + const maybeOptions = channels.at(-1); |
| 25 | + if(typeof maybeOptions === 'object') { |
| 26 | + options = maybeOptions; |
| 27 | + channels.length--; |
| 28 | + } |
| 29 | + } |
| 30 | + return [channels, options]; |
| 31 | +} |
| 32 | + |
| 33 | +function fromPromise(promise, channel, options) { |
17 | 34 | const startWith = options?.startWith;
|
18 | 35 | if(startWith) {
|
19 |
| - return fromPromiseStartWith(promise, transform, startWith); |
| 36 | + return fromPromiseStartWith(promise, channel, startWith); |
| 37 | + } |
| 38 | + return [channel ? promise.then(channel) : promise]; |
| 39 | +} |
| 40 | + |
| 41 | +async function* fromPromiseStartWith(promise, channel, startWith) { |
| 42 | + yield startWith; |
| 43 | + yield channel ? promise.then(channel) : promise; |
| 44 | +} |
| 45 | + |
| 46 | +async function* fromAsyncIterator(iterator, channel, options) { |
| 47 | + const startWith = options?.startWith; |
| 48 | + if(startWith) yield startWith; |
| 49 | + for await(const value of iterator) { |
| 50 | + yield channel ? channel(value) : value; |
20 | 51 | }
|
21 |
| - return [transform ? promise.then(transform) : promise]; |
22 | 52 | }
|
23 | 53 |
|
24 |
| -function branchPromise(promise, transforms) { |
25 |
| - return transforms.map(transform => { |
26 |
| - if(Array.isArray(transform)) { // [transform, options] |
27 |
| - return fromPromise(promise, transform[0], transform[1]); |
| 54 | +function branchPromise(promise, channels) { |
| 55 | + return channels.map(channel => { |
| 56 | + if(Array.isArray(channel)) { // [channel, options] |
| 57 | + return fromPromise(promise, channel[0], channel[1]); |
28 | 58 | }
|
29 |
| - return promise.then(transform); |
| 59 | + return promise.then(channel); |
30 | 60 | });
|
31 | 61 | }
|
32 | 62 |
|
33 |
| -async function* fromPromiseStartWith(promise, transform, startWith) { |
34 |
| - yield startWith; |
35 |
| - yield transform ? promise.then(transform) : promise; |
| 63 | +function branchAsyncIterator(iterator, channels, options) { |
| 64 | + const multicast = new Multicast(iterator); |
| 65 | + return channels.map(channel => { |
| 66 | + if(Array.isArray(channel)) { // [channel, options] |
| 67 | + return multicast.subscriber(channel[0], channel[1]); |
| 68 | + } |
| 69 | + return multicast.subscriber(channel, options); |
| 70 | + }); |
36 | 71 | }
|
37 | 72 |
|
38 | 73 | function throwAsyncSourceTypeError(type) {
|
39 | 74 | throw new TypeError(`\
|
40 | 75 | Unexpected asynchronous data source type "${type}". Expected an async data provider type, or \
|
41 | 76 | a function that returns an async data provider type."`);
|
42 | 77 | }
|
43 |
| - |
44 |
| -function processArguments(transforms) { |
45 |
| - let options = null; |
46 |
| - if(transforms.length) { |
47 |
| - const maybeOptions = transforms.at(-1); |
48 |
| - if(typeof maybeOptions === 'object') { |
49 |
| - options = maybeOptions; |
50 |
| - transforms.length--; |
51 |
| - } |
52 |
| - } |
53 |
| - return [transforms, options]; |
54 |
| -} |
|
0 commit comments