@dxos/util 0.8.4-main.fbb7a13 → 0.8.4-main.fcc0d83b33

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 (103) hide show
  1. package/dist/lib/browser/index.mjs +241 -156
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node-esm/index.mjs +241 -156
  5. package/dist/lib/node-esm/index.mjs.map +4 -4
  6. package/dist/lib/node-esm/meta.json +1 -1
  7. package/dist/types/src/array-to-hex.d.ts.map +1 -1
  8. package/dist/types/src/array.d.ts.map +1 -1
  9. package/dist/types/src/binder.d.ts.map +1 -1
  10. package/dist/types/src/bitfield.d.ts.map +1 -1
  11. package/dist/types/src/browser-storage.d.ts +9 -0
  12. package/dist/types/src/browser-storage.d.ts.map +1 -0
  13. package/dist/types/src/callback-collection.d.ts.map +1 -1
  14. package/dist/types/src/callback.d.ts.map +1 -1
  15. package/dist/types/src/case.d.ts.map +1 -1
  16. package/dist/types/src/chunk-array.d.ts.map +1 -1
  17. package/dist/types/src/circular-buffer.d.ts +1 -0
  18. package/dist/types/src/circular-buffer.d.ts.map +1 -1
  19. package/dist/types/src/clear-undefined.d.ts.map +1 -1
  20. package/dist/types/src/complex.d.ts +15 -0
  21. package/dist/types/src/complex.d.ts.map +1 -1
  22. package/dist/types/src/composite-key.d.ts +10 -0
  23. package/dist/types/src/composite-key.d.ts.map +1 -0
  24. package/dist/types/src/composite-key.test.d.ts +2 -0
  25. package/dist/types/src/composite-key.test.d.ts.map +1 -0
  26. package/dist/types/src/deep.d.ts +0 -3
  27. package/dist/types/src/deep.d.ts.map +1 -1
  28. package/dist/types/src/defer-function.d.ts.map +1 -1
  29. package/dist/types/src/defer.d.ts.map +1 -1
  30. package/dist/types/src/di-container.d.ts.map +1 -1
  31. package/dist/types/src/di-key.d.ts +7 -5
  32. package/dist/types/src/di-key.d.ts.map +1 -1
  33. package/dist/types/src/entry.d.ts.map +1 -1
  34. package/dist/types/src/error-format.d.ts.map +1 -1
  35. package/dist/types/src/filename.d.ts.map +1 -1
  36. package/dist/types/src/for-each-async.d.ts.map +1 -1
  37. package/dist/types/src/human-hash.d.ts.map +1 -1
  38. package/dist/types/src/index.d.ts +4 -2
  39. package/dist/types/src/index.d.ts.map +1 -1
  40. package/dist/types/src/instance-id.d.ts.map +1 -1
  41. package/dist/types/src/interval.d.ts.map +1 -1
  42. package/dist/types/src/join-tables.d.ts.map +1 -1
  43. package/dist/types/src/json.d.ts.map +1 -1
  44. package/dist/types/src/map-values.d.ts.map +1 -1
  45. package/dist/types/src/map.d.ts.map +1 -1
  46. package/dist/types/src/object.d.ts.map +1 -1
  47. package/dist/types/src/order-keys.d.ts.map +1 -1
  48. package/dist/types/src/order.d.ts.map +1 -1
  49. package/dist/types/src/pick.d.ts.map +1 -1
  50. package/dist/types/src/platform.d.ts +1 -1
  51. package/dist/types/src/platform.d.ts.map +1 -1
  52. package/dist/types/src/position.d.ts +1 -1
  53. package/dist/types/src/position.d.ts.map +1 -1
  54. package/dist/types/src/random.d.ts.map +1 -1
  55. package/dist/types/src/range.d.ts.map +1 -1
  56. package/dist/types/src/reducers.d.ts.map +1 -1
  57. package/dist/types/src/remove-undefined-keys.d.ts.map +1 -1
  58. package/dist/types/src/retry.d.ts.map +1 -1
  59. package/dist/types/src/safe-await.d.ts.map +1 -1
  60. package/dist/types/src/safe-instanceof.d.ts.map +1 -1
  61. package/dist/types/src/safe-parse.d.ts +1 -0
  62. package/dist/types/src/safe-parse.d.ts.map +1 -1
  63. package/dist/types/src/safe-stringify.d.ts +1 -1
  64. package/dist/types/src/safe-stringify.d.ts.map +1 -1
  65. package/dist/types/src/safe-stringify.test.d.ts +2 -0
  66. package/dist/types/src/safe-stringify.test.d.ts.map +1 -0
  67. package/dist/types/src/sliding-window-summary.d.ts.map +1 -1
  68. package/dist/types/src/sort.d.ts.map +1 -1
  69. package/dist/types/src/string.d.ts.map +1 -1
  70. package/dist/types/src/sum.d.ts.map +1 -1
  71. package/dist/types/src/throw-unhandled-error.d.ts.map +1 -1
  72. package/dist/types/src/to-fallback.d.ts +18 -4
  73. package/dist/types/src/to-fallback.d.ts.map +1 -1
  74. package/dist/types/src/tracer.d.ts.map +1 -1
  75. package/dist/types/src/tree.d.ts.map +1 -1
  76. package/dist/types/src/types.d.ts +1 -1
  77. package/dist/types/src/types.d.ts.map +1 -1
  78. package/dist/types/src/uint8array.d.ts.map +1 -1
  79. package/dist/types/src/unit.d.ts.map +1 -1
  80. package/dist/types/src/url.d.ts.map +1 -1
  81. package/dist/types/src/weak.d.ts +15 -0
  82. package/dist/types/src/weak.d.ts.map +1 -1
  83. package/dist/types/tsconfig.tsbuildinfo +1 -1
  84. package/package.json +6 -13
  85. package/src/browser-storage.ts +60 -0
  86. package/src/circular-buffer.test.ts +26 -0
  87. package/src/circular-buffer.ts +5 -0
  88. package/src/complex.ts +32 -0
  89. package/src/composite-key.test.ts +31 -0
  90. package/src/composite-key.ts +16 -0
  91. package/src/deep.ts +0 -6
  92. package/src/di-key.ts +10 -8
  93. package/src/error-format.ts +3 -1
  94. package/src/index.ts +4 -2
  95. package/src/platform.ts +28 -6
  96. package/src/safe-parse.ts +8 -0
  97. package/src/safe-stringify.test.ts +96 -0
  98. package/src/safe-stringify.ts +15 -8
  99. package/src/string.ts +6 -2
  100. package/src/to-fallback.ts +39 -156
  101. package/src/types.ts +1 -1
  102. package/src/unit.ts +6 -2
  103. package/src/weak.ts +52 -14
