@@ -8,13 +8,29 @@ import { AbortController } from '@solana/event-target-impl';
8
8
import { DataPublisher } from './data-publisher' ;
9
9
10
10
type Config = Readonly < {
11
+ /**
12
+ * Triggering this abort signal will cause all iterators spawned from this iterator to return
13
+ * once they have published all queued messages.
14
+ */
11
15
abortSignal : AbortSignal ;
16
+ /**
17
+ * Messages from this channel of `dataPublisher` will be the ones yielded through the iterators.
18
+ *
19
+ * Messages only begin to be queued after the first time an iterator begins to poll. Channel
20
+ * messages published before that time will be dropped.
21
+ */
12
22
dataChannelName : string ;
13
23
// FIXME: It would be nice to be able to constrain the type of `dataPublisher` to one that
14
24
// definitely supports the `dataChannelName` and `errorChannelName` channels, and
15
25
// furthermore publishes `TData` on the `dataChannelName` channel. This is more difficult
16
26
// than it should be: https://tsplay.dev/NlZelW
17
27
dataPublisher : DataPublisher ;
28
+ /**
29
+ * Messages from this channel of `dataPublisher` will be the ones thrown through the iterators.
30
+ *
31
+ * Any new iterators created after the first error is encountered will reject with that error
32
+ * when polled.
33
+ */
18
34
errorChannelName : string ;
19
35
} > ;
20
36
@@ -58,6 +74,48 @@ function createExplicitAbortToken() {
58
74
59
75
const UNINITIALIZED = Symbol ( ) ;
60
76
77
+ /**
78
+ * Returns an `AsyncIterable` given a data publisher.
79
+ *
80
+ * The iterable will produce iterators that vend messages published to `dataChannelName` and will
81
+ * throw the first time a message is published to `errorChannelName`. Triggering the abort signal
82
+ * will cause all iterators spawned from this iterator to return once they have published all queued
83
+ * messages.
84
+ *
85
+ * Things to note:
86
+ *
87
+ * - If a message is published over a channel before the `AsyncIterator` attached to it has polled
88
+ * for the next result, the message will be queued in memory.
89
+ * - Messages only begin to be queued after the first time an iterator begins to poll. Channel
90
+ * messages published before that time will be dropped.
91
+ * - If there are messages in the queue and an error occurs, all queued messages will be vended to
92
+ * the iterator before the error is thrown.
93
+ * - If there are messages in the queue and the abort signal fires, all queued messages will be
94
+ * vended to the iterator after which it will return.
95
+ * - Any new iterators created after the first error is encountered will reject with that error when
96
+ * polled.
97
+ *
98
+ * @param config
99
+ *
100
+ * @example
101
+ * ```ts
102
+ * const iterable = createAsyncIterableFromDataPublisher({
103
+ * abortSignal: AbortSignal.timeout(10_000),
104
+ * dataChannelName: 'message',
105
+ * dataPublisher,
106
+ * errorChannelName: 'error',
107
+ * });
108
+ * try {
109
+ * for await (const message of iterable) {
110
+ * console.log('Got message', message);
111
+ * }
112
+ * } catch (e) {
113
+ * console.error('An error was published to the error channel', e);
114
+ * } finally {
115
+ * console.log("It's been 10 seconds; that's enough for now.");
116
+ * }
117
+ * ```
118
+ */
61
119
export function createAsyncIterableFromDataPublisher < TData > ( {
62
120
abortSignal,
63
121
dataChannelName,
0 commit comments