@dxos/async 0.8.4-main.b97322e → 0.8.4-main.bc2380dfbc
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/LICENSE +102 -5
- package/dist/lib/browser/index.mjs +212 -148
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +212 -148
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/callback.d.ts.map +1 -1
- package/dist/types/src/chain.d.ts.map +1 -1
- package/dist/types/src/cleanup.d.ts +2 -2
- package/dist/types/src/cleanup.d.ts.map +1 -1
- package/dist/types/src/debounce.d.ts +29 -9
- package/dist/types/src/debounce.d.ts.map +1 -1
- package/dist/types/src/errors.d.ts.map +1 -1
- package/dist/types/src/event-emitter.d.ts.map +1 -1
- package/dist/types/src/events.d.ts.map +1 -1
- package/dist/types/src/mutex.d.ts.map +1 -1
- package/dist/types/src/observable-value.d.ts.map +1 -1
- package/dist/types/src/observable.d.ts.map +1 -1
- package/dist/types/src/persistent-lifecycle.d.ts +2 -2
- package/dist/types/src/persistent-lifecycle.d.ts.map +1 -1
- package/dist/types/src/stream-to-array.d.ts.map +1 -1
- package/dist/types/src/task-scheduling.d.ts +29 -1
- package/dist/types/src/task-scheduling.d.ts.map +1 -1
- package/dist/types/src/test-stream.d.ts.map +1 -1
- package/dist/types/src/testing.d.ts.map +1 -1
- package/dist/types/src/timeout.d.ts +1 -1
- package/dist/types/src/timeout.d.ts.map +1 -1
- package/dist/types/src/timer.d.ts.map +1 -1
- package/dist/types/src/track-leaks.d.ts.map +1 -1
- package/dist/types/src/trigger.d.ts.map +1 -1
- package/dist/types/src/update-scheduler.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +14 -13
- package/src/cleanup.ts +7 -4
- package/src/debounce.ts +69 -16
- package/src/observable-value.ts +4 -2
- package/src/persistent-lifecycle.test.ts +1 -1
- package/src/persistent-lifecycle.ts +10 -2
- package/src/task-scheduling.ts +95 -1
- package/src/testing.test.ts +1 -1
- package/src/timeout.ts +6 -9
|
@@ -22,7 +22,7 @@ var chain = (chain2) => async (elements) => {
|
|
|
22
22
|
import { ComplexMap } from "@dxos/util";
|
|
23
23
|
var combine = (...cleanupFns) => {
|
|
24
24
|
return () => {
|
|
25
|
-
cleanupFns.flat().forEach((cleanupFn) => cleanupFn());
|
|
25
|
+
cleanupFns.flat().filter((f) => typeof f === "function").forEach((cleanupFn) => cleanupFn());
|
|
26
26
|
};
|
|
27
27
|
};
|
|
28
28
|
var timeout = (cb, ms = 0) => {
|
|
@@ -38,11 +38,9 @@ var addEventListener = (target, type, listener, options) => {
|
|
|
38
38
|
return () => target.removeEventListener(type, listener, options);
|
|
39
39
|
};
|
|
40
40
|
var SubscriptionList = class {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
add(cb) {
|
|
45
|
-
this._cleanups.push(cb);
|
|
41
|
+
_cleanups = [];
|
|
42
|
+
add(...cb) {
|
|
43
|
+
this._cleanups.push(...cb);
|
|
46
44
|
return this;
|
|
47
45
|
}
|
|
48
46
|
clear() {
|
|
@@ -51,6 +49,7 @@ var SubscriptionList = class {
|
|
|
51
49
|
}
|
|
52
50
|
};
|
|
53
51
|
var SubscriptionSet = class {
|
|
52
|
+
_cleanupMap;
|
|
54
53
|
constructor(keyProjection) {
|
|
55
54
|
this._cleanupMap = new ComplexMap(keyProjection);
|
|
56
55
|
}
|
|
@@ -65,29 +64,55 @@ var SubscriptionSet = class {
|
|
|
65
64
|
};
|
|
66
65
|
|
|
67
66
|
// src/debounce.ts
|
|
68
|
-
var
|
|
67
|
+
var delay = (cb, delay2 = 100) => {
|
|
68
|
+
let pending = false;
|
|
69
|
+
return (...args) => {
|
|
70
|
+
if (pending) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
pending = true;
|
|
74
|
+
setTimeout(() => {
|
|
75
|
+
try {
|
|
76
|
+
cb(...args);
|
|
77
|
+
} finally {
|
|
78
|
+
pending = false;
|
|
79
|
+
}
|
|
80
|
+
}, delay2);
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
var debounce = (cb, delay2 = 100) => {
|
|
69
84
|
let t;
|
|
70
85
|
return (...args) => {
|
|
71
86
|
clearTimeout(t);
|
|
72
|
-
t = setTimeout(() => cb(...args),
|
|
87
|
+
t = setTimeout(() => cb(...args), delay2);
|
|
73
88
|
};
|
|
74
89
|
};
|
|
75
|
-
var throttle = (cb,
|
|
90
|
+
var throttle = (cb, delay2 = 100) => {
|
|
76
91
|
let lastCall = 0;
|
|
77
92
|
return (...args) => {
|
|
78
93
|
const now = Date.now();
|
|
79
|
-
if (now - lastCall >=
|
|
94
|
+
if (now - lastCall >= delay2) {
|
|
80
95
|
cb(...args);
|
|
81
96
|
lastCall = now;
|
|
82
97
|
}
|
|
83
98
|
};
|
|
84
99
|
};
|
|
85
|
-
var debounceAndThrottle = (cb,
|
|
86
|
-
|
|
87
|
-
|
|
100
|
+
var debounceAndThrottle = (cb, delay2 = 100) => {
|
|
101
|
+
let timeout2;
|
|
102
|
+
let lastCall = 0;
|
|
88
103
|
return (...args) => {
|
|
89
|
-
|
|
90
|
-
|
|
104
|
+
const now = Date.now();
|
|
105
|
+
const delta = now - lastCall;
|
|
106
|
+
clearTimeout(timeout2);
|
|
107
|
+
if (delta >= delay2) {
|
|
108
|
+
cb(...args);
|
|
109
|
+
lastCall = now;
|
|
110
|
+
} else {
|
|
111
|
+
timeout2 = setTimeout(() => {
|
|
112
|
+
cb(...args);
|
|
113
|
+
lastCall = Date.now();
|
|
114
|
+
}, delay2 - delta);
|
|
115
|
+
}
|
|
91
116
|
};
|
|
92
117
|
};
|
|
93
118
|
|
|
@@ -141,6 +166,9 @@ var sleepWithContext = (ctx, ms) => {
|
|
|
141
166
|
};
|
|
142
167
|
var asyncReturn = () => sleep(0);
|
|
143
168
|
var asyncTimeout = async (promise, timeout2, err) => {
|
|
169
|
+
if (typeof promise === "function") {
|
|
170
|
+
throw new Error("First argument must be a promise.");
|
|
171
|
+
}
|
|
144
172
|
let timeoutId;
|
|
145
173
|
const throwable = err === void 0 || typeof err === "string" ? new TimeoutError(timeout2, err) : err;
|
|
146
174
|
const timeoutPromise = new Promise((resolve, reject) => {
|
|
@@ -149,9 +177,8 @@ var asyncTimeout = async (promise, timeout2, err) => {
|
|
|
149
177
|
}, timeout2);
|
|
150
178
|
unrefTimeout(timeoutId);
|
|
151
179
|
});
|
|
152
|
-
const conditionTimeout = typeof promise === "function" ? promiseFromCallback(promise) : promise;
|
|
153
180
|
return await Promise.race([
|
|
154
|
-
|
|
181
|
+
promise,
|
|
155
182
|
timeoutPromise
|
|
156
183
|
]).finally(() => {
|
|
157
184
|
clearTimeout(timeoutId);
|
|
@@ -188,13 +215,8 @@ var waitForEvent = (eventEmitter, eventName, test, timeout2, error) => {
|
|
|
188
215
|
|
|
189
216
|
// src/events.ts
|
|
190
217
|
import { Context } from "@dxos/context";
|
|
191
|
-
var __dxlog_file = "/__w/dxos/dxos/packages/common/async/src/events.ts";
|
|
192
218
|
var DO_NOT_ERROR_ON_ASYNC_CALLBACK = true;
|
|
193
219
|
var Event = class _Event {
|
|
194
|
-
constructor() {
|
|
195
|
-
this._listeners = /* @__PURE__ */ new Set();
|
|
196
|
-
this._effects = /* @__PURE__ */ new Set();
|
|
197
|
-
}
|
|
198
220
|
/**
|
|
199
221
|
* Wrap objects that have on/off style event emitters.
|
|
200
222
|
*/
|
|
@@ -207,6 +229,8 @@ var Event = class _Event {
|
|
|
207
229
|
});
|
|
208
230
|
return event;
|
|
209
231
|
}
|
|
232
|
+
_listeners = /* @__PURE__ */ new Set();
|
|
233
|
+
_effects = /* @__PURE__ */ new Set();
|
|
210
234
|
/**
|
|
211
235
|
* Emit an event.
|
|
212
236
|
* In most cases should only be called by the class or entity containing the event.
|
|
@@ -245,10 +269,7 @@ var Event = class _Event {
|
|
|
245
269
|
_ctx,
|
|
246
270
|
_callback
|
|
247
271
|
] : [
|
|
248
|
-
new Context(
|
|
249
|
-
F: __dxlog_file,
|
|
250
|
-
L: 132
|
|
251
|
-
}),
|
|
272
|
+
new Context(),
|
|
252
273
|
_ctx
|
|
253
274
|
];
|
|
254
275
|
const weak = !!options?.weak;
|
|
@@ -278,10 +299,7 @@ var Event = class _Event {
|
|
|
278
299
|
_ctx,
|
|
279
300
|
_callback
|
|
280
301
|
] : [
|
|
281
|
-
new Context(
|
|
282
|
-
F: __dxlog_file,
|
|
283
|
-
L: 169
|
|
284
|
-
}),
|
|
302
|
+
new Context(),
|
|
285
303
|
_ctx
|
|
286
304
|
];
|
|
287
305
|
const listener = new EventListener(this, callback, ctx, true, false);
|
|
@@ -450,11 +468,15 @@ var Event = class _Event {
|
|
|
450
468
|
}
|
|
451
469
|
};
|
|
452
470
|
var EventListener = class {
|
|
471
|
+
ctx;
|
|
472
|
+
once;
|
|
473
|
+
weak;
|
|
474
|
+
callback;
|
|
475
|
+
_clearDispose = void 0;
|
|
453
476
|
constructor(event, listener, ctx, once, weak) {
|
|
454
477
|
this.ctx = ctx;
|
|
455
478
|
this.once = once;
|
|
456
479
|
this.weak = weak;
|
|
457
|
-
this._clearDispose = void 0;
|
|
458
480
|
this._clearDispose = ctx.onDispose(() => {
|
|
459
481
|
event._removeListener(this);
|
|
460
482
|
});
|
|
@@ -518,11 +540,9 @@ var weakListeners = () => {
|
|
|
518
540
|
import "@dxos/util";
|
|
519
541
|
import { warnAfterTimeout } from "@dxos/debug";
|
|
520
542
|
var Mutex = class {
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
this._tag = null;
|
|
525
|
-
}
|
|
543
|
+
_queue = Promise.resolve();
|
|
544
|
+
_queueLength = 0;
|
|
545
|
+
_tag = null;
|
|
526
546
|
get tag() {
|
|
527
547
|
return this._tag;
|
|
528
548
|
}
|
|
@@ -568,6 +588,7 @@ var Mutex = class {
|
|
|
568
588
|
}
|
|
569
589
|
};
|
|
570
590
|
var MutexGuard = class {
|
|
591
|
+
_release;
|
|
571
592
|
constructor(_release) {
|
|
572
593
|
this._release = _release;
|
|
573
594
|
}
|
|
@@ -581,7 +602,7 @@ var MutexGuard = class {
|
|
|
581
602
|
this.release();
|
|
582
603
|
}
|
|
583
604
|
};
|
|
584
|
-
var classMutexSymbol = Symbol("class-mutex");
|
|
605
|
+
var classMutexSymbol = /* @__PURE__ */ Symbol("class-mutex");
|
|
585
606
|
var FORCE_DISABLE_WARNING = false;
|
|
586
607
|
var enableWarning = !FORCE_DISABLE_WARNING && globalThis.mochaExecutor;
|
|
587
608
|
var synchronized = (target, propertyName, descriptor) => {
|
|
@@ -612,7 +633,6 @@ import PushStream from "zen-push";
|
|
|
612
633
|
|
|
613
634
|
// src/trigger.ts
|
|
614
635
|
import { invariant } from "@dxos/invariant";
|
|
615
|
-
var __dxlog_file2 = "/__w/dxos/dxos/packages/common/async/src/trigger.ts";
|
|
616
636
|
var trigger = (timeout2) => {
|
|
617
637
|
let callback;
|
|
618
638
|
const promise = new Promise((resolve, reject) => {
|
|
@@ -628,18 +648,22 @@ var trigger = (timeout2) => {
|
|
|
628
648
|
resolver
|
|
629
649
|
];
|
|
630
650
|
};
|
|
631
|
-
var TriggerState = /* @__PURE__ */ function(TriggerState2) {
|
|
651
|
+
var TriggerState = /* @__PURE__ */ (function(TriggerState2) {
|
|
632
652
|
TriggerState2["WAITING"] = "WAITING";
|
|
633
653
|
TriggerState2["RESOLVED"] = "RESOLVED";
|
|
634
654
|
TriggerState2["REJECTED"] = "REJECTED";
|
|
635
655
|
return TriggerState2;
|
|
636
|
-
}({});
|
|
656
|
+
})({});
|
|
637
657
|
var Trigger = class {
|
|
658
|
+
_options;
|
|
659
|
+
_promise;
|
|
660
|
+
_resolve;
|
|
661
|
+
_reject;
|
|
662
|
+
_state = "WAITING";
|
|
638
663
|
constructor(_options = {
|
|
639
664
|
autoReset: false
|
|
640
665
|
}) {
|
|
641
666
|
this._options = _options;
|
|
642
|
-
this._state = "WAITING";
|
|
643
667
|
this.reset();
|
|
644
668
|
}
|
|
645
669
|
get state() {
|
|
@@ -700,15 +724,7 @@ var Trigger = class {
|
|
|
700
724
|
}
|
|
701
725
|
};
|
|
702
726
|
var latch = ({ count = 1, timeout: timeout2 } = {}) => {
|
|
703
|
-
invariant(count >= 0
|
|
704
|
-
F: __dxlog_file2,
|
|
705
|
-
L: 139,
|
|
706
|
-
S: void 0,
|
|
707
|
-
A: [
|
|
708
|
-
"count >= 0",
|
|
709
|
-
""
|
|
710
|
-
]
|
|
711
|
-
});
|
|
727
|
+
invariant(count >= 0);
|
|
712
728
|
let t;
|
|
713
729
|
let doResolve;
|
|
714
730
|
let doReject;
|
|
@@ -748,20 +764,12 @@ var latch = ({ count = 1, timeout: timeout2 } = {}) => {
|
|
|
748
764
|
|
|
749
765
|
// src/observable.ts
|
|
750
766
|
var MulticastObservable = class _MulticastObservable extends Observable {
|
|
767
|
+
_value;
|
|
768
|
+
_observers = /* @__PURE__ */ new Set();
|
|
769
|
+
_observable;
|
|
770
|
+
_completed = new Trigger();
|
|
751
771
|
constructor(subscriber, _value) {
|
|
752
|
-
super((observer) => this._subscribe(observer)), this._value = _value
|
|
753
|
-
next: (value) => {
|
|
754
|
-
this._value = value;
|
|
755
|
-
this._observers.forEach((observer) => observer.next?.(value));
|
|
756
|
-
},
|
|
757
|
-
error: (err) => {
|
|
758
|
-
this._observers.forEach((observer) => observer.error?.(err));
|
|
759
|
-
},
|
|
760
|
-
complete: () => {
|
|
761
|
-
this._completed.wake();
|
|
762
|
-
this._observers.forEach((observer) => observer.complete?.());
|
|
763
|
-
}
|
|
764
|
-
};
|
|
772
|
+
super((observer) => this._subscribe(observer)), this._value = _value;
|
|
765
773
|
this._observable = typeof subscriber === "function" ? new Observable(subscriber) : subscriber;
|
|
766
774
|
this._observable.subscribe(this._handlers);
|
|
767
775
|
}
|
|
@@ -845,18 +853,30 @@ var MulticastObservable = class _MulticastObservable extends Observable {
|
|
|
845
853
|
this._observers.delete(observer);
|
|
846
854
|
};
|
|
847
855
|
}
|
|
856
|
+
_handlers = {
|
|
857
|
+
next: (value) => {
|
|
858
|
+
this._value = value;
|
|
859
|
+
this._observers.forEach((observer) => observer.next?.(value));
|
|
860
|
+
},
|
|
861
|
+
error: (err) => {
|
|
862
|
+
this._observers.forEach((observer) => observer.error?.(err));
|
|
863
|
+
},
|
|
864
|
+
complete: () => {
|
|
865
|
+
this._completed.wake();
|
|
866
|
+
this._observers.forEach((observer) => observer.complete?.());
|
|
867
|
+
}
|
|
868
|
+
};
|
|
848
869
|
};
|
|
849
870
|
var EMPTY_OBSERVABLE = MulticastObservable.of(null);
|
|
850
871
|
|
|
851
872
|
// src/observable-value.ts
|
|
852
873
|
import { createSetDispatch } from "@dxos/util";
|
|
853
874
|
var ObservableProvider = class {
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
this.
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
}
|
|
875
|
+
_handlers = /* @__PURE__ */ new Set();
|
|
876
|
+
_proxy = createSetDispatch({
|
|
877
|
+
handlers: this._handlers
|
|
878
|
+
});
|
|
879
|
+
_value;
|
|
860
880
|
/**
|
|
861
881
|
* Proxy used to dispatch callbacks to each subscription.
|
|
862
882
|
*/
|
|
@@ -877,8 +897,10 @@ var ObservableProvider = class {
|
|
|
877
897
|
}
|
|
878
898
|
};
|
|
879
899
|
var CancellableObservableProvider = class extends ObservableProvider {
|
|
900
|
+
_handleCancel;
|
|
901
|
+
_cancelled = false;
|
|
880
902
|
constructor(_handleCancel) {
|
|
881
|
-
super(), this._handleCancel = _handleCancel
|
|
903
|
+
super(), this._handleCancel = _handleCancel;
|
|
882
904
|
}
|
|
883
905
|
get cancelled() {
|
|
884
906
|
return this._cancelled;
|
|
@@ -899,16 +921,15 @@ import { warnAfterTimeout as warnAfterTimeout2 } from "@dxos/debug";
|
|
|
899
921
|
import { log as log2 } from "@dxos/log";
|
|
900
922
|
|
|
901
923
|
// src/task-scheduling.ts
|
|
902
|
-
import { ContextDisposedError as ContextDisposedError2 } from "@dxos/context";
|
|
924
|
+
import { Context as Context2, ContextDisposedError as ContextDisposedError2 } from "@dxos/context";
|
|
903
925
|
import { StackTrace as StackTrace2 } from "@dxos/debug";
|
|
904
926
|
|
|
905
927
|
// src/track-leaks.ts
|
|
906
928
|
import { StackTrace } from "@dxos/debug";
|
|
907
929
|
import { log } from "@dxos/log";
|
|
908
|
-
var __dxlog_file3 = "/__w/dxos/dxos/packages/common/async/src/track-leaks.ts";
|
|
909
930
|
var enabled = typeof process !== "undefined" && !!process.env.DX_TRACK_LEAKS;
|
|
910
931
|
var openResources = /* @__PURE__ */ new Set();
|
|
911
|
-
var handleSymbol = Symbol("checkLeaksHandle");
|
|
932
|
+
var handleSymbol = /* @__PURE__ */ Symbol("checkLeaksHandle");
|
|
912
933
|
var trackResource = (resourceProvider) => {
|
|
913
934
|
if (!enabled) {
|
|
914
935
|
return () => {
|
|
@@ -955,31 +976,11 @@ var dumpLeaks = () => {
|
|
|
955
976
|
if (!enabled) {
|
|
956
977
|
return;
|
|
957
978
|
}
|
|
958
|
-
log.info(`Leaked resources ${openResources.size}
|
|
959
|
-
F: __dxlog_file3,
|
|
960
|
-
L: 82,
|
|
961
|
-
S: void 0,
|
|
962
|
-
C: (f, a) => f(...a)
|
|
963
|
-
});
|
|
979
|
+
log.info(`Leaked resources ${openResources.size}:`);
|
|
964
980
|
for (const resource of openResources) {
|
|
965
|
-
log.info(`- ${resource.name} at
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
S: void 0,
|
|
969
|
-
C: (f, a) => f(...a)
|
|
970
|
-
});
|
|
971
|
-
log.info(resource.openStack.getStack(1), void 0, {
|
|
972
|
-
F: __dxlog_file3,
|
|
973
|
-
L: 85,
|
|
974
|
-
S: void 0,
|
|
975
|
-
C: (f, a) => f(...a)
|
|
976
|
-
});
|
|
977
|
-
log.info("\n", void 0, {
|
|
978
|
-
F: __dxlog_file3,
|
|
979
|
-
L: 86,
|
|
980
|
-
S: void 0,
|
|
981
|
-
C: (f, a) => f(...a)
|
|
982
|
-
});
|
|
981
|
+
log.info(`- ${resource.name} at`);
|
|
982
|
+
log.info(resource.openStack.getStack(1));
|
|
983
|
+
log.info("\n");
|
|
983
984
|
}
|
|
984
985
|
};
|
|
985
986
|
if (enabled) {
|
|
@@ -988,12 +989,14 @@ if (enabled) {
|
|
|
988
989
|
|
|
989
990
|
// src/task-scheduling.ts
|
|
990
991
|
var DeferredTask = class {
|
|
992
|
+
_ctx;
|
|
993
|
+
_callback;
|
|
994
|
+
_scheduled = false;
|
|
995
|
+
_currentTask = null;
|
|
996
|
+
_nextTask = new Trigger();
|
|
991
997
|
constructor(_ctx, _callback) {
|
|
992
998
|
this._ctx = _ctx;
|
|
993
999
|
this._callback = _callback;
|
|
994
|
-
this._scheduled = false;
|
|
995
|
-
this._currentTask = null;
|
|
996
|
-
this._nextTask = new Trigger();
|
|
997
1000
|
}
|
|
998
1001
|
get scheduled() {
|
|
999
1002
|
return this._scheduled;
|
|
@@ -1034,6 +1037,79 @@ var DeferredTask = class {
|
|
|
1034
1037
|
await this._currentTask;
|
|
1035
1038
|
}
|
|
1036
1039
|
};
|
|
1040
|
+
var AsyncTask = class {
|
|
1041
|
+
#callback;
|
|
1042
|
+
#ctx = void 0;
|
|
1043
|
+
#scheduled = false;
|
|
1044
|
+
#currentTask = null;
|
|
1045
|
+
#nextTask = new Trigger();
|
|
1046
|
+
constructor(callback) {
|
|
1047
|
+
this.#callback = callback;
|
|
1048
|
+
}
|
|
1049
|
+
get scheduled() {
|
|
1050
|
+
return this.#scheduled;
|
|
1051
|
+
}
|
|
1052
|
+
/**
|
|
1053
|
+
* Context of the resource that owns the task.
|
|
1054
|
+
* When the context is disposed, the task is cancelled and cannot be scheduled again.
|
|
1055
|
+
*/
|
|
1056
|
+
open() {
|
|
1057
|
+
this.#ctx = new Context2();
|
|
1058
|
+
}
|
|
1059
|
+
/**
|
|
1060
|
+
* Closes the task and waits for it to finish if it is running.
|
|
1061
|
+
*/
|
|
1062
|
+
async close() {
|
|
1063
|
+
await this.#ctx?.dispose();
|
|
1064
|
+
await this.join();
|
|
1065
|
+
this.#ctx = void 0;
|
|
1066
|
+
}
|
|
1067
|
+
[Symbol.asyncDispose]() {
|
|
1068
|
+
return this.close();
|
|
1069
|
+
}
|
|
1070
|
+
/**
|
|
1071
|
+
* Schedule the task to run asynchronously.
|
|
1072
|
+
*/
|
|
1073
|
+
// TODO(dmaretskyi): Add scheduleAt. Where the earlier time will override the later one.
|
|
1074
|
+
schedule() {
|
|
1075
|
+
if (!this.#ctx || this.#ctx.disposed) {
|
|
1076
|
+
throw new Error("AsyncTask not open");
|
|
1077
|
+
}
|
|
1078
|
+
if (this.#scheduled) {
|
|
1079
|
+
return;
|
|
1080
|
+
}
|
|
1081
|
+
scheduleTask(this.#ctx, async () => {
|
|
1082
|
+
await this.#currentTask;
|
|
1083
|
+
if (!this.#ctx || this.#ctx.disposed) {
|
|
1084
|
+
return;
|
|
1085
|
+
}
|
|
1086
|
+
this.#scheduled = false;
|
|
1087
|
+
const completionTrigger = this.#nextTask;
|
|
1088
|
+
this.#nextTask = new Trigger();
|
|
1089
|
+
this.#currentTask = runInContextAsync(this.#ctx, () => this.#callback()).then(() => {
|
|
1090
|
+
completionTrigger.wake();
|
|
1091
|
+
});
|
|
1092
|
+
});
|
|
1093
|
+
this.#scheduled = true;
|
|
1094
|
+
}
|
|
1095
|
+
/**
|
|
1096
|
+
* Schedule the task to run and wait for it to finish.
|
|
1097
|
+
*/
|
|
1098
|
+
async runBlocking() {
|
|
1099
|
+
if (this.#ctx?.disposed) {
|
|
1100
|
+
throw new ContextDisposedError2();
|
|
1101
|
+
}
|
|
1102
|
+
this.schedule();
|
|
1103
|
+
await this.#nextTask.wait();
|
|
1104
|
+
}
|
|
1105
|
+
/**
|
|
1106
|
+
* Waits for the current task to finish if it is running.
|
|
1107
|
+
* Does not schedule a new task.
|
|
1108
|
+
*/
|
|
1109
|
+
async join() {
|
|
1110
|
+
await this.#currentTask;
|
|
1111
|
+
}
|
|
1112
|
+
};
|
|
1037
1113
|
var runInContext = (ctx, fn) => {
|
|
1038
1114
|
try {
|
|
1039
1115
|
fn();
|
|
@@ -1119,15 +1195,18 @@ function _ts_decorate(decorators, target, key, desc) {
|
|
|
1119
1195
|
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;
|
|
1120
1196
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1121
1197
|
}
|
|
1122
|
-
var __dxlog_file4 = "/__w/dxos/dxos/packages/common/async/src/persistent-lifecycle.ts";
|
|
1123
1198
|
var INIT_RESTART_DELAY = 100;
|
|
1124
1199
|
var DEFAULT_MAX_RESTART_DELAY = 5e3;
|
|
1125
1200
|
var PersistentLifecycle = class extends Resource {
|
|
1201
|
+
_start;
|
|
1202
|
+
_stop;
|
|
1203
|
+
_onRestart;
|
|
1204
|
+
_maxRestartDelay;
|
|
1205
|
+
_currentState = void 0;
|
|
1206
|
+
_restartTask = void 0;
|
|
1207
|
+
_restartAfter = 0;
|
|
1126
1208
|
constructor({ start, stop, onRestart, maxRestartDelay = DEFAULT_MAX_RESTART_DELAY }) {
|
|
1127
1209
|
super();
|
|
1128
|
-
this._currentState = void 0;
|
|
1129
|
-
this._restartTask = void 0;
|
|
1130
|
-
this._restartAfter = 0;
|
|
1131
1210
|
this._start = start;
|
|
1132
1211
|
this._stop = stop;
|
|
1133
1212
|
this._onRestart = onRestart;
|
|
@@ -1141,25 +1220,21 @@ var PersistentLifecycle = class extends Resource {
|
|
|
1141
1220
|
try {
|
|
1142
1221
|
await this._restart();
|
|
1143
1222
|
} catch (err) {
|
|
1223
|
+
if (this._ctx?.disposed) {
|
|
1224
|
+
return;
|
|
1225
|
+
}
|
|
1144
1226
|
log2.warn("Restart failed", {
|
|
1145
1227
|
err
|
|
1146
|
-
}, {
|
|
1147
|
-
F: __dxlog_file4,
|
|
1148
|
-
L: 72,
|
|
1149
|
-
S: this,
|
|
1150
|
-
C: (f, a) => f(...a)
|
|
1151
1228
|
});
|
|
1152
1229
|
this._restartTask?.schedule();
|
|
1153
1230
|
}
|
|
1154
1231
|
});
|
|
1155
1232
|
this._currentState = await this._start().catch((err) => {
|
|
1233
|
+
if (this._ctx?.disposed) {
|
|
1234
|
+
return void 0;
|
|
1235
|
+
}
|
|
1156
1236
|
log2.warn("Start failed", {
|
|
1157
1237
|
err
|
|
1158
|
-
}, {
|
|
1159
|
-
F: __dxlog_file4,
|
|
1160
|
-
L: 78,
|
|
1161
|
-
S: this,
|
|
1162
|
-
C: (f, a) => f(...a)
|
|
1163
1238
|
});
|
|
1164
1239
|
this._restartTask?.schedule();
|
|
1165
1240
|
return void 0;
|
|
@@ -1173,11 +1248,6 @@ var PersistentLifecycle = class extends Resource {
|
|
|
1173
1248
|
async _restart() {
|
|
1174
1249
|
log2(`restarting in ${this._restartAfter}ms`, {
|
|
1175
1250
|
state: this._lifecycleState
|
|
1176
|
-
}, {
|
|
1177
|
-
F: __dxlog_file4,
|
|
1178
|
-
L: 91,
|
|
1179
|
-
S: this,
|
|
1180
|
-
C: (f, a) => f(...a)
|
|
1181
1251
|
});
|
|
1182
1252
|
await this._stopCurrentState();
|
|
1183
1253
|
if (this._lifecycleState !== LifecycleState.OPEN) {
|
|
@@ -1196,12 +1266,7 @@ var PersistentLifecycle = class extends Resource {
|
|
|
1196
1266
|
try {
|
|
1197
1267
|
await this._stop(this._currentState);
|
|
1198
1268
|
} catch (err) {
|
|
1199
|
-
log2.catch(err
|
|
1200
|
-
F: __dxlog_file4,
|
|
1201
|
-
L: 113,
|
|
1202
|
-
S: this,
|
|
1203
|
-
C: (f, a) => f(...a)
|
|
1204
|
-
});
|
|
1269
|
+
log2.catch(err);
|
|
1205
1270
|
}
|
|
1206
1271
|
this._currentState = void 0;
|
|
1207
1272
|
}
|
|
@@ -1225,7 +1290,6 @@ _ts_decorate([
|
|
|
1225
1290
|
|
|
1226
1291
|
// src/push-iterable.ts
|
|
1227
1292
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
1228
|
-
var __dxlog_file5 = "/__w/dxos/dxos/packages/common/async/src/push-iterable.ts";
|
|
1229
1293
|
var makePushIterable = () => {
|
|
1230
1294
|
const buf = [];
|
|
1231
1295
|
const trigger2 = new Trigger({
|
|
@@ -1239,15 +1303,7 @@ var makePushIterable = () => {
|
|
|
1239
1303
|
await trigger2.wait();
|
|
1240
1304
|
}
|
|
1241
1305
|
const item = buf.shift();
|
|
1242
|
-
invariant2(item
|
|
1243
|
-
F: __dxlog_file5,
|
|
1244
|
-
L: 42,
|
|
1245
|
-
S: this,
|
|
1246
|
-
A: [
|
|
1247
|
-
"item",
|
|
1248
|
-
""
|
|
1249
|
-
]
|
|
1250
|
-
});
|
|
1306
|
+
invariant2(item);
|
|
1251
1307
|
switch (item.kind) {
|
|
1252
1308
|
case "next":
|
|
1253
1309
|
return {
|
|
@@ -1334,11 +1390,6 @@ var streamToArray = (stream) => {
|
|
|
1334
1390
|
// src/test-stream.ts
|
|
1335
1391
|
import { Duplex } from "@dxos/node-std/stream";
|
|
1336
1392
|
var TestStream = class extends Duplex {
|
|
1337
|
-
constructor() {
|
|
1338
|
-
super(...arguments);
|
|
1339
|
-
this._received = Buffer.alloc(0);
|
|
1340
|
-
this._onWrite = new Event();
|
|
1341
|
-
}
|
|
1342
1393
|
static async assertConnectivity(stream1, stream2, { timeout: timeout2 = 200 } = {}) {
|
|
1343
1394
|
stream1.push("ping");
|
|
1344
1395
|
stream2.push("pong");
|
|
@@ -1351,6 +1402,8 @@ var TestStream = class extends Duplex {
|
|
|
1351
1402
|
})
|
|
1352
1403
|
]);
|
|
1353
1404
|
}
|
|
1405
|
+
_received = Buffer.alloc(0);
|
|
1406
|
+
_onWrite = new Event();
|
|
1354
1407
|
_write(chunk, encoding, callback) {
|
|
1355
1408
|
this._received = Buffer.concat([
|
|
1356
1409
|
this._received,
|
|
@@ -1428,10 +1481,12 @@ var untilError = (cb) => {
|
|
|
1428
1481
|
|
|
1429
1482
|
// src/timer.ts
|
|
1430
1483
|
var Timer = class {
|
|
1484
|
+
_callback;
|
|
1485
|
+
_state = new Event();
|
|
1486
|
+
_timer;
|
|
1487
|
+
_count = 0;
|
|
1431
1488
|
constructor(_callback) {
|
|
1432
1489
|
this._callback = _callback;
|
|
1433
|
-
this._state = new Event();
|
|
1434
|
-
this._count = 0;
|
|
1435
1490
|
}
|
|
1436
1491
|
get state() {
|
|
1437
1492
|
return this._state;
|
|
@@ -1477,13 +1532,20 @@ var Timer = class {
|
|
|
1477
1532
|
// src/update-scheduler.ts
|
|
1478
1533
|
var TIME_PERIOD = 1e3;
|
|
1479
1534
|
var UpdateScheduler = class {
|
|
1535
|
+
_ctx;
|
|
1536
|
+
_callback;
|
|
1537
|
+
_params;
|
|
1538
|
+
/**
|
|
1539
|
+
* Promise that resolves when the callback is done.
|
|
1540
|
+
* Never rejects.
|
|
1541
|
+
*/
|
|
1542
|
+
_promise = null;
|
|
1543
|
+
_scheduled = false;
|
|
1544
|
+
_lastUpdateTime = -TIME_PERIOD;
|
|
1480
1545
|
constructor(_ctx, _callback, _params = {}) {
|
|
1481
1546
|
this._ctx = _ctx;
|
|
1482
1547
|
this._callback = _callback;
|
|
1483
1548
|
this._params = _params;
|
|
1484
|
-
this._promise = null;
|
|
1485
|
-
this._scheduled = false;
|
|
1486
|
-
this._lastUpdateTime = -TIME_PERIOD;
|
|
1487
1549
|
_ctx.onDispose(async () => {
|
|
1488
1550
|
await this._promise;
|
|
1489
1551
|
});
|
|
@@ -1496,13 +1558,13 @@ var UpdateScheduler = class {
|
|
|
1496
1558
|
await this._promise;
|
|
1497
1559
|
if (this._params.maxFrequency) {
|
|
1498
1560
|
const now = performance.now();
|
|
1499
|
-
const
|
|
1500
|
-
if (
|
|
1561
|
+
const delay2 = this._lastUpdateTime + TIME_PERIOD / this._params.maxFrequency - now;
|
|
1562
|
+
if (delay2 > 0) {
|
|
1501
1563
|
await new Promise((resolve) => {
|
|
1502
1564
|
const timeoutId = setTimeout(() => {
|
|
1503
1565
|
clearContext();
|
|
1504
1566
|
resolve();
|
|
1505
|
-
},
|
|
1567
|
+
}, delay2);
|
|
1506
1568
|
const clearContext = this._ctx.onDispose(() => {
|
|
1507
1569
|
clearTimeout(timeoutId);
|
|
1508
1570
|
resolve();
|
|
@@ -1546,6 +1608,7 @@ var UpdateScheduler = class {
|
|
|
1546
1608
|
}
|
|
1547
1609
|
};
|
|
1548
1610
|
export {
|
|
1611
|
+
AsyncTask,
|
|
1549
1612
|
CancellableObservableProvider,
|
|
1550
1613
|
DeferredTask,
|
|
1551
1614
|
Event,
|
|
@@ -1572,6 +1635,7 @@ export {
|
|
|
1572
1635
|
combine,
|
|
1573
1636
|
debounce,
|
|
1574
1637
|
debounceAndThrottle,
|
|
1638
|
+
delay,
|
|
1575
1639
|
dumpLeaks,
|
|
1576
1640
|
interval,
|
|
1577
1641
|
latch,
|