@dxos/async 0.8.3 → 0.8.4-main.1068cf700f

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.
Files changed (65) hide show
  1. package/dist/lib/browser/index.mjs +346 -218
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node-esm/index.mjs +346 -218
  5. package/dist/lib/node-esm/index.mjs.map +4 -4
  6. package/dist/lib/node-esm/meta.json +1 -1
  7. package/dist/types/src/callback.d.ts +2 -1
  8. package/dist/types/src/callback.d.ts.map +1 -1
  9. package/dist/types/src/chain.d.ts +1 -1
  10. package/dist/types/src/chain.d.ts.map +1 -1
  11. package/dist/types/src/cleanup.d.ts +3 -2
  12. package/dist/types/src/cleanup.d.ts.map +1 -1
  13. package/dist/types/src/debounce.d.ts +34 -1
  14. package/dist/types/src/debounce.d.ts.map +1 -1
  15. package/dist/types/src/debounce.test.d.ts +2 -0
  16. package/dist/types/src/debounce.test.d.ts.map +1 -0
  17. package/dist/types/src/index.d.ts +0 -4
  18. package/dist/types/src/index.d.ts.map +1 -1
  19. package/dist/types/src/persistent-lifecycle.d.ts +2 -2
  20. package/dist/types/src/persistent-lifecycle.d.ts.map +1 -1
  21. package/dist/types/src/task-scheduling.d.ts +29 -1
  22. package/dist/types/src/task-scheduling.d.ts.map +1 -1
  23. package/dist/types/src/testing.d.ts +13 -0
  24. package/dist/types/src/testing.d.ts.map +1 -1
  25. package/dist/types/src/timeout.d.ts +1 -1
  26. package/dist/types/src/timeout.d.ts.map +1 -1
  27. package/dist/types/src/trigger.d.ts +11 -0
  28. package/dist/types/src/trigger.d.ts.map +1 -1
  29. package/dist/types/tsconfig.tsbuildinfo +1 -1
  30. package/package.json +13 -9
  31. package/src/callback.ts +3 -3
  32. package/src/chain.ts +1 -1
  33. package/src/cleanup.ts +6 -5
  34. package/src/debounce.test.ts +115 -0
  35. package/src/debounce.ts +88 -4
  36. package/src/event-emitter.test.ts +2 -1
  37. package/src/events.test.ts +1 -1
  38. package/src/index.ts +0 -4
  39. package/src/observable-value.test.ts +1 -1
  40. package/src/persistent-lifecycle.test.ts +1 -1
  41. package/src/persistent-lifecycle.ts +2 -2
  42. package/src/task-scheduling.ts +95 -1
  43. package/src/testing.test.ts +41 -1
  44. package/src/testing.ts +53 -0
  45. package/src/timeout.ts +23 -22
  46. package/src/trigger.ts +58 -1
  47. package/src/update-scheduler.ts +1 -1
  48. package/dist/lib/node/index.cjs +0 -1638
  49. package/dist/lib/node/index.cjs.map +0 -7
  50. package/dist/lib/node/meta.json +0 -1
  51. package/dist/types/src/latch.d.ts +0 -11
  52. package/dist/types/src/latch.d.ts.map +0 -1
  53. package/dist/types/src/sink.d.ts +0 -6
  54. package/dist/types/src/sink.d.ts.map +0 -1
  55. package/dist/types/src/types.d.ts +0 -2
  56. package/dist/types/src/types.d.ts.map +0 -1
  57. package/dist/types/src/until.d.ts +0 -14
  58. package/dist/types/src/until.d.ts.map +0 -1
  59. package/dist/types/src/until.test.d.ts +0 -2
  60. package/dist/types/src/until.test.d.ts.map +0 -1
  61. package/src/latch.ts +0 -60
  62. package/src/sink.ts +0 -26
  63. package/src/types.ts +0 -5
  64. package/src/until.test.ts +0 -47
  65. package/src/until.ts +0 -58
@@ -1,7 +1,7 @@
1
1
  import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
2
 
