@dxos/util 0.8.4-main.fffef41 → 0.8.4-staging.60fe92afc8

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 (130) hide show
  1. package/LICENSE +102 -5
  2. package/dist/lib/browser/index.mjs +405 -158
  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 +405 -158
  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 +6 -0
  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 +5 -5
  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 +10 -1
  74. package/dist/types/src/safe-stringify.d.ts.map +1 -1
  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 +12 -0
  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 +23 -5
  88. package/dist/types/src/types.d.ts.map +1 -1
  89. package/dist/types/src/uint8array.d.ts +27 -0
  90. package/dist/types/src/uint8array.d.ts.map +1 -1
  91. package/dist/types/src/unit.d.ts.map +1 -1
  92. package/dist/types/src/url.d.ts.map +1 -1
  93. package/dist/types/src/weak.d.ts +15 -0
  94. package/dist/types/src/weak.d.ts.map +1 -1
  95. package/dist/types/tsconfig.tsbuildinfo +1 -1
  96. package/package.json +13 -14
  97. package/src/array.ts +9 -2
  98. package/src/browser-storage.ts +60 -0
  99. package/src/circular-buffer.test.ts +26 -0
  100. package/src/circular-buffer.ts +5 -0
  101. package/src/complex.ts +32 -0
  102. package/src/composite-key.test.ts +31 -0
  103. package/src/composite-key.ts +16 -0
  104. package/src/deep.ts +2 -6
  105. package/src/defer.ts +1 -1
  106. package/src/di-key.ts +10 -8
  107. package/src/error-format.ts +24 -0
  108. package/src/filename.ts +16 -0
  109. package/src/id.test.ts +109 -0
  110. package/src/id.ts +48 -0
  111. package/src/index.ts +6 -0
  112. package/src/map-values.ts +6 -0
  113. package/src/platform.ts +35 -3
  114. package/src/position.test.ts +38 -44
  115. package/src/position.ts +7 -11
  116. package/src/retry.ts +74 -0
  117. package/src/safe-parse.ts +27 -16
  118. package/src/safe-stringify.test.ts +96 -0
  119. package/src/safe-stringify.ts +74 -25
  120. package/src/string.test.ts +24 -1
  121. package/src/string.ts +22 -2
  122. package/src/to-fallback.ts +39 -156
  123. package/src/types.test.ts +11 -1
  124. package/src/types.ts +39 -11
  125. package/src/uint8array.ts +44 -0
  126. package/src/unit.ts +10 -3
  127. package/src/weak.ts +52 -14
  128. package/dist/types/src/explicit-resource-management-polyfill.d.ts +0 -1
  129. package/dist/types/src/explicit-resource-management-polyfill.d.ts.map +0 -1
  130. package/src/explicit-resource-management-polyfill.ts +0 -13
