@dxos/util 0.8.4-main.fffef41 → 0.8.4-staging.ac66bdf99f

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 (75) hide show
  1. package/dist/lib/browser/index.mjs +311 -70
  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 +311 -70
  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.d.ts +3 -2
  8. package/dist/types/src/array.d.ts.map +1 -1
  9. package/dist/types/src/browser-storage.d.ts +9 -0
  10. package/dist/types/src/browser-storage.d.ts.map +1 -0
  11. package/dist/types/src/circular-buffer.d.ts +1 -0
  12. package/dist/types/src/circular-buffer.d.ts.map +1 -1
  13. package/dist/types/src/complex.d.ts +15 -0
  14. package/dist/types/src/complex.d.ts.map +1 -1
  15. package/dist/types/src/composite-key.d.ts +10 -0
  16. package/dist/types/src/composite-key.d.ts.map +1 -0
  17. package/dist/types/src/composite-key.test.d.ts +2 -0
  18. package/dist/types/src/composite-key.test.d.ts.map +1 -0
  19. package/dist/types/src/deep.d.ts +0 -3
  20. package/dist/types/src/deep.d.ts.map +1 -1
  21. package/dist/types/src/defer.d.ts +1 -1
  22. package/dist/types/src/defer.d.ts.map +1 -1
  23. package/dist/types/src/di-key.d.ts +7 -5
  24. package/dist/types/src/di-key.d.ts.map +1 -1
  25. package/dist/types/src/error-format.d.ts +5 -0
  26. package/dist/types/src/error-format.d.ts.map +1 -0
  27. package/dist/types/src/filename.d.ts +9 -0
  28. package/dist/types/src/filename.d.ts.map +1 -0
  29. package/dist/types/src/index.d.ts +5 -0
  30. package/dist/types/src/index.d.ts.map +1 -1
  31. package/dist/types/src/platform.d.ts +4 -1
  32. package/dist/types/src/platform.d.ts.map +1 -1
  33. package/dist/types/src/retry.d.ts +32 -0
  34. package/dist/types/src/retry.d.ts.map +1 -0
  35. package/dist/types/src/safe-parse.d.ts +7 -4
  36. package/dist/types/src/safe-parse.d.ts.map +1 -1
  37. package/dist/types/src/safe-stringify.d.ts +10 -1
  38. package/dist/types/src/safe-stringify.d.ts.map +1 -1
  39. package/dist/types/src/safe-stringify.test.d.ts +2 -0
  40. package/dist/types/src/safe-stringify.test.d.ts.map +1 -0
  41. package/dist/types/src/to-fallback.d.ts +18 -4
  42. package/dist/types/src/to-fallback.d.ts.map +1 -1
  43. package/dist/types/src/types.d.ts +23 -5
  44. package/dist/types/src/types.d.ts.map +1 -1
  45. package/dist/types/src/unit.d.ts.map +1 -1
  46. package/dist/types/src/weak.d.ts +15 -0
  47. package/dist/types/src/weak.d.ts.map +1 -1
  48. package/dist/types/tsconfig.tsbuildinfo +1 -1
  49. package/package.json +11 -10
  50. package/src/array.ts +9 -2
  51. package/src/browser-storage.ts +60 -0
  52. package/src/circular-buffer.test.ts +26 -0
  53. package/src/circular-buffer.ts +5 -0
  54. package/src/complex.ts +32 -0
  55. package/src/composite-key.test.ts +31 -0
  56. package/src/composite-key.ts +16 -0
  57. package/src/deep.ts +2 -6
  58. package/src/defer.ts +1 -1
  59. package/src/di-key.ts +10 -8
  60. package/src/error-format.ts +22 -0
  61. package/src/filename.ts +16 -0
  62. package/src/index.ts +5 -0
  63. package/src/platform.ts +35 -3
  64. package/src/retry.ts +74 -0
  65. package/src/safe-parse.ts +27 -16
  66. package/src/safe-stringify.test.ts +96 -0
  67. package/src/safe-stringify.ts +74 -25
  68. package/src/to-fallback.ts +39 -156
  69. package/src/types.test.ts +11 -1
  70. package/src/types.ts +39 -11
  71. package/src/unit.ts +1 -0
  72. package/src/weak.ts +52 -14
  73. package/dist/types/src/explicit-resource-management-polyfill.d.ts +0 -1
  74. package/dist/types/src/explicit-resource-management-polyfill.d.ts.map +0 -1
  75. 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) {
@@ -179,6 +187,49 @@ var BitField = class _BitField {
179
187
  }
180
188
  };
