async-lube 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/README.md +1 -1
- package/docs/http.md +1 -1
- package/docs/reference.md +4 -2
- package/docs/tasks.md +19 -2
- package/package.json +4 -5
- package/public.d.ts +112 -0
- package/src/attempt.js +17 -7
- package/src/durable/context.js +107 -64
- package/src/durable/error.js +39 -15
- package/src/durable/index.js +18 -10
- package/src/durable/journal.js +29 -14
- package/src/durable/json.js +26 -9
- package/src/durable/lease.js +15 -5
- package/src/durable/persist.js +60 -22
- package/src/durable/run.js +103 -41
- package/src/durable/send.js +30 -13
- package/src/durable/serve.js +30 -24
- package/src/durable/state.js +28 -13
- package/src/durable/store.js +19 -10
- package/src/durable/watch.js +31 -11
- package/src/errors.js +9 -3
- package/src/flow/attempts.js +49 -29
- package/src/flow/builder.js +260 -161
- package/src/flow/compile.js +86 -66
- package/src/flow/graph.js +108 -42
- package/src/flow/index.js +13 -7
- package/src/flow/items.js +79 -46
- package/src/flow/nodes.js +267 -117
- package/src/flow/refs.js +27 -13
- package/src/flow/resources.js +9 -3
- package/src/flow/run.js +287 -114
- package/src/flow/streams.js +44 -19
- package/src/flow/subflows.js +93 -53
- package/src/http/config.js +11 -5
- package/src/http/index.js +25 -14
- package/src/http/refresh.js +29 -12
- package/src/http/request.js +246 -151
- package/src/http/response.js +105 -50
- package/src/http/retry.js +52 -27
- package/src/http/socket.js +220 -172
- package/src/http/sse.js +113 -74
- package/src/http/throttle.js +9 -4
- package/src/http/url.js +58 -35
- package/src/http/xhr.js +29 -24
- package/src/index.js +1 -0
- package/src/key.js +3 -5
- package/src/limiter.js +146 -65
- package/src/offload.js +116 -85
- package/src/offload_module.js +594 -0
- package/src/options.js +8 -4
- package/src/redial.js +129 -0
- package/src/signal.js +14 -4
- package/src/stream.js +353 -198
- package/types/attempt.d.ts.map +1 -1
- package/types/durable/index.d.ts.map +1 -1
- package/types/durable/state.d.ts.map +1 -1
- package/types/durable/store.d.ts.map +1 -1
- package/types/errors.d.ts.map +1 -1
- package/types/http/index.d.ts.map +1 -1
- package/types/index.d.ts +1 -0
- package/types/index.d.ts.map +1 -1
- package/types/limiter.d.ts +5 -1
- package/types/limiter.d.ts.map +1 -1
- package/types/offload.d.ts +2 -16
- package/types/offload.d.ts.map +1 -1
- package/types/redial.d.ts +28 -0
- package/types/redial.d.ts.map +1 -0
- package/types/stream.d.ts +2 -0
- package/types/stream.d.ts.map +1 -1
package/src/stream.js
CHANGED
|
@@ -28,11 +28,6 @@ export function buffer(source, ms) {
|
|
|
28
28
|
let failure
|
|
29
29
|
let finished = false
|
|
30
30
|
const due = create_due(ms)
|
|
31
|
-
function finish() {
|
|
32
|
-
finished = true
|
|
33
|
-
due.clear()
|
|
34
|
-
if (reader) release(reader)
|
|
35
|
-
}
|
|
36
31
|
return {
|
|
37
32
|
[Symbol.asyncIterator]() {
|
|
38
33
|
return reader || finished ? buffer(source, ms) : this
|
|
@@ -43,7 +38,9 @@ export function buffer(source, ms) {
|
|
|
43
38
|
failure = void 0
|
|
44
39
|
throw error
|
|
45
40
|
}
|
|
46
|
-
if (finished)
|
|
41
|
+
if (finished) {
|
|
42
|
+
return { done: true, value: void 0 }
|
|
43
|
+
}
|
|
47
44
|
try {
|
|
48
45
|
reader ??= /** @type {AsyncIterator<T>} */(to_reader(source))/**/
|
|
49
46
|
for (;;) {
|
|
@@ -52,7 +49,9 @@ export function buffer(source, ms) {
|
|
|
52
49
|
const step = await Promise.race(
|
|
53
50
|
racing ? [ next, racing ] : [ next ]
|
|
54
51
|
)
|
|
55
|
-
if (finished)
|
|
52
|
+
if (finished) {
|
|
53
|
+
return { done: true, value: void 0 }
|
|
54
|
+
}
|
|
56
55
|
if (step == "due" || racing && due.fired) {
|
|
57
56
|
const full = batch
|
|
58
57
|
batch = []
|
|
@@ -66,12 +65,18 @@ export function buffer(source, ms) {
|
|
|
66
65
|
return full.length ? { done: false, value: full } : { done: true, value: void 0 }
|
|
67
66
|
}
|
|
68
67
|
batch.push(step.value)
|
|
69
|
-
if (!due.promise)
|
|
68
|
+
if (!due.promise) {
|
|
69
|
+
due.start()
|
|
70
|
+
}
|
|
70
71
|
}
|
|
71
72
|
} catch (error) {
|
|
72
|
-
if (finished)
|
|
73
|
+
if (finished) {
|
|
74
|
+
return { done: true, value: void 0 }
|
|
75
|
+
}
|
|
73
76
|
finish()
|
|
74
|
-
if (!batch.length)
|
|
77
|
+
if (!batch.length) {
|
|
78
|
+
throw error
|
|
79
|
+
}
|
|
75
80
|
const full = batch
|
|
76
81
|
batch = []
|
|
77
82
|
failure = { error }
|
|
@@ -80,10 +85,20 @@ export function buffer(source, ms) {
|
|
|
80
85
|
},
|
|
81
86
|
async return() {
|
|
82
87
|
failure = void 0
|
|
83
|
-
if (!finished)
|
|
88
|
+
if (!finished) {
|
|
89
|
+
finish()
|
|
90
|
+
}
|
|
84
91
|
return { done: true, value: void 0 }
|
|
85
92
|
}
|
|
86
93
|
}
|
|
94
|
+
/** @returns {void} */
|
|
95
|
+
function finish() {
|
|
96
|
+
finished = true
|
|
97
|
+
due.clear()
|
|
98
|
+
if (reader) {
|
|
99
|
+
release(reader)
|
|
100
|
+
}
|
|
101
|
+
}
|
|
87
102
|
}
|
|
88
103
|
/**
|
|
89
104
|
* @param {unknown} value
|
|
@@ -91,10 +106,15 @@ export function buffer(source, ms) {
|
|
|
91
106
|
*/
|
|
92
107
|
function cancel_result(value) {
|
|
93
108
|
const result = /** @type {{ cancel?: unknown } | null | undefined} */(value)/**/
|
|
94
|
-
if (typeof result?.cancel != "function")
|
|
109
|
+
if (typeof result?.cancel != "function") {
|
|
110
|
+
return
|
|
111
|
+
}
|
|
95
112
|
try {
|
|
96
113
|
const cancelled = /** @type {{ cancel: () => unknown }} */(result)/**/.cancel()
|
|
97
|
-
if (typeof /** @type {Partial<PromiseLike<unknown>>} */(cancelled)/**/?.then == "function")
|
|
114
|
+
if (typeof /** @type {Partial<PromiseLike<unknown>>} */(cancelled)/**/?.then == "function") {
|
|
115
|
+
const pending = /** @type {PromiseLike<unknown>} */(cancelled)/**/
|
|
116
|
+
pending.then(noop, noop)
|
|
117
|
+
}
|
|
98
118
|
} catch {}
|
|
99
119
|
}
|
|
100
120
|
/**
|
|
@@ -103,7 +123,9 @@ function cancel_result(value) {
|
|
|
103
123
|
* @returns {void}
|
|
104
124
|
*/
|
|
105
125
|
function check_limit(limit, kind) {
|
|
106
|
-
if (limit == null || limit === Infinity || Number.isInteger(limit) && /** @type {number} */(limit)/**/ >= 1)
|
|
126
|
+
if (limit == null || limit === Infinity || Number.isInteger(limit) && /** @type {number} */(limit)/**/ >= 1) {
|
|
127
|
+
return
|
|
128
|
+
}
|
|
107
129
|
throw TypeError(
|
|
108
130
|
`The limit of ${kind}() must be a positive integer or Infinity`
|
|
109
131
|
)
|
|
@@ -114,7 +136,9 @@ function check_limit(limit, kind) {
|
|
|
114
136
|
* @returns {void}
|
|
115
137
|
*/
|
|
116
138
|
function check_ms(ms, kind) {
|
|
117
|
-
if (typeof ms == "number" && ms >= 0)
|
|
139
|
+
if (typeof ms == "number" && ms >= 0) {
|
|
140
|
+
return
|
|
141
|
+
}
|
|
118
142
|
throw TypeError(
|
|
119
143
|
`${kind}() needs a non-negative number of milliseconds`
|
|
120
144
|
)
|
|
@@ -136,8 +160,9 @@ function create_channel(options = {}) {
|
|
|
136
160
|
"initial" in options ? { value: options.initial } : void 0
|
|
137
161
|
)
|
|
138
162
|
const { signal } = options
|
|
139
|
-
if (signal?.aborted)
|
|
140
|
-
|
|
163
|
+
if (signal?.aborted) {
|
|
164
|
+
source.close()
|
|
165
|
+
} else if (signal) {
|
|
141
166
|
on_abort(signal, () => source.close())
|
|
142
167
|
}
|
|
143
168
|
return {
|
|
@@ -150,9 +175,11 @@ function create_channel(options = {}) {
|
|
|
150
175
|
send: value => source.write(value)
|
|
151
176
|
}
|
|
152
177
|
}
|
|
153
|
-
|
|
178
|
+
/** @type {import("../public.js").ChannelFunction} */
|
|
179
|
+
export const channel = create_channel
|
|
154
180
|
/**
|
|
155
181
|
* @param {number} ms
|
|
182
|
+
* @returns {{ clear(): void; fired: boolean; promise: Promise<"due"> | undefined; start(): void; }}
|
|
156
183
|
*/
|
|
157
184
|
function create_due(ms) {
|
|
158
185
|
const delay = clamp_delay(ms)
|
|
@@ -160,12 +187,6 @@ function create_due(ms) {
|
|
|
160
187
|
let resolve
|
|
161
188
|
/** @type {ReturnType<typeof setTimeout> | undefined} */
|
|
162
189
|
let timer
|
|
163
|
-
function fire() {
|
|
164
|
-
const settle = /** @type {(value: "due") => void} */(resolve)/**/
|
|
165
|
-
due.clear()
|
|
166
|
-
due.fired = true
|
|
167
|
-
settle("due")
|
|
168
|
-
}
|
|
169
190
|
const due = {
|
|
170
191
|
clear() {
|
|
171
192
|
clearTimeout(timer)
|
|
@@ -188,6 +209,13 @@ function create_due(ms) {
|
|
|
188
209
|
}
|
|
189
210
|
}
|
|
190
211
|
return due
|
|
212
|
+
/** @returns {void} */
|
|
213
|
+
function fire() {
|
|
214
|
+
const settle = /** @type {(value: "due") => void} */(resolve)/**/
|
|
215
|
+
due.clear()
|
|
216
|
+
due.fired = true
|
|
217
|
+
settle("due")
|
|
218
|
+
}
|
|
191
219
|
}
|
|
192
220
|
/**
|
|
193
221
|
* @param {number=} limit
|
|
@@ -203,20 +231,6 @@ function create_source(
|
|
|
203
231
|
let ended = false
|
|
204
232
|
/** @type {{ value: unknown } | undefined} */
|
|
205
233
|
let failure
|
|
206
|
-
/**
|
|
207
|
-
* @param {{ value: unknown }=} error
|
|
208
|
-
* @returns {void}
|
|
209
|
-
*/
|
|
210
|
-
function finish(error) {
|
|
211
|
-
if (ended) return
|
|
212
|
-
ended = true
|
|
213
|
-
failure = error
|
|
214
|
-
for (const loop of loops) {
|
|
215
|
-
loop.ended = true
|
|
216
|
-
loop.error = error
|
|
217
|
-
loop.wake?.()
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
234
|
return {
|
|
221
235
|
close: () => finish(void 0),
|
|
222
236
|
get ended() {
|
|
@@ -234,16 +248,6 @@ function create_source(
|
|
|
234
248
|
}
|
|
235
249
|
let finished = false
|
|
236
250
|
let started = false
|
|
237
|
-
/** @returns {IteratorResult<unknown>} */
|
|
238
|
-
function stop() {
|
|
239
|
-
if (!finished) {
|
|
240
|
-
finished = true
|
|
241
|
-
const left = loops.delete(loop)
|
|
242
|
-
loop.wake?.()
|
|
243
|
-
if (left && !loops.size) on_last?.()
|
|
244
|
-
}
|
|
245
|
-
return { done: true, value: void 0 }
|
|
246
|
-
}
|
|
247
251
|
return {
|
|
248
252
|
[Symbol.asyncIterator]() {
|
|
249
253
|
return this
|
|
@@ -255,12 +259,23 @@ function create_source(
|
|
|
255
259
|
loop.error = failure
|
|
256
260
|
if (!ended) {
|
|
257
261
|
loops.add(loop)
|
|
258
|
-
if (current)
|
|
259
|
-
|
|
262
|
+
if (current) {
|
|
263
|
+
loop.buffer.push(current.value)
|
|
264
|
+
}
|
|
265
|
+
if (loops.size == 1) {
|
|
266
|
+
try {
|
|
267
|
+
on_first?.()
|
|
268
|
+
} catch (error) {
|
|
269
|
+
stop()
|
|
270
|
+
throw error
|
|
271
|
+
}
|
|
272
|
+
}
|
|
260
273
|
}
|
|
261
274
|
}
|
|
262
275
|
for (;;) {
|
|
263
|
-
if (finished)
|
|
276
|
+
if (finished) {
|
|
277
|
+
return { done: true, value: void 0 }
|
|
278
|
+
}
|
|
264
279
|
if (loop.head < loop.buffer.length) {
|
|
265
280
|
const value = loop.buffer[loop.head]
|
|
266
281
|
loop.buffer[loop.head++] = void 0
|
|
@@ -278,7 +293,9 @@ function create_source(
|
|
|
278
293
|
stop()
|
|
279
294
|
throw value
|
|
280
295
|
}
|
|
281
|
-
if (loop.ended)
|
|
296
|
+
if (loop.ended) {
|
|
297
|
+
return stop()
|
|
298
|
+
}
|
|
282
299
|
await new Promise(
|
|
283
300
|
resolve => {
|
|
284
301
|
loop.wake = () => resolve(void 0)
|
|
@@ -291,10 +308,26 @@ function create_source(
|
|
|
291
308
|
return stop()
|
|
292
309
|
}
|
|
293
310
|
}
|
|
311
|
+
/** @returns {IteratorResult<unknown>} */
|
|
312
|
+
function stop() {
|
|
313
|
+
if (!finished) {
|
|
314
|
+
finished = true
|
|
315
|
+
const left = loops.delete(loop)
|
|
316
|
+
loop.wake?.()
|
|
317
|
+
if (left && !loops.size) {
|
|
318
|
+
on_last?.()
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return { done: true, value: void 0 }
|
|
322
|
+
}
|
|
294
323
|
},
|
|
295
324
|
write(value) {
|
|
296
|
-
if (ended)
|
|
297
|
-
|
|
325
|
+
if (ended) {
|
|
326
|
+
return
|
|
327
|
+
}
|
|
328
|
+
if (current) {
|
|
329
|
+
current.value = value
|
|
330
|
+
}
|
|
298
331
|
for (const loop of loops) {
|
|
299
332
|
loop.buffer.push(value)
|
|
300
333
|
if (loop.buffer.length - loop.head > limit) {
|
|
@@ -308,6 +341,22 @@ function create_source(
|
|
|
308
341
|
}
|
|
309
342
|
}
|
|
310
343
|
}
|
|
344
|
+
/**
|
|
345
|
+
* @param {{ value: unknown }=} error
|
|
346
|
+
* @returns {void}
|
|
347
|
+
*/
|
|
348
|
+
function finish(error) {
|
|
349
|
+
if (ended) {
|
|
350
|
+
return
|
|
351
|
+
}
|
|
352
|
+
ended = true
|
|
353
|
+
failure = error
|
|
354
|
+
for (const loop of loops) {
|
|
355
|
+
loop.ended = true
|
|
356
|
+
loop.error = error
|
|
357
|
+
loop.wake?.()
|
|
358
|
+
}
|
|
359
|
+
}
|
|
311
360
|
}
|
|
312
361
|
/**
|
|
313
362
|
* Yields the last value of every quiet window of the milliseconds, like the `debounce` of a request.
|
|
@@ -329,11 +378,6 @@ export function debounce(source, ms) {
|
|
|
329
378
|
let held
|
|
330
379
|
let finished = false
|
|
331
380
|
const due = create_due(ms)
|
|
332
|
-
function finish() {
|
|
333
|
-
finished = true
|
|
334
|
-
due.clear()
|
|
335
|
-
if (reader) release(reader)
|
|
336
|
-
}
|
|
337
381
|
return {
|
|
338
382
|
[Symbol.asyncIterator]() {
|
|
339
383
|
return reader || finished ? debounce(source, ms) : this
|
|
@@ -344,7 +388,9 @@ export function debounce(source, ms) {
|
|
|
344
388
|
failure = void 0
|
|
345
389
|
throw error
|
|
346
390
|
}
|
|
347
|
-
if (finished)
|
|
391
|
+
if (finished) {
|
|
392
|
+
return { done: true, value: void 0 }
|
|
393
|
+
}
|
|
348
394
|
try {
|
|
349
395
|
reader ??= /** @type {AsyncIterator<T>} */(to_reader(source))/**/
|
|
350
396
|
for (;;) {
|
|
@@ -353,7 +399,9 @@ export function debounce(source, ms) {
|
|
|
353
399
|
const step = await Promise.race(
|
|
354
400
|
racing ? [ next, racing ] : [ next ]
|
|
355
401
|
)
|
|
356
|
-
if (finished)
|
|
402
|
+
if (finished) {
|
|
403
|
+
return { done: true, value: void 0 }
|
|
404
|
+
}
|
|
357
405
|
if (step == "due" || racing && due.fired) {
|
|
358
406
|
const { value } = /** @type {{ value: T }} */(held)/**/
|
|
359
407
|
held = void 0
|
|
@@ -370,10 +418,14 @@ export function debounce(source, ms) {
|
|
|
370
418
|
due.start()
|
|
371
419
|
}
|
|
372
420
|
} catch (error) {
|
|
373
|
-
if (finished)
|
|
421
|
+
if (finished) {
|
|
422
|
+
return { done: true, value: void 0 }
|
|
423
|
+
}
|
|
374
424
|
finish()
|
|
375
425
|
const last = held
|
|
376
|
-
if (!last)
|
|
426
|
+
if (!last) {
|
|
427
|
+
throw error
|
|
428
|
+
}
|
|
377
429
|
held = void 0
|
|
378
430
|
failure = { error }
|
|
379
431
|
return { done: false, value: last.value }
|
|
@@ -381,10 +433,20 @@ export function debounce(source, ms) {
|
|
|
381
433
|
},
|
|
382
434
|
async return() {
|
|
383
435
|
failure = void 0
|
|
384
|
-
if (!finished)
|
|
436
|
+
if (!finished) {
|
|
437
|
+
finish()
|
|
438
|
+
}
|
|
385
439
|
return { done: true, value: void 0 }
|
|
386
440
|
}
|
|
387
441
|
}
|
|
442
|
+
/** @returns {void} */
|
|
443
|
+
function finish() {
|
|
444
|
+
finished = true
|
|
445
|
+
due.clear()
|
|
446
|
+
if (reader) {
|
|
447
|
+
release(reader)
|
|
448
|
+
}
|
|
449
|
+
}
|
|
388
450
|
}
|
|
389
451
|
/**
|
|
390
452
|
* Counts every period of the milliseconds, 1, 2, 3, for polling and jobs. A loop that takes longer than a period gets
|
|
@@ -397,9 +459,11 @@ export function debounce(source, ms) {
|
|
|
397
459
|
* @returns {AsyncIterable<number>}
|
|
398
460
|
*/
|
|
399
461
|
export function every(ms, options = {}) {
|
|
400
|
-
if (!(typeof ms == "number" && ms > 0))
|
|
401
|
-
|
|
402
|
-
|
|
462
|
+
if (!(typeof ms == "number" && ms > 0)) {
|
|
463
|
+
throw TypeError(
|
|
464
|
+
"every() needs a positive number of milliseconds"
|
|
465
|
+
)
|
|
466
|
+
}
|
|
403
467
|
check_options(
|
|
404
468
|
options,
|
|
405
469
|
[ "immediate", "signal" ],
|
|
@@ -413,21 +477,14 @@ export function every(ms, options = {}) {
|
|
|
413
477
|
let finished = false
|
|
414
478
|
const controller = new AbortController()
|
|
415
479
|
const unlink = link_signal(controller, signal)
|
|
416
|
-
/** @returns {IteratorResult<number>} */
|
|
417
|
-
function finish() {
|
|
418
|
-
if (!finished) {
|
|
419
|
-
finished = true
|
|
420
|
-
controller.abort()
|
|
421
|
-
unlink()
|
|
422
|
-
}
|
|
423
|
-
return { done: true, value: void 0 }
|
|
424
|
-
}
|
|
425
480
|
return {
|
|
426
481
|
[Symbol.asyncIterator]() {
|
|
427
482
|
return this
|
|
428
483
|
},
|
|
429
484
|
async next() {
|
|
430
|
-
if (finished || controller.signal.aborted)
|
|
485
|
+
if (finished || controller.signal.aborted) {
|
|
486
|
+
return finish()
|
|
487
|
+
}
|
|
431
488
|
if (due > Date.now()) {
|
|
432
489
|
try {
|
|
433
490
|
await sleep_until(due, controller.signal)
|
|
@@ -435,7 +492,9 @@ export function every(ms, options = {}) {
|
|
|
435
492
|
return finish()
|
|
436
493
|
}
|
|
437
494
|
}
|
|
438
|
-
if (finished)
|
|
495
|
+
if (finished) {
|
|
496
|
+
return finish()
|
|
497
|
+
}
|
|
439
498
|
const now = Date.now()
|
|
440
499
|
due = (now - due >= ms ? now : due) + ms
|
|
441
500
|
return { done: false, value: ++count }
|
|
@@ -444,6 +503,15 @@ export function every(ms, options = {}) {
|
|
|
444
503
|
return finish()
|
|
445
504
|
}
|
|
446
505
|
}
|
|
506
|
+
/** @returns {IteratorResult<number>} */
|
|
507
|
+
function finish() {
|
|
508
|
+
if (!finished) {
|
|
509
|
+
finished = true
|
|
510
|
+
controller.abort()
|
|
511
|
+
unlink()
|
|
512
|
+
}
|
|
513
|
+
return { done: true, value: void 0 }
|
|
514
|
+
}
|
|
447
515
|
}
|
|
448
516
|
}
|
|
449
517
|
}
|
|
@@ -463,50 +531,14 @@ function switch_latest(source, start) {
|
|
|
463
531
|
let inner
|
|
464
532
|
let outer_done = false
|
|
465
533
|
let finished = false
|
|
466
|
-
/**
|
|
467
|
-
* @returns {void}
|
|
468
|
-
*/
|
|
469
|
-
function close_inner() {
|
|
470
|
-
if (!inner) return
|
|
471
|
-
inner.controller.abort(
|
|
472
|
-
new CancelError("Superseded by a newer value")
|
|
473
|
-
)
|
|
474
|
-
inner.next?.catch(noop)
|
|
475
|
-
release(inner.reader)
|
|
476
|
-
cancel_result(inner.made)
|
|
477
|
-
inner = void 0
|
|
478
|
-
}
|
|
479
|
-
function finish() {
|
|
480
|
-
finished = true
|
|
481
|
-
close_inner()
|
|
482
|
-
if (outer) release(outer)
|
|
483
|
-
}
|
|
484
|
-
/**
|
|
485
|
-
* @param {T} value
|
|
486
|
-
* @returns {void}
|
|
487
|
-
*/
|
|
488
|
-
function open_inner(value) {
|
|
489
|
-
next_outer = /** @type {AsyncIterator<T>} */(outer)/**/.next()
|
|
490
|
-
next_outer.catch(noop)
|
|
491
|
-
const controller = new AbortController()
|
|
492
|
-
const made = start(value, controller.signal)
|
|
493
|
-
const iterable = typeof /** @type {Partial<AsyncIterable<unknown>>} */(made)/**/?.[Symbol.asyncIterator] == "function"
|
|
494
|
-
const reader = /** @type {AsyncIterator<R>} */(iterable ? to_reader(made) : once_reader(made))/**/
|
|
495
|
-
inner = {
|
|
496
|
-
controller,
|
|
497
|
-
made: iterable || typeof /** @type {Partial<PromiseLike<unknown>>} */(made)/**/?.then == "function"
|
|
498
|
-
? made
|
|
499
|
-
: void 0,
|
|
500
|
-
next: void 0,
|
|
501
|
-
reader
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
534
|
return {
|
|
505
535
|
[Symbol.asyncIterator]() {
|
|
506
536
|
return outer || finished ? switch_latest(source, start) : this
|
|
507
537
|
},
|
|
508
538
|
async next() {
|
|
509
|
-
if (finished)
|
|
539
|
+
if (finished) {
|
|
540
|
+
return { done: true, value: void 0 }
|
|
541
|
+
}
|
|
510
542
|
try {
|
|
511
543
|
outer ??= /** @type {AsyncIterator<T>} */(to_reader(source))/**/
|
|
512
544
|
for (;;) {
|
|
@@ -517,7 +549,9 @@ function switch_latest(source, start) {
|
|
|
517
549
|
}
|
|
518
550
|
next_outer ??= outer.next()
|
|
519
551
|
const step = await next_outer
|
|
520
|
-
if (finished)
|
|
552
|
+
if (finished) {
|
|
553
|
+
return { done: true, value: void 0 }
|
|
554
|
+
}
|
|
521
555
|
next_outer = void 0
|
|
522
556
|
if (step.done) {
|
|
523
557
|
finish()
|
|
@@ -543,7 +577,9 @@ function switch_latest(source, start) {
|
|
|
543
577
|
)
|
|
544
578
|
}
|
|
545
579
|
const won = await Promise.race(racing)
|
|
546
|
-
if (finished)
|
|
580
|
+
if (finished) {
|
|
581
|
+
return { done: true, value: void 0 }
|
|
582
|
+
}
|
|
547
583
|
if (won.from_outer) {
|
|
548
584
|
const step = /** @type {IteratorResult<T>} */(won.step)/**/
|
|
549
585
|
next_outer = void 0
|
|
@@ -564,18 +600,64 @@ function switch_latest(source, start) {
|
|
|
564
600
|
return step
|
|
565
601
|
}
|
|
566
602
|
} catch (error) {
|
|
567
|
-
if (finished)
|
|
603
|
+
if (finished) {
|
|
604
|
+
return { done: true, value: void 0 }
|
|
605
|
+
}
|
|
568
606
|
finish()
|
|
569
607
|
throw error
|
|
570
608
|
}
|
|
571
609
|
},
|
|
572
610
|
async return() {
|
|
573
|
-
if (!finished)
|
|
611
|
+
if (!finished) {
|
|
612
|
+
finish()
|
|
613
|
+
}
|
|
574
614
|
return { done: true, value: void 0 }
|
|
575
615
|
}
|
|
576
616
|
}
|
|
617
|
+
/** @returns {void} */
|
|
618
|
+
function close_inner() {
|
|
619
|
+
if (!inner) {
|
|
620
|
+
return
|
|
621
|
+
}
|
|
622
|
+
inner.controller.abort(
|
|
623
|
+
new CancelError("Superseded by a newer value")
|
|
624
|
+
)
|
|
625
|
+
inner.next?.catch(noop)
|
|
626
|
+
release(inner.reader)
|
|
627
|
+
cancel_result(inner.made)
|
|
628
|
+
inner = void 0
|
|
629
|
+
}
|
|
630
|
+
/** @returns {void} */
|
|
631
|
+
function finish() {
|
|
632
|
+
finished = true
|
|
633
|
+
close_inner()
|
|
634
|
+
if (outer) {
|
|
635
|
+
release(outer)
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* @param {T} value
|
|
640
|
+
* @returns {void}
|
|
641
|
+
*/
|
|
642
|
+
function open_inner(value) {
|
|
643
|
+
next_outer = /** @type {AsyncIterator<T>} */(outer)/**/.next()
|
|
644
|
+
next_outer.catch(noop)
|
|
645
|
+
const controller = new AbortController()
|
|
646
|
+
const made = start(value, controller.signal)
|
|
647
|
+
const iterable = typeof /** @type {Partial<AsyncIterable<unknown>>} */(made)/**/?.[Symbol.asyncIterator] == "function"
|
|
648
|
+
const reader = /** @type {AsyncIterator<R>} */(iterable ? to_reader(made) : once_reader(made))/**/
|
|
649
|
+
inner = {
|
|
650
|
+
controller,
|
|
651
|
+
made: iterable || typeof /** @type {Partial<PromiseLike<unknown>>} */(made)/**/?.then == "function"
|
|
652
|
+
? made
|
|
653
|
+
: void 0,
|
|
654
|
+
next: void 0,
|
|
655
|
+
reader
|
|
656
|
+
}
|
|
657
|
+
}
|
|
577
658
|
}
|
|
578
|
-
|
|
659
|
+
/** @type {import("../public.js").LatestFunction} */
|
|
660
|
+
export const latest = switch_latest
|
|
579
661
|
/**
|
|
580
662
|
* @template T
|
|
581
663
|
* @param {...AsyncIterable<T>} sources
|
|
@@ -593,51 +675,28 @@ function merge_streams(...sources) {
|
|
|
593
675
|
/** @type {(() => void) | undefined} */
|
|
594
676
|
let wake
|
|
595
677
|
let finished = false
|
|
596
|
-
function finish() {
|
|
597
|
-
finished = true
|
|
598
|
-
if (readers) for (const reader of readers) release(reader)
|
|
599
|
-
wake?.()
|
|
600
|
-
}
|
|
601
|
-
/**
|
|
602
|
-
* @param {AsyncIterator<T>} reader
|
|
603
|
-
* @returns {void}
|
|
604
|
-
*/
|
|
605
|
-
function read(reader) {
|
|
606
|
-
reader.next()
|
|
607
|
-
.then(
|
|
608
|
-
step => {
|
|
609
|
-
if (finished) return
|
|
610
|
-
ready.push(
|
|
611
|
-
{ error: void 0, reader, step }
|
|
612
|
-
)
|
|
613
|
-
wake?.()
|
|
614
|
-
},
|
|
615
|
-
error => {
|
|
616
|
-
if (finished) return
|
|
617
|
-
ready.push(
|
|
618
|
-
{
|
|
619
|
-
error: { value: error },
|
|
620
|
-
reader,
|
|
621
|
-
step: void 0
|
|
622
|
-
}
|
|
623
|
-
)
|
|
624
|
-
wake?.()
|
|
625
|
-
}
|
|
626
|
-
)
|
|
627
|
-
}
|
|
628
678
|
return {
|
|
629
679
|
[Symbol.asyncIterator]() {
|
|
630
680
|
return readers || finished ? merge_streams(...sources) : this
|
|
631
681
|
},
|
|
632
682
|
async next() {
|
|
633
|
-
if (finished)
|
|
683
|
+
if (finished) {
|
|
684
|
+
return { done: true, value: void 0 }
|
|
685
|
+
}
|
|
634
686
|
try {
|
|
635
687
|
if (!readers) {
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
688
|
+
/** @type {AsyncIterator<T>[]} */
|
|
689
|
+
const opened = []
|
|
690
|
+
readers = opened
|
|
691
|
+
for (const source of sources) {
|
|
692
|
+
opened.push(
|
|
693
|
+
/** @type {AsyncIterator<T>} */(to_reader(source))/**/
|
|
694
|
+
)
|
|
695
|
+
}
|
|
696
|
+
active = opened.length
|
|
697
|
+
for (const reader of opened) {
|
|
698
|
+
read(reader)
|
|
699
|
+
}
|
|
641
700
|
}
|
|
642
701
|
if (last) {
|
|
643
702
|
read(last)
|
|
@@ -650,7 +709,9 @@ function merge_streams(...sources) {
|
|
|
650
709
|
ready = []
|
|
651
710
|
head = 0
|
|
652
711
|
}
|
|
653
|
-
if (error)
|
|
712
|
+
if (error) {
|
|
713
|
+
throw error.value
|
|
714
|
+
}
|
|
654
715
|
if (/** @type {IteratorResult<T>} */(step)/**/.done) {
|
|
655
716
|
active--
|
|
656
717
|
continue
|
|
@@ -658,28 +719,77 @@ function merge_streams(...sources) {
|
|
|
658
719
|
last = reader
|
|
659
720
|
return /** @type {IteratorResult<T>} */(step)/**/
|
|
660
721
|
}
|
|
661
|
-
if (!active)
|
|
722
|
+
if (!active) {
|
|
723
|
+
break
|
|
724
|
+
}
|
|
662
725
|
await new Promise(
|
|
663
726
|
resolve => {
|
|
664
727
|
wake = () => resolve(void 0)
|
|
665
728
|
}
|
|
666
729
|
)
|
|
667
730
|
wake = void 0
|
|
668
|
-
if (finished)
|
|
731
|
+
if (finished) {
|
|
732
|
+
return { done: true, value: void 0 }
|
|
733
|
+
}
|
|
669
734
|
}
|
|
670
735
|
finish()
|
|
671
736
|
return { done: true, value: void 0 }
|
|
672
737
|
} catch (error) {
|
|
673
|
-
if (finished)
|
|
738
|
+
if (finished) {
|
|
739
|
+
return { done: true, value: void 0 }
|
|
740
|
+
}
|
|
674
741
|
finish()
|
|
675
742
|
throw error
|
|
676
743
|
}
|
|
677
744
|
},
|
|
678
745
|
async return() {
|
|
679
|
-
if (!finished)
|
|
746
|
+
if (!finished) {
|
|
747
|
+
finish()
|
|
748
|
+
}
|
|
680
749
|
return { done: true, value: void 0 }
|
|
681
750
|
}
|
|
682
751
|
}
|
|
752
|
+
/** @returns {void} */
|
|
753
|
+
function finish() {
|
|
754
|
+
finished = true
|
|
755
|
+
if (readers) {
|
|
756
|
+
for (const reader of readers) {
|
|
757
|
+
release(reader)
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
wake?.()
|
|
761
|
+
}
|
|
762
|
+
/**
|
|
763
|
+
* @param {AsyncIterator<T>} reader
|
|
764
|
+
* @returns {void}
|
|
765
|
+
*/
|
|
766
|
+
function read(reader) {
|
|
767
|
+
reader.next()
|
|
768
|
+
.then(
|
|
769
|
+
step => {
|
|
770
|
+
if (finished) {
|
|
771
|
+
return
|
|
772
|
+
}
|
|
773
|
+
ready.push(
|
|
774
|
+
{ error: void 0, reader, step }
|
|
775
|
+
)
|
|
776
|
+
wake?.()
|
|
777
|
+
},
|
|
778
|
+
error => {
|
|
779
|
+
if (finished) {
|
|
780
|
+
return
|
|
781
|
+
}
|
|
782
|
+
ready.push(
|
|
783
|
+
{
|
|
784
|
+
error: { value: error },
|
|
785
|
+
reader,
|
|
786
|
+
step: void 0
|
|
787
|
+
}
|
|
788
|
+
)
|
|
789
|
+
wake?.()
|
|
790
|
+
}
|
|
791
|
+
)
|
|
792
|
+
}
|
|
683
793
|
}
|
|
684
794
|
export const merge = /** @type {import("../public.js").MergeFunction} */(merge_streams)/**/
|
|
685
795
|
/**
|
|
@@ -692,8 +802,12 @@ function once_reader(value) {
|
|
|
692
802
|
let inner
|
|
693
803
|
return {
|
|
694
804
|
async next() {
|
|
695
|
-
if (done)
|
|
696
|
-
|
|
805
|
+
if (done) {
|
|
806
|
+
return { done: true, value: void 0 }
|
|
807
|
+
}
|
|
808
|
+
if (inner) {
|
|
809
|
+
return inner.reader.next()
|
|
810
|
+
}
|
|
697
811
|
const settled = await value
|
|
698
812
|
const iterable = typeof /** @type {Partial<AsyncIterable<unknown>>} */(settled)/**/?.[Symbol.asyncIterator] == "function"
|
|
699
813
|
if (done) {
|
|
@@ -730,7 +844,9 @@ function once_reader(value) {
|
|
|
730
844
|
function release(reader) {
|
|
731
845
|
try {
|
|
732
846
|
const returned = /** @type {Promise<unknown> | undefined} */(reader.return?.())/**/
|
|
733
|
-
if (returned && typeof returned.then == "function")
|
|
847
|
+
if (returned && typeof returned.then == "function") {
|
|
848
|
+
returned.then(noop, noop)
|
|
849
|
+
}
|
|
734
850
|
} catch {}
|
|
735
851
|
}
|
|
736
852
|
/**
|
|
@@ -746,7 +862,9 @@ export function share(source, options = {}) {
|
|
|
746
862
|
let shared = share_source(source, options.limit)
|
|
747
863
|
return {
|
|
748
864
|
[Symbol.asyncIterator]() {
|
|
749
|
-
if (shared.source.ended)
|
|
865
|
+
if (shared.source.ended) {
|
|
866
|
+
shared = share_source(source, options.limit)
|
|
867
|
+
}
|
|
750
868
|
return /** @type {AsyncGenerator<T, void, undefined>} */(shared.read())/**/
|
|
751
869
|
}
|
|
752
870
|
}
|
|
@@ -754,11 +872,17 @@ export function share(source, options = {}) {
|
|
|
754
872
|
/**
|
|
755
873
|
* @param {AsyncIterable<unknown>} source
|
|
756
874
|
* @param {number | undefined} limit
|
|
875
|
+
* @returns {{ read: () => AsyncIterableIterator<unknown>; source: StreamSource; }}
|
|
757
876
|
*/
|
|
758
877
|
function share_source(source, limit) {
|
|
759
878
|
const shared = create_source(limit)
|
|
760
879
|
/** @type {AsyncIterator<unknown> | undefined} */
|
|
761
880
|
let reader
|
|
881
|
+
return {
|
|
882
|
+
read: () => shared.read(start, stop),
|
|
883
|
+
source: shared
|
|
884
|
+
}
|
|
885
|
+
/** @returns {void} */
|
|
762
886
|
function start() {
|
|
763
887
|
const current = to_reader(source)
|
|
764
888
|
reader = current
|
|
@@ -766,7 +890,9 @@ function share_source(source, limit) {
|
|
|
766
890
|
try {
|
|
767
891
|
for (;;) {
|
|
768
892
|
const step = await current.next()
|
|
769
|
-
if (reader != current)
|
|
893
|
+
if (reader != current) {
|
|
894
|
+
return
|
|
895
|
+
}
|
|
770
896
|
if (step.done) {
|
|
771
897
|
shared.close()
|
|
772
898
|
return
|
|
@@ -774,18 +900,19 @@ function share_source(source, limit) {
|
|
|
774
900
|
shared.write(step.value)
|
|
775
901
|
}
|
|
776
902
|
} catch (error) {
|
|
777
|
-
if (reader == current)
|
|
903
|
+
if (reader == current) {
|
|
904
|
+
shared.fail(error)
|
|
905
|
+
}
|
|
778
906
|
}
|
|
779
907
|
})()
|
|
780
908
|
}
|
|
909
|
+
/** @returns {void} */
|
|
781
910
|
function stop() {
|
|
782
911
|
const current = reader
|
|
783
912
|
reader = void 0
|
|
784
|
-
if (current)
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
read: () => shared.read(start, stop),
|
|
788
|
-
source: shared
|
|
913
|
+
if (current) {
|
|
914
|
+
release(current)
|
|
915
|
+
}
|
|
789
916
|
}
|
|
790
917
|
}
|
|
791
918
|
/**
|
|
@@ -809,11 +936,6 @@ export function throttle(source, ms) {
|
|
|
809
936
|
let held
|
|
810
937
|
let finished = false
|
|
811
938
|
const window = create_due(ms)
|
|
812
|
-
function finish() {
|
|
813
|
-
finished = true
|
|
814
|
-
window.clear()
|
|
815
|
-
if (reader) release(reader)
|
|
816
|
-
}
|
|
817
939
|
return {
|
|
818
940
|
[Symbol.asyncIterator]() {
|
|
819
941
|
return reader || finished ? throttle(source, ms) : this
|
|
@@ -824,7 +946,9 @@ export function throttle(source, ms) {
|
|
|
824
946
|
failure = void 0
|
|
825
947
|
throw error
|
|
826
948
|
}
|
|
827
|
-
if (finished)
|
|
949
|
+
if (finished) {
|
|
950
|
+
return { done: true, value: void 0 }
|
|
951
|
+
}
|
|
828
952
|
try {
|
|
829
953
|
reader ??= /** @type {AsyncIterator<T>} */(to_reader(source))/**/
|
|
830
954
|
for (;;) {
|
|
@@ -833,7 +957,9 @@ export function throttle(source, ms) {
|
|
|
833
957
|
const step = await Promise.race(
|
|
834
958
|
racing ? [ next, racing ] : [ next ]
|
|
835
959
|
)
|
|
836
|
-
if (finished)
|
|
960
|
+
if (finished) {
|
|
961
|
+
return { done: true, value: void 0 }
|
|
962
|
+
}
|
|
837
963
|
if (step == "due" || racing && window.fired) {
|
|
838
964
|
if (held) {
|
|
839
965
|
const { value } = held
|
|
@@ -858,10 +984,14 @@ export function throttle(source, ms) {
|
|
|
858
984
|
return step
|
|
859
985
|
}
|
|
860
986
|
} catch (error) {
|
|
861
|
-
if (finished)
|
|
987
|
+
if (finished) {
|
|
988
|
+
return { done: true, value: void 0 }
|
|
989
|
+
}
|
|
862
990
|
finish()
|
|
863
991
|
const last = held
|
|
864
|
-
if (!last)
|
|
992
|
+
if (!last) {
|
|
993
|
+
throw error
|
|
994
|
+
}
|
|
865
995
|
held = void 0
|
|
866
996
|
failure = { error }
|
|
867
997
|
return { done: false, value: last.value }
|
|
@@ -869,10 +999,20 @@ export function throttle(source, ms) {
|
|
|
869
999
|
},
|
|
870
1000
|
async return() {
|
|
871
1001
|
failure = void 0
|
|
872
|
-
if (!finished)
|
|
1002
|
+
if (!finished) {
|
|
1003
|
+
finish()
|
|
1004
|
+
}
|
|
873
1005
|
return { done: true, value: void 0 }
|
|
874
1006
|
}
|
|
875
1007
|
}
|
|
1008
|
+
/** @returns {void} */
|
|
1009
|
+
function finish() {
|
|
1010
|
+
finished = true
|
|
1011
|
+
window.clear()
|
|
1012
|
+
if (reader) {
|
|
1013
|
+
release(reader)
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
876
1016
|
}
|
|
877
1017
|
/**
|
|
878
1018
|
* @param {unknown} source
|
|
@@ -880,9 +1020,11 @@ export function throttle(source, ms) {
|
|
|
880
1020
|
*/
|
|
881
1021
|
function to_reader(source) {
|
|
882
1022
|
const iterable = /** @type {Partial<AsyncIterable<unknown>>} */(source)/**/
|
|
883
|
-
if (typeof iterable?.[Symbol.asyncIterator] != "function")
|
|
884
|
-
|
|
885
|
-
|
|
1023
|
+
if (typeof iterable?.[Symbol.asyncIterator] != "function") {
|
|
1024
|
+
throw TypeError(
|
|
1025
|
+
"A stream must be an async iterable"
|
|
1026
|
+
)
|
|
1027
|
+
}
|
|
886
1028
|
return /** @type {AsyncIterable<unknown>} */(source)/**/[Symbol.asyncIterator]()
|
|
887
1029
|
}
|
|
888
1030
|
/**
|
|
@@ -900,17 +1042,14 @@ export function until(source, stop) {
|
|
|
900
1042
|
/** @type {Promise<"stop"> | undefined} */
|
|
901
1043
|
let ended
|
|
902
1044
|
let finished = false
|
|
903
|
-
function finish() {
|
|
904
|
-
finished = true
|
|
905
|
-
if (reader) release(reader)
|
|
906
|
-
if (ender) release(ender)
|
|
907
|
-
}
|
|
908
1045
|
return {
|
|
909
1046
|
[Symbol.asyncIterator]() {
|
|
910
1047
|
return reader || finished ? until(source, stop) : this
|
|
911
1048
|
},
|
|
912
1049
|
async next() {
|
|
913
|
-
if (finished)
|
|
1050
|
+
if (finished) {
|
|
1051
|
+
return { done: true, value: void 0 }
|
|
1052
|
+
}
|
|
914
1053
|
try {
|
|
915
1054
|
if (!reader) {
|
|
916
1055
|
reader = /** @type {AsyncIterator<T>} */(to_reader(source))/**/
|
|
@@ -924,21 +1063,37 @@ export function until(source, stop) {
|
|
|
924
1063
|
/** @type {Promise<"stop">} */(ended)/**/
|
|
925
1064
|
]
|
|
926
1065
|
)
|
|
927
|
-
if (finished)
|
|
1066
|
+
if (finished) {
|
|
1067
|
+
return { done: true, value: void 0 }
|
|
1068
|
+
}
|
|
928
1069
|
if (step == "stop" || step.done) {
|
|
929
1070
|
finish()
|
|
930
1071
|
return { done: true, value: void 0 }
|
|
931
1072
|
}
|
|
932
1073
|
return step
|
|
933
1074
|
} catch (error) {
|
|
934
|
-
if (finished)
|
|
1075
|
+
if (finished) {
|
|
1076
|
+
return { done: true, value: void 0 }
|
|
1077
|
+
}
|
|
935
1078
|
finish()
|
|
936
1079
|
throw error
|
|
937
1080
|
}
|
|
938
1081
|
},
|
|
939
1082
|
async return() {
|
|
940
|
-
if (!finished)
|
|
1083
|
+
if (!finished) {
|
|
1084
|
+
finish()
|
|
1085
|
+
}
|
|
941
1086
|
return { done: true, value: void 0 }
|
|
942
1087
|
}
|
|
943
1088
|
}
|
|
1089
|
+
/** @returns {void} */
|
|
1090
|
+
function finish() {
|
|
1091
|
+
finished = true
|
|
1092
|
+
if (reader) {
|
|
1093
|
+
release(reader)
|
|
1094
|
+
}
|
|
1095
|
+
if (ender) {
|
|
1096
|
+
release(ender)
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
944
1099
|
}
|