@@ -97,6 +97,14 @@ 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) {
@@ -111,7 +119,6 @@ var createBinder = (obj) => ({
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,34 +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 {
210
251
  _callback;
211
252
  call(...args) {
212
- invariant2(this._callback, "Callback not set", {
213
- F: __dxlog_file2,
214
- L: 20,
215
- S: this,
216
- A: [
217
- "this._callback",
218
- "'Callback not set'"
219
- ]
220
- });
253
+ invariant2(this._callback, "Callback not set");
221
254
  return this._callback(...args);
222
255
  }
223
256
  callIfSet(...args) {
224
257
  return this._callback?.(...args);
225
258
  }
226
259
  set(callback) {
227
- invariant2(!this._callback, "Callback already set", {
228
- F: __dxlog_file2,
229
- L: 29,
230
- S: this,
231
- A: [
232
- "!this._callback",
233
- "'Callback already set'"
234
- ]
235
- });
260
+ invariant2(!this._callback, "Callback already set");
236
261
  this._callback = callback;
237
262
  }
238
263
  isSet() {
@@ -300,21 +325,12 @@ var chunkArray = (array, size) => {
300
325
 
301
326
  // src/circular-buffer.ts
302
327
  import { invariant as invariant3 } from "@dxos/invariant";
303
- var __dxlog_file3 = "/__w/dxos/dxos/packages/common/util/src/circular-buffer.ts";
304
328
  var CircularBuffer = class {
305
329
  _buffer;
306
330
  _nextIndex = 0;
307
331
  _elementCount = 0;
308
332
  constructor(size) {
309
- invariant3(size >= 1, void 0, {
310
- F: __dxlog_file3,
311
- L: 13,
312
- S: this,
313
- A: [
314
- "size >= 1",
315
- ""
316
- ]
317
- });
333
+ invariant3(size >= 1);
318
334
  this._buffer = new Array(size);
319
335
  }
320
336
  push(element) {
@@ -327,6 +343,10 @@ var CircularBuffer = class {
327
343
  get elementCount() {
328
344
  return this._elementCount;
329
345
  }
346
+ clear() {
347
+ this._nextIndex = 0;
348
+ this._elementCount = 0;
349
+ }
330
350
  getLast() {
331
351
  if (this._elementCount === 0) {
332
352
  return void 0;
@@ -520,6 +540,36 @@ var ComplexMap = class _ComplexMap {
520
540
  this._values.set(primitive, value);
521
541
  return this;
522
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
+ }
523
573
  get size() {
524
574
  return this._keys.size;
525
575
  }
@@ -559,21 +609,15 @@ var makeMap = (keyProjection) => class BoundComplexMap extends ComplexMap {
559
609
  }
560
610
  };
561
611
 
612
+ // src/composite-key.ts
613
+ var SEPARATOR = ":";
614
+ var compositeKey = (...parts) => parts.join(SEPARATOR);
615
+ var splitCompositeKey = (key) => key.split(SEPARATOR);
616
+
562
617
  // src/deep.ts
563
- import get from "lodash.get";
564
- import set from "lodash.set";
565
618
  import { invariant as invariant4 } from "@dxos/invariant";
566
- var __dxlog_file4 = "/__w/dxos/dxos/packages/common/util/src/deep.ts";
567
619
  var setDeep = (obj, path, value) => {
568
- invariant4(path.length > 0, void 0, {
569
- F: __dxlog_file4,
570
- L: 18,
571
- S: void 0,
572
- A: [
573
- "path.length > 0",
574
- ""
575
- ]
576
- });
620
+ invariant4(path.length > 0);
577
621
  let parent = obj;
578
622
  for (const key of path.slice(0, -1)) {
579
623
  if (parent[key] === void 0) {
@@ -597,6 +641,7 @@ var getDeep = (obj, path) => {
597
641
  var deferFunction = (fnProvider) => (...args) => fnProvider()(...args);
598
642
 
599
643
  // src/defer.ts
644
+ import "@hazae41/symbol-dispose-polyfill";
600
645
  var defer = (fn) => new DeferGuard(fn);
601
646
  var DeferGuard = class {
602
647
  _fn;
@@ -657,6 +702,29 @@ var MapEntry = class {
657
702
  }
658
703
  };
659
704
 
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");
720
+ };
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
+
660
728
  // src/for-each-async.ts
661
729
  var forEachAsync = (items, fn) => Promise.all(items.map(fn));
662
730
 
@@ -992,6 +1060,19 @@ var humanize = (value) => {
992
1060
  return hasher.humanize(value);
993
1061
  };
994
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
+
995
1076
  // src/map.ts
996
1077
  var defaultMap = (map, key, def) => {
997
1078
  let value = map.get(key);
@@ -1003,7 +1084,7 @@ var defaultMap = (map, key, def) => {
1003
1084
  };
1004
1085
 
1005
1086
  // src/instance-id.ts
1006
- var symbol = Symbol.for("dxos.instance-contexts");
1087
+ var symbol = /* @__PURE__ */ Symbol.for("dxos.instance-contexts");
1007
1088
  var instanceContexts = globalThis[symbol] ??= /* @__PURE__ */ new WeakMap();
1008
1089
  var getPrototypeSpecificInstanceId = (instance) => {
1009
1090
  const prototype = Object.getPrototypeOf(instance);
@@ -1011,12 +1092,12 @@ var getPrototypeSpecificInstanceId = (instance) => {
1011
1092
  nextId: 0,
1012
1093
  instanceIds: /* @__PURE__ */ new WeakMap()
1013
1094
  }));
1014
- let id = instanceCtx.instanceIds.get(instance);
1015
- if (id === void 0) {
1016
- id = instanceCtx.nextId++;
1017
- 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);
1018
1099
  }
1019
- return id;
1100
+ return id2;
1020
1101
  };
1021
1102
  var getDebugName = (instance) => {
1022
1103
  if (instance == null) {
@@ -1083,6 +1164,26 @@ var bufferToArray = (buffer) => {
1083
1164
  };
1084
1165
  var stringToArray = (string) => bufferToArray(Buffer.from(string, "hex"));
1085
1166
  var arrayToString = (array) => arrayToBuffer(array).toString("hex");
1167
+ var toUnpaddedBase64 = (bytes) => arrayToBuffer(bytes).toString("base64").replace(/=+$/, "");
1168
+ var encodeUint8ArrayToJson = (bytes) => ({
1169
+ "/": {
1170
+ bytes: toUnpaddedBase64(bytes)
1171
+ }
1172
+ });
1173
+ var isEncodedUint8Array = (value) => {
1174
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
1175
+ return false;
1176
+ }
1177
+ if (Object.keys(value).length !== 1) {
1178
+ return false;
1179
+ }
1180
+ const inner = value["/"];
1181
+ if (typeof inner !== "object" || inner === null || Array.isArray(inner)) {
1182
+ return false;
1183
+ }
1184
+ return Object.keys(inner).length === 1 && typeof inner.bytes === "string";
1185
+ };
1186
+ var decodeUint8ArrayFromJson = (encoded) => bufferToArray(Buffer.from(encoded["/"].bytes, "base64"));
1086
1187
 
1087
1188
  // src/json.ts
1088
1189
  var MAX_DEPTH = 5;
@@ -1212,6 +1313,8 @@ var DeepMapper = class {
1212
1313
  res[i] = this._map(value[i], i);
1213
1314
  }
1214
1315
  return res;
1316
+ } else if (ArrayBuffer.isView(value)) {
1317
+ return value;
1215
1318
  } else if (value !== null && typeof value === "object") {
1216
1319
  const res = {};
1217
1320
  this._cyclic.set(value, res);
@@ -1253,6 +1356,8 @@ var DeepMapperAsync = class {
1253
1356
  res[i] = await this._map(value[i], i);
1254
1357
  }
1255
1358
  return res;
1359
+ } else if (ArrayBuffer.isView(value)) {
1360
+ return value;
1256
1361
  } else if (value !== null && typeof value === "object") {
1257
1362
  const res = {};
1258
1363
  this._cyclic.set(value, res);
@@ -1297,27 +1402,27 @@ var orderKeys = (obj, order) => {
1297
1402
 
1298
1403
  // src/order.ts
1299
1404
  var inferObjectOrder = (objectMap, order = []) => {
1300
- const orderedObjects = order.reduce((acc, id) => {
1301
- if (id in objectMap) {
1302
- acc.objects.push(objectMap[id]);
1303
- acc.ids.add(id);
1405
+ const orderedObjects = order.reduce((acc, id2) => {
1406
+ if (id2 in objectMap) {
1407
+ acc.objects.push(objectMap[id2]);
1408
+ acc.ids.add(id2);
1304
1409
  }
1305
1410
  return acc;
1306
1411
  }, {
1307
1412
  objects: [],
1308
1413
  ids: /* @__PURE__ */ new Set()
1309
1414
  });
1310
- const { objects } = Object.keys(objectMap).reduce((acc, id) => {
1311
- if (!acc.ids.has(id)) {
1312
- acc.objects.push(objectMap[id]);
1415
+ const { objects } = Object.keys(objectMap).reduce((acc, id2) => {
1416
+ if (!acc.ids.has(id2)) {
1417
+ acc.objects.push(objectMap[id2]);
1313
1418
  }
1314
1419
  return acc;
1315
1420
  }, orderedObjects);
1316
1421
  return objects;
1317
1422
  };
1318
1423
  var inferRecordOrder = (objectMap, order = []) => {
1319
- return Object.assign(order.filter((id) => id in objectMap).reduce((acc, id) => {
1320
- acc[id] = null;
1424
+ return Object.assign(order.filter((id2) => id2 in objectMap).reduce((acc, id2) => {
1425
+ acc[id2] = null;
1321
1426
  return acc;
1322
1427
  }, {}), objectMap);
1323
1428
  };
@@ -1352,7 +1457,18 @@ var omit = (obj, keys2) => {
1352
1457
 
1353
1458
  // src/platform.ts
1354
1459
  var isNode = () => typeof process !== "undefined" && process.versions != null && process.versions.node != null;
1355
- var mobileAndTabletCheck = () => {
1460
+ var isBun = () => globalThis.Bun !== void 0;
1461
+ var isTauri = () => !!globalThis.__TAURI__;
1462
+ var isMobile = () => {
1463
+ let check = false;
1464
+ (function(a) {
1465
+ 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))) {
1466
+ check = true;
1467
+ }
1468
+ })(navigator.userAgent || navigator.vendor || window.opera);
1469
+ return check;
1470
+ };
1471
+ var isMobileOrTablet = () => {
1356
1472
  let check = false;
1357
1473
  ((a) => {
1358
1474
  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))) {
@@ -1374,7 +1490,7 @@ var iosCheck = () => {
1374
1490
  };
1375
1491
  var safariCheck = () => typeof navigator !== "undefined" && /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
1376
1492
  var getHostPlatform = () => {
1377
- if (!("navigator" in window)) {
1493
+ if (!("navigator" in globalThis)) {
1378
1494
  return "unknown";
1379
1495
  }
1380
1496
  const platform = (navigator.userAgentData?.platform || navigator.platform)?.toLowerCase();
@@ -1392,12 +1508,12 @@ var getHostPlatform = () => {
1392
1508
  };
1393
1509
 
1394
1510
  // src/position.ts
1395
- var byPosition = ({ position: a = "static" }, { position: b = "static" }) => {
1511
+ var byPosition = ({ position: a }, { position: b }) => {
1396
1512
  if (a === b) {
1397
1513
  return 0;
1398
- } else if (a === "hoist" || b === "fallback") {
1514
+ } else if (a === "first" || b === "last") {
1399
1515
  return -1;
1400
- } else if (b === "hoist" || a === "fallback") {
1516
+ } else if (b === "first" || a === "last") {
1401
1517
  return 1;
1402
1518
  } else {
1403
1519
  return 0;
@@ -1550,6 +1666,43 @@ var removeProperties = (root, condition) => {
1550
1666
  return result;
1551
1667
  };
1552
1668
 
1669
+ // src/retry.ts
1670
+ var DEFAULT_RETRY_OPTIONS = {
1671
+ count: 3,
1672
+ delayMs: 100,
1673
+ exponent: 2,
1674
+ retryOnError: async () => true,
1675
+ retryOnValue: async () => false
1676
+ };
1677
+ var retry = async (options, cb) => {
1678
+ const fullOptions = {
1679
+ ...DEFAULT_RETRY_OPTIONS,
1680
+ ...options
1681
+ };
1682
+ let numRetries = 0, currentDelay = fullOptions.delayMs;
1683
+ while (true) {
1684
+ let result;
1685
+ try {
1686
+ result = await cb();
1687
+ } catch (err) {
1688
+ if (numRetries > fullOptions.count || !await fullOptions.retryOnError(err)) {
1689
+ throw err;
1690
+ }
1691
+ await new Promise((resolve) => setTimeout(resolve, currentDelay));
1692
+ currentDelay *= fullOptions.exponent;
1693
+ numRetries++;
1694
+ continue;
1695
+ }
1696
+ if (!await fullOptions.retryOnValue(result)) {
1697
+ return result;
1698
+ }
1699
+ await new Promise((resolve) => setTimeout(resolve, currentDelay));
1700
+ currentDelay *= fullOptions.exponent;
1701
+ numRetries++;
1702
+ continue;
1703
+ }
1704
+ };
1705
+
1553
1706
  // src/safe-await.ts
1554
1707
  var safeAwaitAll = async (source, taskFactory, onError) => {
1555
1708
  const failedItems = [];
@@ -1569,7 +1722,7 @@ var safeAwaitAll = async (source, taskFactory, onError) => {
1569
1722
  };
1570
1723
 
1571
1724
  // src/safe-instanceof.ts
1572
- var instanceTag = Symbol("instanceTag");
1725
+ var instanceTag = /* @__PURE__ */ Symbol("instanceTag");
1573
1726
  var safeInstanceof = (tag) => (target) => {
1574
1727
  target.prototype[instanceTag] = tag;
1575
1728
  Object.defineProperty(target.prototype, Symbol.hasInstance, {
@@ -1581,57 +1734,88 @@ var safeInstanceof = (tag) => (target) => {
1581
1734
  };
1582
1735
 
1583
1736
  // src/safe-parse.ts
1584
- var safeParseInt = (value, defaultValue) => {
1737
+ function safeParseInt(str, defaultValue) {
1585
1738
  try {
1586
- const n = parseInt(value ?? "");
1587
- return isNaN(n) ? defaultValue : n;
1739
+ const value = parseInt(str ?? "");
1740
+ return isNaN(value) ? defaultValue : value;
1588
1741
  } catch {
1589
1742
  return defaultValue;
1590
1743
  }
1591
- };
1592
- var safeParseFloat = (str, defaultValue) => {
1744
+ }
1745
+ function safeParseFloat(str, defaultValue) {
1593
1746
  try {
1594
- return parseFloat(str);
1747
+ const value = parseFloat(str ?? "");
1748
+ return isNaN(value) ? defaultValue : value;
1595
1749
  } catch {
1596
- return defaultValue ?? 0;
1750
+ return defaultValue;
1597
1751
  }
1598
- };
1599
- var safeParseJson = (data, defaultValue) => {
1600
- if (data && data.length > 0) {
1752
+ }
1753
+ var safeParseJson = (str, defaultValue) => {
1754
+ if (str && str.length > 0) {
1601
1755
  try {
1602
- return JSON.parse(data);
1756
+ return JSON.parse(str);
1603
1757
  } catch {
1604
1758
  }
1605
1759
  }
1606
1760
  return defaultValue;
1607
1761
  };
1762
+ var safeUrl = (str) => {
1763
+ try {
1764
+ return new URL(str ?? "");
1765
+ } catch {
1766
+ return void 0;
1767
+ }
1768
+ };
1608
1769
 
1609
1770
  // src/safe-stringify.ts
1610
1771
  var SKIP = Object.freeze({});
1611
1772
  function safeStringify(obj, filter = defaultFilter, indent = 2) {
1612
- const seen = /* @__PURE__ */ new WeakSet();
1773
+ const seen = /* @__PURE__ */ new WeakMap();
1613
1774
  function replacer(key, value) {
1614
- if (typeof value === "object" && value !== null) {
1615
- if (seen.has(value)) {
1616
- return "[Circular]";
1775
+ try {
1776
+ let path = key;
1777
+ if (!key) {
1778
+ path = "$";
1779
+ if (value != null && typeof value === "object") {
1780
+ seen.set(value, path);
1781
+ }
1782
+ return value;
1783
+ } else if (this) {
1784
+ const parentPath = seen.get(this);
1785
+ path = parentPath ? `${parentPath}.${key}` : key;
1617
1786
  }
1618
- seen.add(value);
1619
- }
1620
- if (filter) {
1621
- const v2 = filter?.(key, value);
1622
- if (v2 !== void 0) {
1623
- return v2 === SKIP ? void 0 : v2;
1787
+ if (value == null) {
1788
+ return value;
1789
+ }
1790
+ if (typeof value === "function") {
1791
+ return void 0;
1624
1792
  }
1793
+ if (typeof value === "object" && Object.getPrototypeOf(value) !== Object.prototype && !Array.isArray(value)) {
1794
+ return void 0;
1795
+ }
1796
+ if (typeof value === "object" && value !== null) {
1797
+ const exists = seen.get(value);
1798
+ if (exists) {
1799
+ return `[${path} => ${exists}]`;
1800
+ }
1801
+ seen.set(value, path);
1802
+ }
1803
+ if (filter) {
1804
+ const filteredValue = filter?.(key, value);
1805
+ if (filteredValue !== void 0) {
1806
+ return filteredValue === SKIP ? void 0 : filteredValue;
1807
+ }
1808
+ }
1809
+ return value;
1810
+ } catch (error) {
1811
+ return `ERROR: ${error.message}`;
1625
1812
  }
1626
- return value;
1627
1813
  }
1628
- let result = "";
1629
1814
  try {
1630
- result = JSON.stringify(obj, replacer, indent);
1815
+ return JSON.stringify(obj, replacer, indent);
1631
1816
  } catch (error) {
1632
- result = `Error: ${error.message}`;
1817
+ return `ERROR: ${error.message}`;
1633
1818
  }
1634
- return result;
1635
1819
  }
1636
1820
  var createReplacer = ({ omit: omit2, parse, maxDepth, maxArrayLen, maxStringLen } = {}) => {
1637
1821
  let currentDepth = 0;
@@ -1644,7 +1828,10 @@ var createReplacer = ({ omit: omit2, parse, maxDepth, maxArrayLen, maxStringLen
1644
1828
  currentDepth = parentDepth + 1;
1645
1829
  }
1646
1830
  if (typeof value === "function") {
1647
- return void 0;
1831
+ return SKIP;
1832
+ }
1833
+ if (maxArrayLen != null && Array.isArray(value) && value.length > maxArrayLen) {
1834
+ return `[length: ${value.length}]`;
1648
1835
  }
1649
1836
  if (value && typeof value === "object") {
1650
1837
  depthMap.set(value, currentDepth);
@@ -1653,7 +1840,7 @@ var createReplacer = ({ omit: omit2, parse, maxDepth, maxArrayLen, maxStringLen
1653
1840
  }
1654
1841
  }
1655
1842
  if (omit2?.includes(key)) {
1656
- return void 0;
1843
+ return SKIP;
1657
1844
  }
1658
1845
  if (parse?.includes(key) && typeof value === "string") {
1659
1846
  try {
@@ -1662,9 +1849,6 @@ var createReplacer = ({ omit: omit2, parse, maxDepth, maxArrayLen, maxStringLen
1662
1849
  return value;
1663
1850
  }
1664
1851
  }
1665
- if (maxArrayLen != null && Array.isArray(value) && value.length > maxArrayLen) {
1666
- return `[length: ${value.length}]`;
1667
- }
1668
1852
  if (maxStringLen != null && typeof value === "string" && value.length > maxStringLen) {
1669
1853
  return value.slice(0, maxStringLen) + "...";
1670
1854
  }
@@ -1675,7 +1859,6 @@ var defaultFilter = createReplacer();
1675
1859
 
1676
1860
  // src/sliding-window-summary.ts
1677
1861
  import { invariant as invariant5 } from "@dxos/invariant";
1678
- var __dxlog_file5 = "/__w/dxos/dxos/packages/common/util/src/sliding-window-summary.ts";
1679
1862
  var SlidingWindowSummary = class {
1680
1863
  _buffer;
1681
1864
  _sum = 0;
@@ -1683,15 +1866,7 @@ var SlidingWindowSummary = class {
1683
1866
  constructor(options) {
1684
1867
  this._buffer = new CircularBuffer(options.dataPoints);
1685
1868
  if (options.precision != null) {
1686
- invariant5(options.precision >= 0, void 0, {
1687
- F: __dxlog_file5,
1688
- L: 26,
1689
- S: this,
1690
- A: [
1691
- "options.precision >= 0",
1692
- ""
1693
- ]
1694
- });
1869
+ invariant5(options.precision >= 0);
1695
1870
  this._precision = Math.pow(10, options.precision);
1696
1871
  }
1697
1872
  }
@@ -1760,6 +1935,10 @@ var capitalize = (str) => {
1760
1935
  }
1761
1936
  return str.charAt(0).toUpperCase() + str.slice(1);
1762
1937
  };
1938
+ function inline(strings, ...values) {
1939
+ const raw = strings.reduce((out, str, i) => out + str + (i < values.length ? String(values[i]) : ""), "");
1940
+ return raw.replace(/\s+/g, " ").trim();
1941
+ }
1763
1942
  function trim(strings, ...values) {
1764
1943
  const raw = strings.reduce((out, str, i) => {
1765
1944
  out += str;
@@ -1772,8 +1951,12 @@ function trim(strings, ...values) {
1772
1951
  return out;
1773
1952
  }, "");
1774
1953
  const lines = raw.split("\n");
1775
- while (lines.length && !lines[0].trim()) lines.shift();
1776
- while (lines.length && !lines[lines.length - 1].trim()) lines.pop();
1954
+ while (lines.length && !lines[0].trim()) {
1955
+ lines.shift();
1956
+ }
1957
+ while (lines.length && !lines[lines.length - 1].trim()) {
1958
+ lines.pop();
1959
+ }
1777
1960
  const minIndent = Math.min(...lines.filter((l) => l.trim()).map((l) => l.match(/^[ \t]*/)?.[0].length ?? 0));
1778
1961
  return lines.map((l) => l.slice(minIndent)).join("\n");
1779
1962
  }
@@ -1791,18 +1974,6 @@ var throwUnhandledError = (error) => {
1791
1974
 
1792
1975
  // src/to-fallback.ts
1793
1976
  var idEmoji = [
1794
- // When changing this set, please check the result in a console or e.g. RunKit (https://runkit.com/thure/642214441dd6ae000855a8de)
1795
- // 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.
1796
- // This set was chosen from the characters in Unicode Emoji v15.0 based on the following criteria:
1797
- // – not people or isolated anthropomorphic faces
1798
- // – not flags
1799
- // – more concrete than abstract
1800
- // – less culturally specific
1801
- // – less easily confused with another emoji in the set
1802
- // – requires less special knowledge to identify
1803
- // – less likely to evoke negative feelings (no meat, no drugs, no weapons, etc)
1804
- // – less common as a signifier in UX
1805
- // NOTE that this is intentionally an array of strings because of the way emoji graphemes work.
1806
1977
  "\u{1F47B}",
1807
1978
  "\u{1F479}",
1808
1979
  "\u{1F47D}",
@@ -1938,17 +2109,18 @@ var idEmoji = [
1938
2109
  ];
1939
2110
  var idHue = [
1940
2111
  "red",
1941
- // 'orange' as const, /* More shades in these palettes are considered “ugly” */
2112
+ "orange",
1942
2113
  "amber",
1943
- // 'yellow' as const, /* More shades in these palettes are considered “ugly” */
2114
+ "yellow",
1944
2115
  "lime",
1945
2116
  "green",
1946
2117
  "emerald",
1947
2118
  "teal",
1948
2119
  "cyan",
1949
- // 'sky' as const, /* Omitted since it is quite similar to the primary accent palette */
1950
- // 'blue' as const, /* Omitted since it is quite similar to the primary accent palette */
1951
- // 'indigo' as const, /* Omitted since it is quite similar to the primary accent palette */
2120
+ // Omit colors similar to primary accent.
2121
+ // 'sky' as const,
2122
+ // 'blue' as const,
2123
+ // 'indigo' as const,
1952
2124
  "violet",
1953
2125
  "purple",
1954
2126
  "fuchsia",
@@ -1987,8 +2159,8 @@ var Tracer = class {
1987
2159
  keys() {
1988
2160
  return Array.from(this._events.keys());
1989
2161
  }
1990
- get(id, filter) {
1991
- const events = this._events.get(id);
2162
+ get(id2, filter) {
2163
+ const events = this._events.get(id2);
1992
2164
  if (filter) {
1993
2165
  return events?.filter((event) => Object.entries(filter).every(([key, value]) => event?.value[key] === value));
1994
2166
  }
@@ -2005,11 +2177,11 @@ var Tracer = class {
2005
2177
  this._recording = false;
2006
2178
  return this;
2007
2179
  }
2008
- emit(id, value) {
2009
- this._post(this._createEvent(id, value));
2180
+ emit(id2, value) {
2181
+ this._post(this._createEvent(id2, value));
2010
2182
  }
2011
- mark(id, value) {
2012
- const event = this._createEvent(id, value);
2183
+ mark(id2, value) {
2184
+ const event = this._createEvent(id2, value);
2013
2185
  const start = performance.now();
2014
2186
  return {
2015
2187
  start,
@@ -2019,9 +2191,9 @@ var Tracer = class {
2019
2191
  }
2020
2192
  };
2021
2193
  }
2022
- _createEvent(id, value) {
2194
+ _createEvent(id2, value) {
2023
2195
  const event = {
2024
- id,
2196
+ id: id2,
2025
2197
  timestamp: Date.now()
2026
2198
  };
2027
2199
  if (value !== void 0) {
@@ -2108,16 +2280,26 @@ var arrayMove = (array, from, to) => {
2108
2280
  array.splice(to < 0 ? array.length + to : to, 0, array.splice(from, 1)[0]);
2109
2281
  return array;
2110
2282
  };
2283
+ function arraySwap(array, from, to) {
2284
+ const current = array[from];
2285
+ array[from] = array[to];
2286
+ array[to] = current;
2287
+ return array;
2288
+ }
2111
2289
 
2112
2290
  // src/unit.ts
2113
2291
  var createFormat = (unit) => {
2114
2292
  return (n, precision = unit.precision ?? 0) => {
2115
2293
  const value = n / unit.quotient;
2294
+ const formattedValue = value.toLocaleString("en-US", {
2295
+ minimumFractionDigits: precision,
2296
+ maximumFractionDigits: precision
2297
+ });
2116
2298
  return {
2117
2299
  unit,
2118
2300
  value,
2119
- formattedValue: value.toFixed(precision),
2120
- toString: () => `${value.toFixed(precision)}${unit.symbol}`
2301
+ formattedValue,
2302
+ toString: () => `${formattedValue}${unit.symbol}`
2121
2303
  };
2122
2304
  };
2123
2305
  };
@@ -2152,6 +2334,10 @@ var Unit = {
2152
2334
  quotient: 1e3,
2153
2335
  precision: 2
2154
2336
  }),
2337
+ Byte: createFormat({
2338
+ symbol: "B",
2339
+ quotient: 1
2340
+ }),
2155
2341
  // Time.
2156
2342
  Hour: createFormat({
2157
2343
  symbol: "h",
@@ -2170,6 +2356,7 @@ var Unit = {
2170
2356
  symbol: "ms",
2171
2357
  quotient: 1
2172
2358
  }),
2359
+ // TODO(burdon): Inconsistent formattedValue.
2173
2360
  Duration: (n) => {
2174
2361
  const hours = Math.floor(n / MS_HOURS);
2175
2362
  const minutes = Math.floor(n % MS_HOURS / MS_MINUTES);
@@ -2187,7 +2374,7 @@ var Unit = {
2187
2374
  }
2188
2375
  if (minutes) {
2189
2376
  const seconds2 = (n - MS_MINUTES * minutes) / MS_SECONDS;
2190
- const formattedValue = seconds2 ? `${minutes}m ${seconds2}s` : `${minutes}m`;
2377
+ const formattedValue = seconds2 ? `${minutes}m ${Math.round(seconds2)}s` : `${minutes}m`;
2191
2378
  return {
2192
2379
  unit: {
2193
2380
  symbol: "m",
@@ -2218,15 +2405,19 @@ var createUrl = (url, search) => {
2218
2405
  // src/weak.ts
2219
2406
  var WeakDictionary = class {
2220
2407
  _internal = /* @__PURE__ */ new Map();
2221
- _finalization = new FinalizationRegistry((cleanUpCallback) => {
2222
- cleanUpCallback();
2408
+ _finalization = new FinalizationRegistry(({ key, ref }) => {
2409
+ if (this._internal.get(key) === ref) {
2410
+ this._internal.delete(key);
2411
+ }
2223
2412
  });
2224
2413
  constructor(entries2) {
2225
- this._internal = new Map(entries2?.map(([key, value]) => [
2226
- key,
2227
- new WeakRef(value)
2228
- ]));
2229
- entries2?.forEach(([key, value]) => this._register(key, value));
2414
+ if (entries2) {
2415
+ for (const [key, value] of entries2) {
2416
+ const ref = new WeakRef(value);
2417
+ this._internal.set(key, ref);
2418
+ this._register(key, value, ref);
2419
+ }
2420
+ }
2230
2421
  }
2231
2422
  *entries() {
2232
2423
  for (const [key, value] of this._internal) {
@@ -2266,10 +2457,45 @@ var WeakDictionary = class {
2266
2457
  return this._internal.get(key)?.deref();
2267
2458
  }
2268
2459
  set(key, value) {
2269
- this._internal.set(key, new WeakRef(value));
2270
- this._register(key, value);
2460
+ const previous = this._internal.get(key)?.deref();
2461
+ if (previous) {
2462
+ this._unregister(previous);
2463
+ }
2464
+ const ref = new WeakRef(value);
2465
+ this._internal.set(key, ref);
2466
+ this._register(key, value, ref);
2271
2467
  return this;
2272
2468
  }
2469
+ /**
2470
+ * Returns the value for the given key if present, otherwise inserts and returns the default value.
2471
+ * @param key - The key to look up or insert.
2472
+ * @param defaultValue - The value to insert if the key is not present.
2473
+ * @returns The existing or newly inserted value.
2474
+ */
2475
+ getOrInsert(key, defaultValue) {
2476
+ const existing = this.get(key);
2477
+ if (existing !== void 0) {
2478
+ return existing;
2479
+ }
2480
+ this.set(key, defaultValue);
2481
+ return defaultValue;
2482
+ }
2483
+ /**
2484
+ * Returns the value for the given key if present, otherwise computes, inserts, and returns a new value.
2485
+ * The callback is only invoked when the key is missing.
2486
+ * @param key - The key to look up or insert.
2487
+ * @param callbackfn - Function to compute the value if the key is not present.
2488
+ * @returns The existing or newly computed value.
2489
+ */
2490
+ getOrInsertComputed(key, callbackfn) {
2491
+ const existing = this.get(key);
2492
+ if (existing !== void 0) {
2493
+ return existing;
2494
+ }
2495
+ const value = callbackfn(key);
2496
+ this.set(key, value);
2497
+ return value;
2498
+ }
2273
2499
  has(key) {
2274
2500
  return this._internal.has(key) && this._internal.get(key).deref() !== void 0;
2275
2501
  }
@@ -2300,9 +2526,10 @@ var WeakDictionary = class {
2300
2526
  }
2301
2527
  });
2302
2528
  }
2303
- _register(key, value) {
2304
- this._finalization.register(value, () => {
2305
- this._internal.delete(key);
2529
+ _register(key, value, ref) {
2530
+ this._finalization.register(value, {
2531
+ key,
2532
+ ref
2306
2533
  }, value);
2307
2534
  }
2308
2535
  _unregister(value) {
@@ -2325,6 +2552,7 @@ export {
2325
2552
  WeakDictionary,
2326
2553
  accessBy,
2327
2554
  arrayMove,
2555
+ arraySwap,
2328
2556
  arrayToBuffer,
2329
2557
  arrayToHex,
2330
2558
  arrayToString,
@@ -2335,18 +2563,26 @@ export {
2335
2563
  capitalize,
2336
2564
  chunkArray,
2337
2565
  clamp,
2566
+ clearCaches,
2567
+ clearIndexedDB,
2568
+ clearOPFS,
2569
+ clearServiceWorkers,
2338
2570
  clearUndefined,
2571
+ coerceArray,
2339
2572
  compareMulti,
2340
2573
  compareObject,
2341
2574
  compareScalar,
2342
2575
  compareString,
2576
+ compositeKey,
2343
2577
  createBinder,
2344
2578
  createBucketReducer,
2579
+ createFilename,
2345
2580
  createGroupReducer,
2346
2581
  createReplacer,
2347
2582
  createSetDispatch,
2348
2583
  createUrl,
2349
2584
  decamelize,
2585
+ decodeUint8ArrayFromJson,
2350
2586
  deepMapValues,
2351
2587
  deepMapValuesAsync,
2352
2588
  defaultFilter,
@@ -2357,11 +2593,12 @@ export {
2357
2593
  diff,
2358
2594
  distinctBy,
2359
2595
  doAsync,
2596
+ encodeUint8ArrayToJson,
2360
2597
  entries,
2361
2598
  entry,
2362
2599
  exponentialBackoffInterval,
2363
2600
  forEachAsync,
2364
- get,
2601
+ formatErrorWithCauses,
2365
2602
  getAsyncProviderValue,
2366
2603
  getDate,
2367
2604
  getDebugName,
@@ -2374,16 +2611,25 @@ export {
2374
2611
  hexToHue,
2375
2612
  humanize,
2376
2613
  hyphenize,
2614
+ id,
2377
2615
  idEmoji,
2378
2616
  idHue,
2379
2617
  inferObjectOrder,
2380
2618
  inferRecordOrder,
2619
+ inline,
2381
2620
  intersectBy,
2382
2621
  intersection,
2383
2622
  iosCheck,
2623
+ isBun,
2624
+ isEncodedUint8Array,
2625
+ isMobile,
2626
+ isMobileOrTablet,
2384
2627
  isNode,
2385
2628
  isNonNullable,
2629
+ isTauri,
2386
2630
  isTruthy,
2631
+ isWellFormedId,
2632
+ isWellFormedIdPart,
2387
2633
  joinTables,
2388
2634
  jsonKeyReplacer,
2389
2635
  jsonReplacer,
@@ -2398,7 +2644,6 @@ export {
2398
2644
  makeSet,
2399
2645
  mapValues,
2400
2646
  median,
2401
- mobileAndTabletCheck,
2402
2647
  numericalValues,
2403
2648
  omit,
2404
2649
  orderKeys,
@@ -2414,6 +2659,7 @@ export {
2414
2659
  removeBy,
2415
2660
  removeProperties,
2416
2661
  removeUndefinedProperties,
2662
+ retry,
2417
2663
  safariCheck,
2418
2664
  safeAwaitAll,
2419
2665
  safeInstanceof,
@@ -2421,9 +2667,10 @@ export {
2421
2667
  safeParseInt,
2422
2668
  safeParseJson,
2423
2669
  safeStringify,
2424
- set,
2670
+ safeUrl,
2425
2671
  setDeep,
2426
2672
  sortKeys,
2673
+ splitCompositeKey,
2427
2674
  stringToArray,
2428
2675
  stringifyTree,
2429
2676
  stripUndefined,