181
189
 
190
+ // src/browser-storage.ts
191
+ var clearIndexedDB = async () => {
192
+ const dbs = await indexedDB.databases();
193
+ const results = await Promise.allSettled(dbs.filter((db) => db.name != null).map((db) => new Promise((resolve, reject) => {
194
+ const request = indexedDB.deleteDatabase(db.name);
195
+ request.onsuccess = () => resolve();
196
+ request.onerror = () => reject(request.error);
197
+ request.onblocked = () => reject(new Error(`IndexedDB deletion blocked: ${db.name}`));
198
+ })));
199
+ const failures = results.filter((r) => r.status === "rejected");
200
+ if (failures.length > 0) {
201
+ throw new AggregateError(failures.map((r) => r.reason), "Failed to delete some IndexedDB databases");
202
+ }
203
+ };
204
+ var clearOPFS = async () => {
205
+ const root = await navigator.storage.getDirectory();
206
+ const errors = [];
207
+ for await (const [name] of root.entries()) {
208
+ try {
209
+ await root.removeEntry(name, {
210
+ recursive: true
211
+ });
212
+ } catch (err) {
213
+ errors.push(err);
214
+ }
215
+ }
216
+ if (errors.length > 0) {
217
+ throw new AggregateError(errors, "Failed to remove some OPFS entries");
218
+ }
219
+ };
220
+ var clearServiceWorkers = async () => {
221
+ const regs = await navigator.serviceWorker.getRegistrations();
222
+ for (const reg of regs) {
223
+ await reg.unregister();
224
+ }
225
+ };
226
+ var clearCaches = async () => {
227
+ const keys2 = await caches.keys();
228
+ for (const key of keys2) {
229
+ await caches.delete(key);
230
+ }
231
+ };
232
+
182
233
  // src/callback-collection.ts