3
- // packages/common/async/src/callback.ts
4
- var createPromiseFromCallback = (run) => new Promise((resolve, reject) => {
3
+ // src/callback.ts
4
+ var promiseFromCallback = (run) => new Promise((resolve, reject) => {
5
5
  run((error, value) => {
6
6
  if (error) {
7
7
  reject(error);
@@ -11,16 +11,16 @@ var createPromiseFromCallback = (run) => new Promise((resolve, reject) => {
11
11
  });
12
12
  });
13
13
 
14
- // packages/common/async/src/chain.ts
15
- var asyncChain = (chain) => async (elements) => {
14
+ // src/chain.ts
15
+ var chain = (chain2) => async (elements) => {
16
16
  let result = await elements;
17
- for (const part of chain) {
17
+ for (const part of chain2) {
18
18
  result = await Promise.all(result.map(async (element) => await part(element)));
19
19
  }
20
20
  return result;
21
21
  };
22
22
 
23
- // packages/common/async/src/cleanup.ts
23
+ // src/cleanup.ts
24
24
  import { ComplexMap } from "@dxos/util";
25
25
  var combine = (...cleanupFns) => {
26
26
  return () => {
@@ -35,16 +35,14 @@ var interval = (cb, ms) => {
35
35
  const t = setInterval(cb, ms);
36
36
  return () => clearInterval(t);
37
37
  };
38
- function addEventListener(target, type, listener, options) {
38
+ var addEventListener = (target, type, listener, options) => {
39
39
  target.addEventListener(type, listener, options);
40
40
  return () => target.removeEventListener(type, listener, options);
41
- }
41
+ };
42
42
  var SubscriptionList = class {
43
- constructor() {
44
- this._cleanups = [];
45
- }
46
- add(cb) {
47
- this._cleanups.push(cb);
43
+ _cleanups = [];
44
+ add(...cb) {
45
+ this._cleanups.push(...cb);
48
46
  return this;
49
47
  }
50
48
  clear() {
@@ -53,6 +51,7 @@ var SubscriptionList = class {
53
51
  }
54
52
  };
55
53
  var SubscriptionSet = class {
54
+ _cleanupMap;
56
55
  constructor(keyProjection) {
57
56
  this._cleanupMap = new ComplexMap(keyProjection);
58
57
  }
@@ -66,16 +65,60 @@ var SubscriptionSet = class {
66
65
  }
67
66
  };
68
67
 
69
- // packages/common/async/src/debounce.ts
70
- var debounce = (cb, wait = 100) => {
68
+ // src/debounce.ts
69
+ var delay = (cb, delay2 = 100) => {
70
+ let pending = false;
71
+ return (...args) => {
72
+ if (pending) {
73
+ return;
74
+ }
75
+ pending = true;
76
+ setTimeout(() => {
77
+ try {
78
+ cb(...args);
79
+ } finally {
80
+ pending = false;
81
+ }
82
+ }, delay2);
83
+ };
84
+ };
85
+ var debounce = (cb, delay2 = 100) => {
71
86
  let t;
72
87
  return (...args) => {
73
88
  clearTimeout(t);
74
- t = setTimeout(() => cb(...args), wait);
89
+ t = setTimeout(() => cb(...args), delay2);
90
+ };
91
+ };
92
+ var throttle = (cb, delay2 = 100) => {
93
+ let lastCall = 0;
94
+ return (...args) => {
95
+ const now = Date.now();
96
+ if (now - lastCall >= delay2) {
97
+ cb(...args);
98
+ lastCall = now;
99
+ }
100
+ };
101
+ };
102
+ var debounceAndThrottle = (cb, delay2 = 100) => {
103
+ let timeout2;
104
+ let lastCall = 0;
105
+ return (...args) => {
106
+ const now = Date.now();
107
+ const delta = now - lastCall;
108
+ clearTimeout(timeout2);
109
+ if (delta >= delay2) {
110
+ cb(...args);
111
+ lastCall = now;
112
+ } else {
113
+ timeout2 = setTimeout(() => {
114
+ cb(...args);
115
+ lastCall = Date.now();
116
+ }, delay2 - delta);
117
+ }
75
118
  };
76
119
  };
77
120
 
78
- // packages/common/async/src/errors.ts
121
+ // src/errors.ts
79
122
  var toError = (err) => err === void 0 || typeof err === "string" ? new Error(err) : err;
80
123
  var TimeoutError = class extends Error {
81
124
  constructor(timeout2, label) {
@@ -90,7 +133,7 @@ var observableError = (observable, err) => {
90
133
  }
91
134
  };
92
135
 
93
- // packages/common/async/src/timeout.ts
136
+ // src/timeout.ts
94
137
  import { ContextDisposedError } from "@dxos/context";
95
138
  var sleep = (ms) => {
96
139
  return new Promise((resolve) => {
@@ -106,6 +149,23 @@ var sleep = (ms) => {
106
149
  sleeper();
107
150
  });
108
151
  };
152
+ var sleepWithContext = (ctx, ms) => {
153
+ const error = new ContextDisposedError();
154
+ return new Promise((resolve, reject) => {
155
+ if (ctx.disposed) {
156
+ reject(error);
157
+ return;
158
+ }
159
+ const timeout2 = setTimeout(() => {
160
+ clearDispose();
161
+ resolve();
162
+ }, ms);
163
+ const clearDispose = ctx.onDispose(() => {
164
+ clearTimeout(timeout2);
165
+ reject(error);
166
+ });
167
+ });
168
+ };
109
169
  var asyncReturn = () => sleep(0);
110
170
  var asyncTimeout = async (promise, timeout2, err) => {
111
171
  let timeoutId;
@@ -116,7 +176,7 @@ var asyncTimeout = async (promise, timeout2, err) => {
116
176
  }, timeout2);
117
177
  unrefTimeout(timeoutId);
118
178
  });
119
- const conditionTimeout = typeof promise === "function" ? createPromiseFromCallback(promise) : promise;
179
+ const conditionTimeout = typeof promise === "function" ? promiseFromCallback(promise) : promise;
120
180
  return await Promise.race([
121
181
  conditionTimeout,
122
182
  timeoutPromise
@@ -129,25 +189,8 @@ var unrefTimeout = (timeoutId) => {
129
189
  timeoutId.unref();
130
190
  }
131
191
  };
132
- var sleepWithContext = (ctx, ms) => {
133
- const error = new ContextDisposedError();
134
- return new Promise((resolve, reject) => {
135
- if (ctx.disposed) {
136
- reject(error);
137
- return;
138
- }
139
- const timeout2 = setTimeout(() => {
140
- clearDispose();
141
- resolve();
142
- }, ms);
143
- const clearDispose = ctx.onDispose(() => {
144
- clearTimeout(timeout2);
145
- reject(error);
146
- });
147
- });
148
- };
149
192
 
150
- // packages/common/async/src/event-emitter.ts
193
+ // src/event-emitter.ts
151
194
  var onEvent = (eventEmitter, eventName, callback) => {
152
195
  eventEmitter.on(eventName, callback);
153
196
  return () => eventEmitter.off(eventName, callback);
@@ -170,15 +213,11 @@ var waitForEvent = (eventEmitter, eventName, test, timeout2, error) => {
170
213
  return timeout2 ? asyncTimeout(promise, timeout2, error ?? new Error()).finally(off) : promise.finally(off);
171
214
  };
172
215
 
173
- // packages/common/async/src/events.ts
216
+ // src/events.ts
174
217
  import { Context } from "@dxos/context";
175
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/common/async/src/events.ts";
218
+ var __dxlog_file = "/__w/dxos/dxos/packages/common/async/src/events.ts";
176
219
  var DO_NOT_ERROR_ON_ASYNC_CALLBACK = true;
177
220
  var Event = class _Event {
178
- constructor() {
179
- this._listeners = /* @__PURE__ */ new Set();
180
- this._effects = /* @__PURE__ */ new Set();
181
- }
182
221
  /**
183
222
  * Wrap objects that have on/off style event emitters.
184
223
  */
@@ -191,6 +230,8 @@ var Event = class _Event {
191
230
  });
192
231
  return event;
193
232
  }
233
+ _listeners = /* @__PURE__ */ new Set();
234
+ _effects = /* @__PURE__ */ new Set();
194
235
  /**
195
236
  * Emit an event.
196
237
  * In most cases should only be called by the class or entity containing the event.
@@ -434,11 +475,15 @@ var Event = class _Event {
434
475
  }
435
476
  };
436
477
  var EventListener = class {
478
+ ctx;
479
+ once;
480
+ weak;
481
+ callback;
482
+ _clearDispose = void 0;
437
483
  constructor(event, listener, ctx, once, weak) {
438
484
  this.ctx = ctx;
439
485
  this.once = once;
440
486
  this.weak = weak;
441
- this._clearDispose = void 0;
442
487
  this._clearDispose = ctx.onDispose(() => {
443
488
  event._removeListener(this);
444
489
  });
@@ -498,65 +543,13 @@ var weakListeners = () => {
498
543
  };
499
544
  };
500
545
 
501
- // packages/common/async/src/latch.ts
502
- import { invariant } from "@dxos/invariant";
503
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/common/async/src/latch.ts";
504
- var latch = ({ count = 1, timeout: timeout2 } = {}) => {
505
- invariant(count >= 0, void 0, {
506
- F: __dxlog_file2,
507
- L: 19,
508
- S: void 0,
509
- A: [
510
- "count >= 0",
511
- ""
512
- ]
513
- });
514
- let t;
515
- let doResolve;
516
- let doReject;
517
- const promise = new Promise((resolve, reject) => {
518
- doResolve = (value) => {
519
- clearTimeout(t);
520
- resolve(value);
521
- };
522
- doReject = (err) => {
523
- clearTimeout(t);
524
- reject(err);
525
- };
526
- });
527
- if (count === 0) {
528
- setTimeout(() => {
529
- doResolve(0);
530
- });
531
- } else {
532
- if (timeout2) {
533
- t = setTimeout(() => {
534
- doReject(new Error(`Timed out after ${timeout2.toLocaleString()}ms`));
535
- }, timeout2);
536
- }
537
- }
538
- let i = 0;
539
- return [
540
- async () => await promise,
541
- () => {
542
- if (++i === count) {
543
- doResolve(i);
544
- }
545
- return i;
546
- },
547
- (err) => doReject(err)
548
- ];
549
- };
550
-
551
- // packages/common/async/src/mutex.ts
546
+ // src/mutex.ts
552
547
  import "@dxos/util";
553
548
  import { warnAfterTimeout } from "@dxos/debug";
554
549
  var Mutex = class {
555
- constructor() {
556
- this._queue = Promise.resolve();
557
- this._queueLength = 0;
558
- this._tag = null;
559
- }
550
+ _queue = Promise.resolve();
551
+ _queueLength = 0;
552
+ _tag = null;
560
553
  get tag() {
561
554
  return this._tag;
562
555
  }
@@ -602,6 +595,7 @@ var Mutex = class {
602
595
  }
603
596
  };
604
597
  var MutexGuard = class {
598
+ _release;
605
599
  constructor(_release) {
606
600
  this._release = _release;
607
601
  }
@@ -640,11 +634,13 @@ var synchronized = (target, propertyName, descriptor) => {
640
634
  });
641
635
  };
642
636
 
643
- // packages/common/async/src/observable.ts
637
+ // src/observable.ts
644
638
  import Observable from "zen-observable";
645
639
  import PushStream from "zen-push";
646
640
 
647
- // packages/common/async/src/trigger.ts
641
+ // src/trigger.ts
642
+ import { invariant } from "@dxos/invariant";
643
+ var __dxlog_file2 = "/__w/dxos/dxos/packages/common/async/src/trigger.ts";
648
644
  var trigger = (timeout2) => {
649
645
  let callback;
650
646
  const promise = new Promise((resolve, reject) => {
@@ -660,18 +656,22 @@ var trigger = (timeout2) => {
660
656
  resolver
661
657
  ];
662
658
  };
663
- var TriggerState = /* @__PURE__ */ function(TriggerState2) {
659
+ var TriggerState = /* @__PURE__ */ (function(TriggerState2) {
664
660
  TriggerState2["WAITING"] = "WAITING";
665
661
  TriggerState2["RESOLVED"] = "RESOLVED";
666
662
  TriggerState2["REJECTED"] = "REJECTED";
667
663
  return TriggerState2;
668
- }({});
664
+ })({});
669
665
  var Trigger = class {
666
+ _options;
667
+ _promise;
668
+ _resolve;
669
+ _reject;
670
+ _state = "WAITING";
670
671
  constructor(_options = {
671
672
  autoReset: false
672
673
  }) {
673
674
  this._options = _options;
674
- this._state = "WAITING";
675
675
  this.reset();
676
676
  }
677
677
  get state() {
@@ -731,23 +731,61 @@ var Trigger = class {
731
731
  return this;
732
732
  }
733
733
  };
734
+ var latch = ({ count = 1, timeout: timeout2 } = {}) => {
735
+ invariant(count >= 0, void 0, {
736
+ F: __dxlog_file2,
737
+ L: 139,
738
+ S: void 0,
739
+ A: [
740
+ "count >= 0",
741
+ ""
742
+ ]
743
+ });
744
+ let t;
745
+ let doResolve;
746
+ let doReject;
747
+ const promise = new Promise((resolve, reject) => {
748
+ doResolve = (value) => {
749
+ clearTimeout(t);
750
+ resolve(value);
751
+ };
752
+ doReject = (err) => {
753
+ clearTimeout(t);
754
+ reject(err);
755
+ };
756
+ });
757
+ if (count === 0) {
758
+ setTimeout(() => {
759
+ doResolve(0);
760
+ });
761
+ } else {
762
+ if (timeout2) {
763
+ t = setTimeout(() => {
764
+ doReject(new Error(`Timed out after ${timeout2.toLocaleString()}ms`));
765
+ }, timeout2);
766
+ }
767
+ }
768
+ let i = 0;
769
+ return [
770
+ async () => await promise,
771
+ () => {
772
+ if (++i === count) {
773
+ doResolve(i);
774
+ }
775
+ return i;
776
+ },
777
+ (err) => doReject(err)
778
+ ];
779
+ };
734
780
 
735
- // packages/common/async/src/observable.ts
781
+ // src/observable.ts
736
782
  var MulticastObservable = class _MulticastObservable extends Observable {
783
+ _value;
784
+ _observers = /* @__PURE__ */ new Set();
785
+ _observable;
786
+ _completed = new Trigger();
737
787
  constructor(subscriber, _value) {
738
- super((observer) => this._subscribe(observer)), this._value = _value, this._observers = /* @__PURE__ */ new Set(), this._completed = new Trigger(), this._handlers = {
739
- next: (value) => {
740
- this._value = value;
741
- this._observers.forEach((observer) => observer.next?.(value));
742
- },
743
- error: (err) => {
744
- this._observers.forEach((observer) => observer.error?.(err));
745
- },
746
- complete: () => {
747
- this._completed.wake();
748
- this._observers.forEach((observer) => observer.complete?.());
749
- }
750
- };
788
+ super((observer) => this._subscribe(observer)), this._value = _value;
751
789
  this._observable = typeof subscriber === "function" ? new Observable(subscriber) : subscriber;
752
790
  this._observable.subscribe(this._handlers);
753
791
  }
@@ -831,18 +869,30 @@ var MulticastObservable = class _MulticastObservable extends Observable {
831
869
  this._observers.delete(observer);
832
870
  };
833
871
  }
872
+ _handlers = {
873
+ next: (value) => {
874
+ this._value = value;
875
+ this._observers.forEach((observer) => observer.next?.(value));
876
+ },
877
+ error: (err) => {
878
+ this._observers.forEach((observer) => observer.error?.(err));
879
+ },
880
+ complete: () => {
881
+ this._completed.wake();
882
+ this._observers.forEach((observer) => observer.complete?.());
883
+ }
884
+ };
834
885
  };
835
886
  var EMPTY_OBSERVABLE = MulticastObservable.of(null);
836
887
 
837
- // packages/common/async/src/observable-value.ts
888
+ // src/observable-value.ts
838
889
  import { createSetDispatch } from "@dxos/util";
839
890
  var ObservableProvider = class {
840
- constructor() {
841
- this._handlers = /* @__PURE__ */ new Set();
842
- this._proxy = createSetDispatch({
843
- handlers: this._handlers
844
- });
845
- }
891
+ _handlers = /* @__PURE__ */ new Set();
892
+ _proxy = createSetDispatch({
893
+ handlers: this._handlers
894
+ });
895
+ _value;
846
896
  /**
847
897
  * Proxy used to dispatch callbacks to each subscription.
848
898
  */
@@ -863,8 +913,10 @@ var ObservableProvider = class {
863
913
  }
864
914
  };
865
915
  var CancellableObservableProvider = class extends ObservableProvider {
916
+ _handleCancel;
917
+ _cancelled = false;
866
918
  constructor(_handleCancel) {
867
- super(), this._handleCancel = _handleCancel, this._cancelled = false;
919
+ super(), this._handleCancel = _handleCancel;
868
920
  }
869
921
  get cancelled() {
870
922
  return this._cancelled;
@@ -879,19 +931,19 @@ var CancellableObservableProvider = class extends ObservableProvider {
879
931
  }
880
932
  };
881
933
 
882
- // packages/common/async/src/persistent-lifecycle.ts
934
+ // src/persistent-lifecycle.ts
883
935
  import { LifecycleState, Resource, cancelWithContext } from "@dxos/context";
884
936
  import { warnAfterTimeout as warnAfterTimeout2 } from "@dxos/debug";
885
937
  import { log as log2 } from "@dxos/log";
886
938
 
887
- // packages/common/async/src/task-scheduling.ts
888
- import { ContextDisposedError as ContextDisposedError2 } from "@dxos/context";
939
+ // src/task-scheduling.ts
940
+ import { Context as Context2, ContextDisposedError as ContextDisposedError2 } from "@dxos/context";
889
941
  import { StackTrace as StackTrace2 } from "@dxos/debug";
890
942
 
891
- // packages/common/async/src/track-leaks.ts
943
+ // src/track-leaks.ts
892
944
  import { StackTrace } from "@dxos/debug";
893
945
  import { log } from "@dxos/log";
894
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/common/async/src/track-leaks.ts";
946
+ var __dxlog_file3 = "/__w/dxos/dxos/packages/common/async/src/track-leaks.ts";
895
947
  var enabled = typeof process !== "undefined" && !!process.env.DX_TRACK_LEAKS;
896
948
  var openResources = /* @__PURE__ */ new Set();
897
949
  var handleSymbol = Symbol("checkLeaksHandle");
@@ -972,14 +1024,17 @@ if (enabled) {
972
1024
  global.dxDumpLeaks = dumpLeaks;
973
1025
  }
974
1026
 
975
- // packages/common/async/src/task-scheduling.ts
1027
+ // src/task-scheduling.ts
1028
+ var __dxlog_file4 = "/__w/dxos/dxos/packages/common/async/src/task-scheduling.ts";
976
1029
  var DeferredTask = class {
1030
+ _ctx;
1031
+ _callback;
1032
+ _scheduled = false;
1033
+ _currentTask = null;
1034
+ _nextTask = new Trigger();
977
1035
  constructor(_ctx, _callback) {
978
1036
  this._ctx = _ctx;
979
1037
  this._callback = _callback;
980
- this._scheduled = false;
981
- this._currentTask = null;
982
- this._nextTask = new Trigger();
983
1038
  }
984
1039
  get scheduled() {
985
1040
  return this._scheduled;
@@ -1020,6 +1075,82 @@ var DeferredTask = class {
1020
1075
  await this._currentTask;
1021
1076
  }
1022
1077
  };
1078
+ var AsyncTask = class {
1079
+ #callback;
1080
+ #ctx = void 0;
1081
+ #scheduled = false;
1082
+ #currentTask = null;
1083
+ #nextTask = new Trigger();
1084
+ constructor(callback) {
1085
+ this.#callback = callback;
1086
+ }
1087
+ get scheduled() {
1088
+ return this.#scheduled;
1089
+ }
1090
+ /**
1091
+ * Context of the resource that owns the task.
1092
+ * When the context is disposed, the task is cancelled and cannot be scheduled again.
1093
+ */
1094
+ open() {
1095
+ this.#ctx = new Context2(void 0, {
1096
+ F: __dxlog_file4,
1097
+ L: 102
1098
+ });
1099
+ }
1100
+ /**
1101
+ * Closes the task and waits for it to finish if it is running.
1102
+ */
1103
+ async close() {
1104
+ await this.#ctx?.dispose();
1105
+ await this.join();
1106
+ this.#ctx = void 0;
1107
+ }
1108
+ [Symbol.asyncDispose]() {
1109
+ return this.close();
1110
+ }
1111
+ /**
1112
+ * Schedule the task to run asynchronously.
1113
+ */
1114
+ // TODO(dmaretskyi): Add scheduleAt. Where the earlier time will override the later one.
1115
+ schedule() {
1116
+ if (!this.#ctx || this.#ctx.disposed) {
1117
+ throw new Error("AsyncTask not open");
1118
+ }
1119
+ if (this.#scheduled) {
1120
+ return;
1121
+ }
1122
+ scheduleTask(this.#ctx, async () => {
1123
+ await this.#currentTask;
1124
+ if (!this.#ctx || this.#ctx.disposed) {
1125
+ return;
1126
+ }
1127
+ this.#scheduled = false;
1128
+ const completionTrigger = this.#nextTask;
1129
+ this.#nextTask = new Trigger();
1130
+ this.#currentTask = runInContextAsync(this.#ctx, () => this.#callback()).then(() => {
1131
+ completionTrigger.wake();
1132
+ });
1133
+ });
1134
+ this.#scheduled = true;
1135
+ }
1136
+ /**
1137
+ * Schedule the task to run and wait for it to finish.
1138
+ */
1139
+ async runBlocking() {
1140
+ if (this.#ctx?.disposed) {
1141
+ throw new ContextDisposedError2();
1142
+ }
1143
+ this.schedule();
1144
+ await this.#nextTask.wait();
1145
+ }
1146
+ /**
1147
+ * Waits for the current task to finish if it is running.
1148
+ * Does not schedule a new task.
1149
+ */
1150
+ async join() {
1151
+ await this.#currentTask;
1152
+ }
1153
+ };
1023
1154
  var runInContext = (ctx, fn) => {
1024
1155
  try {
1025
1156
  fn();
@@ -1098,22 +1229,26 @@ var scheduleExponentialBackoffTaskInterval = (ctx, task, initialInterval) => {
1098
1229
  });
1099
1230
  };
1100
1231
 
1101
- // packages/common/async/src/persistent-lifecycle.ts
1232
+ // src/persistent-lifecycle.ts
1102
1233
  function _ts_decorate(decorators, target, key, desc) {
1103
1234
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1104
1235
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1105
1236
  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;
1106
1237
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1107
1238
  }
1108
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/common/async/src/persistent-lifecycle.ts";
1239
+ var __dxlog_file5 = "/__w/dxos/dxos/packages/common/async/src/persistent-lifecycle.ts";
1109
1240
  var INIT_RESTART_DELAY = 100;
1110
1241
  var DEFAULT_MAX_RESTART_DELAY = 5e3;
1111
1242
  var PersistentLifecycle = class extends Resource {
1243
+ _start;
1244
+ _stop;
1245
+ _onRestart;
1246
+ _maxRestartDelay;
1247
+ _currentState = void 0;
1248
+ _restartTask = void 0;
1249
+ _restartAfter = 0;
1112
1250
  constructor({ start, stop, onRestart, maxRestartDelay = DEFAULT_MAX_RESTART_DELAY }) {
1113
1251
  super();
1114
- this._currentState = void 0;
1115
- this._restartTask = void 0;
1116
- this._restartAfter = 0;
1117
1252
  this._start = start;
1118
1253
  this._stop = stop;
1119
1254
  this._onRestart = onRestart;
@@ -1130,7 +1265,7 @@ var PersistentLifecycle = class extends Resource {
1130
1265
  log2.warn("Restart failed", {
1131
1266
  err
1132
1267
  }, {
1133
- F: __dxlog_file4,
1268
+ F: __dxlog_file5,
1134
1269
  L: 72,
1135
1270
  S: this,
1136
1271
  C: (f, a) => f(...a)
@@ -1142,7 +1277,7 @@ var PersistentLifecycle = class extends Resource {
1142
1277
  log2.warn("Start failed", {
1143
1278
  err
1144
1279
  }, {
1145
- F: __dxlog_file4,
1280
+ F: __dxlog_file5,
1146
1281
  L: 78,
1147
1282
  S: this,
1148
1283
  C: (f, a) => f(...a)
@@ -1160,7 +1295,7 @@ var PersistentLifecycle = class extends Resource {
1160
1295
  log2(`restarting in ${this._restartAfter}ms`, {
1161
1296
  state: this._lifecycleState
1162
1297
  }, {
1163
- F: __dxlog_file4,
1298
+ F: __dxlog_file5,
1164
1299
  L: 91,
1165
1300
  S: this,
1166
1301
  C: (f, a) => f(...a)
@@ -1183,7 +1318,7 @@ var PersistentLifecycle = class extends Resource {
1183
1318
  await this._stop(this._currentState);
1184
1319
  } catch (err) {
1185
1320
  log2.catch(err, void 0, {
1186
- F: __dxlog_file4,
1321
+ F: __dxlog_file5,
1187
1322
  L: 113,
1188
1323
  S: this,
1189
1324
  C: (f, a) => f(...a)
@@ -1209,9 +1344,9 @@ _ts_decorate([
1209
1344
  synchronized
1210
1345
  ], PersistentLifecycle.prototype, "scheduleRestart", null);
1211
1346
 
1212
- // packages/common/async/src/push-iterable.ts
1347
+ // src/push-iterable.ts
1213
1348
  import { invariant as invariant2 } from "@dxos/invariant";
1214
- var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/common/async/src/push-iterable.ts";
1349
+ var __dxlog_file6 = "/__w/dxos/dxos/packages/common/async/src/push-iterable.ts";
1215
1350
  var makePushIterable = () => {
1216
1351
  const buf = [];
1217
1352
  const trigger2 = new Trigger({
@@ -1226,7 +1361,7 @@ var makePushIterable = () => {
1226
1361
  }
1227
1362
  const item = buf.shift();
1228
1363
  invariant2(item, void 0, {
1229
- F: __dxlog_file5,
1364
+ F: __dxlog_file6,
1230
1365
  L: 42,
1231
1366
  S: this,
1232
1367
  A: [
@@ -1275,21 +1410,7 @@ var makePushIterable = () => {
1275
1410
  };
1276
1411
  };
1277
1412
 
1278
- // packages/common/async/src/sink.ts
1279
- var sink = (emitter, event, count = 1) => {
1280
- const [getPromise, resolve] = trigger();
1281
- let counter = 0;
1282
- const listener = () => {
1283
- if (++counter === count) {
1284
- emitter.off(event, listener);
1285
- resolve();
1286
- }
1287
- };
1288
- emitter.on(event, listener);
1289
- return getPromise();
1290
- };
1291
-
1292
- // packages/common/async/src/stream-to-array.ts
1413
+ // src/stream-to-array.ts
1293
1414
  var streamToArray = (stream) => {
1294
1415
  let deferred;
1295
1416
  if (!stream.readable) {
@@ -1331,14 +1452,9 @@ var streamToArray = (stream) => {
1331
1452
  return deferred;
1332
1453
  };
1333
1454
 
1334
- // packages/common/async/src/test-stream.ts
1455
+ // src/test-stream.ts
1335
1456
  import { Duplex } from "node:stream";
1336
1457
  var TestStream = class extends Duplex {
1337
- constructor() {
1338
- super(...arguments);
1339
- this._received = Buffer.alloc(0);
1340
- this._onWrite = new Event();
1341
- }
1342
1458
  static async assertConnectivity(stream1, stream2, { timeout: timeout2 = 200 } = {}) {
1343
1459
  stream1.push("ping");
1344
1460
  stream2.push("pong");
@@ -1351,6 +1467,8 @@ var TestStream = class extends Duplex {
1351
1467
  })
1352
1468
  ]);
1353
1469
  }
1470
+ _received = Buffer.alloc(0);
1471
+ _onWrite = new Event();
1354
1472
  _write(chunk, encoding, callback) {
1355
1473
  this._received = Buffer.concat([
1356
1474
  this._received,
@@ -1367,7 +1485,7 @@ var TestStream = class extends Duplex {
1367
1485
  }
1368
1486
  };
1369
1487
 
1370
- // packages/common/async/src/testing.ts
1488
+ // src/testing.ts
1371
1489
  var waitForCondition = ({ condition, timeout: timeout2 = 0, interval: interval2 = 10, error, breakOnError = false }) => {
1372
1490
  const stopTime = timeout2 ? Date.now() + timeout2 : 0;
1373
1491
  const trigger2 = new Trigger();
@@ -1392,13 +1510,48 @@ var waitForCondition = ({ condition, timeout: timeout2 = 0, interval: interval2
1392
1510
  timeout: timeout2
1393
1511
  });
1394
1512
  };
1513
+ var until = (cb, timeout2) => {
1514
+ return new Promise((resolve, reject) => {
1515
+ const t = timeout2 && setTimeout(() => {
1516
+ reject(new Error(`Timeout after ${t}ms`));
1517
+ }, timeout2);
1518
+ setTimeout(async () => {
1519
+ try {
1520
+ await cb((value) => {
1521
+ t && clearTimeout(t);
1522
+ resolve(value);
1523
+ }, (error) => {
1524
+ t && clearTimeout(t);
1525
+ reject(error);
1526
+ });
1527
+ } catch (err) {
1528
+ reject(err);
1529
+ }
1530
+ });
1531
+ });
1532
+ };
1533
+ var untilPromise = (cb) => cb();
1534
+ var untilError = (cb) => {
1535
+ return new Promise((resolve, reject) => {
1536
+ setTimeout(async () => {
1537
+ try {
1538
+ await cb();
1539
+ reject(new Error("No error was thrown."));
1540
+ } catch (err) {
1541
+ resolve(err);
1542
+ }
1543
+ });
1544
+ });
1545
+ };
1395
1546
 
1396
- // packages/common/async/src/timer.ts
1547
+ // src/timer.ts
1397
1548
  var Timer = class {
1549
+ _callback;
1550
+ _state = new Event();
1551
+ _timer;
1552
+ _count = 0;
1398
1553
  constructor(_callback) {
1399
1554
  this._callback = _callback;
1400
- this._state = new Event();
1401
- this._count = 0;
1402
1555
  }
1403
1556
  get state() {
1404
1557
  return this._state;
@@ -1441,51 +1594,23 @@ var Timer = class {
1441
1594
  }
1442
1595
  };
1443
1596
 
1444
- // packages/common/async/src/until.ts
1445
- var until = (cb, timeout2) => {
1446
- return new Promise((resolve, reject) => {
1447
- const t = timeout2 && setTimeout(() => {
1448
- reject(new Error(`Timeout after ${t}ms`));
1449
- }, timeout2);
1450
- setTimeout(async () => {
1451
- try {
1452
- await cb((value) => {
1453
- t && clearTimeout(t);
1454
- resolve(value);
1455
- }, (error) => {
1456
- t && clearTimeout(t);
1457
- reject(error);
1458
- });
1459
- } catch (err) {
1460
- reject(err);
1461
- }
1462
- });
1463
- });
1464
- };
1465
- var untilPromise = (cb) => cb();
1466
- var untilError = (cb) => {
1467
- return new Promise((resolve, reject) => {
1468
- setTimeout(async () => {
1469
- try {
1470
- await cb();
1471
- reject(new Error("No error was thrown."));
1472
- } catch (err) {
1473
- resolve(err);
1474
- }
1475
- });
1476
- });
1477
- };
1478
-
1479
- // packages/common/async/src/update-scheduler.ts
1597
+ // src/update-scheduler.ts
1480
1598
  var TIME_PERIOD = 1e3;
1481
1599
  var UpdateScheduler = class {
1600
+ _ctx;
1601
+ _callback;
1602
+ _params;
1603
+ /**
1604
+ * Promise that resolves when the callback is done.
1605
+ * Never rejects.
1606
+ */
1607
+ _promise = null;
1608
+ _scheduled = false;
1609
+ _lastUpdateTime = -TIME_PERIOD;
1482
1610
  constructor(_ctx, _callback, _params = {}) {
1483
1611
  this._ctx = _ctx;
1484
1612
  this._callback = _callback;
1485
1613
  this._params = _params;
1486
- this._promise = null;
1487
- this._scheduled = false;
1488
- this._lastUpdateTime = -TIME_PERIOD;
1489
1614
  _ctx.onDispose(async () => {
1490
1615
  await this._promise;
1491
1616
  });
@@ -1498,13 +1623,13 @@ var UpdateScheduler = class {
1498
1623
  await this._promise;
1499
1624
  if (this._params.maxFrequency) {
1500
1625
  const now = performance.now();
1501
- const delay = this._lastUpdateTime + TIME_PERIOD / this._params.maxFrequency - now;
1502
- if (delay > 0) {
1626
+ const delay2 = this._lastUpdateTime + TIME_PERIOD / this._params.maxFrequency - now;
1627
+ if (delay2 > 0) {
1503
1628
  await new Promise((resolve) => {
1504
1629
  const timeoutId = setTimeout(() => {
1505
1630
  clearContext();
1506
1631
  resolve();
1507
- }, delay);
1632
+ }, delay2);
1508
1633
  const clearContext = this._ctx.onDispose(() => {
1509
1634
  clearTimeout(timeoutId);
1510
1635
  resolve();
@@ -1548,6 +1673,7 @@ var UpdateScheduler = class {
1548
1673
  }
1549
1674
  };
1550
1675
  export {
1676
+ AsyncTask,
1551
1677
  CancellableObservableProvider,
1552
1678
  DeferredTask,
1553
1679
  Event,
@@ -1568,29 +1694,31 @@ export {
1568
1694
  UpdateScheduler,
1569
1695
  addEventListener,
1570
1696
  addListener,
1571
- asyncChain,
1572
1697
  asyncReturn,
1573
1698
  asyncTimeout,
1699
+ chain,
1574
1700
  combine,
1575
- createPromiseFromCallback,
1576
1701
  debounce,
1702
+ debounceAndThrottle,
1703
+ delay,
1577
1704
  dumpLeaks,
1578
1705
  interval,
1579
1706
  latch,
1580
1707
  makePushIterable,
1581
1708
  observableError,
1582
1709
  onEvent,
1710
+ promiseFromCallback,
1583
1711
  runInContext,
1584
1712
  runInContextAsync,
1585
1713
  scheduleExponentialBackoffTaskInterval,
1586
1714
  scheduleMicroTask,
1587
1715
  scheduleTask,
1588
1716
  scheduleTaskInterval,
1589
- sink,
1590
1717
  sleep,
1591
1718
  sleepWithContext,
1592
1719
  streamToArray,
1593
1720
  synchronized,
1721
+ throttle,
1594
1722
  timeout,
1595
1723
  toError,
1596
1724
  trackLeaks,