@andrew_l/toolkit 0.3.2 → 0.3.3

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.
package/dist/index.mjs CHANGED
@@ -169,6 +169,9 @@ const primitiveTypeofSet = Object.freeze(
169
169
  const isPrimitive = (value) => {
170
170
  return value === null || primitiveTypeofSet.has(typeof value);
171
171
  };
172
+ function isNode() {
173
+ return typeof globalThis?.process !== "undefined" && process?.versions?.node != null;
174
+ }
172
175
 
173
176
  function arrayable(value) {
174
177
  const result = Array.isArray(value) ? value : value === null ? [] : value === void 0 ? [] : isString(value) ? value.split(",").map((v) => v.trim()).filter(Boolean) : [value];
@@ -280,13 +283,50 @@ function groupBy(array, keyBy, objectMode) {
280
283
 
281
284
  function intersection(...arrays) {
282
285
  if (arrays.length === 0) return [];
283
- if (arrays.length === 1) return arrays[0];
286
+ if (arrays.length === 1) return [...arrays[0]];
284
287
  return arrays.reduce((acc, curr) => {
285
288
  const set = new Set(curr);
286
289
  return acc.filter((item) => set.has(item));
287
290
  });
288
291
  }
289
292
 
293
+ function intersectionBy(keyBy, ...arrays) {
294
+ var arraysLength = arrays.length;
295
+ if (arraysLength === 0) return [];
296
+ if (arraysLength === 1) return [...arrays[0]];
297
+ var getItemKey = isFunction(keyBy) ? keyBy : (item) => item?.[keyBy];
298
+ arrays = arrays.toSorted((a, b) => a.length - b.length);
299
+ var arrayLengths = [arraysLength];
300
+ var arrayIndices = [0];
301
+ var arraySets = [/* @__PURE__ */ new Set()];
302
+ var key1, key2;
303
+ var i;
304
+ for (i = 1; i < arraysLength; i++) {
305
+ arrayLengths[i] = arrays[i].length;
306
+ arrayIndices[i] = 0;
307
+ arraySets[i] = /* @__PURE__ */ new Set();
308
+ }
309
+ return arrays[0].filter((item) => {
310
+ key1 = getItemKey(item);
311
+ if (arraySets[0].has(key1)) return false;
312
+ arraySets[0].add(key1);
313
+ loop: for (i = 1; i < arraysLength; i++) {
314
+ if (arraySets[i].has(key1)) {
315
+ continue loop;
316
+ }
317
+ for (; arrayIndices[i] < arrayLengths[i]; arrayIndices[i]++) {
318
+ key2 = getItemKey(arrays[i][arrayIndices[i]]);
319
+ arraySets[i].add(key2);
320
+ if (Object.is(key1, key2)) {
321
+ continue loop;
322
+ }
323
+ }
324
+ return false;
325
+ }
326
+ return true;
327
+ });
328
+ }
329
+
290
330
  function keyBy(array, keyBy2, objectMode) {
291
331
  const getItemKey = isFunction(keyBy2) ? keyBy2 : (item) => item?.[keyBy2];
292
332
  if (objectMode === true) {
@@ -813,9 +853,14 @@ class BrowserAssertionError extends Error {
813
853
  }
814
854
 
815
855
  let AssertionError = BrowserAssertionError;
816
- if (!globalThis.window) {
817
- import('node:assert').then((r) => AssertionError = r.AssertionError).catch(() => {
818
- });
856
+ if (isNode()) {
857
+ try {
858
+ const assert = require("node:assert");
859
+ if (assert.AssertionError) {
860
+ AssertionError = assert.AssertionError;
861
+ }
862
+ } catch {
863
+ }
819
864
  }
820
865
 
821
866
  function ok(value, message) {
@@ -1749,178 +1794,539 @@ function uint8ToUint32(value) {
1749
1794
  return uint32Array;
1750
1795
  }
1751
1796
 
1752
- const objectKeys = /* @__PURE__ */ new WeakMap();
1753
- const BSON_TYPES = Object.freeze(/* @__PURE__ */ new Set(["ObjectID", "ObjectId"]));
1754
- const SYM_WITH_CACHE = Symbol();
1755
- const argToKey = (value, options = { objectStrategy: "ref" }) => {
1756
- let result = "";
1757
- if (isObject(value)) {
1758
- if (BSON_TYPES.has(value?._bsontype)) {
1759
- return String(value);
1760
- }
1761
- let key;
1762
- if (options.objectStrategy === "json") {
1763
- key = JSON.stringify(value);
1764
- } else {
1765
- key = objectKeys.get(value);
1766
- if (!key) {
1767
- key = createRadomKey();
1768
- objectKeys.set(value, key);
1769
- }
1797
+ const DateType = {
1798
+ placeholder: "$date",
1799
+ encode: (value) => {
1800
+ if (value instanceof Date) {
1801
+ return value.getTime();
1770
1802
  }
1771
- return key;
1772
- } else if (Array.isArray(value)) {
1773
- result += value.map((v) => argToKey(v, options)).join("/");
1774
- } else {
1775
- result = String(value);
1803
+ },
1804
+ decode(value) {
1805
+ return new Date(value);
1776
1806
  }
1777
- return result;
1778
1807
  };
1779
- function createRadomKey() {
1780
- return Date.now() + "_" + randomString(16);
1781
- }
1782
-
1783
- function createWithCache({
1784
- fn,
1785
- getPointer,
1786
- getBucket,
1787
- objectStrategy = "ref"
1788
- }) {
1789
- const isAsync = fn.constructor.name === "AsyncFunction";
1790
- const argToKeyOptions = { objectStrategy };
1791
- const $cache = {
1792
- getBucket: () => getBucket(getPointer()),
1793
- getPointer,
1794
- argToKeyOptions
1795
- };
1796
- const wrapFn = function(...args) {
1797
- const storage = getBucket(getPointer());
1798
- const cacheKey = args.map((v) => argToKey(v, argToKeyOptions)).join("_");
1799
- if (storage.has(cacheKey)) {
1800
- const value = storage.get(cacheKey);
1801
- return isAsync ? Promise.resolve(value) : value;
1808
+ const BinaryType = {
1809
+ placeholder: "$binary",
1810
+ encode: (value) => {
1811
+ if (value instanceof Uint8Array) {
1812
+ return base64.encode(value, { includePadding: true });
1813
+ } else if (value instanceof Uint16Array) {
1814
+ return {
1815
+ value: base64.encode(uint16ToUint8(value), { includePadding: true }),
1816
+ bit: 16
1817
+ };
1818
+ } else if (value instanceof Uint32Array) {
1819
+ return {
1820
+ value: base64.encode(uint32ToUint8(value), { includePadding: true }),
1821
+ bit: 32
1822
+ };
1802
1823
  }
1803
- const newValue = fn.apply(this, args);
1804
- if (isPromise(newValue)) {
1805
- return newValue.then((value) => {
1806
- storage.set(cacheKey, value);
1807
- return value;
1808
- });
1824
+ },
1825
+ decode(value) {
1826
+ if (typeof value === "string") {
1827
+ return base64.decode(value, { strict: true });
1828
+ } else if (value.bit === 16) {
1829
+ return uint8ToUint16(base64.decode(value.value, { strict: true }));
1830
+ } else if (value.bit === 32) {
1831
+ return uint8ToUint32(base64.decode(value.value, { strict: true }));
1809
1832
  }
1810
- storage.set(cacheKey, newValue);
1811
- return newValue;
1812
- };
1813
- wrapFn.$cache = $cache;
1814
- def(wrapFn, SYM_WITH_CACHE, true);
1815
- return wrapFn;
1816
- }
1817
- function isWithCache(value) {
1818
- return !!value && value[SYM_WITH_CACHE] === true;
1819
- }
1820
-
1821
- const cache = /* @__PURE__ */ new WeakMap();
1822
- function withCache(...args) {
1823
- let options = {};
1824
- let fn = noop;
1825
- if (isFunction(args[0])) {
1826
- fn = args[0];
1827
- } else if (isFunction(args[1])) {
1828
- options = args[0] || {};
1829
- fn = args[1];
1833
+ throw new Error("Unexpected $binary bit value: " + value.bit);
1830
1834
  }
1831
- const pointer = options.cachePointer || fn;
1832
- const getPointer = () => pointer;
1833
- const getBucket = (pointer2) => {
1834
- let fnCache = cache.get(pointer2);
1835
- if (!fnCache) {
1836
- fnCache = /* @__PURE__ */ new Map();
1837
- cache.set(pointer2, fnCache);
1835
+ };
1836
+ const BigIntType = {
1837
+ placeholder: "$bigint",
1838
+ encode: (value) => {
1839
+ if (typeof value === "bigint") {
1840
+ return base64.encode(bigIntBytes(value), { includePadding: false });
1838
1841
  }
1839
- return fnCache;
1840
- };
1841
- return createWithCache({
1842
- fn,
1843
- getBucket,
1844
- getPointer,
1845
- ...options
1846
- });
1847
- }
1848
-
1849
- function assertCapacity(value) {
1850
- number$1(value, "capacity must be a number");
1851
- ok(value > 0, "capacity must be more then 0.");
1852
- }
1853
-
1854
- class FixedMap extends Map {
1855
- constructor(_capacity) {
1856
- assertCapacity(_capacity);
1857
- super();
1858
- this._capacity = _capacity;
1859
- this._tail = [];
1842
+ },
1843
+ decode(value) {
1844
+ return bigIntFromBytes(base64.decode(value, { strict: false }));
1860
1845
  }
1861
- _tail;
1862
- set(key, value) {
1863
- if (!super.has.call(this, key)) {
1864
- this._tail.push(key);
1846
+ };
1847
+ const MapType = {
1848
+ placeholder: "$map",
1849
+ encode: (value, encode) => {
1850
+ if (value instanceof Map) {
1851
+ return encode(Array.from(value.entries()));
1865
1852
  }
1866
- super.set.call(this, key, value);
1867
- this._drain();
1868
- return this;
1853
+ },
1854
+ decode(value) {
1855
+ return new Map(value);
1869
1856
  }
1870
- delete(key) {
1871
- const removed = super.delete.call(this, key);
1872
- if (removed) {
1873
- const idx = this._tail.findIndex((v) => v === key);
1874
- if (idx > -1) {
1875
- this._tail.splice(idx, 1);
1876
- }
1857
+ };
1858
+ const SetType = {
1859
+ placeholder: "$set",
1860
+ encode: (value, encode) => {
1861
+ if (value instanceof Set) {
1862
+ return encode(Array.from(value.values()));
1877
1863
  }
1878
- return removed;
1879
- }
1880
- clear() {
1881
- delete this._tail;
1882
- this._tail = [];
1883
- super.clear.call(this);
1884
- }
1885
- get capacity() {
1886
- return this._capacity;
1887
- }
1888
- set capacity(value) {
1889
- assertCapacity(value);
1890
- this._capacity = value;
1891
- this._drain();
1864
+ },
1865
+ decode(value) {
1866
+ return new Set(value);
1892
1867
  }
1893
- _drain() {
1894
- while (this._tail.length > this._capacity) {
1895
- const key = this._tail.shift();
1896
- key !== void 0 && this.delete(key);
1868
+ };
1869
+ const RegexType = {
1870
+ placeholder: "$regex",
1871
+ encode: (value, encode) => {
1872
+ if (value instanceof RegExp) {
1873
+ const regStr = value.toString();
1874
+ const patternStart = regStr.lastIndexOf("/");
1875
+ return {
1876
+ pattern: value.toString().slice(1, patternStart),
1877
+ flags: regStr.slice(patternStart + 1)
1878
+ };
1897
1879
  }
1880
+ },
1881
+ decode(value) {
1882
+ return new RegExp(value.pattern, value.flags);
1898
1883
  }
1899
- }
1900
-
1901
- class TimeBucket {
1902
- _pointer;
1903
- _sizeMs;
1904
- _bucket;
1905
- constructor({ capacity = Infinity, sizeMs }) {
1906
- assetSizeMs(sizeMs);
1907
- this._sizeMs = sizeMs;
1908
- this._pointer = 0;
1909
- this._bucket = capacity === Infinity ? /* @__PURE__ */ new Map() : new FixedMap(capacity);
1910
- }
1911
- get capacity() {
1912
- if (this._bucket instanceof FixedMap) {
1913
- return this._bucket.capacity;
1884
+ };
1885
+ const InfinityType = {
1886
+ placeholder: "$inf",
1887
+ encode: (value, encode) => {
1888
+ if (value === Infinity) {
1889
+ return 1;
1890
+ } else if (value === -Infinity) {
1891
+ return -1;
1914
1892
  }
1915
- return Infinity;
1916
- }
1917
- get sizeMs() {
1918
- return this.sizeMs;
1893
+ },
1894
+ decode(value) {
1895
+ if (value === 1) return Infinity;
1896
+ if (value === -1) return -Infinity;
1897
+ throw new Error("Unexpected $inf value: " + value);
1919
1898
  }
1920
- set sizeMs(value) {
1921
- assetSizeMs(value);
1922
- this._sizeMs = value;
1923
- this._drainBucket();
1899
+ };
1900
+
1901
+ class EJSON {
1902
+ /** @internal */
1903
+ typeHandlers = /* @__PURE__ */ new Map();
1904
+ /** @internal */
1905
+ replacerReady;
1906
+ /** @internal */
1907
+ encode;
1908
+ /** @internal */
1909
+ reviewerReady;
1910
+ /** @internal */
1911
+ pure = true;
1912
+ _vendorName = null;
1913
+ /**
1914
+ * MIME type based on the provided vendor name or defaults to 'application/json'.
1915
+ */
1916
+ mimetype = "application/json";
1917
+ Type = {
1918
+ Date: DateType,
1919
+ Map: MapType,
1920
+ Set: SetType,
1921
+ RegExp: RegexType,
1922
+ Infinity: InfinityType,
1923
+ BigInt: BigIntType,
1924
+ Binary: BinaryType
1925
+ };
1926
+ constructor() {
1927
+ this.replacerReady = this._replacer.bind(this);
1928
+ this.reviewerReady = this._reviewer.bind(this);
1929
+ this.encode = (value) => {
1930
+ return deepCloneWith(value, this.replacerReady);
1931
+ };
1932
+ }
1933
+ /**
1934
+ * The vendor name used for the custom MIME type definition.
1935
+ * If null, defaults to 'application/json'.
1936
+ */
1937
+ get vendorName() {
1938
+ return this._vendorName;
1939
+ }
1940
+ set vendorName(value) {
1941
+ this._vendorName = value;
1942
+ if (!value) {
1943
+ this.mimetype = "application/json";
1944
+ } else {
1945
+ const vendorName = value.split(" ").map((v) => v.toLowerCase()).join(".").replace(/\.\.+/g, ".").replace(/\.$/, "");
1946
+ this.mimetype = `application/vnd.${vendorName}+json`;
1947
+ }
1948
+ }
1949
+ /**
1950
+ * Adds a custom type handler for encoding/decoding logic.
1951
+ * Ensures type placeholders are unique and adhere to conventions.
1952
+ */
1953
+ addType(type) {
1954
+ ok(
1955
+ !this.typeHandlers.has(type.placeholder),
1956
+ `type with ${type.placeholder} already taken.`
1957
+ );
1958
+ ok(
1959
+ type.placeholder.startsWith("$"),
1960
+ "type placeholder must starts with $ symbol."
1961
+ );
1962
+ this.pure = false;
1963
+ this.typeHandlers.set(type.placeholder, type);
1964
+ return this;
1965
+ }
1966
+ /**
1967
+ * Stringifies a JavaScript value using custom encoding logic.
1968
+ * @param {any} value - The value to encode and stringify.
1969
+ * @param {string | number} [space] - Optional space for pretty-printing.
1970
+ * @returns {string} - The JSON stringified value.
1971
+ */
1972
+ stringify(value, space) {
1973
+ if (this.pure) {
1974
+ return JSON.stringify(value, void 0, space);
1975
+ }
1976
+ return JSON.stringify(this.encode(value), void 0, space);
1977
+ }
1978
+ /**
1979
+ * Parses a JSON string using custom decoding logic.
1980
+ * @param {string} value - The JSON string to parse.
1981
+ * @returns {any} - The decoded JavaScript object.
1982
+ */
1983
+ parse(value) {
1984
+ if (this.pure) {
1985
+ return JSON.parse(value);
1986
+ }
1987
+ return JSON.parse(value, this.reviewerReady);
1988
+ }
1989
+ /** @internal */
1990
+ _replacer(value, key) {
1991
+ if (isPlainObject(value)) return;
1992
+ if (Array.isArray(value)) return;
1993
+ if (!isInfinity(value) && !isBigInt(value)) {
1994
+ if (isPrimitive(value)) return;
1995
+ }
1996
+ for (const type of this.typeHandlers.values()) {
1997
+ const res = type.encode(value, this.encode);
1998
+ if (res !== void 0) {
1999
+ return type.encodeInline ? res : { [type.placeholder]: res };
2000
+ }
2001
+ }
2002
+ return value;
2003
+ }
2004
+ /** @internal */
2005
+ _reviewer(_, value) {
2006
+ const key = firstKey(value);
2007
+ if (!key || key[0] !== "$") return value;
2008
+ const type = this.typeHandlers.get(key);
2009
+ if (type) {
2010
+ return type.decode(value[key]);
2011
+ }
2012
+ return value;
2013
+ }
2014
+ }
2015
+ function firstKey(value) {
2016
+ if (!isObject(value)) return null;
2017
+ for (const key in value) {
2018
+ return key;
2019
+ }
2020
+ return null;
2021
+ }
2022
+
2023
+ function createEJSON(withBasicTypes = false) {
2024
+ const ejson = new EJSON();
2025
+ if (withBasicTypes) {
2026
+ ejson.addType(MapType);
2027
+ ejson.addType(SetType);
2028
+ ejson.addType(DateType);
2029
+ ejson.addType(InfinityType);
2030
+ ejson.addType(BigIntType);
2031
+ ejson.addType(BinaryType);
2032
+ ejson.addType(RegexType);
2033
+ }
2034
+ return ejson;
2035
+ }
2036
+
2037
+ class EJSONStream extends TransformStream {
2038
+ ejson;
2039
+ constructor({ ejson, cl, op, sep, onFlush, onStart }) {
2040
+ let firstChunk = true;
2041
+ super({
2042
+ start(controller) {
2043
+ return Promise.resolve().then(() => {
2044
+ if (onStart) {
2045
+ return onStart(controller);
2046
+ }
2047
+ }).then(() => {
2048
+ controller.enqueue(op);
2049
+ });
2050
+ },
2051
+ transform(chunk, controller) {
2052
+ const jsonString = ejson.stringify(chunk);
2053
+ if (firstChunk) {
2054
+ firstChunk = false;
2055
+ } else {
2056
+ controller.enqueue(sep);
2057
+ }
2058
+ controller.enqueue(jsonString);
2059
+ },
2060
+ flush(controller) {
2061
+ controller.enqueue(cl);
2062
+ if (onFlush) {
2063
+ return onFlush(controller);
2064
+ }
2065
+ }
2066
+ });
2067
+ this.ejson = ejson;
2068
+ }
2069
+ /**
2070
+ * The vendor name used for the custom MIME type definition.
2071
+ * If null, defaults to 'application/json'.
2072
+ */
2073
+ get vendorName() {
2074
+ return this.ejson.vendorName;
2075
+ }
2076
+ /**
2077
+ * MIME type based on the provided vendor name or defaults to 'application/json'.
2078
+ */
2079
+ get mimetype() {
2080
+ return this.ejson.mimetype;
2081
+ }
2082
+ }
2083
+
2084
+ const instance = createEJSON(true);
2085
+
2086
+ function createEJSONStream(options = {}) {
2087
+ if (options.resultKey || options.append || options.prepend) {
2088
+ return createEJSONStreamPayload(options);
2089
+ }
2090
+ return new EJSONStream(getOptions(options));
2091
+ }
2092
+ function createEJSONStreamPayload(options) {
2093
+ let { cl, ejson, op, sep } = getOptions(options);
2094
+ const { append, prepend, resultKey } = options;
2095
+ notEmptyString(resultKey, "resultKey required.");
2096
+ const stream = new EJSONStream({
2097
+ ejson,
2098
+ cl,
2099
+ op,
2100
+ sep,
2101
+ onStart(controller) {
2102
+ if (!prepend) {
2103
+ controller.enqueue(`{"${resultKey}":`);
2104
+ return Promise.resolve();
2105
+ }
2106
+ return Promise.resolve().then(() => prepend()).then((data) => {
2107
+ if (data === null || data === void 0) {
2108
+ controller.enqueue(`{"${resultKey}":`);
2109
+ return;
2110
+ }
2111
+ ok(
2112
+ isPlainObject(data),
2113
+ "prepend result expected to be plain object"
2114
+ );
2115
+ const dataPart = instance.stringify(data).slice(0, -1);
2116
+ if (dataPart === "{") {
2117
+ controller.enqueue(`{"${resultKey}":`);
2118
+ return;
2119
+ }
2120
+ controller.enqueue(`${dataPart}${sep}"${resultKey}":`);
2121
+ });
2122
+ },
2123
+ onFlush(controller) {
2124
+ if (!append) {
2125
+ controller.enqueue("}");
2126
+ return Promise.resolve();
2127
+ }
2128
+ return Promise.resolve().then(() => append()).then((data) => {
2129
+ if (data === null || data === void 0) {
2130
+ controller.enqueue("}");
2131
+ return;
2132
+ }
2133
+ ok(
2134
+ isPlainObject(data),
2135
+ "prepend result expected to be plain object"
2136
+ );
2137
+ const dataPart = instance.stringify(data).slice(1);
2138
+ if (dataPart === "}") {
2139
+ controller.enqueue(`}`);
2140
+ return;
2141
+ }
2142
+ controller.enqueue(`${sep}${dataPart}`);
2143
+ });
2144
+ }
2145
+ });
2146
+ return stream;
2147
+ }
2148
+ function getOptions(options) {
2149
+ const { ejson = instance, cl = "]", op = "[", sep = "," } = options;
2150
+ return {
2151
+ cl,
2152
+ ejson,
2153
+ op,
2154
+ sep
2155
+ };
2156
+ }
2157
+
2158
+ const objectKeys = /* @__PURE__ */ new WeakMap();
2159
+ const BSON_TYPES = Object.freeze(/* @__PURE__ */ new Set(["ObjectID", "ObjectId"]));
2160
+ const SYM_WITH_CACHE = Symbol();
2161
+ const argToKey = (value, options = { objectStrategy: "ref" }) => {
2162
+ let result = "";
2163
+ if (isObject(value)) {
2164
+ if (BSON_TYPES.has(value?._bsontype)) {
2165
+ return String(value);
2166
+ }
2167
+ let key;
2168
+ if (options.objectStrategy === "json") {
2169
+ key = instance.stringify(value);
2170
+ } else {
2171
+ key = objectKeys.get(value);
2172
+ if (!key) {
2173
+ key = createRadomKey();
2174
+ objectKeys.set(value, key);
2175
+ }
2176
+ }
2177
+ return key;
2178
+ } else if (Array.isArray(value)) {
2179
+ result += value.map((v) => argToKey(v, options)).join("/");
2180
+ } else {
2181
+ result = String(value);
2182
+ }
2183
+ return result;
2184
+ };
2185
+ function createRadomKey() {
2186
+ return Date.now() + "_" + randomString(16);
2187
+ }
2188
+
2189
+ function createWithCache({
2190
+ fn,
2191
+ getPointer,
2192
+ getBucket,
2193
+ objectStrategy = "ref"
2194
+ }) {
2195
+ const isAsync = fn.constructor.name === "AsyncFunction";
2196
+ const argToKeyOptions = { objectStrategy };
2197
+ const $cache = {
2198
+ getBucket: () => getBucket(getPointer()),
2199
+ getPointer,
2200
+ argToKeyOptions
2201
+ };
2202
+ const wrapFn = function(...args) {
2203
+ const storage = getBucket(getPointer());
2204
+ const cacheKey = args.map((v) => argToKey(v, argToKeyOptions)).join("_");
2205
+ if (storage.has(cacheKey)) {
2206
+ const value = storage.get(cacheKey);
2207
+ return isAsync ? Promise.resolve(value) : value;
2208
+ }
2209
+ const newValue = fn.apply(this, args);
2210
+ if (isPromise(newValue)) {
2211
+ return newValue.then((value) => {
2212
+ storage.set(cacheKey, value);
2213
+ return value;
2214
+ });
2215
+ }
2216
+ storage.set(cacheKey, newValue);
2217
+ return newValue;
2218
+ };
2219
+ wrapFn.$cache = $cache;
2220
+ def(wrapFn, SYM_WITH_CACHE, true);
2221
+ return wrapFn;
2222
+ }
2223
+ function isWithCache(value) {
2224
+ return !!value && value[SYM_WITH_CACHE] === true;
2225
+ }
2226
+
2227
+ const cache = /* @__PURE__ */ new WeakMap();
2228
+ function withCache(...args) {
2229
+ let options = {};
2230
+ let fn = noop;
2231
+ if (isFunction(args[0])) {
2232
+ fn = args[0];
2233
+ } else if (isFunction(args[1])) {
2234
+ options = args[0] || {};
2235
+ fn = args[1];
2236
+ }
2237
+ const pointer = options.cachePointer || fn;
2238
+ const getPointer = () => pointer;
2239
+ const getBucket = (pointer2) => {
2240
+ let fnCache = cache.get(pointer2);
2241
+ if (!fnCache) {
2242
+ fnCache = /* @__PURE__ */ new Map();
2243
+ cache.set(pointer2, fnCache);
2244
+ }
2245
+ return fnCache;
2246
+ };
2247
+ return createWithCache({
2248
+ fn,
2249
+ getBucket,
2250
+ getPointer,
2251
+ ...options
2252
+ });
2253
+ }
2254
+
2255
+ function assertCapacity(value) {
2256
+ number$1(value, "capacity must be a number");
2257
+ ok(value > 0, "capacity must be more then 0.");
2258
+ }
2259
+
2260
+ class FixedMap extends Map {
2261
+ constructor(_capacity) {
2262
+ assertCapacity(_capacity);
2263
+ super();
2264
+ this._capacity = _capacity;
2265
+ this._tail = [];
2266
+ }
2267
+ _tail;
2268
+ set(key, value) {
2269
+ if (!super.has.call(this, key)) {
2270
+ this._tail.push(key);
2271
+ }
2272
+ super.set.call(this, key, value);
2273
+ this._drain();
2274
+ return this;
2275
+ }
2276
+ delete(key) {
2277
+ const removed = super.delete.call(this, key);
2278
+ if (removed) {
2279
+ const idx = this._tail.findIndex((v) => v === key);
2280
+ if (idx > -1) {
2281
+ this._tail.splice(idx, 1);
2282
+ }
2283
+ }
2284
+ return removed;
2285
+ }
2286
+ clear() {
2287
+ delete this._tail;
2288
+ this._tail = [];
2289
+ super.clear.call(this);
2290
+ }
2291
+ get capacity() {
2292
+ return this._capacity;
2293
+ }
2294
+ set capacity(value) {
2295
+ assertCapacity(value);
2296
+ this._capacity = value;
2297
+ this._drain();
2298
+ }
2299
+ _drain() {
2300
+ while (this._tail.length > this._capacity) {
2301
+ const key = this._tail.shift();
2302
+ key !== void 0 && this.delete(key);
2303
+ }
2304
+ }
2305
+ }
2306
+
2307
+ class TimeBucket {
2308
+ _pointer;
2309
+ _sizeMs;
2310
+ _bucket;
2311
+ constructor({ capacity = Infinity, sizeMs }) {
2312
+ assetSizeMs(sizeMs);
2313
+ this._sizeMs = sizeMs;
2314
+ this._pointer = 0;
2315
+ this._bucket = capacity === Infinity ? /* @__PURE__ */ new Map() : new FixedMap(capacity);
2316
+ }
2317
+ get capacity() {
2318
+ if (this._bucket instanceof FixedMap) {
2319
+ return this._bucket.capacity;
2320
+ }
2321
+ return Infinity;
2322
+ }
2323
+ get sizeMs() {
2324
+ return this.sizeMs;
2325
+ }
2326
+ set sizeMs(value) {
2327
+ assetSizeMs(value);
2328
+ this._sizeMs = value;
2329
+ this._drainBucket();
1924
2330
  }
1925
2331
  get size() {
1926
2332
  this._drainBucket();
@@ -3406,678 +3812,317 @@ var TABLE = new Int32Array([
3406
3812
  755167117
3407
3813
  ]);
3408
3814
  function crc32(value, seed) {
3409
- if (isString(value)) {
3410
- return crc32(textEncoder.encode(value), seed);
3411
- }
3412
- var crc = seed === 0 ? 0 : ~~seed ^ -1;
3413
- if (value instanceof Uint8Array) {
3414
- for (var index = 0; index < value.length; index++) {
3415
- crc = TABLE[(crc ^ value[index]) & 255] ^ crc >>> 8;
3416
- }
3417
- } else {
3418
- for (var current of value) {
3419
- for (var index = 0; index < current.length; index++) {
3420
- crc = TABLE[(crc ^ current[index]) & 255] ^ crc >>> 8;
3421
- }
3422
- }
3423
- }
3424
- return crc ^ -1;
3425
- }
3426
-
3427
- function isDateObject(value) {
3428
- return has(value, ["year", "month", "date"]) && isNumber(value.year) && isNumber(value.month) && isNumber(value.date);
3429
- }
3430
-
3431
- function createDateObject(value, returnsNullWhenInvalid = false) {
3432
- let result = null;
3433
- let inputValue = value;
3434
- if (isNumber(inputValue) || isString(inputValue)) {
3435
- inputValue = new Date(inputValue);
3436
- }
3437
- if (isDate(inputValue)) {
3438
- result = {
3439
- year: inputValue.getFullYear(),
3440
- month: inputValue.getMonth() + 1,
3441
- date: inputValue.getDate()
3442
- };
3443
- } else if (isDateObject(inputValue)) {
3444
- result = { ...inputValue };
3445
- }
3446
- ok(
3447
- returnsNullWhenInvalid || !!result,
3448
- `Failed to date parse: ${value}.`
3449
- );
3450
- return result;
3451
- }
3452
-
3453
- function isTimeObject(value) {
3454
- return isPlainObject(value) && "h" in value && "m" in value && isNumber(value.h) && Number.isInteger(value.h) && isNumber(value.m) && Number.isInteger(value.m) && value.h >= 0 && value.h < 24 && value.m >= 0 && value.m < 60;
3455
- }
3456
-
3457
- function createTimeObject(value, returnsNullWhenInvalid = false) {
3458
- let result = null;
3459
- let inputValue = value;
3460
- if (isNumber(inputValue)) {
3461
- inputValue = new Date(inputValue);
3462
- } else if (isString(inputValue)) {
3463
- const [h, m] = inputValue.split(":").map((v) => v.trim().padStart(2, "0")).map((v) => parseInt(v));
3464
- inputValue = { h, m };
3465
- }
3466
- if (isDate(inputValue)) {
3467
- result = {
3468
- h: inputValue.getHours(),
3469
- m: inputValue.getMinutes()
3470
- };
3471
- } else if (isTimeObject(inputValue)) {
3472
- result = { ...inputValue };
3473
- }
3474
- ok(
3475
- returnsNullWhenInvalid || !!result,
3476
- `Failed to time parse: ${value}.`
3477
- );
3478
- return result;
3479
- }
3480
-
3481
- const UNIT_TO_MS = {
3482
- ms: 1,
3483
- s: 1e3,
3484
- m: 1e3 * 60,
3485
- h: 1e3 * 60 * 60,
3486
- d: 1e3 * 60 * 60 * 24,
3487
- w: 1e3 * 60 * 60 * 24 * 7
3488
- };
3489
- class TimeSpan {
3490
- constructor(value, unit) {
3491
- this.value = value;
3492
- this.unit = unit;
3493
- }
3494
- /**
3495
- * The numeric value of the time span
3496
- */
3497
- value;
3498
- /**
3499
- * The unit of the time span.
3500
- */
3501
- unit;
3502
- /**
3503
- * Converts the time span to milliseconds.
3504
- *
3505
- * @returns {number} The equivalent time span in milliseconds.
3506
- * @example
3507
- * const ts = new TimeSpan(2, 'h');
3508
- * ts.milliseconds(); // Returns 7200000
3509
- */
3510
- milliseconds() {
3511
- const multiplier = UNIT_TO_MS[this.unit];
3512
- return this.value * multiplier;
3513
- }
3514
- /**
3515
- * Converts the time span to seconds.
3516
- *
3517
- * @returns {number} The equivalent time span in seconds.
3518
- * @example
3519
- * const ts = new TimeSpan(2, 'm');
3520
- * ts.seconds(); // Returns 120
3521
- */
3522
- seconds() {
3523
- return this.milliseconds() / UNIT_TO_MS.s;
3524
- }
3525
- /**
3526
- * Converts the time span to minutes.
3527
- *
3528
- * @returns {number} The equivalent time span in minutes.
3529
- * @example
3530
- * const ts = new TimeSpan(120, 's');
3531
- * ts.minutes(); // Returns 2
3532
- */
3533
- minutes() {
3534
- return this.milliseconds() / UNIT_TO_MS.m;
3535
- }
3536
- /**
3537
- * Converts the time span to hours.
3538
- *
3539
- * @returns {number} The equivalent time span in hours.
3540
- * @example
3541
- * const ts = new TimeSpan(120, 'm');
3542
- * ts.hours(); // Returns 2
3543
- */
3544
- hours() {
3545
- return this.milliseconds() / UNIT_TO_MS.h;
3546
- }
3547
- /**
3548
- * Converts the time span to days.
3549
- *
3550
- * @returns {number} The equivalent time span in days.
3551
- * @example
3552
- * const ts = new TimeSpan(48, 'h');
3553
- * ts.days(); // Returns 2
3554
- */
3555
- days() {
3556
- return this.milliseconds() / UNIT_TO_MS.d;
3557
- }
3558
- /**
3559
- * Converts the time span to weeks.
3560
- *
3561
- * @returns {number} The equivalent time span in weeks.
3562
- * @example
3563
- * const ts = new TimeSpan(14, 'd');
3564
- * ts.weeks(); // Returns 2
3565
- */
3566
- weeks() {
3567
- return this.milliseconds() / UNIT_TO_MS.w;
3568
- }
3569
- /**
3570
- * Adds a specified value and unit to the current time span.
3571
- *
3572
- * Returns new instance.
3573
- *
3574
- * @param {number} value - The value to add.
3575
- * @param {TimeSpanUnit} [unit='ms'] - The unit of the value to add (default is milliseconds).
3576
- * @returns {TimeSpan} A new TimeSpan instance with the added value.
3577
- * @example
3578
- * const ts = new TimeSpan(1, 'h');
3579
- * ts.add(30, 'm'); // Represents 1.5 hours
3580
- */
3581
- add(value, unit = "ms") {
3582
- const multiplier = UNIT_TO_MS[unit];
3583
- return new TimeSpan(this.milliseconds() + value * multiplier, "ms");
3584
- }
3585
- /**
3586
- * Subtracts a specified value and unit from the current time span.
3587
- *
3588
- * Returns new instance.
3589
- *
3590
- * @param {number} value - The value to subtract.
3591
- * @param {TimeSpanUnit} [unit='ms'] - The unit of the value to subtract (default is milliseconds).
3592
- * @returns {TimeSpan} A new TimeSpan instance with the subtracted value.
3593
- * @example
3594
- * const ts = new TimeSpan(1, 'h');
3595
- * ts.subtract(30, 'm'); // Represents 30 minutes less than 1 hour
3596
- */
3597
- subtract(value, unit = "ms") {
3598
- const multiplier = UNIT_TO_MS[unit];
3599
- return new TimeSpan(this.milliseconds() - value * multiplier, "ms");
3815
+ if (isString(value)) {
3816
+ return crc32(textEncoder.encode(value), seed);
3600
3817
  }
3601
- }
3602
-
3603
- function createTimeSpan(value, unit = "ms") {
3604
- return new TimeSpan(value, unit);
3605
- }
3606
-
3607
- function timestampMs(fromValue = Date.now()) {
3608
- if (isDate(fromValue)) {
3609
- fromValue = fromValue.getTime();
3610
- } else if (isString(fromValue)) {
3611
- const dt = new Date(fromValue);
3612
- fromValue = isDate(dt) ? dt.getTime() : 0;
3818
+ var crc = seed === 0 ? 0 : ~~seed ^ -1;
3819
+ if (value instanceof Uint8Array) {
3820
+ for (var index = 0; index < value.length; index++) {
3821
+ crc = TABLE[(crc ^ value[index]) & 255] ^ crc >>> 8;
3822
+ }
3823
+ } else {
3824
+ for (var current of value) {
3825
+ for (var index = 0; index < current.length; index++) {
3826
+ crc = TABLE[(crc ^ current[index]) & 255] ^ crc >>> 8;
3827
+ }
3828
+ }
3613
3829
  }
3614
- return isNumber(fromValue) ? fromValue : 0;
3615
- }
3616
-
3617
- function dateInDays(days, fromValue = Date.now()) {
3618
- return new Date(timestampMs(fromValue) + days * 60 * 60 * 24 * 1e3);
3830
+ return crc ^ -1;
3619
3831
  }
3620
3832
 
3621
- function dateInSeconds(seconds, fromValue = Date.now()) {
3622
- return new Date(timestampMs(fromValue) + seconds * 1e3);
3833
+ function isDateObject(value) {
3834
+ return has(value, ["year", "month", "date"]) && isNumber(value.year) && isNumber(value.month) && isNumber(value.date);
3623
3835
  }
3624
3836
 
3625
- function getRandomTime(startTime = { h: 0, m: 0 }, endTime = { h: 23, m: 59 }) {
3626
- const h = getRandomInt(startTime.h, endTime.h);
3627
- if (startTime.h === endTime.h) {
3628
- return { h, m: getRandomInt(startTime.m, endTime.m) };
3629
- }
3630
- if (h === startTime.h) {
3631
- return { h, m: getRandomInt(startTime.m, 59) };
3837
+ function createDateObject(value, returnsNullWhenInvalid = false) {
3838
+ let result = null;
3839
+ let inputValue = value;
3840
+ if (isNumber(inputValue) || isString(inputValue)) {
3841
+ inputValue = new Date(inputValue);
3632
3842
  }
3633
- if (h === endTime.h) {
3634
- return { h, m: getRandomInt(0, endTime.m) };
3843
+ if (isDate(inputValue)) {
3844
+ result = {
3845
+ year: inputValue.getFullYear(),
3846
+ month: inputValue.getMonth() + 1,
3847
+ date: inputValue.getDate()
3848
+ };
3849
+ } else if (isDateObject(inputValue)) {
3850
+ result = { ...inputValue };
3635
3851
  }
3636
- return { h, m: getRandomInt(0, 59) };
3637
- }
3638
-
3639
- function hmToSeconds(hm) {
3640
- hm = Number(hm);
3641
- number$1(hm, "expected number value");
3642
- const h = Math.floor(hm);
3643
- const m = round2digits(hm - h) * 100;
3644
- return h * 3600 + m * 60;
3645
- }
3646
-
3647
- function isTimeString(value) {
3648
- if (!isString(value)) return false;
3649
- const parts = value.split(":").map(Number);
3650
- if (parts.length !== 2) return false;
3651
- const [h, m] = parts;
3652
- return h >= 0 && h < 24 && m >= 0 && m < 60;
3653
- }
3654
-
3655
- function isTimeValue(value) {
3656
- return isTimeString(value) || isTimeObject(value);
3657
- }
3658
-
3659
- function isValidWeekDay(value) {
3660
- return isNumber(value) && Number.isInteger(value) && value >= 1 && value <= 7;
3852
+ ok(
3853
+ returnsNullWhenInvalid || !!result,
3854
+ `Failed to date parse: ${value}.`
3855
+ );
3856
+ return result;
3661
3857
  }
3662
3858
 
3663
- function secondsToHm(seconds) {
3664
- const value = Number(seconds);
3665
- number$1(value, "expected number value");
3666
- const h = Math.floor(value / 3600);
3667
- const m = Math.floor(value % 3600 / 60);
3668
- return round2digits(h + m / 100, 2);
3859
+ function isTimeObject(value) {
3860
+ return isPlainObject(value) && "h" in value && "m" in value && isNumber(value.h) && Number.isInteger(value.h) && isNumber(value.m) && Number.isInteger(value.m) && value.h >= 0 && value.h < 24 && value.m >= 0 && value.m < 60;
3669
3861
  }
3670
3862
 
3671
- function timeFromMinutes(value, returnsNullWhenInvalid = false) {
3672
- if (!isNumber(value)) {
3673
- ok(
3674
- returnsNullWhenInvalid,
3675
- "Failed to time parse from minutes: " + value
3676
- );
3677
- return null;
3678
- }
3679
- if (value === 0) {
3680
- return { h: 0, m: 0 };
3681
- }
3682
- value = value % 1440;
3683
- if (value < 0) {
3684
- value += 1440;
3863
+ function createTimeObject(value, returnsNullWhenInvalid = false) {
3864
+ let result = null;
3865
+ let inputValue = value;
3866
+ if (isNumber(inputValue)) {
3867
+ inputValue = new Date(inputValue);
3868
+ } else if (isString(inputValue)) {
3869
+ const [h, m] = inputValue.split(":").map((v) => v.trim().padStart(2, "0")).map((v) => parseInt(v));
3870
+ inputValue = { h, m };
3685
3871
  }
3686
- const h = Math.floor(value / 60);
3687
- const m = value % 60;
3688
- return { h, m };
3689
- }
3690
-
3691
- function timestampToDate(value) {
3692
- if (!isNumber(value)) return null;
3693
- return new Date(value * 1e3);
3694
- }
3695
-
3696
- function timeStringify(value, returnsNullWhenInvalid = false) {
3697
- const timeObject = createTimeObject(value, true);
3698
- if (!timeObject) {
3699
- ok(
3700
- returnsNullWhenInvalid,
3701
- "Failed to stringify time from: " + JSON.stringify(value)
3702
- );
3703
- return null;
3872
+ if (isDate(inputValue)) {
3873
+ result = {
3874
+ h: inputValue.getHours(),
3875
+ m: inputValue.getMinutes()
3876
+ };
3877
+ } else if (isTimeObject(inputValue)) {
3878
+ result = { ...inputValue };
3704
3879
  }
3705
- let { h, m } = timeObject;
3706
- const hStr = Math.ceil(h).toString().padStart(2, "0").slice(-2);
3707
- const mStr = Math.ceil(m).toString().padStart(2, "0").slice(-2);
3708
- return `${hStr}:${mStr}`;
3709
- }
3710
-
3711
- function timeToMinutes(value) {
3712
- const time = createTimeObject(value);
3713
- return time.h * 60 + time.m;
3714
- }
3715
-
3716
- function weeksInYear(year) {
3717
- const target = new Date(Date.UTC(year + 1, 0, 1));
3718
- const dayNumber = target.getDay();
3719
- return dayNumber < 4 ? 52 : 53;
3880
+ ok(
3881
+ returnsNullWhenInvalid || !!result,
3882
+ `Failed to time parse: ${value}.`
3883
+ );
3884
+ return result;
3720
3885
  }
3721
3886
 
3722
- const DateType = {
3723
- placeholder: "$date",
3724
- encode: (value) => {
3725
- if (value instanceof Date) {
3726
- return value.getTime();
3727
- }
3728
- },
3729
- decode(value) {
3730
- return new Date(value);
3731
- }
3732
- };
3733
- const BinaryType = {
3734
- placeholder: "$binary",
3735
- encode: (value) => {
3736
- if (value instanceof Uint8Array) {
3737
- return base64.encode(value, { includePadding: true });
3738
- } else if (value instanceof Uint16Array) {
3739
- return {
3740
- value: base64.encode(uint16ToUint8(value), { includePadding: true }),
3741
- bit: 16
3742
- };
3743
- } else if (value instanceof Uint32Array) {
3744
- return {
3745
- value: base64.encode(uint32ToUint8(value), { includePadding: true }),
3746
- bit: 32
3747
- };
3748
- }
3749
- },
3750
- decode(value) {
3751
- if (typeof value === "string") {
3752
- return base64.decode(value, { strict: true });
3753
- } else if (value.bit === 16) {
3754
- return uint8ToUint16(base64.decode(value.value, { strict: true }));
3755
- } else if (value.bit === 32) {
3756
- return uint8ToUint32(base64.decode(value.value, { strict: true }));
3757
- }
3758
- throw new Error("Unexpected $binary bit value: " + value.bit);
3759
- }
3760
- };
3761
- const BigIntType = {
3762
- placeholder: "$bigint",
3763
- encode: (value) => {
3764
- if (typeof value === "bigint") {
3765
- return base64.encode(bigIntBytes(value), { includePadding: false });
3766
- }
3767
- },
3768
- decode(value) {
3769
- return bigIntFromBytes(base64.decode(value, { strict: false }));
3770
- }
3771
- };
3772
- const MapType = {
3773
- placeholder: "$map",
3774
- encode: (value, encode) => {
3775
- if (value instanceof Map) {
3776
- return encode(Array.from(value.entries()));
3777
- }
3778
- },
3779
- decode(value) {
3780
- return new Map(value);
3781
- }
3782
- };
3783
- const SetType = {
3784
- placeholder: "$set",
3785
- encode: (value, encode) => {
3786
- if (value instanceof Set) {
3787
- return encode(Array.from(value.values()));
3788
- }
3789
- },
3790
- decode(value) {
3791
- return new Set(value);
3792
- }
3887
+ const UNIT_TO_MS = {
3888
+ ms: 1,
3889
+ s: 1e3,
3890
+ m: 1e3 * 60,
3891
+ h: 1e3 * 60 * 60,
3892
+ d: 1e3 * 60 * 60 * 24,
3893
+ w: 1e3 * 60 * 60 * 24 * 7
3793
3894
  };
3794
- const RegexType = {
3795
- placeholder: "$regex",
3796
- encode: (value, encode) => {
3797
- if (value instanceof RegExp) {
3798
- const regStr = value.toString();
3799
- const patternStart = regStr.lastIndexOf("/");
3800
- return {
3801
- pattern: value.toString().slice(1, patternStart),
3802
- flags: regStr.slice(patternStart + 1)
3803
- };
3804
- }
3805
- },
3806
- decode(value) {
3807
- return new RegExp(value.pattern, value.flags);
3895
+ class TimeSpan {
3896
+ constructor(value, unit) {
3897
+ this.value = value;
3898
+ this.unit = unit;
3808
3899
  }
3809
- };
3810
- const InfinityType = {
3811
- placeholder: "$inf",
3812
- encode: (value, encode) => {
3813
- if (value === Infinity) {
3814
- return 1;
3815
- } else if (value === -Infinity) {
3816
- return -1;
3817
- }
3818
- },
3819
- decode(value) {
3820
- if (value === 1) return Infinity;
3821
- if (value === -1) return -Infinity;
3822
- throw new Error("Unexpected $inf value: " + value);
3900
+ /**
3901
+ * The numeric value of the time span
3902
+ */
3903
+ value;
3904
+ /**
3905
+ * The unit of the time span.
3906
+ */
3907
+ unit;
3908
+ /**
3909
+ * Converts the time span to milliseconds.
3910
+ *
3911
+ * @returns {number} The equivalent time span in milliseconds.
3912
+ * @example
3913
+ * const ts = new TimeSpan(2, 'h');
3914
+ * ts.milliseconds(); // Returns 7200000
3915
+ */
3916
+ milliseconds() {
3917
+ const multiplier = UNIT_TO_MS[this.unit];
3918
+ return this.value * multiplier;
3823
3919
  }
3824
- };
3825
-
3826
- class EJSON {
3827
- /** @internal */
3828
- typeHandlers = /* @__PURE__ */ new Map();
3829
- /** @internal */
3830
- replacerReady;
3831
- /** @internal */
3832
- encode;
3833
- /** @internal */
3834
- reviewerReady;
3835
- /** @internal */
3836
- pure = true;
3837
- _vendorName = null;
3838
3920
  /**
3839
- * MIME type based on the provided vendor name or defaults to 'application/json'.
3921
+ * Converts the time span to seconds.
3922
+ *
3923
+ * @returns {number} The equivalent time span in seconds.
3924
+ * @example
3925
+ * const ts = new TimeSpan(2, 'm');
3926
+ * ts.seconds(); // Returns 120
3840
3927
  */
3841
- mimetype = "application/json";
3842
- Type = {
3843
- Date: DateType,
3844
- Map: MapType,
3845
- Set: SetType,
3846
- RegExp: RegexType,
3847
- Infinity: InfinityType,
3848
- BigInt: BigIntType,
3849
- Binary: BinaryType
3850
- };
3851
- constructor() {
3852
- this.replacerReady = this._replacer.bind(this);
3853
- this.reviewerReady = this._reviewer.bind(this);
3854
- this.encode = (value) => {
3855
- return deepCloneWith(value, this.replacerReady);
3856
- };
3928
+ seconds() {
3929
+ return this.milliseconds() / UNIT_TO_MS.s;
3857
3930
  }
3858
3931
  /**
3859
- * The vendor name used for the custom MIME type definition.
3860
- * If null, defaults to 'application/json'.
3932
+ * Converts the time span to minutes.
3933
+ *
3934
+ * @returns {number} The equivalent time span in minutes.
3935
+ * @example
3936
+ * const ts = new TimeSpan(120, 's');
3937
+ * ts.minutes(); // Returns 2
3861
3938
  */
3862
- get vendorName() {
3863
- return this._vendorName;
3939
+ minutes() {
3940
+ return this.milliseconds() / UNIT_TO_MS.m;
3864
3941
  }
3865
- set vendorName(value) {
3866
- this._vendorName = value;
3867
- if (!value) {
3868
- this.mimetype = "application/json";
3869
- } else {
3870
- const vendorName = value.split(" ").map((v) => v.toLowerCase()).join(".").replace(/\.\.+/g, ".").replace(/\.$/, "");
3871
- this.mimetype = `application/vnd.${vendorName}+json`;
3872
- }
3942
+ /**
3943
+ * Converts the time span to hours.
3944
+ *
3945
+ * @returns {number} The equivalent time span in hours.
3946
+ * @example
3947
+ * const ts = new TimeSpan(120, 'm');
3948
+ * ts.hours(); // Returns 2
3949
+ */
3950
+ hours() {
3951
+ return this.milliseconds() / UNIT_TO_MS.h;
3873
3952
  }
3874
3953
  /**
3875
- * Adds a custom type handler for encoding/decoding logic.
3876
- * Ensures type placeholders are unique and adhere to conventions.
3954
+ * Converts the time span to days.
3955
+ *
3956
+ * @returns {number} The equivalent time span in days.
3957
+ * @example
3958
+ * const ts = new TimeSpan(48, 'h');
3959
+ * ts.days(); // Returns 2
3877
3960
  */
3878
- addType(type) {
3879
- ok(
3880
- !this.typeHandlers.has(type.placeholder),
3881
- `type with ${type.placeholder} already taken.`
3882
- );
3883
- ok(
3884
- type.placeholder.startsWith("$"),
3885
- "type placeholder must starts with $ symbol."
3886
- );
3887
- this.pure = false;
3888
- this.typeHandlers.set(type.placeholder, type);
3889
- return this;
3961
+ days() {
3962
+ return this.milliseconds() / UNIT_TO_MS.d;
3890
3963
  }
3891
3964
  /**
3892
- * Stringifies a JavaScript value using custom encoding logic.
3893
- * @param {any} value - The value to encode and stringify.
3894
- * @param {string | number} [space] - Optional space for pretty-printing.
3895
- * @returns {string} - The JSON stringified value.
3965
+ * Converts the time span to weeks.
3966
+ *
3967
+ * @returns {number} The equivalent time span in weeks.
3968
+ * @example
3969
+ * const ts = new TimeSpan(14, 'd');
3970
+ * ts.weeks(); // Returns 2
3896
3971
  */
3897
- stringify(value, space) {
3898
- if (this.pure) {
3899
- return JSON.stringify(value, void 0, space);
3900
- }
3901
- return JSON.stringify(this.encode(value), void 0, space);
3972
+ weeks() {
3973
+ return this.milliseconds() / UNIT_TO_MS.w;
3902
3974
  }
3903
3975
  /**
3904
- * Parses a JSON string using custom decoding logic.
3905
- * @param {string} value - The JSON string to parse.
3906
- * @returns {any} - The decoded JavaScript object.
3976
+ * Adds a specified value and unit to the current time span.
3977
+ *
3978
+ * Returns new instance.
3979
+ *
3980
+ * @param {number} value - The value to add.
3981
+ * @param {TimeSpanUnit} [unit='ms'] - The unit of the value to add (default is milliseconds).
3982
+ * @returns {TimeSpan} A new TimeSpan instance with the added value.
3983
+ * @example
3984
+ * const ts = new TimeSpan(1, 'h');
3985
+ * ts.add(30, 'm'); // Represents 1.5 hours
3907
3986
  */
3908
- parse(value) {
3909
- if (this.pure) {
3910
- return JSON.parse(value);
3911
- }
3912
- return JSON.parse(value, this.reviewerReady);
3987
+ add(value, unit = "ms") {
3988
+ const multiplier = UNIT_TO_MS[unit];
3989
+ return new TimeSpan(this.milliseconds() + value * multiplier, "ms");
3913
3990
  }
3914
- /** @internal */
3915
- _replacer(value, key) {
3916
- if (isPlainObject(value)) return;
3917
- if (Array.isArray(value)) return;
3918
- if (!isInfinity(value) && !isBigInt(value)) {
3919
- if (isPrimitive(value)) return;
3920
- }
3921
- for (const type of this.typeHandlers.values()) {
3922
- const res = type.encode(value, this.encode);
3923
- if (res !== void 0) {
3924
- return type.encodeInline ? res : { [type.placeholder]: res };
3925
- }
3926
- }
3927
- return value;
3991
+ /**
3992
+ * Subtracts a specified value and unit from the current time span.
3993
+ *
3994
+ * Returns new instance.
3995
+ *
3996
+ * @param {number} value - The value to subtract.
3997
+ * @param {TimeSpanUnit} [unit='ms'] - The unit of the value to subtract (default is milliseconds).
3998
+ * @returns {TimeSpan} A new TimeSpan instance with the subtracted value.
3999
+ * @example
4000
+ * const ts = new TimeSpan(1, 'h');
4001
+ * ts.subtract(30, 'm'); // Represents 30 minutes less than 1 hour
4002
+ */
4003
+ subtract(value, unit = "ms") {
4004
+ const multiplier = UNIT_TO_MS[unit];
4005
+ return new TimeSpan(this.milliseconds() - value * multiplier, "ms");
3928
4006
  }
3929
- /** @internal */
3930
- _reviewer(_, value) {
3931
- const key = firstKey(value);
3932
- if (!key || key[0] !== "$") return value;
3933
- const type = this.typeHandlers.get(key);
3934
- if (type) {
3935
- return type.decode(value[key]);
3936
- }
3937
- return value;
4007
+ }
4008
+
4009
+ function createTimeSpan(value, unit = "ms") {
4010
+ return new TimeSpan(value, unit);
4011
+ }
4012
+
4013
+ function timestampMs(fromValue = Date.now()) {
4014
+ if (isDate(fromValue)) {
4015
+ fromValue = fromValue.getTime();
4016
+ } else if (isString(fromValue)) {
4017
+ const dt = new Date(fromValue);
4018
+ fromValue = isDate(dt) ? dt.getTime() : 0;
3938
4019
  }
4020
+ return isNumber(fromValue) ? fromValue : 0;
3939
4021
  }
3940
- function firstKey(value) {
3941
- if (!isObject(value)) return null;
3942
- for (const key in value) {
3943
- return key;
4022
+
4023
+ function dateInDays(days, fromValue = Date.now()) {
4024
+ return new Date(timestampMs(fromValue) + days * 60 * 60 * 24 * 1e3);
4025
+ }
4026
+
4027
+ function dateInSeconds(seconds, fromValue = Date.now()) {
4028
+ return new Date(timestampMs(fromValue) + seconds * 1e3);
4029
+ }
4030
+
4031
+ function getRandomTime(startTime = { h: 0, m: 0 }, endTime = { h: 23, m: 59 }) {
4032
+ const h = getRandomInt(startTime.h, endTime.h);
4033
+ if (startTime.h === endTime.h) {
4034
+ return { h, m: getRandomInt(startTime.m, endTime.m) };
3944
4035
  }
3945
- return null;
4036
+ if (h === startTime.h) {
4037
+ return { h, m: getRandomInt(startTime.m, 59) };
4038
+ }
4039
+ if (h === endTime.h) {
4040
+ return { h, m: getRandomInt(0, endTime.m) };
4041
+ }
4042
+ return { h, m: getRandomInt(0, 59) };
4043
+ }
4044
+
4045
+ function hmToSeconds(hm) {
4046
+ hm = Number(hm);
4047
+ number$1(hm, "expected number value");
4048
+ const h = Math.floor(hm);
4049
+ const m = round2digits(hm - h) * 100;
4050
+ return h * 3600 + m * 60;
4051
+ }
4052
+
4053
+ function isTimeString(value) {
4054
+ if (!isString(value)) return false;
4055
+ const parts = value.split(":").map(Number);
4056
+ if (parts.length !== 2) return false;
4057
+ const [h, m] = parts;
4058
+ return h >= 0 && h < 24 && m >= 0 && m < 60;
3946
4059
  }
3947
4060
 
3948
- function createEJSON(withBasicTypes = false) {
3949
- const ejson = new EJSON();
3950
- if (withBasicTypes) {
3951
- ejson.addType(MapType);
3952
- ejson.addType(SetType);
3953
- ejson.addType(DateType);
3954
- ejson.addType(InfinityType);
3955
- ejson.addType(BigIntType);
3956
- ejson.addType(BinaryType);
3957
- ejson.addType(RegexType);
3958
- }
3959
- return ejson;
4061
+ function isTimeValue(value) {
4062
+ return isTimeString(value) || isTimeObject(value);
3960
4063
  }
3961
4064
 
3962
- class EJSONStream extends TransformStream {
3963
- ejson;
3964
- constructor({ ejson, cl, op, sep, onFlush, onStart }) {
3965
- let firstChunk = true;
3966
- super({
3967
- start(controller) {
3968
- return Promise.resolve().then(() => {
3969
- if (onStart) {
3970
- return onStart(controller);
3971
- }
3972
- }).then(() => {
3973
- controller.enqueue(op);
3974
- });
3975
- },
3976
- transform(chunk, controller) {
3977
- const jsonString = ejson.stringify(chunk);
3978
- if (firstChunk) {
3979
- firstChunk = false;
3980
- } else {
3981
- controller.enqueue(sep);
3982
- }
3983
- controller.enqueue(jsonString);
3984
- },
3985
- flush(controller) {
3986
- controller.enqueue(cl);
3987
- if (onFlush) {
3988
- return onFlush(controller);
3989
- }
3990
- }
3991
- });
3992
- this.ejson = ejson;
4065
+ function isValidWeekDay(value) {
4066
+ return isNumber(value) && Number.isInteger(value) && value >= 1 && value <= 7;
4067
+ }
4068
+
4069
+ function secondsToHm(seconds) {
4070
+ const value = Number(seconds);
4071
+ number$1(value, "expected number value");
4072
+ const h = Math.floor(value / 3600);
4073
+ const m = Math.floor(value % 3600 / 60);
4074
+ return round2digits(h + m / 100, 2);
4075
+ }
4076
+
4077
+ function timeFromMinutes(value, returnsNullWhenInvalid = false) {
4078
+ if (!isNumber(value)) {
4079
+ ok(
4080
+ returnsNullWhenInvalid,
4081
+ "Failed to time parse from minutes: " + value
4082
+ );
4083
+ return null;
3993
4084
  }
3994
- /**
3995
- * The vendor name used for the custom MIME type definition.
3996
- * If null, defaults to 'application/json'.
3997
- */
3998
- get vendorName() {
3999
- return this.ejson.vendorName;
4085
+ if (value === 0) {
4086
+ return { h: 0, m: 0 };
4000
4087
  }
4001
- /**
4002
- * MIME type based on the provided vendor name or defaults to 'application/json'.
4003
- */
4004
- get mimetype() {
4005
- return this.ejson.mimetype;
4088
+ value = value % 1440;
4089
+ if (value < 0) {
4090
+ value += 1440;
4006
4091
  }
4092
+ const h = Math.floor(value / 60);
4093
+ const m = value % 60;
4094
+ return { h, m };
4007
4095
  }
4008
4096
 
4009
- const instance = createEJSON(true);
4097
+ function timestampToDate(value) {
4098
+ if (!isNumber(value)) return null;
4099
+ return new Date(value * 1e3);
4100
+ }
4010
4101
 
4011
- function createEJSONStream(options = {}) {
4012
- if (options.resultKey || options.append || options.prepend) {
4013
- return createEJSONStreamPayload(options);
4102
+ function timeStringify(value, returnsNullWhenInvalid = false) {
4103
+ const timeObject = createTimeObject(value, true);
4104
+ if (!timeObject) {
4105
+ ok(
4106
+ returnsNullWhenInvalid,
4107
+ "Failed to stringify time from: " + JSON.stringify(value)
4108
+ );
4109
+ return null;
4014
4110
  }
4015
- return new EJSONStream(getOptions(options));
4111
+ let { h, m } = timeObject;
4112
+ const hStr = Math.ceil(h).toString().padStart(2, "0").slice(-2);
4113
+ const mStr = Math.ceil(m).toString().padStart(2, "0").slice(-2);
4114
+ return `${hStr}:${mStr}`;
4016
4115
  }
4017
- function createEJSONStreamPayload(options) {
4018
- let { cl, ejson, op, sep } = getOptions(options);
4019
- const { append, prepend, resultKey } = options;
4020
- notEmptyString(resultKey, "resultKey required.");
4021
- const stream = new EJSONStream({
4022
- ejson,
4023
- cl,
4024
- op,
4025
- sep,
4026
- onStart(controller) {
4027
- if (!prepend) {
4028
- controller.enqueue(`{"${resultKey}":`);
4029
- return Promise.resolve();
4030
- }
4031
- return Promise.resolve().then(() => prepend()).then((data) => {
4032
- if (data === null || data === void 0) {
4033
- controller.enqueue(`{"${resultKey}":`);
4034
- return;
4035
- }
4036
- ok(
4037
- isPlainObject(data),
4038
- "prepend result expected to be plain object"
4039
- );
4040
- const dataPart = instance.stringify(data).slice(0, -1);
4041
- if (dataPart === "{") {
4042
- controller.enqueue(`{"${resultKey}":`);
4043
- return;
4044
- }
4045
- controller.enqueue(`${dataPart}${sep}"${resultKey}":`);
4046
- });
4047
- },
4048
- onFlush(controller) {
4049
- if (!append) {
4050
- controller.enqueue("}");
4051
- return Promise.resolve();
4052
- }
4053
- return Promise.resolve().then(() => append()).then((data) => {
4054
- if (data === null || data === void 0) {
4055
- controller.enqueue("}");
4056
- return;
4057
- }
4058
- ok(
4059
- isPlainObject(data),
4060
- "prepend result expected to be plain object"
4061
- );
4062
- const dataPart = instance.stringify(data).slice(1);
4063
- if (dataPart === "}") {
4064
- controller.enqueue(`}`);
4065
- return;
4066
- }
4067
- controller.enqueue(`${sep}${dataPart}`);
4068
- });
4069
- }
4070
- });
4071
- return stream;
4116
+
4117
+ function timeToMinutes(value) {
4118
+ const time = createTimeObject(value);
4119
+ return time.h * 60 + time.m;
4072
4120
  }
4073
- function getOptions(options) {
4074
- const { ejson = instance, cl = "]", op = "[", sep = "," } = options;
4075
- return {
4076
- cl,
4077
- ejson,
4078
- op,
4079
- sep
4080
- };
4121
+
4122
+ function weeksInYear(year) {
4123
+ const target = new Date(Date.UTC(year + 1, 0, 1));
4124
+ const dayNumber = target.getDay();
4125
+ return dayNumber < 4 ? 52 : 53;
4081
4126
  }
4082
4127
 
4083
4128
  const env = (() => {
@@ -4142,7 +4187,7 @@ function createEnvParser(targetObject) {
4142
4187
  return defaultValue;
4143
4188
  }
4144
4189
  try {
4145
- return JSON.parse(targetObject[key]);
4190
+ return instance.parse(targetObject[key]);
4146
4191
  } catch (err) {
4147
4192
  console.warn("Failed to parse json env variable", key);
4148
4193
  return defaultValue;
@@ -4750,28 +4795,6 @@ const logger = (...baseArgs) => {
4750
4795
  return instance;
4751
4796
  };
4752
4797
 
4753
- function asyncFilter(array, predicate) {
4754
- var i = 0;
4755
- var result = [];
4756
- var cooldown = nextTickIteration(10);
4757
- return new Promise((resolve, reject) => {
4758
- var processNextBatch = () => {
4759
- if (i < array.length) {
4760
- cooldown().then(() => predicate(array[i], i, array)).then((valid) => {
4761
- if (Boolean(valid)) {
4762
- result.push(array[i]);
4763
- }
4764
- i++;
4765
- setTimeout(processNextBatch, 0);
4766
- }).catch(reject);
4767
- } else {
4768
- resolve(result);
4769
- }
4770
- };
4771
- processNextBatch();
4772
- });
4773
- }
4774
-
4775
4798
  function nextTickIteration(amount, delay = "tick") {
4776
4799
  let counter = 0;
4777
4800
  const tickInterval = delay === "tick";
@@ -4791,6 +4814,45 @@ function nextTickIteration(amount, delay = "tick") {
4791
4814
  };
4792
4815
  }
4793
4816
 
4817
+ function asyncFilter(array, predicate, { concurrency = 1 } = {}) {
4818
+ concurrency = Math.max(concurrency, 1);
4819
+ if (array.length === 0) {
4820
+ return Promise.resolve([]);
4821
+ }
4822
+ var result = [];
4823
+ var currentIndex = 0;
4824
+ var completed = 0;
4825
+ var hasError = false;
4826
+ var cooldown = nextTickIteration(10);
4827
+ return new Promise((resolve, reject) => {
4828
+ var processItem = (index) => {
4829
+ if (hasError || index >= array.length) return;
4830
+ cooldown().then(() => predicate(array[index], index, array)).then((include) => {
4831
+ if (hasError) return;
4832
+ if (include) {
4833
+ result.push(index);
4834
+ }
4835
+ completed++;
4836
+ if (completed >= array.length) {
4837
+ resolve(result.toSorted((a, b) => a - b).map((idx) => array[idx]));
4838
+ } else {
4839
+ if (currentIndex < array.length) {
4840
+ processItem(currentIndex++);
4841
+ }
4842
+ }
4843
+ }).catch((error) => {
4844
+ if (!hasError) {
4845
+ hasError = true;
4846
+ reject(error);
4847
+ }
4848
+ });
4849
+ };
4850
+ for (; currentIndex < concurrency; currentIndex++) {
4851
+ processItem(currentIndex);
4852
+ }
4853
+ });
4854
+ }
4855
+
4794
4856
  function asyncFind(array, callbackfn) {
4795
4857
  var i = 0;
4796
4858
  var cooldown = nextTickIteration(10);
@@ -4815,35 +4877,36 @@ function asyncFind(array, callbackfn) {
4815
4877
 
4816
4878
  function asyncForEach(array, callbackfn, { concurrency = 1 } = {}) {
4817
4879
  concurrency = Math.max(concurrency, 1);
4818
- var i = 0;
4880
+ if (array.length === 0) {
4881
+ return Promise.resolve();
4882
+ }
4883
+ var hasError = false;
4884
+ var completed = 0;
4885
+ var currentIndex = 0;
4819
4886
  var cooldown = nextTickIteration(10);
4820
- var tasks = Array(concurrency);
4821
4887
  return new Promise((resolve, reject) => {
4822
- var processNextBatch = () => {
4823
- if (i >= array.length) {
4824
- resolve();
4825
- return;
4826
- }
4827
- cooldown().then(() => {
4828
- for (var idx = 0; idx < concurrency; idx++) {
4829
- tasks[idx] = Promise.resolve(i);
4830
- if (i < array.length) {
4831
- tasks[idx] = tasks[idx].then(
4832
- (itemIndex) => callbackfn(array[itemIndex], itemIndex, array)
4833
- );
4888
+ var processItem = (index) => {
4889
+ if (hasError || index >= array.length) return;
4890
+ cooldown().then(() => callbackfn(array[index], index, array)).then((transformed) => {
4891
+ if (hasError) return;
4892
+ completed++;
4893
+ if (completed >= array.length) {
4894
+ resolve();
4895
+ } else {
4896
+ if (currentIndex < array.length) {
4897
+ processItem(currentIndex++);
4834
4898
  }
4835
- i++;
4836
4899
  }
4837
- return Promise.all(tasks);
4838
- }).then(() => {
4839
- if (i < array.length) {
4840
- setTimeout(processNextBatch, 0);
4841
- } else {
4842
- resolve();
4900
+ }).catch((error) => {
4901
+ if (!hasError) {
4902
+ hasError = true;
4903
+ reject(error);
4843
4904
  }
4844
- }).catch(reject);
4905
+ });
4845
4906
  };
4846
- processNextBatch();
4907
+ for (; currentIndex < concurrency; currentIndex++) {
4908
+ processItem(currentIndex);
4909
+ }
4847
4910
  });
4848
4911
  }
4849
4912
 
@@ -4984,38 +5047,38 @@ class AsyncIterableQueue {
4984
5047
 
4985
5048
  function asyncMap(array, callbackfn, { concurrency = 1 } = {}) {
4986
5049
  concurrency = Math.max(concurrency, 1);
4987
- var result = [];
4988
- var i = 0;
5050
+ if (array.length === 0) {
5051
+ return Promise.resolve([]);
5052
+ }
5053
+ var hasError = false;
5054
+ var result = Array(array.length);
5055
+ var completed = 0;
5056
+ var currentIndex = 0;
4989
5057
  var cooldown = nextTickIteration(10);
4990
- var tasks = Array(concurrency);
4991
5058
  return new Promise((resolve, reject) => {
4992
- var processNextBatch = () => {
4993
- if (i >= array.length) {
4994
- resolve(result);
4995
- } else {
4996
- cooldown().then(() => {
4997
- for (var idx = 0; idx < concurrency; idx++) {
4998
- tasks[idx] = Promise.resolve(i);
4999
- if (i < array.length) {
5000
- tasks[idx] = tasks[idx].then(
5001
- (itemIndex) => callbackfn(array[itemIndex], itemIndex, array)
5002
- ).then((transformed) => {
5003
- result.push(transformed);
5004
- });
5005
- }
5006
- i++;
5007
- }
5008
- return Promise.all(tasks);
5009
- }).then(() => {
5010
- if (i < array.length) {
5011
- setTimeout(processNextBatch, 0);
5012
- } else {
5013
- resolve(result);
5059
+ var processItem = (index) => {
5060
+ if (hasError || index >= array.length) return;
5061
+ cooldown().then(() => callbackfn(array[index], index, array)).then((transformed) => {
5062
+ if (hasError) return;
5063
+ result[index] = transformed;
5064
+ completed++;
5065
+ if (completed >= array.length) {
5066
+ resolve(result);
5067
+ } else {
5068
+ if (currentIndex < array.length) {
5069
+ processItem(currentIndex++);
5014
5070
  }
5015
- }).catch(reject);
5016
- }
5071
+ }
5072
+ }).catch((error) => {
5073
+ if (!hasError) {
5074
+ hasError = true;
5075
+ reject(error);
5076
+ }
5077
+ });
5017
5078
  };
5018
- processNextBatch();
5079
+ for (; currentIndex < concurrency; currentIndex++) {
5080
+ processItem(currentIndex);
5081
+ }
5019
5082
  });
5020
5083
  }
5021
5084
 
@@ -5459,5 +5522,59 @@ function timeout(ms, promiseOrCallback, timeoutError = new AppError(408)) {
5459
5522
  });
5460
5523
  }
5461
5524
 
5462
- export { AppError, AsyncIterableQueue, BrowserAssertionError, CancellablePromise, ColorParser, instance as EJSON, EJSON as EJSONInstance, EJSONStream, FindMean, FixedMap, FixedWeakMap, LruCache, Queue, ResourcePool, SimpleEventEmitter, SortedArray, TWEMOJI_REGEX, TimeBucket, TimeSpan, alpha, arrayable, assert, asyncFilter, asyncFind, asyncForEach, asyncMap, avg, avgCircular, base62, base62Fast, base64, base64ToBytes, base64url, basex, bigIntBytes, bigIntFromBytes, blendColors, buildCssColor, bytesToBase64, cache, cacheBucket, cacheFixed, cacheLRU, camelCase, capitalize, captureStackTrace, catchError, channelsToHSL, channelsToHex, channelsToRGB, checkBitmask, chunk, chunkSeries, clamp, cleanEmpty, cleanObject, colorToChannels, compareBytes, concatenateBytes, contrastRatio, convertToUnit, crc32, createCustomizer, createCustomizerFactory, createDateObject, createDeepCloneWith, createEJSON, createEJSONStream, createEnvParser, createRandomizer, createSecureCustomizer, createTimeObject, createTimeSpan, createWithCache, cssVariable, dateInDays, dateInSeconds, debounce, deepAssign, deepClone, deepCloneWith, deepDefaults, deepFreeze, def, defer, delay, difference, dropCache, env, escapeHtml, escapeNumeric, escapeRegExp, fastIdle, fastIdlePromise, fastRaf, findMean, flagsToMap, flatten, formatMoney, formatNumber, get, getFileExtension, getFileName, getInitials, getMostSpecificPaths, getRandomInt, getRandomTime, getWords, groupBy, has, hasOwn, hasProtocol, hex, hexToChannels, hmToSeconds, hslToChannels, humanFileSize, humanize, interpolateColor, intersection, isBigInt, isBoolean, isCached, isClient, isColorChannels, isCustomizerFactory, isDate, isDateObject, isDef, isEmpty, isEqual, isError, isFunction, isInfinity, isMap, isNullOrUndefined, isNumber, isObject, isOneEmoji, isPlainObject, isPrimitive, isPromise, isRegExp, isSet, isSkip, isString, isSuccess, isSymbol, isTimeObject, isTimeString, isTimeValue, isValidWeekDay, isWeakMap, isWeakSet, isWithCache, isoToFlagEmoji, kebabCase, keyBy, logger, loggerSetLevel, lowerCase, luminance, maskingEmail, maskingPhone, maskingWords, nextTickIteration, noop, objectId, omit, omitPrefixed, orderBy, parseAllNumbers, parseAlpha, parsePercentage, percentOf, pick, pickPrefixed, qs, rafPromise, randomString, removeVS16s, retryOnError, rgbToChannels, round2digits, secondsToHm, set, shuffle, snakeCase, sprintf, startCase, strAssign, sum, textDecoder, textEncoder, throttle, timeFromMinutes, timeStringify, timeToMinutes, timeout, timestamp, timestampMs, timestampToDate, tintedTextColor, toError, toMap, truncate, typeOf, uint16ToUint8, uint32ToUint8, uint8ToUint16, uint8ToUint32, unflatten, union, uniq, uniqBy, unset, weeksInYear, weightedRoundRobin, withCache, withCacheBucket, withCacheBucketBatch, withCacheFixed, withCacheLRU, withDeepClone, withPointerCache, wrapText };
5525
+ const stringifyArgs = (...args) => {
5526
+ return args.map((v) => argToKey(v, { objectStrategy: "json" })).join("_");
5527
+ };
5528
+ function withResolve(fn, getCacheKey) {
5529
+ const cache = /* @__PURE__ */ new Map();
5530
+ const cacheKeyVariants = arrayable(getCacheKey);
5531
+ return function(...args) {
5532
+ let cacheKey = stringifyArgs(...args);
5533
+ if (cacheKeyVariants?.length) {
5534
+ for (const getCacheKey2 of cacheKeyVariants) {
5535
+ const newCacheKey = getCacheKey2(args, stringifyArgs);
5536
+ if (newCacheKey === null) {
5537
+ cacheKey = Symbol();
5538
+ break;
5539
+ } else if (isString(newCacheKey) && cache.has(newCacheKey)) {
5540
+ cacheKey = newCacheKey;
5541
+ break;
5542
+ }
5543
+ }
5544
+ }
5545
+ const defers = cache.get(cacheKey) || [];
5546
+ const size = defers.length;
5547
+ const q = defer();
5548
+ defers.push(q);
5549
+ cache.set(cacheKey, defers);
5550
+ if (size) {
5551
+ return q.promise;
5552
+ }
5553
+ resolver(this, cacheKey, args);
5554
+ return q.promise;
5555
+ };
5556
+ function resolver(self, cacheKey, args) {
5557
+ const onSuccess = (r) => {
5558
+ const defers = cache.get(cacheKey) || [];
5559
+ for (const q of defers) {
5560
+ q.resolve(r);
5561
+ }
5562
+ cache.delete(cacheKey);
5563
+ };
5564
+ const onError = (r) => {
5565
+ const defers = cache.get(cacheKey) || [];
5566
+ for (const q of defers) {
5567
+ q.reject(r);
5568
+ }
5569
+ cache.delete(cacheKey);
5570
+ };
5571
+ try {
5572
+ fn.apply(self, args).then(onSuccess).catch(onError);
5573
+ } catch (err) {
5574
+ onError(err);
5575
+ }
5576
+ }
5577
+ }
5578
+
5579
+ export { AppError, AsyncIterableQueue, BrowserAssertionError, CancellablePromise, ColorParser, instance as EJSON, EJSON as EJSONInstance, EJSONStream, FindMean, FixedMap, FixedWeakMap, LruCache, Queue, ResourcePool, SimpleEventEmitter, SortedArray, TWEMOJI_REGEX, TimeBucket, TimeSpan, alpha, arrayable, assert, asyncFilter, asyncFind, asyncForEach, asyncMap, avg, avgCircular, base62, base62Fast, base64, base64ToBytes, base64url, basex, bigIntBytes, bigIntFromBytes, blendColors, buildCssColor, bytesToBase64, cache, cacheBucket, cacheFixed, cacheLRU, camelCase, capitalize, captureStackTrace, catchError, channelsToHSL, channelsToHex, channelsToRGB, checkBitmask, chunk, chunkSeries, clamp, cleanEmpty, cleanObject, colorToChannels, compareBytes, concatenateBytes, contrastRatio, convertToUnit, crc32, createCustomizer, createCustomizerFactory, createDateObject, createDeepCloneWith, createEJSON, createEJSONStream, createEnvParser, createRandomizer, createSecureCustomizer, createTimeObject, createTimeSpan, createWithCache, cssVariable, dateInDays, dateInSeconds, debounce, deepAssign, deepClone, deepCloneWith, deepDefaults, deepFreeze, def, defer, delay, difference, dropCache, env, escapeHtml, escapeNumeric, escapeRegExp, fastIdle, fastIdlePromise, fastRaf, findMean, flagsToMap, flatten, formatMoney, formatNumber, get, getFileExtension, getFileName, getInitials, getMostSpecificPaths, getRandomInt, getRandomTime, getWords, groupBy, has, hasOwn, hasProtocol, hex, hexToChannels, hmToSeconds, hslToChannels, humanFileSize, humanize, interpolateColor, intersection, intersectionBy, isBigInt, isBoolean, isCached, isClient, isColorChannels, isCustomizerFactory, isDate, isDateObject, isDef, isEmpty, isEqual, isError, isFunction, isInfinity, isMap, isNode, isNullOrUndefined, isNumber, isObject, isOneEmoji, isPlainObject, isPrimitive, isPromise, isRegExp, isSet, isSkip, isString, isSuccess, isSymbol, isTimeObject, isTimeString, isTimeValue, isValidWeekDay, isWeakMap, isWeakSet, isWithCache, isoToFlagEmoji, kebabCase, keyBy, logger, loggerSetLevel, lowerCase, luminance, maskingEmail, maskingPhone, maskingWords, nextTickIteration, noop, objectId, omit, omitPrefixed, orderBy, parseAllNumbers, parseAlpha, parsePercentage, percentOf, pick, pickPrefixed, qs, rafPromise, randomString, removeVS16s, retryOnError, rgbToChannels, round2digits, secondsToHm, set, shuffle, snakeCase, sprintf, startCase, strAssign, sum, textDecoder, textEncoder, throttle, timeFromMinutes, timeStringify, timeToMinutes, timeout, timestamp, timestampMs, timestampToDate, tintedTextColor, toError, toMap, truncate, typeOf, uint16ToUint8, uint32ToUint8, uint8ToUint16, uint8ToUint32, unflatten, union, uniq, uniqBy, unset, weeksInYear, weightedRoundRobin, withCache, withCacheBucket, withCacheBucketBatch, withCacheFixed, withCacheLRU, withDeepClone, withPointerCache, withResolve, wrapText };
5463
5580
  //# sourceMappingURL=index.mjs.map