@@ -119,7 +119,6 @@ var createBinder = (obj) => ({
119
119
 
120
120
  // src/bitfield.ts
121
121
  import { invariant } from "@dxos/invariant";
122
- var __dxlog_file = "/__w/dxos/dxos/packages/common/util/src/bitfield.ts";
123
122
  var BitField = class _BitField {
124
123
  static get(data, idx) {
125
124
  const bit = data[idx >> 3] >> 7 - idx % 8 & 1;
@@ -151,15 +150,7 @@ var BitField = class _BitField {
151
150
  return result;
152
151
  }
153
152
  static and(first, second) {
154
- invariant(first.length === second.length, "Bitfields must be of the same length", {
155
- F: __dxlog_file,
156
- L: 52,
157
- S: this,
158
- A: [
159
- "first.length === second.length",
160
- "'Bitfields must be of the same length'"
161
- ]
162
- });
153
+ invariant(first.length === second.length, "Bitfields must be of the same length");
163
154
  const result = new Uint8Array(first.length);
164
155
  for (let i = 0; i < first.length; i++) {
165
156
  result[i] = first[i] & second[i];
@@ -187,6 +178,49 @@ var BitField = class _BitField {
187
178
  }
188
179
  };
189
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
+
190
224
  // src/callback-collection.ts
191
225
  var CallbackCollection = class {
192
226
  #callbacks = [];
@@ -213,34 +247,17 @@ var CallbackCollection = class {
213
247
 
214
248
  // src/callback.ts
215
249
  import { invariant as invariant2 } from "@dxos/invariant";
216
- var __dxlog_file2 = "/__w/dxos/dxos/packages/common/util/src/callback.ts";
217
250
  var Callback = class {
218
251
  _callback;
219
252
  call(...args) {
220
- invariant2(this._callback, "Callback not set", {
221
- F: __dxlog_file2,
222
- L: 20,
223
- S: this,
224
- A: [
225
- "this._callback",
226
- "'Callback not set'"
227
- ]
228
- });
253
+ invariant2(this._callback, "Callback not set");
229
254
  return this._callback(...args);
230
255
  }
231
256
  callIfSet(...args) {
232
257
  return this._callback?.(...args);
233
258
  }
234
259
  set(callback) {
235
- invariant2(!this._callback, "Callback already set", {
236
- F: __dxlog_file2,
237
- L: 29,
238
- S: this,
239
- A: [
240
- "!this._callback",
241
- "'Callback already set'"
242
- ]
243
- });
260
+ invariant2(!this._callback, "Callback already set");
244
261
  this._callback = callback;
245
262
  }
246
263
  isSet() {
@@ -308,21 +325,12 @@ var chunkArray = (array, size) => {
308
325
 
309
326
  // src/circular-buffer.ts
310
327
  import { invariant as invariant3 } from "@dxos/invariant";
311
- var __dxlog_file3 = "/__w/dxos/dxos/packages/common/util/src/circular-buffer.ts";
312
328
  var CircularBuffer = class {
313
329
  _buffer;
314
330
  _nextIndex = 0;
315
331
  _elementCount = 0;
316
332
  constructor(size) {
317
- invariant3(size >= 1, void 0, {
318
- F: __dxlog_file3,
319
- L: 13,
320
- S: this,
321
- A: [
322
- "size >= 1",
323
- ""
324
- ]
325
- });
333
+ invariant3(size >= 1);
326
334
  this._buffer = new Array(size);
327
335
  }
328
336
  push(element) {
@@ -335,6 +343,10 @@ var CircularBuffer = class {
335
343
  get elementCount() {
336
344
  return this._elementCount;
337
345
  }
346
+ clear() {
347
+ this._nextIndex = 0;
348
+ this._elementCount = 0;
349
+ }
338
350
  getLast() {
339
351
  if (this._elementCount === 0) {
340
352
  return void 0;
@@ -528,6 +540,36 @@ var ComplexMap = class _ComplexMap {
528
540
  this._values.set(primitive, value);
529
541
  return this;
530
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
+ }
531
573
  get size() {
532
574
  return this._keys.size;
533
575
  }
@@ -567,21 +609,15 @@ var makeMap = (keyProjection) => class BoundComplexMap extends ComplexMap {
567
609
  }
568
610
  };
569
611
 
612
+ // src/composite-key.ts
613
+ var SEPARATOR = ":";
614
+ var compositeKey = (...parts) => parts.join(SEPARATOR);
615
+ var splitCompositeKey = (key) => key.split(SEPARATOR);
616
+
570
617
  // src/deep.ts
571
- import get from "lodash.get";
572
- import set from "lodash.set";
573
618
  import { invariant as invariant4 } from "@dxos/invariant";
574
- var __dxlog_file4 = "/__w/dxos/dxos/packages/common/util/src/deep.ts";
575
619
  var setDeep = (obj, path, value) => {
576
- invariant4(path.length > 0, void 0, {
577
- F: __dxlog_file4,
578
- L: 18,
579
- S: void 0,
580
- A: [
581
- "path.length > 0",
582
- ""
583
- ]
584
- });
620
+ invariant4(path.length > 0);
585
621
  let parent = obj;
586
622
  for (const key of path.slice(0, -1)) {
587
623
  if (parent[key] === void 0) {
@@ -666,6 +702,23 @@ var MapEntry = class {
666
702
  }
667
703
  };
668
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
+
669
722
  // src/filename.ts
670
723
  var createFilename = ({ parts = [], ext, date = /* @__PURE__ */ new Date() }) => [
671
724
  date.toISOString().replace(/[:.]/g, "-"),
@@ -1018,7 +1071,7 @@ var defaultMap = (map, key, def) => {
1018
1071
  };
1019
1072
 
1020
1073
  // src/instance-id.ts
1021
- var symbol = Symbol.for("dxos.instance-contexts");
1074
+ var symbol = /* @__PURE__ */ Symbol.for("dxos.instance-contexts");
1022
1075
  var instanceContexts = globalThis[symbol] ??= /* @__PURE__ */ new WeakMap();
1023
1076
  var getPrototypeSpecificInstanceId = (instance) => {
1024
1077
  const prototype = Object.getPrototypeOf(instance);
@@ -1400,7 +1453,7 @@ var iosCheck = () => {
1400
1453
  };
1401
1454
  var safariCheck = () => typeof navigator !== "undefined" && /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
1402
1455
  var getHostPlatform = () => {
1403
- if (!("navigator" in window)) {
1456
+ if (!("navigator" in globalThis)) {
1404
1457
  return "unknown";
1405
1458
  }
1406
1459
  const platform = (navigator.userAgentData?.platform || navigator.platform)?.toLowerCase();
@@ -1576,6 +1629,43 @@ var removeProperties = (root, condition) => {
1576
1629
  return result;
1577
1630
  };
1578
1631
 
1632
+ // src/retry.ts
1633
+ var DEFAULT_RETRY_OPTIONS = {
1634
+ count: 3,
1635
+ delayMs: 100,
1636
+ exponent: 2,
1637
+ retryOnError: async () => true,
1638
+ retryOnValue: async () => false
1639
+ };
1640
+ var retry = async (options, cb) => {
1641
+ const fullOptions = {
1642
+ ...DEFAULT_RETRY_OPTIONS,
1643
+ ...options
1644
+ };
1645
+ let numRetries = 0, currentDelay = fullOptions.delayMs;
1646
+ while (true) {
1647
+ let result;
1648
+ try {
1649
+ result = await cb();
1650
+ } catch (err) {
1651
+ if (numRetries > fullOptions.count || !await fullOptions.retryOnError(err)) {
1652
+ throw err;
1653
+ }
1654
+ await new Promise((resolve) => setTimeout(resolve, currentDelay));
1655
+ currentDelay *= fullOptions.exponent;
1656
+ numRetries++;
1657
+ continue;
1658
+ }
1659
+ if (!await fullOptions.retryOnValue(result)) {
1660
+ return result;
1661
+ }
1662
+ await new Promise((resolve) => setTimeout(resolve, currentDelay));
1663
+ currentDelay *= fullOptions.exponent;
1664
+ numRetries++;
1665
+ continue;
1666
+ }
1667
+ };
1668
+
1579
1669
  // src/safe-await.ts
1580
1670
  var safeAwaitAll = async (source, taskFactory, onError) => {
1581
1671
  const failedItems = [];
@@ -1595,7 +1685,7 @@ var safeAwaitAll = async (source, taskFactory, onError) => {
1595
1685
  };
1596
1686
 
1597
1687
  // src/safe-instanceof.ts
1598
- var instanceTag = Symbol("instanceTag");
1688
+ var instanceTag = /* @__PURE__ */ Symbol("instanceTag");
1599
1689
  var safeInstanceof = (tag) => (target) => {
1600
1690
  target.prototype[instanceTag] = tag;
1601
1691
  Object.defineProperty(target.prototype, Symbol.hasInstance, {
@@ -1632,6 +1722,13 @@ var safeParseJson = (str, defaultValue) => {
1632
1722
  }
1633
1723
  return defaultValue;
1634
1724
  };
1725
+ var safeUrl = (str) => {
1726
+ try {
1727
+ return new URL(str ?? "");
1728
+ } catch {
1729
+ return void 0;
1730
+ }
1731
+ };
1635
1732
 
1636
1733
  // src/safe-stringify.ts
1637
1734
  var SKIP = Object.freeze({});
@@ -1642,6 +1739,9 @@ function safeStringify(obj, filter = defaultFilter, indent = 2) {
1642
1739
  let path = key;
1643
1740
  if (!key) {
1644
1741
  path = "$";
1742
+ if (value != null && typeof value === "object") {
1743
+ seen.set(value, path);
1744
+ }
1645
1745
  return value;
1646
1746
  } else if (this) {
1647
1747
  const parentPath = seen.get(this);
@@ -1653,7 +1753,7 @@ function safeStringify(obj, filter = defaultFilter, indent = 2) {
1653
1753
  if (typeof value === "function") {
1654
1754
  return void 0;
1655
1755
  }
1656
- if (typeof value === "object" && Object.getPrototypeOf(value) !== Object.prototype) {
1756
+ if (typeof value === "object" && Object.getPrototypeOf(value) !== Object.prototype && !Array.isArray(value)) {
1657
1757
  return void 0;
1658
1758
  }
1659
1759
  if (typeof value === "object" && value !== null) {
@@ -1674,7 +1774,11 @@ function safeStringify(obj, filter = defaultFilter, indent = 2) {
1674
1774
  return `ERROR: ${error.message}`;
1675
1775
  }
1676
1776
  }
1677
- return JSON.stringify(obj, replacer, indent);
1777
+ try {
1778
+ return JSON.stringify(obj, replacer, indent);
1779
+ } catch (error) {
1780
+ return `ERROR: ${error.message}`;
1781
+ }
1678
1782
  }
1679
1783
  var createReplacer = ({ omit: omit2, parse, maxDepth, maxArrayLen, maxStringLen } = {}) => {
1680
1784
  let currentDepth = 0;
@@ -1689,6 +1793,9 @@ var createReplacer = ({ omit: omit2, parse, maxDepth, maxArrayLen, maxStringLen
1689
1793
  if (typeof value === "function") {
1690
1794
  return SKIP;
1691
1795
  }
1796
+ if (maxArrayLen != null && Array.isArray(value) && value.length > maxArrayLen) {
1797
+ return `[length: ${value.length}]`;
1798
+ }
1692
1799
  if (value && typeof value === "object") {
1693
1800
  depthMap.set(value, currentDepth);
1694
1801
  if (maxDepth != null && currentDepth >= maxDepth) {
@@ -1705,9 +1812,6 @@ var createReplacer = ({ omit: omit2, parse, maxDepth, maxArrayLen, maxStringLen
1705
1812
  return value;
1706
1813
  }
1707
1814
  }
1708
- if (maxArrayLen != null && Array.isArray(value) && value.length > maxArrayLen) {
1709
- return `[length: ${value.length}]`;
1710
- }
1711
1815
  if (maxStringLen != null && typeof value === "string" && value.length > maxStringLen) {
1712
1816
  return value.slice(0, maxStringLen) + "...";
1713
1817
  }
@@ -1718,7 +1822,6 @@ var defaultFilter = createReplacer();
1718
1822
 
1719
1823
  // src/sliding-window-summary.ts
1720
1824
  import { invariant as invariant5 } from "@dxos/invariant";
1721
- var __dxlog_file5 = "/__w/dxos/dxos/packages/common/util/src/sliding-window-summary.ts";
1722
1825
  var SlidingWindowSummary = class {
1723
1826
  _buffer;
1724
1827
  _sum = 0;
@@ -1726,15 +1829,7 @@ var SlidingWindowSummary = class {
1726
1829
  constructor(options) {
1727
1830
  this._buffer = new CircularBuffer(options.dataPoints);
1728
1831
  if (options.precision != null) {
1729
- invariant5(options.precision >= 0, void 0, {
1730
- F: __dxlog_file5,
1731
- L: 26,
1732
- S: this,
1733
- A: [
1734
- "options.precision >= 0",
1735
- ""
1736
- ]
1737
- });
1832
+ invariant5(options.precision >= 0);
1738
1833
  this._precision = Math.pow(10, options.precision);
1739
1834
  }
1740
1835
  }
@@ -1815,8 +1910,12 @@ function trim(strings, ...values) {
1815
1910
  return out;
1816
1911
  }, "");
1817
1912
  const lines = raw.split("\n");
1818
- while (lines.length && !lines[0].trim()) lines.shift();
1819
- while (lines.length && !lines[lines.length - 1].trim()) lines.pop();
1913
+ while (lines.length && !lines[0].trim()) {
1914
+ lines.shift();
1915
+ }
1916
+ while (lines.length && !lines[lines.length - 1].trim()) {
1917
+ lines.pop();
1918
+ }
1820
1919
  const minIndent = Math.min(...lines.filter((l) => l.trim()).map((l) => l.match(/^[ \t]*/)?.[0].length ?? 0));
1821
1920
  return lines.map((l) => l.slice(minIndent)).join("\n");
1822
1921
  }
@@ -1834,18 +1933,6 @@ var throwUnhandledError = (error) => {
1834
1933
 
1835
1934
  // src/to-fallback.ts
1836
1935
  var idEmoji = [
1837
- // When changing this set, please check the result in a console or e.g. RunKit (https://runkit.com/thure/642214441dd6ae000855a8de)
1838
- // 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.
1839
- // This set was chosen from the characters in Unicode Emoji v15.0 based on the following criteria:
1840
- // – not people or isolated anthropomorphic faces
1841
- // – not flags
1842
- // – more concrete than abstract
1843
- // – less culturally specific
1844
- // – less easily confused with another emoji in the set
1845
- // – requires less special knowledge to identify
1846
- // – less likely to evoke negative feelings (no meat, no drugs, no weapons, etc)
1847
- // – less common as a signifier in UX
1848
- // NOTE that this is intentionally an array of strings because of the way emoji graphemes work.
1849
1936
  "\u{1F47B}",
1850
1937
  "\u{1F479}",
1851
1938
  "\u{1F47D}",
@@ -1981,17 +2068,18 @@ var idEmoji = [
1981
2068
  ];
1982
2069
  var idHue = [
1983
2070
  "red",
1984
- // 'orange' as const, /* More shades in these palettes are considered “ugly” */
2071
+ "orange",
1985
2072
  "amber",
1986
- // 'yellow' as const, /* More shades in these palettes are considered “ugly” */
2073
+ "yellow",
1987
2074
  "lime",
1988
2075
  "green",
1989
2076
  "emerald",
1990
2077
  "teal",
1991
2078
  "cyan",
1992
- // 'sky' as const, /* Omitted since it is quite similar to the primary accent palette */
1993
- // 'blue' as const, /* Omitted since it is quite similar to the primary accent palette */
1994
- // 'indigo' as const, /* Omitted since it is quite similar to the primary accent palette */
2079
+ // Omit colors similar to primary accent.
2080
+ // 'sky' as const,
2081
+ // 'blue' as const,
2082
+ // 'indigo' as const,
1995
2083
  "violet",
1996
2084
  "purple",
1997
2085
  "fuchsia",
@@ -2162,11 +2250,15 @@ function arraySwap(array, from, to) {
2162
2250
  var createFormat = (unit) => {
2163
2251
  return (n, precision = unit.precision ?? 0) => {
2164
2252
  const value = n / unit.quotient;
2253
+ const formattedValue = value.toLocaleString("en-US", {
2254
+ minimumFractionDigits: precision,
2255
+ maximumFractionDigits: precision
2256
+ });
2165
2257
  return {
2166
2258
  unit,
2167
2259
  value,
2168
- formattedValue: value.toFixed(precision),
2169
- toString: () => `${value.toFixed(precision)}${unit.symbol}`
2260
+ formattedValue,
2261
+ toString: () => `${formattedValue}${unit.symbol}`
2170
2262
  };
2171
2263
  };
2172
2264
  };
@@ -2271,15 +2363,19 @@ var createUrl = (url, search) => {
2271
2363
  // src/weak.ts
2272
2364
  var WeakDictionary = class {
2273
2365
  _internal = /* @__PURE__ */ new Map();
2274
- _finalization = new FinalizationRegistry((cleanUpCallback) => {
2275
- cleanUpCallback();
2366
+ _finalization = new FinalizationRegistry(({ key, ref }) => {
2367
+ if (this._internal.get(key) === ref) {
2368
+ this._internal.delete(key);
2369
+ }
2276
2370
  });
2277
2371
  constructor(entries2) {
2278
- this._internal = new Map(entries2?.map(([key, value]) => [
2279
- key,
2280
- new WeakRef(value)
2281
- ]));
2282
- entries2?.forEach(([key, value]) => this._register(key, value));
2372
+ if (entries2) {
2373
+ for (const [key, value] of entries2) {
2374
+ const ref = new WeakRef(value);
2375
+ this._internal.set(key, ref);
2376
+ this._register(key, value, ref);
2377
+ }
2378
+ }
2283
2379
  }
2284
2380
  *entries() {
2285
2381
  for (const [key, value] of this._internal) {
@@ -2319,10 +2415,45 @@ var WeakDictionary = class {
2319
2415
  return this._internal.get(key)?.deref();
2320
2416
  }
2321
2417
  set(key, value) {
2322
- this._internal.set(key, new WeakRef(value));
2323
- this._register(key, value);
2418
+ const previous = this._internal.get(key)?.deref();
2419
+ if (previous) {
2420
+ this._unregister(previous);
2421
+ }
2422
+ const ref = new WeakRef(value);
2423
+ this._internal.set(key, ref);
2424
+ this._register(key, value, ref);
2324
2425
  return this;
2325
2426
  }
2427
+ /**
2428
+ * Returns the value for the given key if present, otherwise inserts and returns the default value.
2429
+ * @param key - The key to look up or insert.
2430
+ * @param defaultValue - The value to insert if the key is not present.
2431
+ * @returns The existing or newly inserted value.
2432
+ */
2433
+ getOrInsert(key, defaultValue) {
2434
+ const existing = this.get(key);
2435
+ if (existing !== void 0) {
2436
+ return existing;
2437
+ }
2438
+ this.set(key, defaultValue);
2439
+ return defaultValue;
2440
+ }
2441
+ /**
2442
+ * Returns the value for the given key if present, otherwise computes, inserts, and returns a new value.
2443
+ * The callback is only invoked when the key is missing.
2444
+ * @param key - The key to look up or insert.
2445
+ * @param callbackfn - Function to compute the value if the key is not present.
2446
+ * @returns The existing or newly computed value.
2447
+ */
2448
+ getOrInsertComputed(key, callbackfn) {
2449
+ const existing = this.get(key);
2450
+ if (existing !== void 0) {
2451
+ return existing;
2452
+ }
2453
+ const value = callbackfn(key);
2454
+ this.set(key, value);
2455
+ return value;
2456
+ }
2326
2457
  has(key) {
2327
2458
  return this._internal.has(key) && this._internal.get(key).deref() !== void 0;
2328
2459
  }
@@ -2353,67 +2484,16 @@ var WeakDictionary = class {
2353
2484
  }
2354
2485
  });
2355
2486
  }
2356
- _register(key, value) {
2357
- this._finalization.register(value, () => {
2358
- this._internal.delete(key);
2487
+ _register(key, value, ref) {
2488
+ this._finalization.register(value, {
2489
+ key,
2490
+ ref
2359
2491
  }, value);
2360
2492
  }
2361
2493
  _unregister(value) {
2362
2494
  this._finalization.unregister(value);
2363
2495
  }
2364
2496
  };
2365
-
2366
- // src/error-format.ts
2367
- var formatErrorWithCauses = (error) => {
2368
- const lines = [];
2369
- let current = error;
2370
- let level = 0;
2371
- while (current) {
2372
- const prefix = level === 0 ? "" : `Caused by: `;
2373
- lines.push(prefix + (current.stack ?? String(current)));
2374
- if (!(current.cause instanceof Error)) break;
2375
- current = current.cause;
2376
- level += 1;
2377
- }
2378
- return lines.join("\n\n");
2379
- };
2380
-
2381
- // src/retry.ts
2382
- var DEFAULT_RETRY_OPTIONS = {
2383
- count: 3,
2384
- delayMs: 100,
2385
- exponent: 2,
2386
- retryOnError: async () => true,
2387
- retryOnValue: async () => false
2388
- };
2389
- var retry = async (options, cb) => {
2390
- const fullOptions = {
2391
- ...DEFAULT_RETRY_OPTIONS,
2392
- ...options
2393
- };
2394
- let numRetries = 0, currentDelay = fullOptions.delayMs;
2395
- while (true) {
2396
- let result;
2397
- try {
2398
- result = await cb();
2399
- } catch (err) {
2400
- if (numRetries > fullOptions.count || !await fullOptions.retryOnError(err)) {
2401
- throw err;
2402
- }
2403
- await new Promise((resolve) => setTimeout(resolve, currentDelay));
2404
- currentDelay *= fullOptions.exponent;
2405
- numRetries++;
2406
- continue;
2407
- }
2408
- if (!await fullOptions.retryOnValue(result)) {
2409
- return result;
2410
- }
2411
- await new Promise((resolve) => setTimeout(resolve, currentDelay));
2412
- currentDelay *= fullOptions.exponent;
2413
- numRetries++;
2414
- continue;
2415
- }
2416
- };
2417
2497
  export {
2418
2498
  BitField,
2419
2499
  Callback,
@@ -2441,12 +2521,17 @@ export {
2441
2521
  capitalize,
2442
2522
  chunkArray,
2443
2523
  clamp,
2524
+ clearCaches,
2525
+ clearIndexedDB,
2526
+ clearOPFS,
2527
+ clearServiceWorkers,
2444
2528
  clearUndefined,
2445
2529
  coerceArray,
2446
2530
  compareMulti,
2447
2531
  compareObject,
2448
2532
  compareScalar,
2449
2533
  compareString,
2534
+ compositeKey,
2450
2535
  createBinder,
2451
2536
  createBucketReducer,
2452
2537
  createFilename,
@@ -2470,7 +2555,6 @@ export {
2470
2555
  exponentialBackoffInterval,
2471
2556
  forEachAsync,
2472
2557
  formatErrorWithCauses,
2473
- get,
2474
2558
  getAsyncProviderValue,
2475
2559
  getDate,
2476
2560
  getDebugName,
@@ -2534,9 +2618,10 @@ export {
2534
2618
  safeParseInt,
2535
2619
  safeParseJson,
2536
2620
  safeStringify,
2537
- set,
2621
+ safeUrl,
2538
2622
  setDeep,
2539
2623
  sortKeys,
2624
+ splitCompositeKey,
2540
2625
  stringToArray,
2541
2626
  stringifyTree,
2542
2627
  stripUndefined,