183
234
  var CallbackCollection = class {
184
235
  #callbacks = [];
@@ -327,6 +378,10 @@ var CircularBuffer = class {
327
378
  get elementCount() {
328
379
  return this._elementCount;
329
380
  }
381
+ clear() {
382
+ this._nextIndex = 0;
383
+ this._elementCount = 0;
384
+ }
330
385
  getLast() {
331
386
  if (this._elementCount === 0) {
332
387
  return void 0;
@@ -520,6 +575,36 @@ var ComplexMap = class _ComplexMap {
520
575
  this._values.set(primitive, value);
521
576
  return this;
522
577
  }
578
+ /**
579
+ * Returns the value for the given key if present, otherwise inserts and returns the default value.
580
+ * @param key - The key to look up or insert.
581
+ * @param defaultValue - The value to insert if the key is not present.
582
+ * @returns The existing or newly inserted value.
583
+ */
584
+ getOrInsert(key, defaultValue) {
585
+ const primitive = this._keyProjection(key);
586
+ if (this._values.has(primitive)) {
587
+ return this._values.get(primitive);
588
+ }
589
+ this.set(key, defaultValue);
590
+ return defaultValue;
591
+ }
592
+ /**
593
+ * Returns the value for the given key if present, otherwise computes, inserts, and returns a new value.
594
+ * The callback is only invoked when the key is missing.
595
+ * @param key - The key to look up or insert.
596
+ * @param callbackfn - Function to compute the value if the key is not present.
597
+ * @returns The existing or newly computed value.
598
+ */
599
+ getOrInsertComputed(key, callbackfn) {
600
+ const primitive = this._keyProjection(key);
601
+ if (this._values.has(primitive)) {
602
+ return this._values.get(primitive);
603
+ }
604
+ const value = callbackfn(key);
605
+ this.set(key, value);
606
+ return value;
607
+ }
523
608
  get size() {
524
609
  return this._keys.size;
525
610
  }
@@ -559,15 +644,18 @@ var makeMap = (keyProjection) => class BoundComplexMap extends ComplexMap {
559
644
  }
560
645
  };
561
646
 
647
+ // src/composite-key.ts
648
+ var SEPARATOR = ":";
649
+ var compositeKey = (...parts) => parts.join(SEPARATOR);
650
+ var splitCompositeKey = (key) => key.split(SEPARATOR);
651
+
562
652
  // src/deep.ts
563
- import get from "lodash.get";
564
- import set from "lodash.set";
565
653
  import { invariant as invariant4 } from "@dxos/invariant";
566
654
  var __dxlog_file4 = "/__w/dxos/dxos/packages/common/util/src/deep.ts";
567
655
  var setDeep = (obj, path, value) => {
568
656
  invariant4(path.length > 0, void 0, {
569
657
  F: __dxlog_file4,
570
- L: 18,
658
+ L: 12,
571
659
  S: void 0,
572
660
  A: [
573
661
  "path.length > 0",
@@ -597,6 +685,7 @@ var getDeep = (obj, path) => {
597
685
  var deferFunction = (fnProvider) => (...args) => fnProvider()(...args);
598
686
 
599
687
  // src/defer.ts
688
+ import "@hazae41/symbol-dispose-polyfill";
600
689
  var defer = (fn) => new DeferGuard(fn);
601
690
  var DeferGuard = class {
602
691
  _fn;
@@ -657,6 +746,27 @@ var MapEntry = class {
657
746
  }
658
747
  };
659
748
 
749
+ // src/error-format.ts
750
+ var formatErrorWithCauses = (error) => {
751
+ const lines = [];
752
+ let current = error;
753
+ let level = 0;
754
+ while (current) {
755
+ const prefix = level === 0 ? "" : `Caused by: `;
756
+ lines.push(prefix + (current.stack ?? String(current)));
757
+ if (!(current.cause instanceof Error)) break;
758
+ current = current.cause;
759
+ level += 1;
760
+ }
761
+ return lines.join("\n\n");
762
+ };
763
+
764
+ // src/filename.ts
765
+ var createFilename = ({ parts = [], ext, date = /* @__PURE__ */ new Date() }) => [
766
+ date.toISOString().replace(/[:.]/g, "-"),
767
+ ...parts
768
+ ].join("_") + (ext ? `.${ext}` : "");
769
+
660
770
  // src/for-each-async.ts
661
771
  var forEachAsync = (items, fn) => Promise.all(items.map(fn));
662
772
 
@@ -1003,7 +1113,7 @@ var defaultMap = (map, key, def) => {
1003
1113
  };
1004
1114
 
1005
1115
  // src/instance-id.ts
1006
- var symbol = Symbol.for("dxos.instance-contexts");
1116
+ var symbol = /* @__PURE__ */ Symbol.for("dxos.instance-contexts");
1007
1117
  var instanceContexts = globalThis[symbol] ??= /* @__PURE__ */ new WeakMap();
1008
1118
  var getPrototypeSpecificInstanceId = (instance) => {
1009
1119
  const prototype = Object.getPrototypeOf(instance);
@@ -1352,7 +1462,18 @@ var omit = (obj, keys2) => {
1352
1462
 
1353
1463
  // src/platform.ts
1354
1464
  var isNode = () => typeof process !== "undefined" && process.versions != null && process.versions.node != null;
1355
- var mobileAndTabletCheck = () => {
1465
+ var isBun = () => globalThis.Bun !== void 0;
1466
+ var isTauri = () => !!globalThis.__TAURI__;
1467
+ var isMobile = () => {
1468
+ let check = false;
1469
+ (function(a) {
1470
+ 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))) {
1471
+ check = true;
1472
+ }
1473
+ })(navigator.userAgent || navigator.vendor || window.opera);
1474
+ return check;
1475
+ };
1476
+ var isMobileOrTablet = () => {
1356
1477
  let check = false;
1357
1478
  ((a) => {
1358
1479
  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 +1495,7 @@ var iosCheck = () => {
1374
1495
  };
1375
1496
  var safariCheck = () => typeof navigator !== "undefined" && /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
1376
1497
  var getHostPlatform = () => {
1377
- if (!("navigator" in window)) {
1498
+ if (!("navigator" in globalThis)) {
1378
1499
  return "unknown";
1379
1500
  }
1380
1501
  const platform = (navigator.userAgentData?.platform || navigator.platform)?.toLowerCase();
@@ -1550,6 +1671,43 @@ var removeProperties = (root, condition) => {
1550
1671
  return result;
1551
1672
  };
1552
1673
 
1674
+ // src/retry.ts
1675
+ var DEFAULT_RETRY_OPTIONS = {
1676
+ count: 3,
1677
+ delayMs: 100,
1678
+ exponent: 2,
1679
+ retryOnError: async () => true,
1680
+ retryOnValue: async () => false
1681
+ };
1682
+ var retry = async (options, cb) => {
1683
+ const fullOptions = {
1684
+ ...DEFAULT_RETRY_OPTIONS,
1685
+ ...options
1686
+ };
1687
+ let numRetries = 0, currentDelay = fullOptions.delayMs;
1688
+ while (true) {
1689
+ let result;
1690
+ try {
1691
+ result = await cb();
1692
+ } catch (err) {
1693
+ if (numRetries > fullOptions.count || !await fullOptions.retryOnError(err)) {
1694
+ throw err;
1695
+ }
1696
+ await new Promise((resolve) => setTimeout(resolve, currentDelay));
1697
+ currentDelay *= fullOptions.exponent;
1698
+ numRetries++;
1699
+ continue;
1700
+ }
1701
+ if (!await fullOptions.retryOnValue(result)) {
1702
+ return result;
1703
+ }
1704
+ await new Promise((resolve) => setTimeout(resolve, currentDelay));
1705
+ currentDelay *= fullOptions.exponent;
1706
+ numRetries++;
1707
+ continue;
1708
+ }
1709
+ };
1710
+
1553
1711
  // src/safe-await.ts
1554
1712
  var safeAwaitAll = async (source, taskFactory, onError) => {
1555
1713
  const failedItems = [];
@@ -1569,7 +1727,7 @@ var safeAwaitAll = async (source, taskFactory, onError) => {
1569
1727
  };
1570
1728
 
1571
1729
  // src/safe-instanceof.ts
1572
- var instanceTag = Symbol("instanceTag");
1730
+ var instanceTag = /* @__PURE__ */ Symbol("instanceTag");
1573
1731
  var safeInstanceof = (tag) => (target) => {
1574
1732
  target.prototype[instanceTag] = tag;
1575
1733
  Object.defineProperty(target.prototype, Symbol.hasInstance, {
@@ -1581,57 +1739,88 @@ var safeInstanceof = (tag) => (target) => {
1581
1739
  };
1582
1740
 
1583
1741
  // src/safe-parse.ts
1584
- var safeParseInt = (value, defaultValue) => {
1742
+ function safeParseInt(str, defaultValue) {
1585
1743
  try {
1586
- const n = parseInt(value ?? "");
1587
- return isNaN(n) ? defaultValue : n;
1744
+ const value = parseInt(str ?? "");
1745
+ return isNaN(value) ? defaultValue : value;
1588
1746
  } catch {
1589
1747
  return defaultValue;
1590
1748
  }
1591
- };
1592
- var safeParseFloat = (str, defaultValue) => {
1749
+ }
1750
+ function safeParseFloat(str, defaultValue) {
1593
1751
  try {
1594
- return parseFloat(str);
1752
+ const value = parseFloat(str ?? "");
1753
+ return isNaN(value) ? defaultValue : value;
1595
1754
  } catch {
1596
- return defaultValue ?? 0;
1755
+ return defaultValue;
1597
1756
  }
1598
- };
1599
- var safeParseJson = (data, defaultValue) => {
1600
- if (data && data.length > 0) {
1757
+ }
1758
+ var safeParseJson = (str, defaultValue) => {
1759
+ if (str && str.length > 0) {
1601
1760
  try {
1602
- return JSON.parse(data);
1761
+ return JSON.parse(str);
1603
1762
  } catch {
1604
1763
  }
1605
1764
  }
1606
1765
  return defaultValue;
1607
1766
  };
1767
+ var safeUrl = (str) => {
1768
+ try {
1769
+ return new URL(str ?? "");
1770
+ } catch {
1771
+ return void 0;
1772
+ }
1773
+ };
1608
1774
 
1609
1775
  // src/safe-stringify.ts
1610
1776
  var SKIP = Object.freeze({});
1611
1777
  function safeStringify(obj, filter = defaultFilter, indent = 2) {
1612
- const seen = /* @__PURE__ */ new WeakSet();
1778
+ const seen = /* @__PURE__ */ new WeakMap();
1613
1779
  function replacer(key, value) {
1614
- if (typeof value === "object" && value !== null) {
1615
- if (seen.has(value)) {
1616
- return "[Circular]";
1780
+ try {
1781
+ let path = key;
1782
+ if (!key) {
1783
+ path = "$";
1784
+ if (value != null && typeof value === "object") {
1785
+ seen.set(value, path);
1786
+ }
1787
+ return value;
1788
+ } else if (this) {
1789
+ const parentPath = seen.get(this);
1790
+ path = parentPath ? `${parentPath}.${key}` : key;
1617
1791
  }
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;
1792
+ if (value == null) {
1793
+ return value;
1794
+ }
1795
+ if (typeof value === "function") {
1796
+ return void 0;
1797
+ }
1798
+ if (typeof value === "object" && Object.getPrototypeOf(value) !== Object.prototype && !Array.isArray(value)) {
1799
+ return void 0;
1800
+ }
1801
+ if (typeof value === "object" && value !== null) {
1802
+ const exists = seen.get(value);
1803
+ if (exists) {
1804
+ return `[${path} => ${exists}]`;
1805
+ }
1806
+ seen.set(value, path);
1624
1807
  }
1808
+ if (filter) {
1809
+ const filteredValue = filter?.(key, value);
1810
+ if (filteredValue !== void 0) {
1811
+ return filteredValue === SKIP ? void 0 : filteredValue;
1812
+ }
1813
+ }
1814
+ return value;
1815
+ } catch (error) {
1816
+ return `ERROR: ${error.message}`;
1625
1817
  }
1626
- return value;
1627
1818
  }
1628
- let result = "";
1629
1819
  try {
1630
- result = JSON.stringify(obj, replacer, indent);
1820
+ return JSON.stringify(obj, replacer, indent);
1631
1821
  } catch (error) {
1632
- result = `Error: ${error.message}`;
1822
+ return `ERROR: ${error.message}`;
1633
1823
  }
1634
- return result;
1635
1824
  }
1636
1825
  var createReplacer = ({ omit: omit2, parse, maxDepth, maxArrayLen, maxStringLen } = {}) => {
1637
1826
  let currentDepth = 0;
@@ -1644,7 +1833,10 @@ var createReplacer = ({ omit: omit2, parse, maxDepth, maxArrayLen, maxStringLen
1644
1833
  currentDepth = parentDepth + 1;
1645
1834
  }
1646
1835
  if (typeof value === "function") {
1647
- return void 0;
1836
+ return SKIP;
1837
+ }
1838
+ if (maxArrayLen != null && Array.isArray(value) && value.length > maxArrayLen) {
1839
+ return `[length: ${value.length}]`;
1648
1840
  }
1649
1841
  if (value && typeof value === "object") {
1650
1842
  depthMap.set(value, currentDepth);
@@ -1653,7 +1845,7 @@ var createReplacer = ({ omit: omit2, parse, maxDepth, maxArrayLen, maxStringLen
1653
1845
  }
1654
1846
  }
1655
1847
  if (omit2?.includes(key)) {
1656
- return void 0;
1848
+ return SKIP;
1657
1849
  }
1658
1850
  if (parse?.includes(key) && typeof value === "string") {
1659
1851
  try {
@@ -1662,9 +1854,6 @@ var createReplacer = ({ omit: omit2, parse, maxDepth, maxArrayLen, maxStringLen
1662
1854
  return value;
1663
1855
  }
1664
1856
  }
1665
- if (maxArrayLen != null && Array.isArray(value) && value.length > maxArrayLen) {
1666
- return `[length: ${value.length}]`;
1667
- }
1668
1857
  if (maxStringLen != null && typeof value === "string" && value.length > maxStringLen) {
1669
1858
  return value.slice(0, maxStringLen) + "...";
1670
1859
  }
@@ -1791,18 +1980,6 @@ var throwUnhandledError = (error) => {
1791
1980
 
1792
1981
  // src/to-fallback.ts
1793
1982
  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
1983
  "\u{1F47B}",
1807
1984
  "\u{1F479}",
1808
1985
  "\u{1F47D}",
@@ -1938,17 +2115,18 @@ var idEmoji = [
1938
2115
  ];
1939
2116
  var idHue = [
1940
2117
  "red",
1941
- // 'orange' as const, /* More shades in these palettes are considered “ugly” */
2118
+ "orange",
1942
2119
  "amber",
1943
- // 'yellow' as const, /* More shades in these palettes are considered “ugly” */
2120
+ "yellow",
1944
2121
  "lime",
1945
2122
  "green",
1946
2123
  "emerald",
1947
2124
  "teal",
1948
2125
  "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 */
2126
+ // Omit colors similar to primary accent.
2127
+ // 'sky' as const,
2128
+ // 'blue' as const,
2129
+ // 'indigo' as const,
1952
2130
  "violet",
1953
2131
  "purple",
1954
2132
  "fuchsia",
@@ -2108,6 +2286,12 @@ var arrayMove = (array, from, to) => {
2108
2286
  array.splice(to < 0 ? array.length + to : to, 0, array.splice(from, 1)[0]);
2109
2287
  return array;
2110
2288
  };
2289
+ function arraySwap(array, from, to) {
2290
+ const current = array[from];
2291
+ array[from] = array[to];
2292
+ array[to] = current;
2293
+ return array;
2294
+ }
2111
2295
 
2112
2296
  // src/unit.ts
2113
2297
  var createFormat = (unit) => {
@@ -2152,6 +2336,10 @@ var Unit = {
2152
2336
  quotient: 1e3,
2153
2337
  precision: 2
2154
2338
  }),
2339
+ Byte: createFormat({
2340
+ symbol: "B",
2341
+ quotient: 1
2342
+ }),
2155
2343
  // Time.
2156
2344
  Hour: createFormat({
2157
2345
  symbol: "h",
@@ -2218,15 +2406,19 @@ var createUrl = (url, search) => {
2218
2406
  // src/weak.ts
2219
2407
  var WeakDictionary = class {
2220
2408
  _internal = /* @__PURE__ */ new Map();
2221
- _finalization = new FinalizationRegistry((cleanUpCallback) => {
2222
- cleanUpCallback();
2409
+ _finalization = new FinalizationRegistry(({ key, ref }) => {
2410
+ if (this._internal.get(key) === ref) {
2411
+ this._internal.delete(key);
2412
+ }
2223
2413
  });
2224
2414
  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));
2415
+ if (entries2) {
2416
+ for (const [key, value] of entries2) {
2417
+ const ref = new WeakRef(value);
2418
+ this._internal.set(key, ref);
2419
+ this._register(key, value, ref);
2420
+ }
2421
+ }
2230
2422
  }
2231
2423
  *entries() {
2232
2424
  for (const [key, value] of this._internal) {
@@ -2266,10 +2458,45 @@ var WeakDictionary = class {
2266
2458
  return this._internal.get(key)?.deref();
2267
2459
  }
2268
2460
  set(key, value) {
2269
- this._internal.set(key, new WeakRef(value));
2270
- this._register(key, value);
2461
+ const previous = this._internal.get(key)?.deref();
2462
+ if (previous) {
2463
+ this._unregister(previous);
2464
+ }
2465
+ const ref = new WeakRef(value);
2466
+ this._internal.set(key, ref);
2467
+ this._register(key, value, ref);
2271
2468
  return this;
2272
2469
  }
2470
+ /**
2471
+ * Returns the value for the given key if present, otherwise inserts and returns the default value.
2472
+ * @param key - The key to look up or insert.
2473
+ * @param defaultValue - The value to insert if the key is not present.
2474
+ * @returns The existing or newly inserted value.
2475
+ */
2476
+ getOrInsert(key, defaultValue) {
2477
+ const existing = this.get(key);
2478
+ if (existing !== void 0) {
2479
+ return existing;
2480
+ }
2481
+ this.set(key, defaultValue);
2482
+ return defaultValue;
2483
+ }
2484
+ /**
2485
+ * Returns the value for the given key if present, otherwise computes, inserts, and returns a new value.
2486
+ * The callback is only invoked when the key is missing.
2487
+ * @param key - The key to look up or insert.
2488
+ * @param callbackfn - Function to compute the value if the key is not present.
2489
+ * @returns The existing or newly computed value.
2490
+ */
2491
+ getOrInsertComputed(key, callbackfn) {
2492
+ const existing = this.get(key);
2493
+ if (existing !== void 0) {
2494
+ return existing;
2495
+ }
2496
+ const value = callbackfn(key);
2497
+ this.set(key, value);
2498
+ return value;
2499
+ }
2273
2500
  has(key) {
2274
2501
  return this._internal.has(key) && this._internal.get(key).deref() !== void 0;
2275
2502
  }
@@ -2300,9 +2527,10 @@ var WeakDictionary = class {
2300
2527
  }
2301
2528
  });
2302
2529
  }
2303
- _register(key, value) {
2304
- this._finalization.register(value, () => {
2305
- this._internal.delete(key);
2530
+ _register(key, value, ref) {
2531
+ this._finalization.register(value, {
2532
+ key,
2533
+ ref
2306
2534
  }, value);
2307
2535
  }
2308
2536
  _unregister(value) {
@@ -2325,6 +2553,7 @@ export {
2325
2553
  WeakDictionary,
2326
2554
  accessBy,
2327
2555
  arrayMove,
2556
+ arraySwap,
2328
2557
  arrayToBuffer,
2329
2558
  arrayToHex,
2330
2559
  arrayToString,
@@ -2335,13 +2564,20 @@ export {
2335
2564
  capitalize,
2336
2565
  chunkArray,
2337
2566
  clamp,
2567
+ clearCaches,
2568
+ clearIndexedDB,
2569
+ clearOPFS,
2570
+ clearServiceWorkers,
2338
2571
  clearUndefined,
2572
+ coerceArray,
2339
2573
  compareMulti,
2340
2574
  compareObject,
2341
2575
  compareScalar,
2342
2576
  compareString,
2577
+ compositeKey,
2343
2578
  createBinder,
2344
2579
  createBucketReducer,
2580
+ createFilename,
2345
2581
  createGroupReducer,
2346
2582
  createReplacer,
2347
2583
  createSetDispatch,
@@ -2361,7 +2597,7 @@ export {
2361
2597
  entry,
2362
2598
  exponentialBackoffInterval,
2363
2599
  forEachAsync,
2364
- get,
2600
+ formatErrorWithCauses,
2365
2601
  getAsyncProviderValue,
2366
2602
  getDate,
2367
2603
  getDebugName,
@@ -2381,8 +2617,12 @@ export {
2381
2617
  intersectBy,
2382
2618
  intersection,
2383
2619
  iosCheck,
2620
+ isBun,
2621
+ isMobile,
2622
+ isMobileOrTablet,
2384
2623
  isNode,
2385
2624
  isNonNullable,
2625
+ isTauri,
2386
2626
  isTruthy,
2387
2627
  joinTables,
2388
2628
  jsonKeyReplacer,
@@ -2398,7 +2638,6 @@ export {
2398
2638
  makeSet,
2399
2639
  mapValues,
2400
2640
  median,
2401
- mobileAndTabletCheck,
2402
2641
  numericalValues,
2403
2642
  omit,
2404
2643
  orderKeys,
@@ -2414,6 +2653,7 @@ export {
2414
2653
  removeBy,
2415
2654
  removeProperties,
2416
2655
  removeUndefinedProperties,
2656
+ retry,
2417
2657
  safariCheck,
2418
2658
  safeAwaitAll,
2419
2659
  safeInstanceof,
@@ -2421,9 +2661,10 @@ export {
2421
2661
  safeParseInt,
2422
2662
  safeParseJson,
2423
2663
  safeStringify,
2424
- set,
2664
+ safeUrl,
2425
2665
  setDeep,
2426
2666
  sortKeys,
2667
+ splitCompositeKey,
2427
2668
  stringToArray,
2428
2669
  stringifyTree,
2429
2670
  stripUndefined,