@dxos/util 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.
Files changed (141) hide show
  1. package/LICENSE +102 -5
  2. package/dist/lib/browser/index.mjs +604 -229
  3. package/dist/lib/browser/index.mjs.map +4 -4
  4. package/dist/lib/browser/meta.json +1 -1
  5. package/dist/lib/node-esm/index.mjs +604 -229
  6. package/dist/lib/node-esm/index.mjs.map +4 -4
  7. package/dist/lib/node-esm/meta.json +1 -1
  8. package/dist/types/src/array-to-hex.d.ts.map +1 -1
  9. package/dist/types/src/array.d.ts +3 -2
  10. package/dist/types/src/array.d.ts.map +1 -1
  11. package/dist/types/src/binder.d.ts.map +1 -1
  12. package/dist/types/src/bitfield.d.ts.map +1 -1
  13. package/dist/types/src/browser-storage.d.ts +9 -0
  14. package/dist/types/src/browser-storage.d.ts.map +1 -0
  15. package/dist/types/src/callback-collection.d.ts.map +1 -1
  16. package/dist/types/src/callback.d.ts.map +1 -1
  17. package/dist/types/src/case.d.ts.map +1 -1
  18. package/dist/types/src/chunk-array.d.ts.map +1 -1
  19. package/dist/types/src/circular-buffer.d.ts +1 -0
  20. package/dist/types/src/circular-buffer.d.ts.map +1 -1
  21. package/dist/types/src/clear-undefined.d.ts.map +1 -1
  22. package/dist/types/src/complex.d.ts +15 -0
  23. package/dist/types/src/complex.d.ts.map +1 -1
  24. package/dist/types/src/composite-key.d.ts +10 -0
  25. package/dist/types/src/composite-key.d.ts.map +1 -0
  26. package/dist/types/src/composite-key.test.d.ts +2 -0
  27. package/dist/types/src/composite-key.test.d.ts.map +1 -0
  28. package/dist/types/src/deep.d.ts +0 -3
  29. package/dist/types/src/deep.d.ts.map +1 -1
  30. package/dist/types/src/defer-function.d.ts.map +1 -1
  31. package/dist/types/src/defer.d.ts +1 -1
  32. package/dist/types/src/defer.d.ts.map +1 -1
  33. package/dist/types/src/di-container.d.ts.map +1 -1
  34. package/dist/types/src/di-key.d.ts +7 -5
  35. package/dist/types/src/di-key.d.ts.map +1 -1
  36. package/dist/types/src/entry.d.ts.map +1 -1
  37. package/dist/types/src/error-format.d.ts +5 -0
  38. package/dist/types/src/error-format.d.ts.map +1 -0
  39. package/dist/types/src/filename.d.ts +9 -0
  40. package/dist/types/src/filename.d.ts.map +1 -0
  41. package/dist/types/src/for-each-async.d.ts.map +1 -1
  42. package/dist/types/src/human-hash.d.ts.map +1 -1
  43. package/dist/types/src/id.d.ts +30 -0
  44. package/dist/types/src/id.d.ts.map +1 -0
  45. package/dist/types/src/id.test.d.ts +2 -0
  46. package/dist/types/src/id.test.d.ts.map +1 -0
  47. package/dist/types/src/index.d.ts +8 -1
  48. package/dist/types/src/index.d.ts.map +1 -1
  49. package/dist/types/src/instance-id.d.ts.map +1 -1
  50. package/dist/types/src/interval.d.ts.map +1 -1
  51. package/dist/types/src/join-tables.d.ts.map +1 -1
  52. package/dist/types/src/json.d.ts.map +1 -1
  53. package/dist/types/src/map-values.d.ts.map +1 -1
  54. package/dist/types/src/map.d.ts.map +1 -1
  55. package/dist/types/src/object.d.ts.map +1 -1
  56. package/dist/types/src/order-keys.d.ts.map +1 -1
  57. package/dist/types/src/order.d.ts.map +1 -1
  58. package/dist/types/src/pick.d.ts.map +1 -1
  59. package/dist/types/src/platform.d.ts +5 -2
  60. package/dist/types/src/platform.d.ts.map +1 -1
  61. package/dist/types/src/position.d.ts +1 -1
  62. package/dist/types/src/position.d.ts.map +1 -1
  63. package/dist/types/src/random.d.ts.map +1 -1
  64. package/dist/types/src/range.d.ts.map +1 -1
  65. package/dist/types/src/reducers.d.ts.map +1 -1
  66. package/dist/types/src/remove-undefined-keys.d.ts.map +1 -1
  67. package/dist/types/src/retry.d.ts +32 -0
  68. package/dist/types/src/retry.d.ts.map +1 -0
  69. package/dist/types/src/safe-await.d.ts.map +1 -1
  70. package/dist/types/src/safe-instanceof.d.ts.map +1 -1
  71. package/dist/types/src/safe-parse.d.ts +7 -4
  72. package/dist/types/src/safe-parse.d.ts.map +1 -1
  73. package/dist/types/src/safe-stringify.d.ts +22 -0
  74. package/dist/types/src/safe-stringify.d.ts.map +1 -0
  75. package/dist/types/src/safe-stringify.test.d.ts +2 -0
  76. package/dist/types/src/safe-stringify.test.d.ts.map +1 -0
  77. package/dist/types/src/sliding-window-summary.d.ts.map +1 -1
  78. package/dist/types/src/sort.d.ts.map +1 -1
  79. package/dist/types/src/string.d.ts +5 -1
  80. package/dist/types/src/string.d.ts.map +1 -1
  81. package/dist/types/src/sum.d.ts.map +1 -1
  82. package/dist/types/src/throw-unhandled-error.d.ts.map +1 -1
  83. package/dist/types/src/to-fallback.d.ts +18 -4
  84. package/dist/types/src/to-fallback.d.ts.map +1 -1
  85. package/dist/types/src/tracer.d.ts.map +1 -1
  86. package/dist/types/src/tree.d.ts.map +1 -1
  87. package/dist/types/src/types.d.ts +24 -6
  88. package/dist/types/src/types.d.ts.map +1 -1
  89. package/dist/types/src/uint8array.d.ts.map +1 -1
  90. package/dist/types/src/unit.d.ts +14 -0
  91. package/dist/types/src/unit.d.ts.map +1 -0
  92. package/dist/types/src/unit.test.d.ts +2 -0
  93. package/dist/types/src/unit.test.d.ts.map +1 -0
  94. package/dist/types/src/url.d.ts.map +1 -1
  95. package/dist/types/src/weak.d.ts +15 -0
  96. package/dist/types/src/weak.d.ts.map +1 -1
  97. package/dist/types/tsconfig.tsbuildinfo +1 -1
  98. package/package.json +15 -17
  99. package/src/array.test.ts +1 -1
  100. package/src/array.ts +9 -2
  101. package/src/binder.ts +2 -2
  102. package/src/browser-storage.ts +60 -0
  103. package/src/circular-buffer.test.ts +27 -1
  104. package/src/circular-buffer.ts +5 -0
  105. package/src/complex.test.ts +1 -1
  106. package/src/complex.ts +32 -0
  107. package/src/composite-key.test.ts +31 -0
  108. package/src/composite-key.ts +16 -0
  109. package/src/deep.ts +2 -6
  110. package/src/defer.ts +1 -1
  111. package/src/di-key.ts +10 -8
  112. package/src/error-format.ts +24 -0
  113. package/src/filename.ts +16 -0
  114. package/src/human-hash.test.ts +1 -1
  115. package/src/id.test.ts +109 -0
  116. package/src/id.ts +48 -0
  117. package/src/index.ts +8 -1
  118. package/src/platform.ts +35 -3
  119. package/src/position.test.ts +2 -2
  120. package/src/retry.ts +74 -0
  121. package/src/safe-parse.ts +29 -17
  122. package/src/safe-stringify.test.ts +96 -0
  123. package/src/safe-stringify.ts +153 -0
  124. package/src/sort.test.ts +1 -1
  125. package/src/string.test.ts +1 -1
  126. package/src/string.ts +36 -6
  127. package/src/to-fallback.ts +44 -160
  128. package/src/tree.test.ts +1 -1
  129. package/src/types.test.ts +11 -1
  130. package/src/types.ts +40 -12
  131. package/src/uint8array.test.ts +1 -1
  132. package/src/unit.test.ts +25 -0
  133. package/src/unit.ts +87 -0
  134. package/src/weak.test.ts +1 -1
  135. package/src/weak.ts +52 -14
  136. package/dist/types/src/explicit-resource-management-polyfill.d.ts +0 -1
  137. package/dist/types/src/explicit-resource-management-polyfill.d.ts.map +0 -1
  138. package/dist/types/src/first-two-chars.d.ts +0 -9
  139. package/dist/types/src/first-two-chars.d.ts.map +0 -1
  140. package/src/explicit-resource-management-polyfill.ts +0 -13
  141. package/src/first-two-chars.ts +0 -44
