@dxos/async 0.8.4-main.67995b8 → 0.8.4-main.6fa680abb7

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.
@@ -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
- constructor() {
42
- this._cleanups = [];
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 debounce = (cb, delay = 100) => {
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), delay);
87
+ t = setTimeout(() => cb(...args), delay2);
73
88
  };
74
89
  };
75
- var throttle = (cb, delay = 100) => {
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 >= delay) {
94
+ if (now - lastCall >= delay2) {
80
95
  cb(...args);
81
96
  lastCall = now;
82
97
  }
83
98
  };
84
99
  };
85
- var debounceAndThrottle = (cb, delay = 100) => {
86
- const debounced = debounce(cb, delay);
87
- const throttled = throttle(cb, delay);
100
+ var debounceAndThrottle = (cb, delay2 = 100) => {
101
+ let timeout2;
102
+ let lastCall = 0;
88
103
  return (...args) => {
89
- debounced(...args);
90
- throttled(...args);
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
 
@@ -191,10 +216,6 @@ import { Context } from "@dxos/context";
191
216
  var __dxlog_file = "/__w/dxos/dxos/packages/common/async/src/events.ts";
192
217
  var DO_NOT_ERROR_ON_ASYNC_CALLBACK = true;
193
218
  var Event = class _Event {
194
- constructor() {
195
- this._listeners = /* @__PURE__ */ new Set();
196
- this._effects = /* @__PURE__ */ new Set();
197
- }
198
219
  /**
199
220
  * Wrap objects that have on/off style event emitters.
200
221
  */
@@ -207,6 +228,8 @@ var Event = class _Event {
207
228
  });
208
229
  return event;
209
230
  }
231
+ _listeners = /* @__PURE__ */ new Set();
232
+ _effects = /* @__PURE__ */ new Set();
210
233
  /**
211
234
  * Emit an event.
212
235
  * In most cases should only be called by the class or entity containing the event.
@@ -450,11 +473,15 @@ var Event = class _Event {
450
473
  }
451
474
  };
452
475
  var EventListener = class {
476
+ ctx;
477
+ once;
478
+ weak;
479
+ callback;
480
+ _clearDispose = void 0;
453
481
  constructor(event, listener, ctx, once, weak) {
454
482
  this.ctx = ctx;
455
483
  this.once = once;
456
484
  this.weak = weak;
457
- this._clearDispose = void 0;
458
485
  this._clearDispose = ctx.onDispose(() => {
459
486
  event._removeListener(this);
460
487
  });
@@ -518,11 +545,9 @@ var weakListeners = () => {
518
545
  import "@dxos/util";
519
546
  import { warnAfterTimeout } from "@dxos/debug";
520
547
  var Mutex = class {
521
- constructor() {
522
- this._queue = Promise.resolve();
523
- this._queueLength = 0;
524
- this._tag = null;
525
- }
548
+ _queue = Promise.resolve();
549
+ _queueLength = 0;
550
+ _tag = null;
526
551
  get tag() {
527
552
  return this._tag;
528
553
  }
@@ -568,6 +593,7 @@ var Mutex = class {
568
593
  }
569
594
  };
570
595
  var MutexGuard = class {
596
+ _release;
571
597
  constructor(_release) {
572
598
  this._release = _release;
573
599
  }
@@ -581,7 +607,7 @@ var MutexGuard = class {
581
607
  this.release();
582
608
  }
583
609
  };
584
- var classMutexSymbol = Symbol("class-mutex");
610
+ var classMutexSymbol = /* @__PURE__ */ Symbol("class-mutex");
585
611
  var FORCE_DISABLE_WARNING = false;
586
612
  var enableWarning = !FORCE_DISABLE_WARNING && globalThis.mochaExecutor;
587
613
  var synchronized = (target, propertyName, descriptor) => {
@@ -628,18 +654,22 @@ var trigger = (timeout2) => {
628
654
  resolver
629
655
  ];
630
656
  };
631
- var TriggerState = /* @__PURE__ */ function(TriggerState2) {
657
+ var TriggerState = /* @__PURE__ */ (function(TriggerState2) {
632
658
  TriggerState2["WAITING"] = "WAITING";
633
659
  TriggerState2["RESOLVED"] = "RESOLVED";
634
660
  TriggerState2["REJECTED"] = "REJECTED";
635
661
  return TriggerState2;
636
- }({});
662
+ })({});
637
663
  var Trigger = class {
664
+ _options;
665
+ _promise;
666
+ _resolve;
667
+ _reject;
668
+ _state = "WAITING";
638
669
  constructor(_options = {
639
670
  autoReset: false
640
671
  }) {
641
672
  this._options = _options;
642
- this._state = "WAITING";
643
673
  this.reset();
644
674
  }
645
675
  get state() {
@@ -748,20 +778,12 @@ var latch = ({ count = 1, timeout: timeout2 } = {}) => {
748
778
 
749
779
  // src/observable.ts
750
780
  var MulticastObservable = class _MulticastObservable extends Observable {
781
+ _value;
782
+ _observers = /* @__PURE__ */ new Set();
783
+ _observable;
784
+ _completed = new Trigger();
751
785
  constructor(subscriber, _value) {
752
- super((observer) => this._subscribe(observer)), this._value = _value, this._observers = /* @__PURE__ */ new Set(), this._completed = new Trigger(), this._handlers = {
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
- };
786
+ super((observer) => this._subscribe(observer)), this._value = _value;
765
787
  this._observable = typeof subscriber === "function" ? new Observable(subscriber) : subscriber;
766
788
  this._observable.subscribe(this._handlers);
767
789
  }
@@ -845,18 +867,30 @@ var MulticastObservable = class _MulticastObservable extends Observable {
845
867
  this._observers.delete(observer);
846
868
  };
847
869
  }
870
+ _handlers = {
871
+ next: (value) => {
872
+ this._value = value;
873
+ this._observers.forEach((observer) => observer.next?.(value));
874
+ },
875
+ error: (err) => {
876
+ this._observers.forEach((observer) => observer.error?.(err));
877
+ },
878
+ complete: () => {
879
+ this._completed.wake();
880
+ this._observers.forEach((observer) => observer.complete?.());
881
+ }
882
+ };
848
883
  };
849
884
  var EMPTY_OBSERVABLE = MulticastObservable.of(null);
850
885
 
851
886
  // src/observable-value.ts
852
887
  import { createSetDispatch } from "@dxos/util";
853
888
  var ObservableProvider = class {
854
- constructor() {
855
- this._handlers = /* @__PURE__ */ new Set();
856
- this._proxy = createSetDispatch({
857
- handlers: this._handlers
858
- });
859
- }
889
+ _handlers = /* @__PURE__ */ new Set();
890
+ _proxy = createSetDispatch({
891
+ handlers: this._handlers
892
+ });
893
+ _value;
860
894
  /**
861
895
  * Proxy used to dispatch callbacks to each subscription.
862
896
  */
@@ -877,8 +911,10 @@ var ObservableProvider = class {
877
911
  }
878
912
  };
879
913
  var CancellableObservableProvider = class extends ObservableProvider {
914
+ _handleCancel;
915
+ _cancelled = false;
880
916
  constructor(_handleCancel) {
881
- super(), this._handleCancel = _handleCancel, this._cancelled = false;
917
+ super(), this._handleCancel = _handleCancel;
882
918
  }
883
919
  get cancelled() {
884
920
  return this._cancelled;
@@ -899,7 +935,7 @@ import { warnAfterTimeout as warnAfterTimeout2 } from "@dxos/debug";
899
935
  import { log as log2 } from "@dxos/log";
900
936
 
901
937
  // src/task-scheduling.ts
902
- import { ContextDisposedError as ContextDisposedError2 } from "@dxos/context";
938
+ import { Context as Context2, ContextDisposedError as ContextDisposedError2 } from "@dxos/context";
903
939
  import { StackTrace as StackTrace2 } from "@dxos/debug";
904
940
 
905
941
  // src/track-leaks.ts
@@ -908,7 +944,7 @@ import { log } from "@dxos/log";
908
944
  var __dxlog_file3 = "/__w/dxos/dxos/packages/common/async/src/track-leaks.ts";
909
945
  var enabled = typeof process !== "undefined" && !!process.env.DX_TRACK_LEAKS;
910
946
  var openResources = /* @__PURE__ */ new Set();
911
- var handleSymbol = Symbol("checkLeaksHandle");
947
+ var handleSymbol = /* @__PURE__ */ Symbol("checkLeaksHandle");
912
948
  var trackResource = (resourceProvider) => {
913
949
  if (!enabled) {
914
950
  return () => {
@@ -987,13 +1023,16 @@ if (enabled) {
987
1023
  }
988
1024
 
989
1025
  // src/task-scheduling.ts
1026
+ var __dxlog_file4 = "/__w/dxos/dxos/packages/common/async/src/task-scheduling.ts";
990
1027
  var DeferredTask = class {
1028
+ _ctx;
1029
+ _callback;
1030
+ _scheduled = false;
1031
+ _currentTask = null;
1032
+ _nextTask = new Trigger();
991
1033
  constructor(_ctx, _callback) {
992
1034
  this._ctx = _ctx;
993
1035
  this._callback = _callback;
994
- this._scheduled = false;
995
- this._currentTask = null;
996
- this._nextTask = new Trigger();
997
1036
  }
998
1037
  get scheduled() {
999
1038
  return this._scheduled;
@@ -1034,6 +1073,82 @@ var DeferredTask = class {
1034
1073
  await this._currentTask;
1035
1074
  }
1036
1075
  };
1076
+ var AsyncTask = class {
1077
+ #callback;
1078
+ #ctx = void 0;
1079
+ #scheduled = false;
1080
+ #currentTask = null;
1081
+ #nextTask = new Trigger();
1082
+ constructor(callback) {
1083
+ this.#callback = callback;
1084
+ }
1085
+ get scheduled() {
1086
+ return this.#scheduled;
1087
+ }
1088
+ /**
1089
+ * Context of the resource that owns the task.
1090
+ * When the context is disposed, the task is cancelled and cannot be scheduled again.
1091
+ */
1092
+ open() {
1093
+ this.#ctx = new Context2(void 0, {
1094
+ F: __dxlog_file4,
1095
+ L: 102
1096
+ });
1097
+ }
1098
+ /**
1099
+ * Closes the task and waits for it to finish if it is running.
1100
+ */
1101
+ async close() {
1102
+ await this.#ctx?.dispose();
1103
+ await this.join();
1104
+ this.#ctx = void 0;
1105
+ }
1106
+ [Symbol.asyncDispose]() {
1107
+ return this.close();
1108
+ }
1109
+ /**
1110
+ * Schedule the task to run asynchronously.
1111
+ */
1112
+ // TODO(dmaretskyi): Add scheduleAt. Where the earlier time will override the later one.
1113
+ schedule() {
1114
+ if (!this.#ctx || this.#ctx.disposed) {
1115
+ throw new Error("AsyncTask not open");
1116
+ }
1117
+ if (this.#scheduled) {
1118
+ return;
1119
+ }
1120
+ scheduleTask(this.#ctx, async () => {
1121
+ await this.#currentTask;
1122
+ if (!this.#ctx || this.#ctx.disposed) {
1123
+ return;
1124
+ }
1125
+ this.#scheduled = false;
1126
+ const completionTrigger = this.#nextTask;
1127
+ this.#nextTask = new Trigger();
1128
+ this.#currentTask = runInContextAsync(this.#ctx, () => this.#callback()).then(() => {
1129
+ completionTrigger.wake();
1130
+ });
1131
+ });
1132
+ this.#scheduled = true;
1133
+ }
1134
+ /**
1135
+ * Schedule the task to run and wait for it to finish.
1136
+ */
1137
+ async runBlocking() {
1138
+ if (this.#ctx?.disposed) {
1139
+ throw new ContextDisposedError2();
1140
+ }
1141
+ this.schedule();
1142
+ await this.#nextTask.wait();
1143
+ }
1144
+ /**
1145
+ * Waits for the current task to finish if it is running.
1146
+ * Does not schedule a new task.
1147
+ */
1148
+ async join() {
1149
+ await this.#currentTask;
1150
+ }
1151
+ };
1037
1152
  var runInContext = (ctx, fn) => {
1038
1153
  try {
1039
1154
  fn();
@@ -1119,15 +1234,19 @@ function _ts_decorate(decorators, target, key, desc) {
1119
1234
  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
1235
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1121
1236
  }
1122
- var __dxlog_file4 = "/__w/dxos/dxos/packages/common/async/src/persistent-lifecycle.ts";
1237
+ var __dxlog_file5 = "/__w/dxos/dxos/packages/common/async/src/persistent-lifecycle.ts";
1123
1238
  var INIT_RESTART_DELAY = 100;
1124
1239
  var DEFAULT_MAX_RESTART_DELAY = 5e3;
1125
1240
  var PersistentLifecycle = class extends Resource {
1241
+ _start;
1242
+ _stop;
1243
+ _onRestart;
1244
+ _maxRestartDelay;
1245
+ _currentState = void 0;
1246
+ _restartTask = void 0;
1247
+ _restartAfter = 0;
1126
1248
  constructor({ start, stop, onRestart, maxRestartDelay = DEFAULT_MAX_RESTART_DELAY }) {
1127
1249
  super();
1128
- this._currentState = void 0;
1129
- this._restartTask = void 0;
1130
- this._restartAfter = 0;
1131
1250
  this._start = start;
1132
1251
  this._stop = stop;
1133
1252
  this._onRestart = onRestart;
@@ -1144,7 +1263,7 @@ var PersistentLifecycle = class extends Resource {
1144
1263
  log2.warn("Restart failed", {
1145
1264
  err
1146
1265
  }, {
1147
- F: __dxlog_file4,
1266
+ F: __dxlog_file5,
1148
1267
  L: 72,
1149
1268
  S: this,
1150
1269
  C: (f, a) => f(...a)
@@ -1156,7 +1275,7 @@ var PersistentLifecycle = class extends Resource {
1156
1275
  log2.warn("Start failed", {
1157
1276
  err
1158
1277
  }, {
1159
- F: __dxlog_file4,
1278
+ F: __dxlog_file5,
1160
1279
  L: 78,
1161
1280
  S: this,
1162
1281
  C: (f, a) => f(...a)
@@ -1174,7 +1293,7 @@ var PersistentLifecycle = class extends Resource {
1174
1293
  log2(`restarting in ${this._restartAfter}ms`, {
1175
1294
  state: this._lifecycleState
1176
1295
  }, {
1177
- F: __dxlog_file4,
1296
+ F: __dxlog_file5,
1178
1297
  L: 91,
1179
1298
  S: this,
1180
1299
  C: (f, a) => f(...a)
@@ -1197,7 +1316,7 @@ var PersistentLifecycle = class extends Resource {
1197
1316
  await this._stop(this._currentState);
1198
1317
  } catch (err) {
1199
1318
  log2.catch(err, void 0, {
1200
- F: __dxlog_file4,
1319
+ F: __dxlog_file5,
1201
1320
  L: 113,
1202
1321
  S: this,
1203
1322
  C: (f, a) => f(...a)
@@ -1225,7 +1344,7 @@ _ts_decorate([
1225
1344
 
1226
1345
  // src/push-iterable.ts
1227
1346
  import { invariant as invariant2 } from "@dxos/invariant";
1228
- var __dxlog_file5 = "/__w/dxos/dxos/packages/common/async/src/push-iterable.ts";
1347
+ var __dxlog_file6 = "/__w/dxos/dxos/packages/common/async/src/push-iterable.ts";
1229
1348
  var makePushIterable = () => {
1230
1349
  const buf = [];
1231
1350
  const trigger2 = new Trigger({
@@ -1240,7 +1359,7 @@ var makePushIterable = () => {
1240
1359
  }
1241
1360
  const item = buf.shift();
1242
1361
  invariant2(item, void 0, {
1243
- F: __dxlog_file5,
1362
+ F: __dxlog_file6,
1244
1363
  L: 42,
1245
1364
  S: this,
1246
1365
  A: [
@@ -1334,11 +1453,6 @@ var streamToArray = (stream) => {
1334
1453
  // src/test-stream.ts
1335
1454
  import { Duplex } from "@dxos/node-std/stream";
1336
1455
  var TestStream = class extends Duplex {
1337
- constructor() {
1338
- super(...arguments);
1339
- this._received = Buffer.alloc(0);
1340
- this._onWrite = new Event();
1341
- }
1342
1456
  static async assertConnectivity(stream1, stream2, { timeout: timeout2 = 200 } = {}) {
1343
1457
  stream1.push("ping");
1344
1458
  stream2.push("pong");
@@ -1351,6 +1465,8 @@ var TestStream = class extends Duplex {
1351
1465
  })
1352
1466
  ]);
1353
1467
  }
1468
+ _received = Buffer.alloc(0);
1469
+ _onWrite = new Event();
1354
1470
  _write(chunk, encoding, callback) {
1355
1471
  this._received = Buffer.concat([
1356
1472
  this._received,
@@ -1428,10 +1544,12 @@ var untilError = (cb) => {
1428
1544
 
1429
1545
  // src/timer.ts
1430
1546
  var Timer = class {
1547
+ _callback;
1548
+ _state = new Event();
1549
+ _timer;
1550
+ _count = 0;
1431
1551
  constructor(_callback) {
1432
1552
  this._callback = _callback;
1433
- this._state = new Event();
1434
- this._count = 0;
1435
1553
  }
1436
1554
  get state() {
1437
1555
  return this._state;
@@ -1477,13 +1595,20 @@ var Timer = class {
1477
1595
  // src/update-scheduler.ts
1478
1596
  var TIME_PERIOD = 1e3;
1479
1597
  var UpdateScheduler = class {
1598
+ _ctx;
1599
+ _callback;
1600
+ _params;
1601
+ /**
1602
+ * Promise that resolves when the callback is done.
1603
+ * Never rejects.
1604
+ */
1605
+ _promise = null;
1606
+ _scheduled = false;
1607
+ _lastUpdateTime = -TIME_PERIOD;
1480
1608
  constructor(_ctx, _callback, _params = {}) {
1481
1609
  this._ctx = _ctx;
1482
1610
  this._callback = _callback;
1483
1611
  this._params = _params;
1484
- this._promise = null;
1485
- this._scheduled = false;
1486
- this._lastUpdateTime = -TIME_PERIOD;
1487
1612
  _ctx.onDispose(async () => {
1488
1613
  await this._promise;
1489
1614
  });
@@ -1496,13 +1621,13 @@ var UpdateScheduler = class {
1496
1621
  await this._promise;
1497
1622
  if (this._params.maxFrequency) {
1498
1623
  const now = performance.now();
1499
- const delay = this._lastUpdateTime + TIME_PERIOD / this._params.maxFrequency - now;
1500
- if (delay > 0) {
1624
+ const delay2 = this._lastUpdateTime + TIME_PERIOD / this._params.maxFrequency - now;
1625
+ if (delay2 > 0) {
1501
1626
  await new Promise((resolve) => {
1502
1627
  const timeoutId = setTimeout(() => {
1503
1628
  clearContext();
1504
1629
  resolve();
1505
- }, delay);
1630
+ }, delay2);
1506
1631
  const clearContext = this._ctx.onDispose(() => {
1507
1632
  clearTimeout(timeoutId);
1508
1633
  resolve();
@@ -1546,6 +1671,7 @@ var UpdateScheduler = class {
1546
1671
  }
1547
1672
  };
1548
1673
  export {
1674
+ AsyncTask,
1549
1675
  CancellableObservableProvider,
1550
1676
  DeferredTask,
1551
1677
  Event,
@@ -1572,6 +1698,7 @@ export {
1572
1698
  combine,
1573
1699
  debounce,
1574
1700
  debounceAndThrottle,
1701
+ delay,
1575
1702
  dumpLeaks,
1576
1703
  interval,
1577
1704
  latch,