@dxos/async 0.8.3 → 0.8.4-main.f9ba587

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.
@@ -1,1638 +0,0 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
- var node_exports = {};
30
- __export(node_exports, {
31
- CancellableObservableProvider: () => CancellableObservableProvider,
32
- DeferredTask: () => DeferredTask,
33
- Event: () => Event,
34
- MulticastObservable: () => MulticastObservable,
35
- Mutex: () => Mutex,
36
- MutexGuard: () => MutexGuard,
37
- Observable: () => import_zen_observable.default,
38
- ObservableProvider: () => ObservableProvider,
39
- PersistentLifecycle: () => PersistentLifecycle,
40
- PushStream: () => import_zen_push.default,
41
- SubscriptionList: () => SubscriptionList,
42
- SubscriptionSet: () => SubscriptionSet,
43
- TestStream: () => TestStream,
44
- TimeoutError: () => TimeoutError,
45
- Timer: () => Timer,
46
- Trigger: () => Trigger,
47
- TriggerState: () => TriggerState,
48
- UpdateScheduler: () => UpdateScheduler,
49
- addEventListener: () => addEventListener,
50
- addListener: () => addListener,
51
- asyncChain: () => asyncChain,
52
- asyncReturn: () => asyncReturn,
53
- asyncTimeout: () => asyncTimeout,
54
- combine: () => combine,
55
- createPromiseFromCallback: () => createPromiseFromCallback,
56
- debounce: () => debounce,
57
- dumpLeaks: () => dumpLeaks,
58
- interval: () => interval,
59
- latch: () => latch,
60
- makePushIterable: () => makePushIterable,
61
- observableError: () => observableError,
62
- onEvent: () => onEvent,
63
- runInContext: () => runInContext,
64
- runInContextAsync: () => runInContextAsync,
65
- scheduleExponentialBackoffTaskInterval: () => scheduleExponentialBackoffTaskInterval,
66
- scheduleMicroTask: () => scheduleMicroTask,
67
- scheduleTask: () => scheduleTask,
68
- scheduleTaskInterval: () => scheduleTaskInterval,
69
- sink: () => sink,
70
- sleep: () => sleep,
71
- sleepWithContext: () => sleepWithContext,
72
- streamToArray: () => streamToArray,
73
- synchronized: () => synchronized,
74
- timeout: () => timeout,
75
- toError: () => toError,
76
- trackLeaks: () => trackLeaks,
77
- trackResource: () => trackResource,
78
- trigger: () => trigger,
79
- unrefTimeout: () => unrefTimeout,
80
- until: () => until,
81
- untilError: () => untilError,
82
- untilPromise: () => untilPromise,
83
- waitForCondition: () => waitForCondition,
84
- waitForEvent: () => waitForEvent
85
- });
86
- module.exports = __toCommonJS(node_exports);
87
- var import_util = require("@dxos/util");
88
- var import_context = require("@dxos/context");
89
- var import_context2 = require("@dxos/context");
90
- var import_invariant = require("@dxos/invariant");
91
- var import_util2 = require("@dxos/util");
92
- var import_debug = require("@dxos/debug");
93
- var import_zen_observable = __toESM(require("zen-observable"));
94
- var import_zen_push = __toESM(require("zen-push"));
95
- var import_util3 = require("@dxos/util");
96
- var import_context3 = require("@dxos/context");
97
- var import_debug2 = require("@dxos/debug");
98
- var import_log = require("@dxos/log");
99
- var import_context4 = require("@dxos/context");
100
- var import_debug3 = require("@dxos/debug");
101
- var import_debug4 = require("@dxos/debug");
102
- var import_log2 = require("@dxos/log");
103
- var import_invariant2 = require("@dxos/invariant");
104
- var import_node_stream = require("node:stream");
105
- var createPromiseFromCallback = (run) => new Promise((resolve, reject) => {
106
- run((error, value) => {
107
- if (error) {
108
- reject(error);
109
- } else {
110
- resolve(value);
111
- }
112
- });
113
- });
114
- var asyncChain = (chain) => async (elements) => {
115
- let result = await elements;
116
- for (const part of chain) {
117
- result = await Promise.all(result.map(async (element) => await part(element)));
118
- }
119
- return result;
120
- };
121
- var combine = (...cleanupFns) => {
122
- return () => {
123
- cleanupFns.flat().forEach((cleanupFn) => cleanupFn());
124
- };
125
- };
126
- var timeout = (cb, ms = 0) => {
127
- const t = setTimeout(cb, ms);
128
- return () => clearTimeout(t);
129
- };
130
- var interval = (cb, ms) => {
131
- const t = setInterval(cb, ms);
132
- return () => clearInterval(t);
133
- };
134
- function addEventListener(target, type, listener, options) {
135
- target.addEventListener(type, listener, options);
136
- return () => target.removeEventListener(type, listener, options);
137
- }
138
- var SubscriptionList = class {
139
- constructor() {
140
- this._cleanups = [];
141
- }
142
- add(cb) {
143
- this._cleanups.push(cb);
144
- return this;
145
- }
146
- clear() {
147
- this._cleanups.forEach((cb) => cb());
148
- this._cleanups.length = 0;
149
- }
150
- };
151
- var SubscriptionSet = class {
152
- constructor(keyProjection) {
153
- this._cleanupMap = new import_util.ComplexMap(keyProjection);
154
- }
155
- set(key, cb) {
156
- this._cleanupMap.set(key, cb);
157
- return this;
158
- }
159
- clear() {
160
- this._cleanupMap.forEach((cb) => cb());
161
- this._cleanupMap.clear();
162
- }
163
- };
164
- var debounce = (cb, wait = 100) => {
165
- let t;
166
- return (...args) => {
167
- clearTimeout(t);
168
- t = setTimeout(() => cb(...args), wait);
169
- };
170
- };
171
- var toError = (err) => err === void 0 || typeof err === "string" ? new Error(err) : err;
172
- var TimeoutError = class extends Error {
173
- constructor(timeout2, label) {
174
- super(timeout2 ? `Timeout [${timeout2.toLocaleString()}ms]${label === void 0 ? "" : `: ${label}`}` : "Timeout");
175
- }
176
- };
177
- var observableError = (observable, err) => {
178
- if (err instanceof TimeoutError) {
179
- observable.callback.onTimeout?.(err);
180
- } else {
181
- observable.callback.onError(toError(err));
182
- }
183
- };
184
- var sleep = (ms) => {
185
- return new Promise((resolve) => {
186
- const finish = Date.now() + ms;
187
- const sleeper = () => {
188
- const delta = finish - Date.now();
189
- if (delta > 0) {
190
- setTimeout(sleeper, delta);
191
- } else {
192
- resolve();
193
- }
194
- };
195
- sleeper();
196
- });
197
- };
198
- var asyncReturn = () => sleep(0);
199
- var asyncTimeout = async (promise, timeout2, err) => {
200
- let timeoutId;
201
- const throwable = err === void 0 || typeof err === "string" ? new TimeoutError(timeout2, err) : err;
202
- const timeoutPromise = new Promise((resolve, reject) => {
203
- timeoutId = setTimeout(() => {
204
- reject(throwable);
205
- }, timeout2);
206
- unrefTimeout(timeoutId);
207
- });
208
- const conditionTimeout = typeof promise === "function" ? createPromiseFromCallback(promise) : promise;
209
- return await Promise.race([
210
- conditionTimeout,
211
- timeoutPromise
212
- ]).finally(() => {
213
- clearTimeout(timeoutId);
214
- });
215
- };
216
- var unrefTimeout = (timeoutId) => {
217
- if (typeof timeoutId === "object" && "unref" in timeoutId) {
218
- timeoutId.unref();
219
- }
220
- };
221
- var sleepWithContext = (ctx, ms) => {
222
- const error = new import_context.ContextDisposedError();
223
- return new Promise((resolve, reject) => {
224
- if (ctx.disposed) {
225
- reject(error);
226
- return;
227
- }
228
- const timeout2 = setTimeout(() => {
229
- clearDispose();
230
- resolve();
231
- }, ms);
232
- const clearDispose = ctx.onDispose(() => {
233
- clearTimeout(timeout2);
234
- reject(error);
235
- });
236
- });
237
- };
238
- var onEvent = (eventEmitter, eventName, callback) => {
239
- eventEmitter.on(eventName, callback);
240
- return () => eventEmitter.off(eventName, callback);
241
- };
242
- var addListener = (eventEmitter, eventName, callback) => {
243
- const off = onEvent(eventEmitter, eventName, callback);
244
- return {
245
- remove: () => off()
246
- };
247
- };
248
- var waitForEvent = (eventEmitter, eventName, test, timeout2, error) => {
249
- let off;
250
- const promise = new Promise((resolve) => {
251
- off = onEvent(eventEmitter, eventName, (...args) => {
252
- if (!test || test(...args)) {
253
- resolve(...args);
254
- }
255
- });
256
- });
257
- return timeout2 ? asyncTimeout(promise, timeout2, error ?? new Error()).finally(off) : promise.finally(off);
258
- };
259
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/common/async/src/events.ts";
260
- var DO_NOT_ERROR_ON_ASYNC_CALLBACK = true;
261
- var Event = class _Event {
262
- constructor() {
263
- this._listeners = /* @__PURE__ */ new Set();
264
- this._effects = /* @__PURE__ */ new Set();
265
- }
266
- /**
267
- * Wrap objects that have on/off style event emitters.
268
- */
269
- static wrap(emitter, eventName) {
270
- const event = new _Event();
271
- event.addEffect(() => {
272
- const onEvent2 = (data) => event.emit(data);
273
- emitter.on(eventName, onEvent2);
274
- return () => emitter.off(eventName, onEvent2);
275
- });
276
- return event;
277
- }
278
- /**
279
- * Emit an event.
280
- * In most cases should only be called by the class or entity containing the event.
281
- * All listeners are called in order of subscription with persistent ones first.
282
- * Listeners are called synchronously in the same stack.
283
- * A thrown exception in the listener will stop the event from being emitted to the rest of the listeners.
284
- *
285
- * @param data param that will be passed to all listeners.
286
- */
287
- emit(data) {
288
- for (const listener of this._listeners) {
289
- listener.trigger(data);
290
- if (listener.once) {
291
- this._listeners.delete(listener);
292
- }
293
- }
294
- }
295
- /**
296
- * Emit an event and wait for async listeners to complete.
297
- * In most cases should only be called by the class or entity containing the event.
298
- * All listeners are called in order of subscription with persistent ones first.
299
- * Listeners are called sequentially.
300
- *
301
- * @param data param that will be passed to all listeners.
302
- */
303
- async emitAsync(data) {
304
- for (const listener of this._listeners) {
305
- await listener.triggerAsync(data);
306
- if (listener.once) {
307
- this._listeners.delete(listener);
308
- }
309
- }
310
- }
311
- on(_ctx, _callback, options) {
312
- const [ctx, callback] = _ctx instanceof import_context2.Context ? [
313
- _ctx,
314
- _callback
315
- ] : [
316
- new import_context2.Context(void 0, {
317
- F: __dxlog_file,
318
- L: 132
319
- }),
320
- _ctx
321
- ];
322
- const weak = !!options?.weak;
323
- const once = !!options?.once;
324
- const listener = new EventListener(this, callback, ctx, once, weak);
325
- this._addListener(listener);
326
- return () => {
327
- this._removeListener(listener);
328
- };
329
- }
330
- /**
331
- * Unsubscribe this callback from new events. Includes persistent and once-listeners.
332
- * NOTE: It is recommended to use `Event.on`'s return value instead.
333
- * If the callback is not subscribed this is no-op.
334
- *
335
- * @param callback
336
- */
337
- off(callback) {
338
- for (const listener of this._listeners) {
339
- if (listener.derefCallback() === callback) {
340
- this._removeListener(listener);
341
- }
342
- }
343
- }
344
- once(_ctx, _callback) {
345
- const [ctx, callback] = _ctx instanceof import_context2.Context ? [
346
- _ctx,
347
- _callback
348
- ] : [
349
- new import_context2.Context(void 0, {
350
- F: __dxlog_file,
351
- L: 169
352
- }),
353
- _ctx
354
- ];
355
- const listener = new EventListener(this, callback, ctx, true, false);
356
- this._addListener(listener);
357
- return () => {
358
- this._removeListener(listener);
359
- };
360
- }
361
- /**
362
- * An async iterator that iterates over events.
363
- * This iterator runs indefinitely.
364
- */
365
- async *[Symbol.asyncIterator]() {
366
- while (true) {
367
- yield await new Promise((resolve) => {
368
- this.once(resolve);
369
- });
370
- }
371
- }
372
- /**
373
- * Returns a promise that resolves with the first event emitted that matches the provided predicate.
374
- *
375
- * @param predicate
376
- */
377
- waitFor(predicate) {
378
- return new Promise((resolve) => {
379
- const unsubscribe = this.on((data) => {
380
- if (predicate(data)) {
381
- unsubscribe();
382
- resolve(data);
383
- }
384
- });
385
- });
386
- }
387
- /**
388
- * Returns a promise that resolves once a specific number of events was emitted since this method was called.
389
- *
390
- * @param expectedCount
391
- */
392
- waitForCount(expectedCount) {
393
- let count = 0;
394
- return this.waitFor(() => ++count === expectedCount);
395
- }
396
- /**
397
- * Similar to waitFor, but the promise resolves immediately if the condition is already true.
398
- */
399
- // TODO(burdon): Should pass event property to predicate.
400
- async waitForCondition(predicate) {
401
- if (!predicate()) {
402
- await this.waitFor(predicate);
403
- }
404
- }
405
- /**
406
- * Returns the number of persistent listeners.
407
- */
408
- listenerCount() {
409
- return this._listeners.size;
410
- }
411
- /**
412
- * Add a side effect that will be activated once the event has at least one subscriber.
413
- * The provided callback can return a function that will be used to clean up after the last subscriber unsubscribes from the event.
414
- * The API is similar to `useEffect` from React.
415
- *
416
- * ## Example:
417
- * ```typescript
418
- * event.addEffect(() => {
419
- * // do stuff
420
- * return () => {
421
- * // clean-up
422
- * };
423
- * });
424
- * ```
425
- *
426
- * @returns Callback that will remove this effect once called.
427
- */
428
- addEffect(effect) {
429
- const handle = {
430
- effect,
431
- cleanup: void 0
432
- };
433
- if (this.listenerCount() > 0) {
434
- handle.cleanup = handle.effect();
435
- }
436
- this._effects.add(handle);
437
- return () => {
438
- handle.cleanup?.();
439
- this._effects.delete(handle);
440
- };
441
- }
442
- /**
443
- * Triggers an event with at least `timeout` milliseconds between each event.
444
- * If the event is triggered more often, the event is delayed until the timeout is reached.
445
- * If event is emitted for the first time or event wasn't fired for `timeout` milliseconds,
446
- * the event is emitted after `timeout / 8` ms.
447
- */
448
- // TODO(burdon): Factor out generic function.
449
- debounce(timeout2 = 0) {
450
- let firing;
451
- let lastFired;
452
- const debouncedEvent = new _Event();
453
- debouncedEvent.addEffect(() => {
454
- const unsubscribe = this.on(() => {
455
- if (!firing) {
456
- const fireIn = !lastFired || Date.now() - lastFired > timeout2 ? timeout2 / 8 : timeout2;
457
- firing = setTimeout(() => {
458
- lastFired = Date.now();
459
- firing = void 0;
460
- debouncedEvent.emit();
461
- }, fireIn);
462
- }
463
- });
464
- return () => {
465
- unsubscribe();
466
- clearTimeout(firing);
467
- };
468
- });
469
- return debouncedEvent;
470
- }
471
- /**
472
- * Turn any variant of `Event<T>` into an `Event<void>` discarding the callback parameter.
473
- */
474
- discardParameter() {
475
- return this;
476
- }
477
- /**
478
- * Pipe the events into another event.
479
- * @param event
480
- */
481
- pipeInto(event) {
482
- return this.on((data) => event.emit(data));
483
- }
484
- /**
485
- * Overridden to not return implementation details.
486
- */
487
- toJSON() {
488
- return {
489
- listenerCount: this.listenerCount()
490
- };
491
- }
492
- _addListener(listener) {
493
- this._listeners.add(listener);
494
- if (this.listenerCount() === 1) {
495
- this._runEffects();
496
- }
497
- }
498
- /**
499
- * @internal
500
- */
501
- _removeListener(listener) {
502
- this._listeners.delete(listener);
503
- listener.remove();
504
- if (this.listenerCount() === 0) {
505
- this._cleanupEffects();
506
- }
507
- }
508
- _runEffects() {
509
- for (const handle of this._effects) {
510
- handle.cleanup = handle.effect();
511
- }
512
- }
513
- _cleanupEffects() {
514
- for (const handle of this._effects) {
515
- handle.cleanup?.();
516
- handle.cleanup = void 0;
517
- }
518
- }
519
- };
520
- var EventListener = class {
521
- constructor(event, listener, ctx, once, weak) {
522
- this.ctx = ctx;
523
- this.once = once;
524
- this.weak = weak;
525
- this._clearDispose = void 0;
526
- this._clearDispose = ctx.onDispose(() => {
527
- event._removeListener(this);
528
- });
529
- if (weak) {
530
- this.callback = new WeakRef(listener);
531
- weakListeners().registry?.register(listener, {
532
- event: new WeakRef(event),
533
- listener: this
534
- }, this);
535
- } else {
536
- this.callback = listener;
537
- }
538
- }
539
- derefCallback() {
540
- return this.weak ? this.callback.deref() : this.callback;
541
- }
542
- trigger(data) {
543
- let result;
544
- try {
545
- const callback = this.derefCallback();
546
- result = callback?.(data);
547
- } catch (err) {
548
- this.ctx.raise(err);
549
- }
550
- if (!DO_NOT_ERROR_ON_ASYNC_CALLBACK) {
551
- if (result instanceof Promise) {
552
- throw new TypeError("Event has async callbacks, use emitAsync instead");
553
- }
554
- }
555
- }
556
- async triggerAsync(data) {
557
- try {
558
- const callback = this.derefCallback();
559
- await callback?.(data);
560
- } catch (err) {
561
- this.ctx.raise(err);
562
- }
563
- }
564
- remove() {
565
- this._clearDispose?.();
566
- weakListeners().registry?.unregister(this);
567
- }
568
- };
569
- var weakListenersState = null;
570
- var FINALIZATION_REGISTRY_SUPPORTED = !!globalThis.FinalizationRegistry;
571
- var weakListeners = () => {
572
- if (!FINALIZATION_REGISTRY_SUPPORTED) {
573
- return {
574
- registry: void 0
575
- };
576
- }
577
- weakListenersState ??= new FinalizationRegistry(({ event, listener }) => {
578
- event.deref()?._removeListener(listener);
579
- });
580
- return {
581
- registry: weakListenersState
582
- };
583
- };
584
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/common/async/src/latch.ts";
585
- var latch = ({ count = 1, timeout: timeout2 } = {}) => {
586
- (0, import_invariant.invariant)(count >= 0, void 0, {
587
- F: __dxlog_file2,
588
- L: 19,
589
- S: void 0,
590
- A: [
591
- "count >= 0",
592
- ""
593
- ]
594
- });
595
- let t;
596
- let doResolve;
597
- let doReject;
598
- const promise = new Promise((resolve, reject) => {
599
- doResolve = (value) => {
600
- clearTimeout(t);
601
- resolve(value);
602
- };
603
- doReject = (err) => {
604
- clearTimeout(t);
605
- reject(err);
606
- };
607
- });
608
- if (count === 0) {
609
- setTimeout(() => {
610
- doResolve(0);
611
- });
612
- } else {
613
- if (timeout2) {
614
- t = setTimeout(() => {
615
- doReject(new Error(`Timed out after ${timeout2.toLocaleString()}ms`));
616
- }, timeout2);
617
- }
618
- }
619
- let i = 0;
620
- return [
621
- async () => await promise,
622
- () => {
623
- if (++i === count) {
624
- doResolve(i);
625
- }
626
- return i;
627
- },
628
- (err) => doReject(err)
629
- ];
630
- };
631
- var Mutex = class {
632
- constructor() {
633
- this._queue = Promise.resolve();
634
- this._queueLength = 0;
635
- this._tag = null;
636
- }
637
- get tag() {
638
- return this._tag;
639
- }
640
- isLocked() {
641
- return this._queueLength > 0;
642
- }
643
- /**
644
- * Acquires the lock.
645
- * Caller is responsible for releasing the lock using the returned callback.
646
- * NOTE: Using `executeSynchronized` is preferred over using `acquire` directly.
647
- * @returns Release callback
648
- */
649
- async acquire(tag) {
650
- const prev = this._queue;
651
- let guard;
652
- this._queueLength++;
653
- this._queue = new Promise((resolve) => {
654
- guard = new MutexGuard(() => {
655
- this._queueLength--;
656
- this._tag = null;
657
- resolve();
658
- });
659
- });
660
- await prev;
661
- if (tag !== void 0) {
662
- this._tag = tag;
663
- }
664
- return guard;
665
- }
666
- /**
667
- * Waits for all previous executions to complete and then executes a given function.
668
- * Only a single function can be executed at a time.
669
- * Function are executed in the same order as `executeSynchronized` is called.
670
- * WARNING: Calling `executeSynchronized` inside of `executeSynchronized` on the same lock instance is a deadlock.
671
- */
672
- async executeSynchronized(fun) {
673
- const guard = await this.acquire();
674
- try {
675
- return await fun();
676
- } finally {
677
- guard.release();
678
- }
679
- }
680
- };
681
- var MutexGuard = class {
682
- constructor(_release) {
683
- this._release = _release;
684
- }
685
- /**
686
- * Releases the lock.
687
- */
688
- release() {
689
- this._release();
690
- }
691
- [Symbol.dispose]() {
692
- this.release();
693
- }
694
- };
695
- var classMutexSymbol = Symbol("class-mutex");
696
- var FORCE_DISABLE_WARNING = false;
697
- var enableWarning = !FORCE_DISABLE_WARNING && globalThis.mochaExecutor;
698
- var synchronized = (target, propertyName, descriptor) => {
699
- const method = descriptor.value;
700
- descriptor.value = async function synchronizedMethod(...args) {
701
- const mutex = this[classMutexSymbol] ??= new Mutex();
702
- const tag = `${target.constructor.name}.${propertyName}`;
703
- let guard;
704
- if (!enableWarning) {
705
- guard = await mutex.acquire(tag);
706
- } else {
707
- guard = await (0, import_debug.warnAfterTimeout)(1e4, `lock on ${tag} (taken by ${mutex.tag})`, () => mutex.acquire(tag));
708
- }
709
- try {
710
- return await method.apply(this, args);
711
- } finally {
712
- guard.release();
713
- }
714
- };
715
- Object.defineProperty(descriptor.value, "name", {
716
- value: propertyName + "$synchronized"
717
- });
718
- };
719
- var trigger = (timeout2) => {
720
- let callback;
721
- const promise = new Promise((resolve, reject) => {
722
- if (timeout2) {
723
- setTimeout(() => reject(new Error(`Timed out after ${timeout2.toLocaleString()}ms`)), timeout2);
724
- }
725
- callback = resolve;
726
- });
727
- const provider = () => promise;
728
- const resolver = (value) => callback(value);
729
- return [
730
- provider,
731
- resolver
732
- ];
733
- };
734
- var TriggerState = /* @__PURE__ */ function(TriggerState2) {
735
- TriggerState2["WAITING"] = "WAITING";
736
- TriggerState2["RESOLVED"] = "RESOLVED";
737
- TriggerState2["REJECTED"] = "REJECTED";
738
- return TriggerState2;
739
- }({});
740
- var Trigger = class {
741
- constructor(_options = {
742
- autoReset: false
743
- }) {
744
- this._options = _options;
745
- this._state = "WAITING";
746
- this.reset();
747
- }
748
- get state() {
749
- return this._state;
750
- }
751
- /**
752
- * Wait until wake is called, with optional timeout.
753
- */
754
- async wait({ timeout: timeout2 } = {}) {
755
- if (timeout2) {
756
- return asyncTimeout(this._promise, timeout2, new TimeoutError(timeout2));
757
- } else {
758
- return this._promise;
759
- }
760
- }
761
- /**
762
- * Wake blocked callers (if any).
763
- * NOOP if the trigger is already resolved.
764
- */
765
- wake(value) {
766
- if (this._state !== "WAITING") {
767
- return this;
768
- }
769
- this._state = "RESOLVED";
770
- this._resolve(value);
771
- if (this._options.autoReset) {
772
- return this.reset();
773
- }
774
- return this;
775
- }
776
- /**
777
- * Reset promise (new waiters will wait).
778
- */
779
- reset() {
780
- this._state = "WAITING";
781
- this._promise = new Promise((resolve, reject) => {
782
- this._resolve = resolve;
783
- this._reject = reject;
784
- });
785
- this._promise.catch(() => {
786
- });
787
- return this;
788
- }
789
- /**
790
- * Throw error to blocked callers (if any).
791
- * NOOP if the trigger is already resolved.
792
- */
793
- throw(error) {
794
- if (this._state !== "WAITING") {
795
- return this;
796
- }
797
- this._state = "REJECTED";
798
- this._reject(error);
799
- if (this._options.autoReset) {
800
- return this.reset();
801
- }
802
- return this;
803
- }
804
- };
805
- var MulticastObservable = class _MulticastObservable extends import_zen_observable.default {
806
- constructor(subscriber, _value) {
807
- super((observer) => this._subscribe(observer)), this._value = _value, this._observers = /* @__PURE__ */ new Set(), this._completed = new Trigger(), this._handlers = {
808
- next: (value) => {
809
- this._value = value;
810
- this._observers.forEach((observer) => observer.next?.(value));
811
- },
812
- error: (err) => {
813
- this._observers.forEach((observer) => observer.error?.(err));
814
- },
815
- complete: () => {
816
- this._completed.wake();
817
- this._observers.forEach((observer) => observer.complete?.());
818
- }
819
- };
820
- this._observable = typeof subscriber === "function" ? new import_zen_observable.default(subscriber) : subscriber;
821
- this._observable.subscribe(this._handlers);
822
- }
823
- static from(value, initialValue) {
824
- if ("emit" in value) {
825
- return new _MulticastObservable((observer) => {
826
- value.on((data) => {
827
- observer.next(data);
828
- });
829
- }, initialValue);
830
- }
831
- const observable = import_zen_observable.default.from(value);
832
- return new _MulticastObservable(observable, initialValue);
833
- }
834
- static of(...items) {
835
- return new _MulticastObservable(import_zen_observable.default.of(...items.slice(1)), items[0]);
836
- }
837
- /**
838
- * @returns Stable reference to an observable that always returns `undefined`.
839
- */
840
- static empty() {
841
- return EMPTY_OBSERVABLE;
842
- }
843
- /**
844
- * Get the current value of the observable.
845
- */
846
- get() {
847
- if (this._value === void 0) {
848
- throw new Error("MulticastObservable is not initialized.");
849
- }
850
- return this._value;
851
- }
852
- /**
853
- * Wait for the observable to complete.
854
- *
855
- * @returns Promise that resolves to the value of the observable at the time of completion.
856
- */
857
- async wait({ timeout: timeout2 } = {}) {
858
- await this._completed.wait({
859
- timeout: timeout2
860
- });
861
- return this.get();
862
- }
863
- forEach(callback) {
864
- return this._observable.forEach(callback);
865
- }
866
- map(callback) {
867
- return new _MulticastObservable(this._observable.map(callback), this._value && callback(this._value));
868
- }
869
- filter(callback) {
870
- return new _MulticastObservable(this._observable.filter(callback), this._value && callback(this._value) ? this._value : void 0);
871
- }
872
- reduce(callback, initialValue) {
873
- return new _MulticastObservable(initialValue ? this._observable.reduce(callback, initialValue) : this._observable.reduce(callback), initialValue ?? this._value);
874
- }
875
- flatMap(callback) {
876
- return new _MulticastObservable(this._observable.flatMap(callback), this._value && callback(this._value).get());
877
- }
878
- concat(...observables) {
879
- return new _MulticastObservable(this._observable.concat(...observables), this._value);
880
- }
881
- /**
882
- * Concatenates multicast observables without losing the current value.
883
- * @param reducer reduces the values of any multicast observables being concatenated into a single value
884
- * @param observables observables to concatenate
885
- * @returns concatenated observable
886
- */
887
- losslessConcat(reducer, ...observables) {
888
- const multicast = observables.filter((observable) => observable instanceof _MulticastObservable);
889
- const value = reducer(this._value, multicast.map((observable) => observable.get()));
890
- return new _MulticastObservable(this._observable.concat(...observables), value);
891
- }
892
- _subscribe(observer) {
893
- if (!this._observers.has(observer)) {
894
- this._observers.add(observer);
895
- }
896
- if (this._value !== void 0) {
897
- observer.next?.(this._value);
898
- }
899
- return () => {
900
- this._observers.delete(observer);
901
- };
902
- }
903
- };
904
- var EMPTY_OBSERVABLE = MulticastObservable.of(null);
905
- var ObservableProvider = class {
906
- constructor() {
907
- this._handlers = /* @__PURE__ */ new Set();
908
- this._proxy = (0, import_util3.createSetDispatch)({
909
- handlers: this._handlers
910
- });
911
- }
912
- /**
913
- * Proxy used to dispatch callbacks to each subscription.
914
- */
915
- get callback() {
916
- return this._proxy;
917
- }
918
- get value() {
919
- return this._value;
920
- }
921
- setValue(value) {
922
- this._value = value;
923
- }
924
- subscribe(handler) {
925
- this._handlers.add(handler);
926
- return () => {
927
- this._handlers.delete(handler);
928
- };
929
- }
930
- };
931
- var CancellableObservableProvider = class extends ObservableProvider {
932
- constructor(_handleCancel) {
933
- super(), this._handleCancel = _handleCancel, this._cancelled = false;
934
- }
935
- get cancelled() {
936
- return this._cancelled;
937
- }
938
- async cancel() {
939
- if (this._cancelled) {
940
- return;
941
- }
942
- this._cancelled = true;
943
- await this._handleCancel?.();
944
- this.callback.onCancelled?.();
945
- }
946
- };
947
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/common/async/src/track-leaks.ts";
948
- var enabled = typeof process !== "undefined" && !!process.env.DX_TRACK_LEAKS;
949
- var openResources = /* @__PURE__ */ new Set();
950
- var handleSymbol = Symbol("checkLeaksHandle");
951
- var trackResource = (resourceProvider) => {
952
- if (!enabled) {
953
- return () => {
954
- };
955
- }
956
- const resource = resourceProvider();
957
- openResources.add(resource);
958
- return () => {
959
- openResources.delete(resource);
960
- };
961
- };
962
- var trackLeaks = (open, close) => (target) => {
963
- if (!enabled) {
964
- return;
965
- }
966
- const openMethod = target.prototype[open];
967
- const closeMethod = target.prototype[close];
968
- if (!openMethod || !closeMethod) {
969
- throw new Error(`Cannot find ${open} or ${close} method in ${target.name}`);
970
- }
971
- {
972
- target.prototype[open] = async function(...args) {
973
- this[handleSymbol] = trackResource(() => ({
974
- name: target.name,
975
- openStack: new import_debug4.StackTrace()
976
- }));
977
- return openMethod.apply(this, args);
978
- };
979
- Object.defineProperty(target.prototype[open], "name", {
980
- value: open + "$checkLeaks"
981
- });
982
- }
983
- {
984
- target.prototype[close] = async function(...args) {
985
- this[handleSymbol]?.();
986
- return closeMethod.apply(this, args);
987
- };
988
- Object.defineProperty(target.prototype[close], "name", {
989
- value: close + "$checkLeaks"
990
- });
991
- }
992
- };
993
- var dumpLeaks = () => {
994
- if (!enabled) {
995
- return;
996
- }
997
- import_log2.log.info(`Leaked resources ${openResources.size}:`, void 0, {
998
- F: __dxlog_file3,
999
- L: 82,
1000
- S: void 0,
1001
- C: (f, a) => f(...a)
1002
- });
1003
- for (const resource of openResources) {
1004
- import_log2.log.info(`- ${resource.name} at`, void 0, {
1005
- F: __dxlog_file3,
1006
- L: 84,
1007
- S: void 0,
1008
- C: (f, a) => f(...a)
1009
- });
1010
- import_log2.log.info(resource.openStack.getStack(1), void 0, {
1011
- F: __dxlog_file3,
1012
- L: 85,
1013
- S: void 0,
1014
- C: (f, a) => f(...a)
1015
- });
1016
- import_log2.log.info("\n", void 0, {
1017
- F: __dxlog_file3,
1018
- L: 86,
1019
- S: void 0,
1020
- C: (f, a) => f(...a)
1021
- });
1022
- }
1023
- };
1024
- if (enabled) {
1025
- global.dxDumpLeaks = dumpLeaks;
1026
- }
1027
- var DeferredTask = class {
1028
- constructor(_ctx, _callback) {
1029
- this._ctx = _ctx;
1030
- this._callback = _callback;
1031
- this._scheduled = false;
1032
- this._currentTask = null;
1033
- this._nextTask = new Trigger();
1034
- }
1035
- get scheduled() {
1036
- return this._scheduled;
1037
- }
1038
- /**
1039
- * Schedule the task to run asynchronously.
1040
- */
1041
- schedule() {
1042
- if (this._scheduled) {
1043
- return;
1044
- }
1045
- scheduleTask(this._ctx, async () => {
1046
- await this._currentTask;
1047
- this._scheduled = false;
1048
- const completionTrigger = this._nextTask;
1049
- this._nextTask = new Trigger();
1050
- this._currentTask = runInContextAsync(this._ctx, () => this._callback()).then(() => {
1051
- completionTrigger.wake();
1052
- });
1053
- });
1054
- this._scheduled = true;
1055
- }
1056
- /**
1057
- * Schedule the task to run and wait for it to finish.
1058
- */
1059
- async runBlocking() {
1060
- if (this._ctx.disposed) {
1061
- throw new import_context4.ContextDisposedError();
1062
- }
1063
- this.schedule();
1064
- await this._nextTask.wait();
1065
- }
1066
- /**
1067
- * Waits for the current task to finish if it is running.
1068
- * Does not schedule a new task.
1069
- */
1070
- async join() {
1071
- await this._currentTask;
1072
- }
1073
- };
1074
- var runInContext = (ctx, fn) => {
1075
- try {
1076
- fn();
1077
- } catch (err) {
1078
- ctx.raise(err);
1079
- }
1080
- };
1081
- var runInContextAsync = async (ctx, fn) => {
1082
- try {
1083
- await fn();
1084
- } catch (err) {
1085
- ctx.raise(err);
1086
- }
1087
- };
1088
- var scheduleMicroTask = (ctx, fn) => {
1089
- queueMicrotask(async () => {
1090
- if (ctx.disposed) {
1091
- return;
1092
- }
1093
- await runInContextAsync(ctx, fn);
1094
- });
1095
- };
1096
- var scheduleTask = (ctx, fn, afterMs) => {
1097
- const clearTracking = trackResource(() => ({
1098
- name: `task (${fn.name || "anonymous"})`,
1099
- openStack: new import_debug3.StackTrace()
1100
- }));
1101
- const timeout2 = setTimeout(async () => {
1102
- clearDispose();
1103
- await runInContextAsync(ctx, fn);
1104
- clearTracking();
1105
- }, afterMs);
1106
- const clearDispose = ctx.onDispose(() => {
1107
- clearTracking();
1108
- clearTimeout(timeout2);
1109
- });
1110
- };
1111
- var scheduleTaskInterval = (ctx, task, interval2) => {
1112
- const clearTracking = trackResource(() => ({
1113
- name: `repeating task (${task.name || "anonymous"})`,
1114
- openStack: new import_debug3.StackTrace()
1115
- }));
1116
- let timeoutId;
1117
- const run = async () => {
1118
- await runInContextAsync(ctx, task);
1119
- if (ctx.disposed) {
1120
- return;
1121
- }
1122
- timeoutId = setTimeout(run, interval2);
1123
- };
1124
- timeoutId = setTimeout(run, interval2);
1125
- ctx.onDispose(() => {
1126
- clearTracking();
1127
- clearTimeout(timeoutId);
1128
- });
1129
- };
1130
- var scheduleExponentialBackoffTaskInterval = (ctx, task, initialInterval) => {
1131
- const clearTracking = trackResource(() => ({
1132
- name: `repeating task (${task.name || "anonymous"})`,
1133
- openStack: new import_debug3.StackTrace()
1134
- }));
1135
- let timeoutId;
1136
- let interval2 = initialInterval;
1137
- const repeat = async () => {
1138
- await runInContextAsync(ctx, task);
1139
- if (ctx.disposed) {
1140
- return;
1141
- }
1142
- interval2 *= 2;
1143
- timeoutId = setTimeout(repeat, interval2);
1144
- };
1145
- timeoutId = setTimeout(repeat, interval2);
1146
- ctx.onDispose(() => {
1147
- clearTracking();
1148
- clearTimeout(timeoutId);
1149
- });
1150
- };
1151
- function _ts_decorate(decorators, target, key, desc) {
1152
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1153
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1154
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1155
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1156
- }
1157
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/common/async/src/persistent-lifecycle.ts";
1158
- var INIT_RESTART_DELAY = 100;
1159
- var DEFAULT_MAX_RESTART_DELAY = 5e3;
1160
- var PersistentLifecycle = class extends import_context3.Resource {
1161
- constructor({ start, stop, onRestart, maxRestartDelay = DEFAULT_MAX_RESTART_DELAY }) {
1162
- super();
1163
- this._currentState = void 0;
1164
- this._restartTask = void 0;
1165
- this._restartAfter = 0;
1166
- this._start = start;
1167
- this._stop = stop;
1168
- this._onRestart = onRestart;
1169
- this._maxRestartDelay = maxRestartDelay;
1170
- }
1171
- get state() {
1172
- return this._currentState;
1173
- }
1174
- async _open() {
1175
- this._restartTask = new DeferredTask(this._ctx, async () => {
1176
- try {
1177
- await this._restart();
1178
- } catch (err) {
1179
- import_log.log.warn("Restart failed", {
1180
- err
1181
- }, {
1182
- F: __dxlog_file4,
1183
- L: 72,
1184
- S: this,
1185
- C: (f, a) => f(...a)
1186
- });
1187
- this._restartTask?.schedule();
1188
- }
1189
- });
1190
- this._currentState = await this._start().catch((err) => {
1191
- import_log.log.warn("Start failed", {
1192
- err
1193
- }, {
1194
- F: __dxlog_file4,
1195
- L: 78,
1196
- S: this,
1197
- C: (f, a) => f(...a)
1198
- });
1199
- this._restartTask?.schedule();
1200
- return void 0;
1201
- });
1202
- }
1203
- async _close() {
1204
- await this._restartTask?.join();
1205
- await this._stopCurrentState();
1206
- this._restartTask = void 0;
1207
- }
1208
- async _restart() {
1209
- (0, import_log.log)(`restarting in ${this._restartAfter}ms`, {
1210
- state: this._lifecycleState
1211
- }, {
1212
- F: __dxlog_file4,
1213
- L: 91,
1214
- S: this,
1215
- C: (f, a) => f(...a)
1216
- });
1217
- await this._stopCurrentState();
1218
- if (this._lifecycleState !== import_context3.LifecycleState.OPEN) {
1219
- return;
1220
- }
1221
- await (0, import_context3.cancelWithContext)(this._ctx, sleep(this._restartAfter));
1222
- this._restartAfter = Math.min(Math.max(this._restartAfter * 2, INIT_RESTART_DELAY), this._maxRestartDelay);
1223
- await (0, import_debug2.warnAfterTimeout)(5e3, "Connection establishment takes too long", async () => {
1224
- this._currentState = await this._start();
1225
- });
1226
- this._restartAfter = 0;
1227
- await this._onRestart?.();
1228
- }
1229
- async _stopCurrentState() {
1230
- if (this._currentState) {
1231
- try {
1232
- await this._stop(this._currentState);
1233
- } catch (err) {
1234
- import_log.log.catch(err, void 0, {
1235
- F: __dxlog_file4,
1236
- L: 113,
1237
- S: this,
1238
- C: (f, a) => f(...a)
1239
- });
1240
- }
1241
- this._currentState = void 0;
1242
- }
1243
- }
1244
- /**
1245
- * Scheduling restart should be done from outside.
1246
- */
1247
- async scheduleRestart() {
1248
- if (this._lifecycleState !== import_context3.LifecycleState.OPEN) {
1249
- return;
1250
- }
1251
- this._restartTask.schedule();
1252
- }
1253
- };
1254
- _ts_decorate([
1255
- synchronized
1256
- ], PersistentLifecycle.prototype, "_open", null);
1257
- _ts_decorate([
1258
- synchronized
1259
- ], PersistentLifecycle.prototype, "scheduleRestart", null);
1260
- var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/common/async/src/push-iterable.ts";
1261
- var makePushIterable = () => {
1262
- const buf = [];
1263
- const trigger2 = new Trigger({
1264
- autoReset: true
1265
- });
1266
- return {
1267
- [Symbol.asyncIterator]() {
1268
- return {
1269
- next: async () => {
1270
- while (buf.length === 0) {
1271
- await trigger2.wait();
1272
- }
1273
- const item = buf.shift();
1274
- (0, import_invariant2.invariant)(item, void 0, {
1275
- F: __dxlog_file5,
1276
- L: 42,
1277
- S: this,
1278
- A: [
1279
- "item",
1280
- ""
1281
- ]
1282
- });
1283
- switch (item.kind) {
1284
- case "next":
1285
- return {
1286
- value: item.value,
1287
- done: false
1288
- };
1289
- case "return":
1290
- return {
1291
- value: item.value,
1292
- done: true
1293
- };
1294
- case "throw":
1295
- throw item.value;
1296
- }
1297
- }
1298
- };
1299
- },
1300
- next: (value) => {
1301
- buf.push({
1302
- kind: "next",
1303
- value
1304
- });
1305
- trigger2.wake();
1306
- },
1307
- return: (value) => {
1308
- buf.push({
1309
- kind: "return",
1310
- value
1311
- });
1312
- trigger2.wake();
1313
- },
1314
- throw: (value) => {
1315
- buf.push({
1316
- kind: "throw",
1317
- value
1318
- });
1319
- trigger2.wake();
1320
- }
1321
- };
1322
- };
1323
- var sink = (emitter, event, count = 1) => {
1324
- const [getPromise, resolve] = trigger();
1325
- let counter = 0;
1326
- const listener = () => {
1327
- if (++counter === count) {
1328
- emitter.off(event, listener);
1329
- resolve();
1330
- }
1331
- };
1332
- emitter.on(event, listener);
1333
- return getPromise();
1334
- };
1335
- var streamToArray = (stream) => {
1336
- let deferred;
1337
- if (!stream.readable) {
1338
- deferred = Promise.resolve([]);
1339
- } else {
1340
- deferred = new Promise((resolve, reject) => {
1341
- if (!stream.readable) {
1342
- return resolve([]);
1343
- }
1344
- let arr = [];
1345
- const onData = (doc) => {
1346
- arr?.push(doc);
1347
- };
1348
- const onEnd = (err) => {
1349
- if (err) {
1350
- reject(err);
1351
- } else {
1352
- resolve(arr);
1353
- }
1354
- cleanup();
1355
- };
1356
- const onClose = () => {
1357
- resolve(arr);
1358
- cleanup();
1359
- };
1360
- const cleanup = () => {
1361
- arr = [];
1362
- stream.removeListener("data", onData);
1363
- stream.removeListener("end", onEnd);
1364
- stream.removeListener("error", onEnd);
1365
- stream.removeListener("close", onClose);
1366
- };
1367
- stream.on("data", onData);
1368
- stream.on("end", onEnd);
1369
- stream.on("error", onEnd);
1370
- stream.on("close", onClose);
1371
- });
1372
- }
1373
- return deferred;
1374
- };
1375
- var TestStream = class extends import_node_stream.Duplex {
1376
- constructor() {
1377
- super(...arguments);
1378
- this._received = Buffer.alloc(0);
1379
- this._onWrite = new Event();
1380
- }
1381
- static async assertConnectivity(stream1, stream2, { timeout: timeout2 = 200 } = {}) {
1382
- stream1.push("ping");
1383
- stream2.push("pong");
1384
- await Promise.all([
1385
- stream2.assertReceivedAsync("ping", {
1386
- timeout: timeout2
1387
- }),
1388
- stream1.assertReceivedAsync("pong", {
1389
- timeout: timeout2
1390
- })
1391
- ]);
1392
- }
1393
- _write(chunk, encoding, callback) {
1394
- this._received = Buffer.concat([
1395
- this._received,
1396
- chunk
1397
- ]);
1398
- this._onWrite.emit();
1399
- callback();
1400
- }
1401
- _read(size) {
1402
- }
1403
- assertReceivedAsync(data, { timeout: timeout2 = 200 } = {}) {
1404
- const dataBuffer = Buffer.isBuffer(data) ? data : Buffer.from(data);
1405
- return asyncTimeout(this._onWrite.waitForCondition(() => this._received.equals(dataBuffer)), timeout2);
1406
- }
1407
- };
1408
- var waitForCondition = ({ condition, timeout: timeout2 = 0, interval: interval2 = 10, error, breakOnError = false }) => {
1409
- const stopTime = timeout2 ? Date.now() + timeout2 : 0;
1410
- const trigger2 = new Trigger();
1411
- const waiter = async () => {
1412
- while (!stopTime || Date.now() < stopTime) {
1413
- try {
1414
- const value = await condition();
1415
- if (value) {
1416
- trigger2.wake(value);
1417
- break;
1418
- }
1419
- } catch (err) {
1420
- if (breakOnError === true) {
1421
- trigger2.throw(err);
1422
- }
1423
- }
1424
- await sleep(interval2);
1425
- }
1426
- };
1427
- setTimeout(waiter, 0);
1428
- return trigger2.wait({
1429
- timeout: timeout2
1430
- });
1431
- };
1432
- var Timer = class {
1433
- constructor(_callback) {
1434
- this._callback = _callback;
1435
- this._state = new Event();
1436
- this._count = 0;
1437
- }
1438
- get state() {
1439
- return this._state;
1440
- }
1441
- get running() {
1442
- return !!this._timer;
1443
- }
1444
- start(options, cb) {
1445
- if (isNaN(options.count) || isNaN(options.interval)) {
1446
- throw new Error(`Invalid options: ${JSON.stringify(options)}`);
1447
- }
1448
- if (this.running) {
1449
- this.stop();
1450
- }
1451
- const stop = () => {
1452
- this.stop();
1453
- cb?.();
1454
- };
1455
- const run = () => {
1456
- if (this._count >= (options.count ?? 0)) {
1457
- stop();
1458
- } else {
1459
- const interval2 = (options.interval ?? 0) + Math.random() * (options.jitter ?? 0);
1460
- this._timer = setTimeout(async () => {
1461
- await this._callback(this._count++);
1462
- run();
1463
- }, interval2);
1464
- }
1465
- };
1466
- this._state.emit(true);
1467
- this._count = 0;
1468
- setTimeout(run);
1469
- return this;
1470
- }
1471
- stop() {
1472
- clearInterval(this._timer);
1473
- this._timer = void 0;
1474
- this._state.emit(false);
1475
- return this;
1476
- }
1477
- };
1478
- var until = (cb, timeout2) => {
1479
- return new Promise((resolve, reject) => {
1480
- const t = timeout2 && setTimeout(() => {
1481
- reject(new Error(`Timeout after ${t}ms`));
1482
- }, timeout2);
1483
- setTimeout(async () => {
1484
- try {
1485
- await cb((value) => {
1486
- t && clearTimeout(t);
1487
- resolve(value);
1488
- }, (error) => {
1489
- t && clearTimeout(t);
1490
- reject(error);
1491
- });
1492
- } catch (err) {
1493
- reject(err);
1494
- }
1495
- });
1496
- });
1497
- };
1498
- var untilPromise = (cb) => cb();
1499
- var untilError = (cb) => {
1500
- return new Promise((resolve, reject) => {
1501
- setTimeout(async () => {
1502
- try {
1503
- await cb();
1504
- reject(new Error("No error was thrown."));
1505
- } catch (err) {
1506
- resolve(err);
1507
- }
1508
- });
1509
- });
1510
- };
1511
- var TIME_PERIOD = 1e3;
1512
- var UpdateScheduler = class {
1513
- constructor(_ctx, _callback, _params = {}) {
1514
- this._ctx = _ctx;
1515
- this._callback = _callback;
1516
- this._params = _params;
1517
- this._promise = null;
1518
- this._scheduled = false;
1519
- this._lastUpdateTime = -TIME_PERIOD;
1520
- _ctx.onDispose(async () => {
1521
- await this._promise;
1522
- });
1523
- }
1524
- trigger() {
1525
- if (this._scheduled) {
1526
- return;
1527
- }
1528
- scheduleMicroTask(this._ctx, async () => {
1529
- await this._promise;
1530
- if (this._params.maxFrequency) {
1531
- const now = performance.now();
1532
- const delay = this._lastUpdateTime + TIME_PERIOD / this._params.maxFrequency - now;
1533
- if (delay > 0) {
1534
- await new Promise((resolve) => {
1535
- const timeoutId = setTimeout(() => {
1536
- clearContext();
1537
- resolve();
1538
- }, delay);
1539
- const clearContext = this._ctx.onDispose(() => {
1540
- clearTimeout(timeoutId);
1541
- resolve();
1542
- });
1543
- });
1544
- }
1545
- }
1546
- if (this._ctx.disposed) {
1547
- return;
1548
- }
1549
- this._lastUpdateTime = performance.now();
1550
- this._scheduled = false;
1551
- this._promise = this._callback().then(() => {
1552
- this._promise = null;
1553
- }, (error) => {
1554
- this._promise = null;
1555
- this._ctx.raise(error);
1556
- });
1557
- });
1558
- this._scheduled = true;
1559
- }
1560
- forceTrigger() {
1561
- scheduleMicroTask(this._ctx, async () => {
1562
- this._callback().catch((err) => this._ctx.raise(err));
1563
- });
1564
- }
1565
- /**
1566
- * Waits for the current task to finish if it is running.
1567
- * Does not schedule a new task.
1568
- */
1569
- async join() {
1570
- await this._promise;
1571
- }
1572
- /**
1573
- * Force schedule the task to run and wait for it to finish.
1574
- */
1575
- async runBlocking() {
1576
- await this._promise;
1577
- this._promise = this._callback();
1578
- await this._promise;
1579
- }
1580
- };
1581
- // Annotate the CommonJS export names for ESM import in node:
1582
- 0 && (module.exports = {
1583
- CancellableObservableProvider,
1584
- DeferredTask,
1585
- Event,
1586
- MulticastObservable,
1587
- Mutex,
1588
- MutexGuard,
1589
- Observable,
1590
- ObservableProvider,
1591
- PersistentLifecycle,
1592
- PushStream,
1593
- SubscriptionList,
1594
- SubscriptionSet,
1595
- TestStream,
1596
- TimeoutError,
1597
- Timer,
1598
- Trigger,
1599
- TriggerState,
1600
- UpdateScheduler,
1601
- addEventListener,
1602
- addListener,
1603
- asyncChain,
1604
- asyncReturn,
1605
- asyncTimeout,
1606
- combine,
1607
- createPromiseFromCallback,
1608
- debounce,
1609
- dumpLeaks,
1610
- interval,
1611
- latch,
1612
- makePushIterable,
1613
- observableError,
1614
- onEvent,
1615
- runInContext,
1616
- runInContextAsync,
1617
- scheduleExponentialBackoffTaskInterval,
1618
- scheduleMicroTask,
1619
- scheduleTask,
1620
- scheduleTaskInterval,
1621
- sink,
1622
- sleep,
1623
- sleepWithContext,
1624
- streamToArray,
1625
- synchronized,
1626
- timeout,
1627
- toError,
1628
- trackLeaks,
1629
- trackResource,
1630
- trigger,
1631
- unrefTimeout,
1632
- until,
1633
- untilError,
1634
- untilPromise,
1635
- waitForCondition,
1636
- waitForEvent
1637
- });
1638
- //# sourceMappingURL=index.cjs.map