@@ -97,21 +97,28 @@ var intersectBy = (arrays, selector) => {
97
97
  return lookups.every((lookup) => lookup.has(key));
98
98
  });
99
99
  };
100
+ var coerceArray = (arr) => {
101
+ if (arr === void 0) {
102
+ return [];
103
+ }
104
+ return Array.isArray(arr) ? arr : [
105
+ arr
106
+ ];
107
+ };
100
108
 
101
109
  // src/assume.ts
102
110
  function assumeType(value) {
103
111
  }
104
112
 
105
113
  // src/binder.ts
106
- import util from "node:util";
114
+ import { promisify } from "node:util";
107
115
  var createBinder = (obj) => ({
108
116
  fn: (fn) => fn.bind(obj),
109
- async: (fn) => util.promisify(fn.bind(obj))
117
+ async: (fn) => promisify(fn.bind(obj))
110
118
  });
111
119
 
112
120
  // src/bitfield.ts
113
121
  import { invariant } from "@dxos/invariant";
114
- var __dxlog_file = "/__w/dxos/dxos/packages/common/util/src/bitfield.ts";
115
122
  var BitField = class _BitField {
116
123
  static get(data, idx) {
117
124
  const bit = data[idx >> 3] >> 7 - idx % 8 & 1;
@@ -143,15 +150,7 @@ var BitField = class _BitField {
143
150
  return result;
144
151
  }
145
152
  static and(first, second) {
146
- invariant(first.length === second.length, "Bitfields must be of the same length", {
147
- F: __dxlog_file,
148
- L: 52,
149
- S: this,
150
- A: [
151
- "first.length === second.length",
152
- "'Bitfields must be of the same length'"
153
- ]
154
- });
153
+ invariant(first.length === second.length, "Bitfields must be of the same length");
155
154
  const result = new Uint8Array(first.length);
156
155
  for (let i = 0; i < first.length; i++) {
157
156
  result[i] = first[i] & second[i];
@@ -179,6 +178,49 @@ var BitField = class _BitField {
179
178
  }
180
179
  };
181
180
 
181
+ // src/browser-storage.ts
182
+ var clearIndexedDB = async () => {
183
+ const dbs = await indexedDB.databases();
184
+ const results = await Promise.allSettled(dbs.filter((db) => db.name != null).map((db) => new Promise((resolve, reject) => {
185
+ const request = indexedDB.deleteDatabase(db.name);
186
+ request.onsuccess = () => resolve();
187
+ request.onerror = () => reject(request.error);
188
+ request.onblocked = () => reject(new Error(`IndexedDB deletion blocked: ${db.name}`));
189
+ })));
190
+ const failures = results.filter((r) => r.status === "rejected");
191
+ if (failures.length > 0) {
192
+ throw new AggregateError(failures.map((r) => r.reason), "Failed to delete some IndexedDB databases");
193
+ }
194
+ };
195
+ var clearOPFS = async () => {
196
+ const root = await navigator.storage.getDirectory();
197
+ const errors = [];
198
+ for await (const [name] of root.entries()) {
199
+ try {
200
+ await root.removeEntry(name, {
201
+ recursive: true
202
+ });
203
+ } catch (err) {
204
+ errors.push(err);
205
+ }
206
+ }
207
+ if (errors.length > 0) {
208
+ throw new AggregateError(errors, "Failed to remove some OPFS entries");
209
+ }
210
+ };
211
+ var clearServiceWorkers = async () => {
212
+ const regs = await navigator.serviceWorker.getRegistrations();
213
+ for (const reg of regs) {
214
+ await reg.unregister();
215
+ }
216
+ };
217
+ var clearCaches = async () => {
218
+ const keys2 = await caches.keys();
219
+ for (const key of keys2) {
220
+ await caches.delete(key);
221
+ }
222
+ };
223
+
182
224
  // src/callback-collection.ts
183
225
  var CallbackCollection = class {
184
226
  #callbacks = [];
@@ -205,33 +247,17 @@ var CallbackCollection = class {
205
247
 
206
248
  // src/callback.ts
207
249
  import { invariant as invariant2 } from "@dxos/invariant";
208
- var __dxlog_file2 = "/__w/dxos/dxos/packages/common/util/src/callback.ts";
209
250
  var Callback = class {
251
+ _callback;
210
252
  call(...args) {
211
- invariant2(this._callback, "Callback not set", {
212
- F: __dxlog_file2,
213
- L: 20,
214
- S: this,
215
- A: [
216
- "this._callback",
217
- "'Callback not set'"
218
- ]
219
- });
253
+ invariant2(this._callback, "Callback not set");
220
254
  return this._callback(...args);
221
255
  }
222
256
  callIfSet(...args) {
223
257
  return this._callback?.(...args);
224
258
  }
225
259
  set(callback) {
226
- invariant2(!this._callback, "Callback already set", {
227
- F: __dxlog_file2,
228
- L: 29,
229
- S: this,
230
- A: [
231
- "!this._callback",
232
- "'Callback already set'"
233
- ]
234
- });
260
+ invariant2(!this._callback, "Callback already set");
235
261
  this._callback = callback;
236
262
  }
237
263
  isSet() {
@@ -299,20 +325,12 @@ var chunkArray = (array, size) => {
299
325
 
300
326
  // src/circular-buffer.ts
301
327
  import { invariant as invariant3 } from "@dxos/invariant";
302
- var __dxlog_file3 = "/__w/dxos/dxos/packages/common/util/src/circular-buffer.ts";
303
328
  var CircularBuffer = class {
329
+ _buffer;
330
+ _nextIndex = 0;
331
+ _elementCount = 0;
304
332
  constructor(size) {
305
- this._nextIndex = 0;
306
- this._elementCount = 0;
307
- invariant3(size >= 1, void 0, {
308
- F: __dxlog_file3,
309
- L: 13,
310
- S: this,
311
- A: [
312
- "size >= 1",
313
- ""
314
- ]
315
- });
333
+ invariant3(size >= 1);
316
334
  this._buffer = new Array(size);
317
335
  }
318
336
  push(element) {
@@ -325,6 +343,10 @@ var CircularBuffer = class {
325
343
  get elementCount() {
326
344
  return this._elementCount;
327
345
  }
346
+ clear() {
347
+ this._nextIndex = 0;
348
+ this._elementCount = 0;
349
+ }
328
350
  getLast() {
329
351
  if (this._elementCount === 0) {
330
352
  return void 0;
@@ -374,10 +396,11 @@ import { inspect } from "node:util";
374
396
  import { inspectObject, raise } from "@dxos/debug";
375
397
  var MAX_SERIALIZATION_LENGTH = 10;
376
398
  var ComplexSet = class {
399
+ _projection;
400
+ _values = /* @__PURE__ */ new Map();
377
401
  // prettier-ignore
378
402
  constructor(_projection, values) {
379
403
  this._projection = _projection;
380
- this._values = /* @__PURE__ */ new Map();
381
404
  if (values) {
382
405
  for (const value of values) {
383
406
  this.add(value);
@@ -467,11 +490,12 @@ var makeSet = (projection) => {
467
490
  };
468
491
  };
469
492
  var ComplexMap = class _ComplexMap {
493
+ _keyProjection;
494
+ _keys = /* @__PURE__ */ new Map();
495
+ _values = /* @__PURE__ */ new Map();
470
496
  // prettier-ignore
471
497
  constructor(_keyProjection, entries2) {
472
498
  this._keyProjection = _keyProjection;
473
- this._keys = /* @__PURE__ */ new Map();
474
- this._values = /* @__PURE__ */ new Map();
475
499
  if (entries2) {
476
500
  for (const [key, value] of entries2) {
477
501
  this.set(key, value);
@@ -516,6 +540,36 @@ var ComplexMap = class _ComplexMap {
516
540
  this._values.set(primitive, value);
517
541
  return this;
518
542
  }
543
+ /**
544
+ * Returns the value for the given key if present, otherwise inserts and returns the default value.
545
+ * @param key - The key to look up or insert.
546
+ * @param defaultValue - The value to insert if the key is not present.
547
+ * @returns The existing or newly inserted value.
548
+ */
549
+ getOrInsert(key, defaultValue) {
550
+ const primitive = this._keyProjection(key);
551
+ if (this._values.has(primitive)) {
552
+ return this._values.get(primitive);
553
+ }
554
+ this.set(key, defaultValue);
555
+ return defaultValue;
556
+ }
557
+ /**
558
+ * Returns the value for the given key if present, otherwise computes, inserts, and returns a new value.
559
+ * The callback is only invoked when the key is missing.
560
+ * @param key - The key to look up or insert.
561
+ * @param callbackfn - Function to compute the value if the key is not present.
562
+ * @returns The existing or newly computed value.
563
+ */
564
+ getOrInsertComputed(key, callbackfn) {
565
+ const primitive = this._keyProjection(key);
566
+ if (this._values.has(primitive)) {
567
+ return this._values.get(primitive);
568
+ }
569
+ const value = callbackfn(key);
570
+ this.set(key, value);
571
+ return value;
572
+ }
519
573
  get size() {
520
574
  return this._keys.size;
521
575
  }
@@ -555,21 +609,15 @@ var makeMap = (keyProjection) => class BoundComplexMap extends ComplexMap {
555
609
  }
556
610
  };
557
611
 
612
+ // src/composite-key.ts
613
+ var SEPARATOR = ":";
614
+ var compositeKey = (...parts) => parts.join(SEPARATOR);
615
+ var splitCompositeKey = (key) => key.split(SEPARATOR);
616
+
558
617
  // src/deep.ts
559
- import get from "lodash.get";
560
- import set from "lodash.set";
561
618
  import { invariant as invariant4 } from "@dxos/invariant";
562
- var __dxlog_file4 = "/__w/dxos/dxos/packages/common/util/src/deep.ts";
563
619
  var setDeep = (obj, path, value) => {
564
- invariant4(path.length > 0, void 0, {
565
- F: __dxlog_file4,
566
- L: 18,
567
- S: void 0,
568
- A: [
569
- "path.length > 0",
570
- ""
571
- ]
572
- });
620
+ invariant4(path.length > 0);
573
621
  let parent = obj;
574
622
  for (const key of path.slice(0, -1)) {
575
623
  if (parent[key] === void 0) {
@@ -592,13 +640,11 @@ var getDeep = (obj, path) => {
592
640
  // src/defer-function.ts
593
641
  var deferFunction = (fnProvider) => (...args) => fnProvider()(...args);
594
642
 
595
- // src/explicit-resource-management-polyfill.ts
596
- Symbol.dispose ??= Symbol("Symbol.dispose");
597
- Symbol.asyncDispose ??= Symbol("Symbol.asyncDispose");
598
-
599
643
  // src/defer.ts
644
+ import "@hazae41/symbol-dispose-polyfill";
600
645
  var defer = (fn) => new DeferGuard(fn);
601
646
  var DeferGuard = class {
647
+ _fn;
602
648
  /**
603
649
  * @internal
604
650
  */
@@ -614,6 +660,7 @@ var DeferGuard = class {
614
660
  };
615
661
  var deferAsync = (fn) => new DeferAsyncGuard(fn);
616
662
  var DeferAsyncGuard = class {
663
+ _fn;
617
664
  /**
618
665
  * @internal
619
666
  */
@@ -628,6 +675,8 @@ var DeferAsyncGuard = class {
628
675
  // src/entry.ts
629
676
  var entry = (map, key) => new MapEntry(map, key);
630
677
  var MapEntry = class {
678
+ _map;
679
+ _key;
631
680
  /**
632
681
  * @internal
633
682
  */
@@ -653,33 +702,29 @@ var MapEntry = class {
653
702
  }
654
703
  };
655
704
 
656
- // src/first-two-chars.ts
657
- var renderableCharRegex = /^(?![\p{Control}\p{Mark}\p{Separator}\p{Surrogate}\p{Unassigned}\p{P}])[\p{L}\p{N}\p{S}\p{Emoji}]$/u;
658
- var getFirstTwoRenderableChars = (label) => {
659
- const characters = Array.from(label);
660
- const result = [
661
- "",
662
- ""
663
- ];
664
- let foundFirst = false;
665
- for (let i = 0; i < characters.length; i++) {
666
- const char = characters[i];
667
- if (renderableCharRegex.test(char)) {
668
- if (!foundFirst) {
669
- result[0] = char;
670
- foundFirst = true;
671
- } else {
672
- const textBetween = characters.slice(result[0].length, i).join("");
673
- if (/[^\p{L}\p{N}_]/u.test(textBetween)) {
674
- result[1] = char;
675
- break;
676
- }
677
- }
678
- }
679
- }
680
- return result;
705
+ // src/error-format.ts
706
+ var formatErrorWithCauses = (error) => {
707
+ const lines = [];
708
+ let current = error;
709
+ let level = 0;
710
+ while (current) {
711
+ const prefix = level === 0 ? "" : `Caused by: `;
712
+ lines.push(prefix + (current.stack ?? String(current)));
713
+ if (!(current.cause instanceof Error)) {
714
+ break;
715
+ }
716
+ current = current.cause;
717
+ level += 1;
718
+ }
719
+ return lines.join("\n\n");
681
720
  };
682
721
 
722
+ // src/filename.ts
723
+ var createFilename = ({ parts = [], ext, date = /* @__PURE__ */ new Date() }) => [
724
+ date.toISOString().replace(/[:.]/g, "-"),
725
+ ...parts
726
+ ].join("_") + (ext ? `.${ext}` : "");
727
+
683
728
  // src/for-each-async.ts
684
729
  var forEachAsync = (items, fn) => Promise.all(items.map(fn));
685
730
 
@@ -944,6 +989,7 @@ var DEFAULT_WORDLIST = [
944
989
  "zulu"
945
990
  ];
946
991
  var HumanHasher = class {
992
+ wordlist;
947
993
  /**
948
994
  * Transforms hex digests to human-readable strings.
949
995
  *
@@ -1014,6 +1060,19 @@ var humanize = (value) => {
1014
1060
  return hasher.humanize(value);
1015
1061
  };
1016
1062
 
1063
+ // src/id.ts
1064
+ var PART = /^[a-zA-Z][a-zA-Z0-9]{0,62}$/;
1065
+ var ID = /^[a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(\.[a-zA-Z]([a-zA-Z0-9]{0,62})?)$/;
1066
+ function id(strings, ...values) {
1067
+ const raw = strings.reduce((out, str, i) => out + str + (i < values.length ? String(values[i]) : ""), "");
1068
+ if (!ID.test(raw)) {
1069
+ throw new Error(`Invalid id (expected AT Protocol NSID): ${JSON.stringify(raw)}`);
1070
+ }
1071
+ return raw;
1072
+ }
1073
+ var isWellFormedId = (value) => ID.test(value);
1074
+ var isWellFormedIdPart = (value) => PART.test(value);
1075
+
1017
1076
  // src/map.ts
1018
1077
  var defaultMap = (map, key, def) => {
1019
1078
  let value = map.get(key);
@@ -1025,7 +1084,7 @@ var defaultMap = (map, key, def) => {
1025
1084
  };
1026
1085
 
1027
1086
  // src/instance-id.ts
1028
- var symbol = Symbol.for("dxos.instance-contexts");
1087
+ var symbol = /* @__PURE__ */ Symbol.for("dxos.instance-contexts");
1029
1088
  var instanceContexts = globalThis[symbol] ??= /* @__PURE__ */ new WeakMap();
1030
1089
  var getPrototypeSpecificInstanceId = (instance) => {
1031
1090
  const prototype = Object.getPrototypeOf(instance);
@@ -1033,12 +1092,12 @@ var getPrototypeSpecificInstanceId = (instance) => {
1033
1092
  nextId: 0,
1034
1093
  instanceIds: /* @__PURE__ */ new WeakMap()
1035
1094
  }));
1036
- let id = instanceCtx.instanceIds.get(instance);
1037
- if (id === void 0) {
1038
- id = instanceCtx.nextId++;
1039
- instanceCtx.instanceIds.set(instance, id);
1095
+ let id2 = instanceCtx.instanceIds.get(instance);
1096
+ if (id2 === void 0) {
1097
+ id2 = instanceCtx.nextId++;
1098
+ instanceCtx.instanceIds.set(instance, id2);
1040
1099
  }
1041
- return id;
1100
+ return id2;
1042
1101
  };
1043
1102
  var getDebugName = (instance) => {
1044
1103
  if (instance == null) {
@@ -1209,31 +1268,10 @@ var deepMapValues = (value, fn) => {
1209
1268
  return new DeepMapper(fn).map(value);
1210
1269
  };
1211
1270
  var DeepMapper = class {
1271
+ _fn;
1272
+ _cyclic = /* @__PURE__ */ new Map();
1212
1273
  constructor(_fn) {
1213
1274
  this._fn = _fn;
1214
- this._cyclic = /* @__PURE__ */ new Map();
1215
- this._recurse = (value) => {
1216
- if (this._cyclic.has(value)) {
1217
- return this._cyclic.get(value);
1218
- }
1219
- if (Array.isArray(value)) {
1220
- const res = new Array(value.length);
1221
- this._cyclic.set(value, res);
1222
- for (let i = 0; i < value.length; i++) {
1223
- res[i] = this._map(value[i], i);
1224
- }
1225
- return res;
1226
- } else if (value !== null && typeof value === "object") {
1227
- const res = {};
1228
- this._cyclic.set(value, res);
1229
- for (const key in value) {
1230
- res[key] = this._map(value[key], key);
1231
- }
1232
- return res;
1233
- } else {
1234
- return value;
1235
- }
1236
- };
1237
1275
  }
1238
1276
  map(value) {
1239
1277
  return this._map(value, void 0);
@@ -1244,36 +1282,37 @@ var DeepMapper = class {
1244
1282
  }
1245
1283
  return this._fn(value, this._recurse, key);
1246
1284
  }
1285
+ _recurse = (value) => {
1286
+ if (this._cyclic.has(value)) {
1287
+ return this._cyclic.get(value);
1288
+ }
1289
+ if (Array.isArray(value)) {
1290
+ const res = new Array(value.length);
1291
+ this._cyclic.set(value, res);
1292
+ for (let i = 0; i < value.length; i++) {
1293
+ res[i] = this._map(value[i], i);
1294
+ }
1295
+ return res;
1296
+ } else if (value !== null && typeof value === "object") {
1297
+ const res = {};
1298
+ this._cyclic.set(value, res);
1299
+ for (const key in value) {
1300
+ res[key] = this._map(value[key], key);
1301
+ }
1302
+ return res;
1303
+ } else {
1304
+ return value;
1305
+ }
1306
+ };
1247
1307
  };
1248
1308
  var deepMapValuesAsync = (value, fn) => {
1249
1309
  return new DeepMapperAsync(fn).map(value);
1250
1310
  };
1251
1311
  var DeepMapperAsync = class {
1312
+ _fn;
1313
+ _cyclic = /* @__PURE__ */ new Map();
1252
1314
  constructor(_fn) {
1253
1315
  this._fn = _fn;
1254
- this._cyclic = /* @__PURE__ */ new Map();
1255
- this._recurse = async (value) => {
1256
- if (this._cyclic.has(value)) {
1257
- return this._cyclic.get(value);
1258
- }
1259
- if (Array.isArray(value)) {
1260
- const res = new Array(value.length);
1261
- this._cyclic.set(value, res);
1262
- for (let i = 0; i < value.length; i++) {
1263
- res[i] = await this._map(value[i], i);
1264
- }
1265
- return res;
1266
- } else if (value !== null && typeof value === "object") {
1267
- const res = {};
1268
- this._cyclic.set(value, res);
1269
- for (const key in value) {
1270
- res[key] = await this._map(value[key], key);
1271
- }
1272
- return res;
1273
- } else {
1274
- return value;
1275
- }
1276
- };
1277
1316
  }
1278
1317
  map(value) {
1279
1318
  return this._map(value, void 0);
@@ -1284,6 +1323,28 @@ var DeepMapperAsync = class {
1284
1323
  }
1285
1324
  return this._fn(value, this._recurse, key);
1286
1325
  }
1326
+ _recurse = async (value) => {
1327
+ if (this._cyclic.has(value)) {
1328
+ return this._cyclic.get(value);
1329
+ }
1330
+ if (Array.isArray(value)) {
1331
+ const res = new Array(value.length);
1332
+ this._cyclic.set(value, res);
1333
+ for (let i = 0; i < value.length; i++) {
1334
+ res[i] = await this._map(value[i], i);
1335
+ }
1336
+ return res;
1337
+ } else if (value !== null && typeof value === "object") {
1338
+ const res = {};
1339
+ this._cyclic.set(value, res);
1340
+ for (const key in value) {
1341
+ res[key] = await this._map(value[key], key);
1342
+ }
1343
+ return res;
1344
+ } else {
1345
+ return value;
1346
+ }
1347
+ };
1287
1348
  };
1288
1349
  var visitValues = (object, visitor) => {
1289
1350
  if (Array.isArray(object)) {
@@ -1317,27 +1378,27 @@ var orderKeys = (obj, order) => {
1317
1378
 
1318
1379
  // src/order.ts
1319
1380
  var inferObjectOrder = (objectMap, order = []) => {
1320
- const orderedObjects = order.reduce((acc, id) => {
1321
- if (id in objectMap) {
1322
- acc.objects.push(objectMap[id]);
1323
- acc.ids.add(id);
1381
+ const orderedObjects = order.reduce((acc, id2) => {
1382
+ if (id2 in objectMap) {
1383
+ acc.objects.push(objectMap[id2]);
1384
+ acc.ids.add(id2);
1324
1385
  }
1325
1386
  return acc;
1326
1387
  }, {
1327
1388
  objects: [],
1328
1389
  ids: /* @__PURE__ */ new Set()
1329
1390
  });
1330
- const { objects } = Object.keys(objectMap).reduce((acc, id) => {
1331
- if (!acc.ids.has(id)) {
1332
- acc.objects.push(objectMap[id]);
1391
+ const { objects } = Object.keys(objectMap).reduce((acc, id2) => {
1392
+ if (!acc.ids.has(id2)) {
1393
+ acc.objects.push(objectMap[id2]);
1333
1394
  }
1334
1395
  return acc;
1335
1396
  }, orderedObjects);
1336
1397
  return objects;
1337
1398
  };
1338
1399
  var inferRecordOrder = (objectMap, order = []) => {
1339
- return Object.assign(order.filter((id) => id in objectMap).reduce((acc, id) => {
1340
- acc[id] = null;
1400
+ return Object.assign(order.filter((id2) => id2 in objectMap).reduce((acc, id2) => {
1401
+ acc[id2] = null;
1341
1402
  return acc;
1342
1403
  }, {}), objectMap);
1343
1404
  };
@@ -1372,7 +1433,18 @@ var omit = (obj, keys2) => {
1372
1433
 
1373
1434
  // src/platform.ts
1374
1435
  var isNode = () => typeof process !== "undefined" && process.versions != null && process.versions.node != null;
1375
- var mobileAndTabletCheck = () => {
1436
+ var isBun = () => globalThis.Bun !== void 0;
1437
+ var isTauri = () => !!globalThis.__TAURI__;
1438
+ var isMobile = () => {
1439
+ let check = false;
1440
+ (function(a) {
1441
+ if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) {
1442
+ check = true;
1443
+ }
1444
+ })(navigator.userAgent || navigator.vendor || window.opera);
1445
+ return check;
1446
+ };
1447
+ var isMobileOrTablet = () => {
1376
1448
  let check = false;
1377
1449
  ((a) => {
1378
1450
  if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) {
@@ -1394,7 +1466,7 @@ var iosCheck = () => {
1394
1466
  };
1395
1467
  var safariCheck = () => typeof navigator !== "undefined" && /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
1396
1468
  var getHostPlatform = () => {
1397
- if (!("navigator" in window)) {
1469
+ if (!("navigator" in globalThis)) {
1398
1470
  return "unknown";
1399
1471
  }
1400
1472
  const platform = (navigator.userAgentData?.platform || navigator.platform)?.toLowerCase();
@@ -1570,6 +1642,43 @@ var removeProperties = (root, condition) => {
1570
1642
  return result;
1571
1643
  };
1572
1644
 
1645
+ // src/retry.ts
1646
+ var DEFAULT_RETRY_OPTIONS = {
1647
+ count: 3,
1648
+ delayMs: 100,
1649
+ exponent: 2,
1650
+ retryOnError: async () => true,
1651
+ retryOnValue: async () => false
1652
+ };
1653
+ var retry = async (options, cb) => {
1654
+ const fullOptions = {
1655
+ ...DEFAULT_RETRY_OPTIONS,
1656
+ ...options
1657
+ };
1658
+ let numRetries = 0, currentDelay = fullOptions.delayMs;
1659
+ while (true) {
1660
+ let result;
1661
+ try {
1662
+ result = await cb();
1663
+ } catch (err) {
1664
+ if (numRetries > fullOptions.count || !await fullOptions.retryOnError(err)) {
1665
+ throw err;
1666
+ }
1667
+ await new Promise((resolve) => setTimeout(resolve, currentDelay));
1668
+ currentDelay *= fullOptions.exponent;
1669
+ numRetries++;
1670
+ continue;
1671
+ }
1672
+ if (!await fullOptions.retryOnValue(result)) {
1673
+ return result;
1674
+ }
1675
+ await new Promise((resolve) => setTimeout(resolve, currentDelay));
1676
+ currentDelay *= fullOptions.exponent;
1677
+ numRetries++;
1678
+ continue;
1679
+ }
1680
+ };
1681
+
1573
1682
  // src/safe-await.ts
1574
1683
  var safeAwaitAll = async (source, taskFactory, onError) => {
1575
1684
  const failedItems = [];
@@ -1589,7 +1698,7 @@ var safeAwaitAll = async (source, taskFactory, onError) => {
1589
1698
  };
1590
1699
 
1591
1700
  // src/safe-instanceof.ts
1592
- var instanceTag = Symbol("instanceTag");
1701
+ var instanceTag = /* @__PURE__ */ Symbol("instanceTag");
1593
1702
  var safeInstanceof = (tag) => (target) => {
1594
1703
  target.prototype[instanceTag] = tag;
1595
1704
  Object.defineProperty(target.prototype, Symbol.hasInstance, {
@@ -1601,48 +1710,139 @@ var safeInstanceof = (tag) => (target) => {
1601
1710
  };
1602
1711
 
1603
1712
  // src/safe-parse.ts
1604
- var safeParseInt = (value, defaultValue) => {
1713
+ function safeParseInt(str, defaultValue) {
1714
+ try {
1715
+ const value = parseInt(str ?? "");
1716
+ return isNaN(value) ? defaultValue : value;
1717
+ } catch {
1718
+ return defaultValue;
1719
+ }
1720
+ }
1721
+ function safeParseFloat(str, defaultValue) {
1605
1722
  try {
1606
- const n = parseInt(value ?? "");
1607
- return isNaN(n) ? defaultValue : n;
1608
- } catch (err) {
1723
+ const value = parseFloat(str ?? "");
1724
+ return isNaN(value) ? defaultValue : value;
1725
+ } catch {
1609
1726
  return defaultValue;
1610
1727
  }
1728
+ }
1729
+ var safeParseJson = (str, defaultValue) => {
1730
+ if (str && str.length > 0) {
1731
+ try {
1732
+ return JSON.parse(str);
1733
+ } catch {
1734
+ }
1735
+ }
1736
+ return defaultValue;
1611
1737
  };
1612
- var safeParseFloat = (str, defaultValue) => {
1738
+ var safeUrl = (str) => {
1613
1739
  try {
1614
- return parseFloat(str);
1740
+ return new URL(str ?? "");
1615
1741
  } catch {
1616
- return defaultValue ?? 0;
1742
+ return void 0;
1617
1743
  }
1618
1744
  };
1619
- var safeParseJson = (data, defaultValue) => {
1620
- if (data && data.length > 0) {
1745
+
1746
+ // src/safe-stringify.ts
1747
+ var SKIP = Object.freeze({});
1748
+ function safeStringify(obj, filter = defaultFilter, indent = 2) {
1749
+ const seen = /* @__PURE__ */ new WeakMap();
1750
+ function replacer(key, value) {
1621
1751
  try {
1622
- return JSON.parse(data);
1623
- } catch (err) {
1752
+ let path = key;
1753
+ if (!key) {
1754
+ path = "$";
1755
+ if (value != null && typeof value === "object") {
1756
+ seen.set(value, path);
1757
+ }
1758
+ return value;
1759
+ } else if (this) {
1760
+ const parentPath = seen.get(this);
1761
+ path = parentPath ? `${parentPath}.${key}` : key;
1762
+ }
1763
+ if (value == null) {
1764
+ return value;
1765
+ }
1766
+ if (typeof value === "function") {
1767
+ return void 0;
1768
+ }
1769
+ if (typeof value === "object" && Object.getPrototypeOf(value) !== Object.prototype && !Array.isArray(value)) {
1770
+ return void 0;
1771
+ }
1772
+ if (typeof value === "object" && value !== null) {
1773
+ const exists = seen.get(value);
1774
+ if (exists) {
1775
+ return `[${path} => ${exists}]`;
1776
+ }
1777
+ seen.set(value, path);
1778
+ }
1779
+ if (filter) {
1780
+ const filteredValue = filter?.(key, value);
1781
+ if (filteredValue !== void 0) {
1782
+ return filteredValue === SKIP ? void 0 : filteredValue;
1783
+ }
1784
+ }
1785
+ return value;
1786
+ } catch (error) {
1787
+ return `ERROR: ${error.message}`;
1624
1788
  }
1625
1789
  }
1626
- return defaultValue;
1790
+ try {
1791
+ return JSON.stringify(obj, replacer, indent);
1792
+ } catch (error) {
1793
+ return `ERROR: ${error.message}`;
1794
+ }
1795
+ }
1796
+ var createReplacer = ({ omit: omit2, parse, maxDepth, maxArrayLen, maxStringLen } = {}) => {
1797
+ let currentDepth = 0;
1798
+ const depthMap = /* @__PURE__ */ new WeakMap();
1799
+ return function(key, value) {
1800
+ if (key === "") {
1801
+ currentDepth = 0;
1802
+ } else if (this && typeof this === "object") {
1803
+ const parentDepth = depthMap.get(this) ?? 0;
1804
+ currentDepth = parentDepth + 1;
1805
+ }
1806
+ if (typeof value === "function") {
1807
+ return SKIP;
1808
+ }
1809
+ if (maxArrayLen != null && Array.isArray(value) && value.length > maxArrayLen) {
1810
+ return `[length: ${value.length}]`;
1811
+ }
1812
+ if (value && typeof value === "object") {
1813
+ depthMap.set(value, currentDepth);
1814
+ if (maxDepth != null && currentDepth >= maxDepth) {
1815
+ return Array.isArray(value) ? `[{ length: ${value.length} }]` : `{ keys: ${Object.keys(value).length} }`;
1816
+ }
1817
+ }
1818
+ if (omit2?.includes(key)) {
1819
+ return SKIP;
1820
+ }
1821
+ if (parse?.includes(key) && typeof value === "string") {
1822
+ try {
1823
+ return JSON.parse(value);
1824
+ } catch {
1825
+ return value;
1826
+ }
1827
+ }
1828
+ if (maxStringLen != null && typeof value === "string" && value.length > maxStringLen) {
1829
+ return value.slice(0, maxStringLen) + "...";
1830
+ }
1831
+ return value;
1832
+ };
1627
1833
  };
1834
+ var defaultFilter = createReplacer();
1628
1835
 
1629
1836
  // src/sliding-window-summary.ts
1630
1837
  import { invariant as invariant5 } from "@dxos/invariant";
1631
- var __dxlog_file5 = "/__w/dxos/dxos/packages/common/util/src/sliding-window-summary.ts";
1632
1838
  var SlidingWindowSummary = class {
1839
+ _buffer;
1840
+ _sum = 0;
1841
+ _precision;
1633
1842
  constructor(options) {
1634
- this._sum = 0;
1635
1843
  this._buffer = new CircularBuffer(options.dataPoints);
1636
1844
  if (options.precision != null) {
1637
- invariant5(options.precision >= 0, void 0, {
1638
- F: __dxlog_file5,
1639
- L: 26,
1640
- S: this,
1641
- A: [
1642
- "options.precision >= 0",
1643
- ""
1644
- ]
1645
- });
1845
+ invariant5(options.precision >= 0);
1646
1846
  this._precision = Math.pow(10, options.precision);
1647
1847
  }
1648
1848
  }
@@ -1711,12 +1911,28 @@ var capitalize = (str) => {
1711
1911
  }
1712
1912
  return str.charAt(0).toUpperCase() + str.slice(1);
1713
1913
  };
1714
- var trim = (strings, ...values) => {
1715
- const full = String.raw(strings, ...values);
1716
- const lines = full.replace(/^\n/, "").split("\n");
1717
- const indent = Math.min(...lines.filter((l) => l.trim()).map((l) => l.match(/^ */)[0].length));
1718
- return lines.map((l) => l.slice(indent)).join("\n");
1719
- };
1914
+ function trim(strings, ...values) {
1915
+ const raw = strings.reduce((out, str, i) => {
1916
+ out += str;
1917
+ if (i < values.length) {
1918
+ const match = str.match(/(^|\n)([ \t]*)$/);
1919
+ const baseIndent = match ? match[2] : "";
1920
+ const val = String(values[i]).replace(/\r?\n/g, "\n" + baseIndent);
1921
+ out += val;
1922
+ }
1923
+ return out;
1924
+ }, "");
1925
+ const lines = raw.split("\n");
1926
+ while (lines.length && !lines[0].trim()) {
1927
+ lines.shift();
1928
+ }
1929
+ while (lines.length && !lines[lines.length - 1].trim()) {
1930
+ lines.pop();
1931
+ }
1932
+ const minIndent = Math.min(...lines.filter((l) => l.trim()).map((l) => l.match(/^[ \t]*/)?.[0].length ?? 0));
1933
+ return lines.map((l) => l.slice(minIndent)).join("\n");
1934
+ }
1935
+ var kebabize = (str) => str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, ($, ofs) => (ofs ? "-" : "") + $.toLowerCase());
1720
1936
 
1721
1937
  // src/sum.ts
1722
1938
  var sum = (values) => values.reduce((a, b) => a + b, 0);
@@ -1730,18 +1946,6 @@ var throwUnhandledError = (error) => {
1730
1946
 
1731
1947
  // src/to-fallback.ts
1732
1948
  var idEmoji = [
1733
- // When changing this set, please check the result in a console or e.g. RunKit (https://runkit.com/thure/642214441dd6ae000855a8de)
1734
- // Emoji sometimes use a combination of code points, and some code points aren't visible on their own, so by adding or deleting you may unintentionally create non-visible items.
1735
- // This set was chosen from the characters in Unicode Emoji v15.0 based on the following criteria:
1736
- // – not people or isolated anthropomorphic faces
1737
- // – not flags
1738
- // – more concrete than abstract
1739
- // – less culturally specific
1740
- // – less easily confused with another emoji in the set
1741
- // – requires less special knowledge to identify
1742
- // – less likely to evoke negative feelings (no meat, no drugs, no weapons, etc)
1743
- // – less common as a signifier in UX
1744
- // NOTE that this is intentionally an array of strings because of the way emoji graphemes work.
1745
1949
  "\u{1F47B}",
1746
1950
  "\u{1F479}",
1747
1951
  "\u{1F47D}",
@@ -1877,17 +2081,18 @@ var idEmoji = [
1877
2081
  ];
1878
2082
  var idHue = [
1879
2083
  "red",
1880
- // 'orange' as const, /* More shades in these palettes are considered “ugly” */
2084
+ "orange",
1881
2085
  "amber",
1882
- // 'yellow' as const, /* More shades in these palettes are considered “ugly” */
2086
+ "yellow",
1883
2087
  "lime",
1884
2088
  "green",
1885
2089
  "emerald",
1886
2090
  "teal",
1887
2091
  "cyan",
1888
- // 'sky' as const, /* Omitted since it is quite similar to the primary accent palette */
1889
- // 'blue' as const, /* Omitted since it is quite similar to the primary accent palette */
1890
- // 'indigo' as const, /* Omitted since it is quite similar to the primary accent palette */
2092
+ // Omit colors similar to primary accent.
2093
+ // 'sky' as const,
2094
+ // 'blue' as const,
2095
+ // 'indigo' as const,
1891
2096
  "violet",
1892
2097
  "purple",
1893
2098
  "fuchsia",
@@ -1915,10 +2120,8 @@ var toFallback = (hash) => {
1915
2120
 
1916
2121
  // src/tracer.ts
1917
2122
  var Tracer = class {
1918
- constructor() {
1919
- this._events = /* @__PURE__ */ new Map();
1920
- this._recording = false;
1921
- }
2123
+ _events = /* @__PURE__ */ new Map();
2124
+ _recording = false;
1922
2125
  // TODO(burdon): Start/stop methods for recording data? By id?
1923
2126
  // Alternatively, enable subscriptions to track/compute series.
1924
2127
  // TODO(burdon): Hierarchical traces?
@@ -1928,8 +2131,8 @@ var Tracer = class {
1928
2131
  keys() {
1929
2132
  return Array.from(this._events.keys());
1930
2133
  }
1931
- get(id, filter) {
1932
- const events = this._events.get(id);
2134
+ get(id2, filter) {
2135
+ const events = this._events.get(id2);
1933
2136
  if (filter) {
1934
2137
  return events?.filter((event) => Object.entries(filter).every(([key, value]) => event?.value[key] === value));
1935
2138
  }
@@ -1946,11 +2149,11 @@ var Tracer = class {
1946
2149
  this._recording = false;
1947
2150
  return this;
1948
2151
  }
1949
- emit(id, value) {
1950
- this._post(this._createEvent(id, value));
2152
+ emit(id2, value) {
2153
+ this._post(this._createEvent(id2, value));
1951
2154
  }
1952
- mark(id, value) {
1953
- const event = this._createEvent(id, value);
2155
+ mark(id2, value) {
2156
+ const event = this._createEvent(id2, value);
1954
2157
  const start = performance.now();
1955
2158
  return {
1956
2159
  start,
@@ -1960,9 +2163,9 @@ var Tracer = class {
1960
2163
  }
1961
2164
  };
1962
2165
  }
1963
- _createEvent(id, value) {
2166
+ _createEvent(id2, value) {
1964
2167
  const event = {
1965
- id,
2168
+ id: id2,
1966
2169
  timestamp: Date.now()
1967
2170
  };
1968
2171
  if (value !== void 0) {
@@ -2019,7 +2222,7 @@ var stringifyTree = (node, ancestors = [], rows = []) => {
2019
2222
  };
2020
2223
 
2021
2224
  // src/types.ts
2022
- var isNotFalsy = (value) => !!value;
2225
+ var isTruthy = (value) => !!value;
2023
2226
  var isNonNullable = (value) => value != null;
2024
2227
  var doAsync = async (fn) => fn();
2025
2228
  var getProviderValue = (provider, arg) => {
@@ -2049,6 +2252,117 @@ var arrayMove = (array, from, to) => {
2049
2252
  array.splice(to < 0 ? array.length + to : to, 0, array.splice(from, 1)[0]);
2050
2253
  return array;
2051
2254
  };
2255
+ function arraySwap(array, from, to) {
2256
+ const current = array[from];
2257
+ array[from] = array[to];
2258
+ array[to] = current;
2259
+ return array;
2260
+ }
2261
+
2262
+ // src/unit.ts
2263
+ var createFormat = (unit) => {
2264
+ return (n, precision = unit.precision ?? 0) => {
2265
+ const value = n / unit.quotient;
2266
+ const formattedValue = value.toLocaleString("en-US", {
2267
+ minimumFractionDigits: precision,
2268
+ maximumFractionDigits: precision
2269
+ });
2270
+ return {
2271
+ unit,
2272
+ value,
2273
+ formattedValue,
2274
+ toString: () => `${formattedValue}${unit.symbol}`
2275
+ };
2276
+ };
2277
+ };
2278
+ var MS_SECONDS = 1e3;
2279
+ var MS_MINUTES = 60 * MS_SECONDS;
2280
+ var MS_HOURS = 60 * MS_MINUTES;
2281
+ var Unit = {
2282
+ // General.
2283
+ Percent: createFormat({
2284
+ symbol: "%",
2285
+ quotient: 1 / 100,
2286
+ precision: 2
2287
+ }),
2288
+ Thousand: createFormat({
2289
+ symbol: "k",
2290
+ quotient: 1e3,
2291
+ precision: 2
2292
+ }),
2293
+ // Bytes (note KB vs KiB).
2294
+ Gigabyte: createFormat({
2295
+ symbol: "GB",
2296
+ quotient: 1e3 * 1e3 * 1e3,
2297
+ precision: 2
2298
+ }),
2299
+ Megabyte: createFormat({
2300
+ symbol: "MB",
2301
+ quotient: 1e3 * 1e3,
2302
+ precision: 2
2303
+ }),
2304
+ Kilobyte: createFormat({
2305
+ symbol: "KB",
2306
+ quotient: 1e3,
2307
+ precision: 2
2308
+ }),
2309
+ Byte: createFormat({
2310
+ symbol: "B",
2311
+ quotient: 1
2312
+ }),
2313
+ // Time.
2314
+ Hour: createFormat({
2315
+ symbol: "h",
2316
+ quotient: MS_HOURS
2317
+ }),
2318
+ Minute: createFormat({
2319
+ symbol: "m",
2320
+ quotient: MS_MINUTES
2321
+ }),
2322
+ Second: createFormat({
2323
+ symbol: "s",
2324
+ quotient: MS_SECONDS,
2325
+ precision: 1
2326
+ }),
2327
+ Millisecond: createFormat({
2328
+ symbol: "ms",
2329
+ quotient: 1
2330
+ }),
2331
+ Duration: (n) => {
2332
+ const hours = Math.floor(n / MS_HOURS);
2333
+ const minutes = Math.floor(n % MS_HOURS / MS_MINUTES);
2334
+ if (hours) {
2335
+ const formattedValue = minutes ? `${hours}h ${minutes}m` : `${hours}h`;
2336
+ return {
2337
+ unit: {
2338
+ symbol: "h",
2339
+ quotient: MS_HOURS
2340
+ },
2341
+ value: hours,
2342
+ formattedValue,
2343
+ toString: () => formattedValue
2344
+ };
2345
+ }
2346
+ if (minutes) {
2347
+ const seconds2 = (n - MS_MINUTES * minutes) / MS_SECONDS;
2348
+ const formattedValue = seconds2 ? `${minutes}m ${seconds2}s` : `${minutes}m`;
2349
+ return {
2350
+ unit: {
2351
+ symbol: "m",
2352
+ quotient: MS_MINUTES
2353
+ },
2354
+ value: minutes,
2355
+ formattedValue,
2356
+ toString: () => formattedValue
2357
+ };
2358
+ }
2359
+ const seconds = n >= MS_SECONDS;
2360
+ if (seconds) {
2361
+ return Unit.Second(n);
2362
+ }
2363
+ return Unit.Millisecond(n);
2364
+ }
2365
+ };
2052
2366
 
2053
2367
  // src/url.ts
2054
2368
  var createUrl = (url, search) => {
@@ -2061,16 +2375,20 @@ var createUrl = (url, search) => {
2061
2375
 
2062
2376
  // src/weak.ts
2063
2377
  var WeakDictionary = class {
2378
+ _internal = /* @__PURE__ */ new Map();
2379
+ _finalization = new FinalizationRegistry(({ key, ref }) => {
2380
+ if (this._internal.get(key) === ref) {
2381
+ this._internal.delete(key);
2382
+ }
2383
+ });
2064
2384
  constructor(entries2) {
2065
- this._internal = /* @__PURE__ */ new Map();
2066
- this._finalization = new FinalizationRegistry((cleanUpCallback) => {
2067
- cleanUpCallback();
2068
- });
2069
- this._internal = new Map(entries2?.map(([key, value]) => [
2070
- key,
2071
- new WeakRef(value)
2072
- ]));
2073
- entries2?.forEach(([key, value]) => this._register(key, value));
2385
+ if (entries2) {
2386
+ for (const [key, value] of entries2) {
2387
+ const ref = new WeakRef(value);
2388
+ this._internal.set(key, ref);
2389
+ this._register(key, value, ref);
2390
+ }
2391
+ }
2074
2392
  }
2075
2393
  *entries() {
2076
2394
  for (const [key, value] of this._internal) {
@@ -2110,10 +2428,45 @@ var WeakDictionary = class {
2110
2428
  return this._internal.get(key)?.deref();
2111
2429
  }
2112
2430
  set(key, value) {
2113
- this._internal.set(key, new WeakRef(value));
2114
- this._register(key, value);
2431
+ const previous = this._internal.get(key)?.deref();
2432
+ if (previous) {
2433
+ this._unregister(previous);
2434
+ }
2435
+ const ref = new WeakRef(value);
2436
+ this._internal.set(key, ref);
2437
+ this._register(key, value, ref);
2115
2438
  return this;
2116
2439
  }
2440
+ /**
2441
+ * Returns the value for the given key if present, otherwise inserts and returns the default value.
2442
+ * @param key - The key to look up or insert.
2443
+ * @param defaultValue - The value to insert if the key is not present.
2444
+ * @returns The existing or newly inserted value.
2445
+ */
2446
+ getOrInsert(key, defaultValue) {
2447
+ const existing = this.get(key);
2448
+ if (existing !== void 0) {
2449
+ return existing;
2450
+ }
2451
+ this.set(key, defaultValue);
2452
+ return defaultValue;
2453
+ }
2454
+ /**
2455
+ * Returns the value for the given key if present, otherwise computes, inserts, and returns a new value.
2456
+ * The callback is only invoked when the key is missing.
2457
+ * @param key - The key to look up or insert.
2458
+ * @param callbackfn - Function to compute the value if the key is not present.
2459
+ * @returns The existing or newly computed value.
2460
+ */
2461
+ getOrInsertComputed(key, callbackfn) {
2462
+ const existing = this.get(key);
2463
+ if (existing !== void 0) {
2464
+ return existing;
2465
+ }
2466
+ const value = callbackfn(key);
2467
+ this.set(key, value);
2468
+ return value;
2469
+ }
2117
2470
  has(key) {
2118
2471
  return this._internal.has(key) && this._internal.get(key).deref() !== void 0;
2119
2472
  }
@@ -2144,9 +2497,10 @@ var WeakDictionary = class {
2144
2497
  }
2145
2498
  });
2146
2499
  }
2147
- _register(key, value) {
2148
- this._finalization.register(value, () => {
2149
- this._internal.delete(key);
2500
+ _register(key, value, ref) {
2501
+ this._finalization.register(value, {
2502
+ key,
2503
+ ref
2150
2504
  }, value);
2151
2505
  }
2152
2506
  _unregister(value) {
@@ -2162,11 +2516,14 @@ export {
2162
2516
  ComplexSet,
2163
2517
  HumanHasher,
2164
2518
  MapEntry,
2519
+ SKIP,
2165
2520
  SlidingWindowSummary,
2166
2521
  Tracer,
2522
+ Unit,
2167
2523
  WeakDictionary,
2168
2524
  accessBy,
2169
2525
  arrayMove,
2526
+ arraySwap,
2170
2527
  arrayToBuffer,
2171
2528
  arrayToHex,
2172
2529
  arrayToString,
@@ -2177,19 +2534,28 @@ export {
2177
2534
  capitalize,
2178
2535
  chunkArray,
2179
2536
  clamp,
2537
+ clearCaches,
2538
+ clearIndexedDB,
2539
+ clearOPFS,
2540
+ clearServiceWorkers,
2180
2541
  clearUndefined,
2542
+ coerceArray,
2181
2543
  compareMulti,
2182
2544
  compareObject,
2183
2545
  compareScalar,
2184
2546
  compareString,
2547
+ compositeKey,
2185
2548
  createBinder,
2186
2549
  createBucketReducer,
2550
+ createFilename,
2187
2551
  createGroupReducer,
2552
+ createReplacer,
2188
2553
  createSetDispatch,
2189
2554
  createUrl,
2190
2555
  decamelize,
2191
2556
  deepMapValues,
2192
2557
  deepMapValuesAsync,
2558
+ defaultFilter,
2193
2559
  defaultMap,
2194
2560
  defer,
2195
2561
  deferAsync,
@@ -2201,12 +2567,11 @@ export {
2201
2567
  entry,
2202
2568
  exponentialBackoffInterval,
2203
2569
  forEachAsync,
2204
- get,
2570
+ formatErrorWithCauses,
2205
2571
  getAsyncProviderValue,
2206
2572
  getDate,
2207
2573
  getDebugName,
2208
2574
  getDeep,
2209
- getFirstTwoRenderableChars,
2210
2575
  getHostPlatform,
2211
2576
  getPrototypeSpecificInstanceId,
2212
2577
  getProviderValue,
@@ -2215,6 +2580,7 @@ export {
2215
2580
  hexToHue,
2216
2581
  humanize,
2217
2582
  hyphenize,
2583
+ id,
2218
2584
  idEmoji,
2219
2585
  idHue,
2220
2586
  inferObjectOrder,
@@ -2222,14 +2588,21 @@ export {
2222
2588
  intersectBy,
2223
2589
  intersection,
2224
2590
  iosCheck,
2591
+ isBun,
2592
+ isMobile,
2593
+ isMobileOrTablet,
2225
2594
  isNode,
2226
2595
  isNonNullable,
2227
- isNotFalsy,
2596
+ isTauri,
2597
+ isTruthy,
2598
+ isWellFormedId,
2599
+ isWellFormedIdPart,
2228
2600
  joinTables,
2229
2601
  jsonKeyReplacer,
2230
2602
  jsonReplacer,
2231
2603
  jsonify,
2232
2604
  jsonlogify,
2605
+ kebabize,
2233
2606
  keyToEmoji,
2234
2607
  keyToFallback,
2235
2608
  keyToHue,
@@ -2238,7 +2611,6 @@ export {
2238
2611
  makeSet,
2239
2612
  mapValues,
2240
2613
  median,
2241
- mobileAndTabletCheck,
2242
2614
  numericalValues,
2243
2615
  omit,
2244
2616
  orderKeys,
@@ -2254,15 +2626,18 @@ export {
2254
2626
  removeBy,
2255
2627
  removeProperties,
2256
2628
  removeUndefinedProperties,
2629
+ retry,
2257
2630
  safariCheck,
2258
2631
  safeAwaitAll,
2259
2632
  safeInstanceof,
2260
2633
  safeParseFloat,
2261
2634
  safeParseInt,
2262
2635
  safeParseJson,
2263
- set,
2636
+ safeStringify,
2637
+ safeUrl,
2264
2638
  setDeep,
2265
2639
  sortKeys,
2640
+ splitCompositeKey,
2266
2641
  stringToArray,
2267
2642
  stringifyTree,
2268
2643
  stripUndefined,