@andrew_l/toolkit 0.3.2 → 0.3.4
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.cjs +1328 -787
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +368 -207
- package/dist/index.d.mts +368 -207
- package/dist/index.d.ts +368 -207
- package/dist/index.mjs +1323 -788
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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 (
|
|
817
|
-
|
|
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) {
|
|
@@ -885,7 +930,7 @@ function fn(value, message) {
|
|
|
885
930
|
}
|
|
886
931
|
}
|
|
887
932
|
function greaterThan(value, target, message) {
|
|
888
|
-
if (!isNumber(value) || value
|
|
933
|
+
if (!isNumber(value) || value <= target) {
|
|
889
934
|
throw toError$1(
|
|
890
935
|
greaterThan,
|
|
891
936
|
value,
|
|
@@ -1677,6 +1722,433 @@ function bigIntFromBytes(bytes) {
|
|
|
1677
1722
|
return decoded;
|
|
1678
1723
|
}
|
|
1679
1724
|
|
|
1725
|
+
function toError(value, unknownMessage = "Unknown error") {
|
|
1726
|
+
if (isError(value)) {
|
|
1727
|
+
return value;
|
|
1728
|
+
}
|
|
1729
|
+
const error = new Error(unknownMessage, { cause: value });
|
|
1730
|
+
Error.captureStackTrace(error, toError);
|
|
1731
|
+
return error;
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1734
|
+
function createFunction(fnName, code, ...args) {
|
|
1735
|
+
try {
|
|
1736
|
+
const fn = new Function(...args, code);
|
|
1737
|
+
fn.code = code;
|
|
1738
|
+
return fn;
|
|
1739
|
+
} catch (err) {
|
|
1740
|
+
throw new Error(
|
|
1741
|
+
`failed to create bitPack.${fnName}()
|
|
1742
|
+
Error: ${toError(err).message}
|
|
1743
|
+
-- CODE START --
|
|
1744
|
+
${code}
|
|
1745
|
+
-- CODE END--`
|
|
1746
|
+
);
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1749
|
+
|
|
1750
|
+
function bitPack(options) {
|
|
1751
|
+
notEmpty(options.fields, "fields cannot be empty");
|
|
1752
|
+
greaterThan(options.totalBits, 0, "totalBits must be greater than 0");
|
|
1753
|
+
const fields = buildFieldsInfo$1(options.fields, options.totalBits);
|
|
1754
|
+
const plan = buildPlan(fields);
|
|
1755
|
+
const containersCount = Math.ceil(options.totalBits / 32);
|
|
1756
|
+
const buf = new Uint8Array(containersCount * 4);
|
|
1757
|
+
const baseCode = [
|
|
1758
|
+
"\n// Field init",
|
|
1759
|
+
initFields(fields),
|
|
1760
|
+
"\n// Plan",
|
|
1761
|
+
compilePlan(plan, options.optimize)
|
|
1762
|
+
];
|
|
1763
|
+
const fnBufferCode = [
|
|
1764
|
+
...baseCode,
|
|
1765
|
+
"\n// Return result",
|
|
1766
|
+
buildBufferResult(containersCount)
|
|
1767
|
+
].join("\n");
|
|
1768
|
+
const fnBuffer = createFunction(
|
|
1769
|
+
"buffer",
|
|
1770
|
+
fnBufferCode,
|
|
1771
|
+
"data"
|
|
1772
|
+
);
|
|
1773
|
+
const fnBigIntCode = [
|
|
1774
|
+
...baseCode,
|
|
1775
|
+
"\n// Return result",
|
|
1776
|
+
buildBigIntResult(containersCount)
|
|
1777
|
+
].join("\n");
|
|
1778
|
+
const fnBigInt = createFunction(
|
|
1779
|
+
"bigint",
|
|
1780
|
+
fnBigIntCode,
|
|
1781
|
+
"data"
|
|
1782
|
+
);
|
|
1783
|
+
const fnNumberCode = [
|
|
1784
|
+
...baseCode,
|
|
1785
|
+
"\n// Return result",
|
|
1786
|
+
buildNumberResult()
|
|
1787
|
+
].join("\n");
|
|
1788
|
+
const fnNumber = createFunction(
|
|
1789
|
+
"number",
|
|
1790
|
+
fnNumberCode,
|
|
1791
|
+
"data"
|
|
1792
|
+
);
|
|
1793
|
+
const fnBitsCode = [
|
|
1794
|
+
...baseCode,
|
|
1795
|
+
"\n// Return result",
|
|
1796
|
+
buildBitsResult(containersCount, options.totalBits)
|
|
1797
|
+
].join("\n");
|
|
1798
|
+
const fnBits = createFunction("bits", fnBitsCode, "data");
|
|
1799
|
+
if (!options.debug) {
|
|
1800
|
+
def(fnBuffer, "code", void 0);
|
|
1801
|
+
def(fnBigInt, "code", void 0);
|
|
1802
|
+
def(fnNumber, "code", void 0);
|
|
1803
|
+
def(fnBits, "code", void 0);
|
|
1804
|
+
}
|
|
1805
|
+
return {
|
|
1806
|
+
buffer: fnBuffer,
|
|
1807
|
+
bigint: fnBigInt,
|
|
1808
|
+
number: fnNumber,
|
|
1809
|
+
bits: fnBits,
|
|
1810
|
+
plan: options.debug ? plan : void 0,
|
|
1811
|
+
__buf: buf
|
|
1812
|
+
};
|
|
1813
|
+
}
|
|
1814
|
+
function initFields(fields) {
|
|
1815
|
+
return fields.map((field) => {
|
|
1816
|
+
if (field.bits > 32) {
|
|
1817
|
+
return [
|
|
1818
|
+
`var ${field.id}_high = (data['${field.name}'] / 0x100000000) | 0;`,
|
|
1819
|
+
`var ${field.id}_low = (data['${field.name}'] >>> 0);`
|
|
1820
|
+
].join("\n");
|
|
1821
|
+
}
|
|
1822
|
+
if (field.take === "high") {
|
|
1823
|
+
return `var ${field.id} = (data['${field.name}'] / 0x100000000) | 0;`;
|
|
1824
|
+
}
|
|
1825
|
+
return `var ${field.id} = (data['${field.name}'] & 0x${field.mask.toString(16)}) >>> 0;`;
|
|
1826
|
+
}).join("\n");
|
|
1827
|
+
}
|
|
1828
|
+
function buildBufferResult(containersCount) {
|
|
1829
|
+
const lines = [`var buf = this.__buf;`];
|
|
1830
|
+
for (let i = 0; i < containersCount; i++) {
|
|
1831
|
+
const containerIndex = containersCount - 1 - i;
|
|
1832
|
+
lines.push(
|
|
1833
|
+
`buf[${i * 4}] = c_${containerIndex} >>> 24;`,
|
|
1834
|
+
`buf[${i * 4 + 1}] = c_${containerIndex} >>> 16;`,
|
|
1835
|
+
`buf[${i * 4 + 2}] = c_${containerIndex} >>> 8;`,
|
|
1836
|
+
`buf[${i * 4 + 3}] = c_${containerIndex};`
|
|
1837
|
+
);
|
|
1838
|
+
}
|
|
1839
|
+
lines.push("return buf;");
|
|
1840
|
+
return lines.join("\n");
|
|
1841
|
+
}
|
|
1842
|
+
function buildBigIntResult(containersCount) {
|
|
1843
|
+
const parts = [];
|
|
1844
|
+
for (let i = 0; i < containersCount; i++) {
|
|
1845
|
+
const containerIndex = containersCount - 1 - i;
|
|
1846
|
+
if (containerIndex > 0) {
|
|
1847
|
+
parts.push(
|
|
1848
|
+
`(BigInt(c_${containerIndex} >>> 0) << ${containerIndex * 32}n)`
|
|
1849
|
+
);
|
|
1850
|
+
} else {
|
|
1851
|
+
parts.push(`BigInt(c_${containerIndex} >>> 0)`);
|
|
1852
|
+
}
|
|
1853
|
+
}
|
|
1854
|
+
return `return (
|
|
1855
|
+
${parts.join(" |\n ")}
|
|
1856
|
+
);`;
|
|
1857
|
+
}
|
|
1858
|
+
function buildNumberResult(containersCount) {
|
|
1859
|
+
return `return c_0;`;
|
|
1860
|
+
}
|
|
1861
|
+
function buildBitsResult(containersCount, totalBits) {
|
|
1862
|
+
const parts = [];
|
|
1863
|
+
for (let i = 0; i < containersCount; i++) {
|
|
1864
|
+
const containerIndex = containersCount - 1 - i;
|
|
1865
|
+
if (containerIndex > 0) {
|
|
1866
|
+
parts.push(
|
|
1867
|
+
`(BigInt(c_${containerIndex} >>> 0) << ${containerIndex * 32}n)`
|
|
1868
|
+
);
|
|
1869
|
+
} else {
|
|
1870
|
+
parts.push(`BigInt(c_${containerIndex} >>> 0)`);
|
|
1871
|
+
}
|
|
1872
|
+
}
|
|
1873
|
+
return `return (
|
|
1874
|
+
${parts.join(" |\n ")}
|
|
1875
|
+
).toString(2).padStart(${totalBits}, '0');`;
|
|
1876
|
+
}
|
|
1877
|
+
function compilePlan(plan, optimize) {
|
|
1878
|
+
if (optimize) {
|
|
1879
|
+
plan = optimizePlan(plan);
|
|
1880
|
+
}
|
|
1881
|
+
const assigned = /* @__PURE__ */ new Set();
|
|
1882
|
+
return plan.map((item) => compilePlanItem(item, assigned)).join("\n");
|
|
1883
|
+
}
|
|
1884
|
+
function optimizePlan(plan) {
|
|
1885
|
+
return plan.reduce((result, item) => {
|
|
1886
|
+
const prev = result.at(-1);
|
|
1887
|
+
if (canMergeSetOperations(prev, item)) {
|
|
1888
|
+
result.pop();
|
|
1889
|
+
result.push({
|
|
1890
|
+
object: "set",
|
|
1891
|
+
container: item.container,
|
|
1892
|
+
child: {
|
|
1893
|
+
object: "value",
|
|
1894
|
+
value: [
|
|
1895
|
+
compilePlanItem(prev.child),
|
|
1896
|
+
compilePlanItem(item.child)
|
|
1897
|
+
].join(" |\n ")
|
|
1898
|
+
}
|
|
1899
|
+
});
|
|
1900
|
+
} else {
|
|
1901
|
+
result.push(item);
|
|
1902
|
+
}
|
|
1903
|
+
return result;
|
|
1904
|
+
}, []);
|
|
1905
|
+
}
|
|
1906
|
+
function canMergeSetOperations(prev, current) {
|
|
1907
|
+
return prev?.object === "set" && current.object === "set" && prev.container === current.container;
|
|
1908
|
+
}
|
|
1909
|
+
function compilePlanItem(plan, assigned) {
|
|
1910
|
+
switch (plan.object) {
|
|
1911
|
+
case "set":
|
|
1912
|
+
if (assigned && !assigned.has(plan.container)) {
|
|
1913
|
+
assigned.add(plan.container);
|
|
1914
|
+
return `var c_${plan.container} = ${compilePlanItem(plan.child)};`;
|
|
1915
|
+
}
|
|
1916
|
+
return `c_${plan.container} |= ${compilePlanItem(plan.child)};`;
|
|
1917
|
+
case "value":
|
|
1918
|
+
const offset = plan.offset ?? 0;
|
|
1919
|
+
return offset > 0 ? `(${plan.value}) << ${offset}` : `(${plan.value})`;
|
|
1920
|
+
default:
|
|
1921
|
+
throw new Error(`Unknown plan object: ${plan.object}`);
|
|
1922
|
+
}
|
|
1923
|
+
}
|
|
1924
|
+
function buildPlan(fields) {
|
|
1925
|
+
const result = [];
|
|
1926
|
+
for (const field of fields) {
|
|
1927
|
+
const startContainer = Math.floor(field.startBit / 32);
|
|
1928
|
+
const endContainer = Math.floor(field.endBit / 32);
|
|
1929
|
+
if (startContainer === endContainer) {
|
|
1930
|
+
addSingleContainerField(field, result);
|
|
1931
|
+
} else if (field.bits <= 32) {
|
|
1932
|
+
addSpanningField(field, result);
|
|
1933
|
+
} else {
|
|
1934
|
+
addLargeField(field, result);
|
|
1935
|
+
}
|
|
1936
|
+
}
|
|
1937
|
+
return result;
|
|
1938
|
+
}
|
|
1939
|
+
function addSingleContainerField(field, result) {
|
|
1940
|
+
result.push({
|
|
1941
|
+
object: "set",
|
|
1942
|
+
container: Math.floor(field.startBit / 32),
|
|
1943
|
+
child: {
|
|
1944
|
+
object: "value",
|
|
1945
|
+
offset: field.startBit % 32,
|
|
1946
|
+
value: field.id
|
|
1947
|
+
}
|
|
1948
|
+
});
|
|
1949
|
+
}
|
|
1950
|
+
function addSpanningField(field, result) {
|
|
1951
|
+
const startContainer = Math.floor(field.startBit / 32);
|
|
1952
|
+
const endContainer = Math.floor(field.endBit / 32);
|
|
1953
|
+
const firstContainerBits = 32 - field.startBit % 32;
|
|
1954
|
+
result.push({
|
|
1955
|
+
object: "set",
|
|
1956
|
+
container: startContainer,
|
|
1957
|
+
child: {
|
|
1958
|
+
object: "value",
|
|
1959
|
+
offset: field.startBit % 32,
|
|
1960
|
+
value: `(${field.id}) & ${(1 << firstContainerBits) - 1}`
|
|
1961
|
+
}
|
|
1962
|
+
});
|
|
1963
|
+
result.push({
|
|
1964
|
+
object: "set",
|
|
1965
|
+
container: endContainer,
|
|
1966
|
+
child: {
|
|
1967
|
+
object: "value",
|
|
1968
|
+
value: `(${field.id}) >>> ${firstContainerBits}`
|
|
1969
|
+
}
|
|
1970
|
+
});
|
|
1971
|
+
}
|
|
1972
|
+
function addLargeField(field, result) {
|
|
1973
|
+
const startContainer = Math.floor(field.startBit / 32);
|
|
1974
|
+
const endContainer = Math.floor(field.endBit / 32);
|
|
1975
|
+
const startOffset = field.startBit % 32;
|
|
1976
|
+
ok(
|
|
1977
|
+
startContainer !== endContainer,
|
|
1978
|
+
`Large field ${field.name} fits in single container - logic error`
|
|
1979
|
+
);
|
|
1980
|
+
ok(
|
|
1981
|
+
endContainer - startContainer === 1,
|
|
1982
|
+
`Fields spanning more than 2 containers (${field.bits} bits) not yet supported`
|
|
1983
|
+
);
|
|
1984
|
+
const bitsInLowerContainer = 32 - startOffset;
|
|
1985
|
+
result.push({
|
|
1986
|
+
object: "set",
|
|
1987
|
+
container: endContainer,
|
|
1988
|
+
child: {
|
|
1989
|
+
object: "value",
|
|
1990
|
+
offset: startOffset,
|
|
1991
|
+
value: `${field.id}_high`
|
|
1992
|
+
}
|
|
1993
|
+
});
|
|
1994
|
+
if (bitsInLowerContainer < 32) {
|
|
1995
|
+
result.push({
|
|
1996
|
+
object: "set",
|
|
1997
|
+
container: endContainer,
|
|
1998
|
+
child: {
|
|
1999
|
+
object: "value",
|
|
2000
|
+
value: `${field.id}_low >>> ${bitsInLowerContainer}`
|
|
2001
|
+
}
|
|
2002
|
+
});
|
|
2003
|
+
}
|
|
2004
|
+
if (field.bits > 32) {
|
|
2005
|
+
result.push({
|
|
2006
|
+
object: "set",
|
|
2007
|
+
container: startContainer,
|
|
2008
|
+
child: {
|
|
2009
|
+
object: "value",
|
|
2010
|
+
offset: startOffset,
|
|
2011
|
+
value: `${field.id}_low`
|
|
2012
|
+
}
|
|
2013
|
+
});
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
function buildFieldsInfo$1(fields, totalBits) {
|
|
2017
|
+
const result = [];
|
|
2018
|
+
let currentBitPosition = totalBits;
|
|
2019
|
+
fields.forEach((field, idx) => {
|
|
2020
|
+
const startBit = currentBitPosition - field.bits;
|
|
2021
|
+
const endBit = currentBitPosition - 1;
|
|
2022
|
+
result.push({
|
|
2023
|
+
id: `f_${idx}`,
|
|
2024
|
+
...field,
|
|
2025
|
+
startBit,
|
|
2026
|
+
endBit,
|
|
2027
|
+
mask: Math.pow(2, field.bits) - 1
|
|
2028
|
+
});
|
|
2029
|
+
currentBitPosition -= field.bits;
|
|
2030
|
+
});
|
|
2031
|
+
return result;
|
|
2032
|
+
}
|
|
2033
|
+
|
|
2034
|
+
function bitUnpack(options) {
|
|
2035
|
+
notEmpty(options.fields, "fields cannot be empty");
|
|
2036
|
+
greaterThan(options.totalBits, 0, "totalBits must be greater than 0");
|
|
2037
|
+
const fields = buildFieldsInfo(options.fields, options.totalBits);
|
|
2038
|
+
const fnBigIntCode = [`return ${compileFields(fields)};`].join("\n");
|
|
2039
|
+
const fnBigInt = createFunction(
|
|
2040
|
+
"bigint",
|
|
2041
|
+
fnBigIntCode,
|
|
2042
|
+
"data"
|
|
2043
|
+
);
|
|
2044
|
+
const fnNumberCode = [
|
|
2045
|
+
"\n// Extract container from number",
|
|
2046
|
+
"data = BigInt(data);",
|
|
2047
|
+
"\n// Return result",
|
|
2048
|
+
`return ${compileFields(fields)};`
|
|
2049
|
+
].join("\n");
|
|
2050
|
+
const fnNumber = createFunction(
|
|
2051
|
+
"number",
|
|
2052
|
+
fnNumberCode,
|
|
2053
|
+
"data"
|
|
2054
|
+
);
|
|
2055
|
+
const fnBufferCode = [
|
|
2056
|
+
"\n// Extract bytes from buffer (big-endian)",
|
|
2057
|
+
extractBigIntFromBuffer(options.totalBits),
|
|
2058
|
+
"\n// Return result",
|
|
2059
|
+
`return ${compileFields(fields)};`
|
|
2060
|
+
].join("\n");
|
|
2061
|
+
const fnBuffer = createFunction(
|
|
2062
|
+
"buffer",
|
|
2063
|
+
fnBufferCode,
|
|
2064
|
+
"data"
|
|
2065
|
+
);
|
|
2066
|
+
const fnBitsCode = [
|
|
2067
|
+
"\n// Convert bits string to bigint",
|
|
2068
|
+
'var data = BigInt("0b" + bits);',
|
|
2069
|
+
"\n// Return result",
|
|
2070
|
+
`return ${compileFields(fields)};`
|
|
2071
|
+
].join("\n");
|
|
2072
|
+
const fnBits = createFunction("bits", fnBitsCode, "bits");
|
|
2073
|
+
if (!options.debug) {
|
|
2074
|
+
def(fnBuffer, "code", void 0);
|
|
2075
|
+
def(fnBigInt, "code", void 0);
|
|
2076
|
+
def(fnNumber, "code", void 0);
|
|
2077
|
+
def(fnBits, "code", void 0);
|
|
2078
|
+
}
|
|
2079
|
+
return {
|
|
2080
|
+
buffer: fnBuffer,
|
|
2081
|
+
bigint: fnBigInt,
|
|
2082
|
+
number: fnNumber,
|
|
2083
|
+
bits: fnBits
|
|
2084
|
+
};
|
|
2085
|
+
}
|
|
2086
|
+
function compileFields(fields) {
|
|
2087
|
+
const lines = ["{"];
|
|
2088
|
+
for (const field of fields) {
|
|
2089
|
+
if (field.startBit === 0) {
|
|
2090
|
+
lines.push(
|
|
2091
|
+
` ['${field.name}']: Number(data & 0x${field.mask.toString(16)}n),`
|
|
2092
|
+
);
|
|
2093
|
+
} else {
|
|
2094
|
+
lines.push(
|
|
2095
|
+
` ['${field.name}']: Number((data >> ${field.startBit}n) & 0x${field.mask.toString(16)}n),`
|
|
2096
|
+
);
|
|
2097
|
+
}
|
|
2098
|
+
}
|
|
2099
|
+
lines.push("}");
|
|
2100
|
+
return lines.join("\n");
|
|
2101
|
+
}
|
|
2102
|
+
function extractBigIntFromBuffer(totalBits) {
|
|
2103
|
+
const totalBytes = Math.ceil(totalBits / 8);
|
|
2104
|
+
const chunks = [];
|
|
2105
|
+
let byteIndex = 0;
|
|
2106
|
+
let remainingBytes = totalBytes;
|
|
2107
|
+
while (remainingBytes > 0) {
|
|
2108
|
+
if (remainingBytes >= 4) {
|
|
2109
|
+
const shift = (remainingBytes - 4) * 8;
|
|
2110
|
+
const chunk = `((data[${byteIndex}] << 24) | (data[${byteIndex + 1}] << 16) | (data[${byteIndex + 2}] << 8) | data[${byteIndex + 3}]) >>> 0`;
|
|
2111
|
+
if (shift === 0) {
|
|
2112
|
+
chunks.push(`BigInt(${chunk})`);
|
|
2113
|
+
} else {
|
|
2114
|
+
chunks.push(`(BigInt(${chunk}) << ${shift}n)`);
|
|
2115
|
+
}
|
|
2116
|
+
byteIndex += 4;
|
|
2117
|
+
remainingBytes -= 4;
|
|
2118
|
+
} else {
|
|
2119
|
+
let chunk;
|
|
2120
|
+
if (remainingBytes === 3) {
|
|
2121
|
+
chunk = `(data[${byteIndex}] << 16) | (data[${byteIndex + 1}] << 8) | data[${byteIndex + 2}]`;
|
|
2122
|
+
} else if (remainingBytes === 2) {
|
|
2123
|
+
chunk = `(data[${byteIndex}] << 8) | data[${byteIndex + 1}]`;
|
|
2124
|
+
} else {
|
|
2125
|
+
chunk = `data[${byteIndex}]`;
|
|
2126
|
+
}
|
|
2127
|
+
chunks.push(`BigInt(${chunk})`);
|
|
2128
|
+
remainingBytes = 0;
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
2131
|
+
return `data =
|
|
2132
|
+
${chunks.join("\n | ")};`;
|
|
2133
|
+
}
|
|
2134
|
+
function buildFieldsInfo(fields, totalBits) {
|
|
2135
|
+
const result = [];
|
|
2136
|
+
let currentBitPosition = totalBits;
|
|
2137
|
+
fields.forEach((field, idx) => {
|
|
2138
|
+
const startBit = currentBitPosition - field.bits;
|
|
2139
|
+
const endBit = currentBitPosition - 1;
|
|
2140
|
+
result.push({
|
|
2141
|
+
id: `f_${idx}`,
|
|
2142
|
+
...field,
|
|
2143
|
+
mask: (1n << BigInt(field.bits)) - 1n,
|
|
2144
|
+
startBit,
|
|
2145
|
+
endBit
|
|
2146
|
+
});
|
|
2147
|
+
currentBitPosition -= field.bits;
|
|
2148
|
+
});
|
|
2149
|
+
return result;
|
|
2150
|
+
}
|
|
2151
|
+
|
|
1680
2152
|
function bytesToBase64(data, { encoding = "base64", padding } = {}) {
|
|
1681
2153
|
if (encoding === "base64") {
|
|
1682
2154
|
return base64.encode(data, { includePadding: padding ?? true });
|
|
@@ -1749,92 +2221,453 @@ function uint8ToUint32(value) {
|
|
|
1749
2221
|
return uint32Array;
|
|
1750
2222
|
}
|
|
1751
2223
|
|
|
1752
|
-
const
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
if (isObject(value)) {
|
|
1758
|
-
if (BSON_TYPES.has(value?._bsontype)) {
|
|
1759
|
-
return String(value);
|
|
2224
|
+
const DateType = {
|
|
2225
|
+
placeholder: "$date",
|
|
2226
|
+
encode: (value) => {
|
|
2227
|
+
if (value instanceof Date) {
|
|
2228
|
+
return value.getTime();
|
|
1760
2229
|
}
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
2230
|
+
},
|
|
2231
|
+
decode(value) {
|
|
2232
|
+
return new Date(value);
|
|
2233
|
+
}
|
|
2234
|
+
};
|
|
2235
|
+
const BinaryType = {
|
|
2236
|
+
placeholder: "$binary",
|
|
2237
|
+
encode: (value) => {
|
|
2238
|
+
if (value instanceof Uint8Array) {
|
|
2239
|
+
return base64.encode(value, { includePadding: true });
|
|
2240
|
+
} else if (value instanceof Uint16Array) {
|
|
2241
|
+
return {
|
|
2242
|
+
value: base64.encode(uint16ToUint8(value), { includePadding: true }),
|
|
2243
|
+
bit: 16
|
|
2244
|
+
};
|
|
2245
|
+
} else if (value instanceof Uint32Array) {
|
|
2246
|
+
return {
|
|
2247
|
+
value: base64.encode(uint32ToUint8(value), { includePadding: true }),
|
|
2248
|
+
bit: 32
|
|
2249
|
+
};
|
|
1770
2250
|
}
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
2251
|
+
},
|
|
2252
|
+
decode(value) {
|
|
2253
|
+
if (typeof value === "string") {
|
|
2254
|
+
return base64.decode(value, { strict: true });
|
|
2255
|
+
} else if (value.bit === 16) {
|
|
2256
|
+
return uint8ToUint16(base64.decode(value.value, { strict: true }));
|
|
2257
|
+
} else if (value.bit === 32) {
|
|
2258
|
+
return uint8ToUint32(base64.decode(value.value, { strict: true }));
|
|
2259
|
+
}
|
|
2260
|
+
throw new Error("Unexpected $binary bit value: " + value.bit);
|
|
1776
2261
|
}
|
|
1777
|
-
return result;
|
|
1778
2262
|
};
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
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;
|
|
2263
|
+
const BigIntType = {
|
|
2264
|
+
placeholder: "$bigint",
|
|
2265
|
+
encode: (value) => {
|
|
2266
|
+
if (typeof value === "bigint") {
|
|
2267
|
+
return base64.encode(bigIntBytes(value), { includePadding: false });
|
|
1802
2268
|
}
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
2269
|
+
},
|
|
2270
|
+
decode(value) {
|
|
2271
|
+
return bigIntFromBytes(base64.decode(value, { strict: false }));
|
|
2272
|
+
}
|
|
2273
|
+
};
|
|
2274
|
+
const MapType = {
|
|
2275
|
+
placeholder: "$map",
|
|
2276
|
+
encode: (value, encode) => {
|
|
2277
|
+
if (value instanceof Map) {
|
|
2278
|
+
return encode(Array.from(value.entries()));
|
|
1809
2279
|
}
|
|
1810
|
-
|
|
1811
|
-
|
|
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];
|
|
2280
|
+
},
|
|
2281
|
+
decode(value) {
|
|
2282
|
+
return new Map(value);
|
|
1830
2283
|
}
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
if (
|
|
1836
|
-
|
|
1837
|
-
|
|
2284
|
+
};
|
|
2285
|
+
const SetType = {
|
|
2286
|
+
placeholder: "$set",
|
|
2287
|
+
encode: (value, encode) => {
|
|
2288
|
+
if (value instanceof Set) {
|
|
2289
|
+
return encode(Array.from(value.values()));
|
|
2290
|
+
}
|
|
2291
|
+
},
|
|
2292
|
+
decode(value) {
|
|
2293
|
+
return new Set(value);
|
|
2294
|
+
}
|
|
2295
|
+
};
|
|
2296
|
+
const RegexType = {
|
|
2297
|
+
placeholder: "$regex",
|
|
2298
|
+
encode: (value, encode) => {
|
|
2299
|
+
if (value instanceof RegExp) {
|
|
2300
|
+
const regStr = value.toString();
|
|
2301
|
+
const patternStart = regStr.lastIndexOf("/");
|
|
2302
|
+
return {
|
|
2303
|
+
pattern: value.toString().slice(1, patternStart),
|
|
2304
|
+
flags: regStr.slice(patternStart + 1)
|
|
2305
|
+
};
|
|
2306
|
+
}
|
|
2307
|
+
},
|
|
2308
|
+
decode(value) {
|
|
2309
|
+
return new RegExp(value.pattern, value.flags);
|
|
2310
|
+
}
|
|
2311
|
+
};
|
|
2312
|
+
const InfinityType = {
|
|
2313
|
+
placeholder: "$inf",
|
|
2314
|
+
encode: (value, encode) => {
|
|
2315
|
+
if (value === Infinity) {
|
|
2316
|
+
return 1;
|
|
2317
|
+
} else if (value === -Infinity) {
|
|
2318
|
+
return -1;
|
|
2319
|
+
}
|
|
2320
|
+
},
|
|
2321
|
+
decode(value) {
|
|
2322
|
+
if (value === 1) return Infinity;
|
|
2323
|
+
if (value === -1) return -Infinity;
|
|
2324
|
+
throw new Error("Unexpected $inf value: " + value);
|
|
2325
|
+
}
|
|
2326
|
+
};
|
|
2327
|
+
|
|
2328
|
+
class EJSON {
|
|
2329
|
+
/** @internal */
|
|
2330
|
+
typeHandlers = /* @__PURE__ */ new Map();
|
|
2331
|
+
/** @internal */
|
|
2332
|
+
replacerReady;
|
|
2333
|
+
/** @internal */
|
|
2334
|
+
encode;
|
|
2335
|
+
/** @internal */
|
|
2336
|
+
reviewerReady;
|
|
2337
|
+
/** @internal */
|
|
2338
|
+
pure = true;
|
|
2339
|
+
_vendorName = null;
|
|
2340
|
+
/**
|
|
2341
|
+
* MIME type based on the provided vendor name or defaults to 'application/json'.
|
|
2342
|
+
*/
|
|
2343
|
+
mimetype = "application/json";
|
|
2344
|
+
Type = {
|
|
2345
|
+
Date: DateType,
|
|
2346
|
+
Map: MapType,
|
|
2347
|
+
Set: SetType,
|
|
2348
|
+
RegExp: RegexType,
|
|
2349
|
+
Infinity: InfinityType,
|
|
2350
|
+
BigInt: BigIntType,
|
|
2351
|
+
Binary: BinaryType
|
|
2352
|
+
};
|
|
2353
|
+
constructor() {
|
|
2354
|
+
this.replacerReady = this._replacer.bind(this);
|
|
2355
|
+
this.reviewerReady = this._reviewer.bind(this);
|
|
2356
|
+
this.encode = (value) => {
|
|
2357
|
+
return deepCloneWith(value, this.replacerReady);
|
|
2358
|
+
};
|
|
2359
|
+
}
|
|
2360
|
+
/**
|
|
2361
|
+
* The vendor name used for the custom MIME type definition.
|
|
2362
|
+
* If null, defaults to 'application/json'.
|
|
2363
|
+
*/
|
|
2364
|
+
get vendorName() {
|
|
2365
|
+
return this._vendorName;
|
|
2366
|
+
}
|
|
2367
|
+
set vendorName(value) {
|
|
2368
|
+
this._vendorName = value;
|
|
2369
|
+
if (!value) {
|
|
2370
|
+
this.mimetype = "application/json";
|
|
2371
|
+
} else {
|
|
2372
|
+
const vendorName = value.split(" ").map((v) => v.toLowerCase()).join(".").replace(/\.\.+/g, ".").replace(/\.$/, "");
|
|
2373
|
+
this.mimetype = `application/vnd.${vendorName}+json`;
|
|
2374
|
+
}
|
|
2375
|
+
}
|
|
2376
|
+
/**
|
|
2377
|
+
* Adds a custom type handler for encoding/decoding logic.
|
|
2378
|
+
* Ensures type placeholders are unique and adhere to conventions.
|
|
2379
|
+
*/
|
|
2380
|
+
addType(type) {
|
|
2381
|
+
ok(
|
|
2382
|
+
!this.typeHandlers.has(type.placeholder),
|
|
2383
|
+
`type with ${type.placeholder} already taken.`
|
|
2384
|
+
);
|
|
2385
|
+
ok(
|
|
2386
|
+
type.placeholder.startsWith("$"),
|
|
2387
|
+
"type placeholder must starts with $ symbol."
|
|
2388
|
+
);
|
|
2389
|
+
this.pure = false;
|
|
2390
|
+
this.typeHandlers.set(type.placeholder, type);
|
|
2391
|
+
return this;
|
|
2392
|
+
}
|
|
2393
|
+
/**
|
|
2394
|
+
* Stringifies a JavaScript value using custom encoding logic.
|
|
2395
|
+
* @param {any} value - The value to encode and stringify.
|
|
2396
|
+
* @param {string | number} [space] - Optional space for pretty-printing.
|
|
2397
|
+
* @returns {string} - The JSON stringified value.
|
|
2398
|
+
*/
|
|
2399
|
+
stringify(value, space) {
|
|
2400
|
+
if (this.pure) {
|
|
2401
|
+
return JSON.stringify(value, void 0, space);
|
|
2402
|
+
}
|
|
2403
|
+
return JSON.stringify(this.encode(value), void 0, space);
|
|
2404
|
+
}
|
|
2405
|
+
/**
|
|
2406
|
+
* Parses a JSON string using custom decoding logic.
|
|
2407
|
+
* @param {string} value - The JSON string to parse.
|
|
2408
|
+
* @returns {any} - The decoded JavaScript object.
|
|
2409
|
+
*/
|
|
2410
|
+
parse(value) {
|
|
2411
|
+
if (this.pure) {
|
|
2412
|
+
return JSON.parse(value);
|
|
2413
|
+
}
|
|
2414
|
+
return JSON.parse(value, this.reviewerReady);
|
|
2415
|
+
}
|
|
2416
|
+
/** @internal */
|
|
2417
|
+
_replacer(value, key) {
|
|
2418
|
+
if (isPlainObject(value)) return;
|
|
2419
|
+
if (Array.isArray(value)) return;
|
|
2420
|
+
if (!isInfinity(value) && !isBigInt(value)) {
|
|
2421
|
+
if (isPrimitive(value)) return;
|
|
2422
|
+
}
|
|
2423
|
+
for (const type of this.typeHandlers.values()) {
|
|
2424
|
+
const res = type.encode(value, this.encode);
|
|
2425
|
+
if (res !== void 0) {
|
|
2426
|
+
return type.encodeInline ? res : { [type.placeholder]: res };
|
|
2427
|
+
}
|
|
2428
|
+
}
|
|
2429
|
+
return value;
|
|
2430
|
+
}
|
|
2431
|
+
/** @internal */
|
|
2432
|
+
_reviewer(_, value) {
|
|
2433
|
+
const key = firstKey(value);
|
|
2434
|
+
if (!key || key[0] !== "$") return value;
|
|
2435
|
+
const type = this.typeHandlers.get(key);
|
|
2436
|
+
if (type) {
|
|
2437
|
+
return type.decode(value[key]);
|
|
2438
|
+
}
|
|
2439
|
+
return value;
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2442
|
+
function firstKey(value) {
|
|
2443
|
+
if (!isObject(value)) return null;
|
|
2444
|
+
for (const key in value) {
|
|
2445
|
+
return key;
|
|
2446
|
+
}
|
|
2447
|
+
return null;
|
|
2448
|
+
}
|
|
2449
|
+
|
|
2450
|
+
function createEJSON(withBasicTypes = false) {
|
|
2451
|
+
const ejson = new EJSON();
|
|
2452
|
+
if (withBasicTypes) {
|
|
2453
|
+
ejson.addType(MapType);
|
|
2454
|
+
ejson.addType(SetType);
|
|
2455
|
+
ejson.addType(DateType);
|
|
2456
|
+
ejson.addType(InfinityType);
|
|
2457
|
+
ejson.addType(BigIntType);
|
|
2458
|
+
ejson.addType(BinaryType);
|
|
2459
|
+
ejson.addType(RegexType);
|
|
2460
|
+
}
|
|
2461
|
+
return ejson;
|
|
2462
|
+
}
|
|
2463
|
+
|
|
2464
|
+
class EJSONStream extends TransformStream {
|
|
2465
|
+
ejson;
|
|
2466
|
+
constructor({ ejson, cl, op, sep, onFlush, onStart }) {
|
|
2467
|
+
let firstChunk = true;
|
|
2468
|
+
super({
|
|
2469
|
+
start(controller) {
|
|
2470
|
+
return Promise.resolve().then(() => {
|
|
2471
|
+
if (onStart) {
|
|
2472
|
+
return onStart(controller);
|
|
2473
|
+
}
|
|
2474
|
+
}).then(() => {
|
|
2475
|
+
controller.enqueue(op);
|
|
2476
|
+
});
|
|
2477
|
+
},
|
|
2478
|
+
transform(chunk, controller) {
|
|
2479
|
+
const jsonString = ejson.stringify(chunk);
|
|
2480
|
+
if (firstChunk) {
|
|
2481
|
+
firstChunk = false;
|
|
2482
|
+
} else {
|
|
2483
|
+
controller.enqueue(sep);
|
|
2484
|
+
}
|
|
2485
|
+
controller.enqueue(jsonString);
|
|
2486
|
+
},
|
|
2487
|
+
flush(controller) {
|
|
2488
|
+
controller.enqueue(cl);
|
|
2489
|
+
if (onFlush) {
|
|
2490
|
+
return onFlush(controller);
|
|
2491
|
+
}
|
|
2492
|
+
}
|
|
2493
|
+
});
|
|
2494
|
+
this.ejson = ejson;
|
|
2495
|
+
}
|
|
2496
|
+
/**
|
|
2497
|
+
* The vendor name used for the custom MIME type definition.
|
|
2498
|
+
* If null, defaults to 'application/json'.
|
|
2499
|
+
*/
|
|
2500
|
+
get vendorName() {
|
|
2501
|
+
return this.ejson.vendorName;
|
|
2502
|
+
}
|
|
2503
|
+
/**
|
|
2504
|
+
* MIME type based on the provided vendor name or defaults to 'application/json'.
|
|
2505
|
+
*/
|
|
2506
|
+
get mimetype() {
|
|
2507
|
+
return this.ejson.mimetype;
|
|
2508
|
+
}
|
|
2509
|
+
}
|
|
2510
|
+
|
|
2511
|
+
const instance = createEJSON(true);
|
|
2512
|
+
|
|
2513
|
+
function createEJSONStream(options = {}) {
|
|
2514
|
+
if (options.resultKey || options.append || options.prepend) {
|
|
2515
|
+
return createEJSONStreamPayload(options);
|
|
2516
|
+
}
|
|
2517
|
+
return new EJSONStream(getOptions(options));
|
|
2518
|
+
}
|
|
2519
|
+
function createEJSONStreamPayload(options) {
|
|
2520
|
+
let { cl, ejson, op, sep } = getOptions(options);
|
|
2521
|
+
const { append, prepend, resultKey } = options;
|
|
2522
|
+
notEmptyString(resultKey, "resultKey required.");
|
|
2523
|
+
const stream = new EJSONStream({
|
|
2524
|
+
ejson,
|
|
2525
|
+
cl,
|
|
2526
|
+
op,
|
|
2527
|
+
sep,
|
|
2528
|
+
onStart(controller) {
|
|
2529
|
+
if (!prepend) {
|
|
2530
|
+
controller.enqueue(`{"${resultKey}":`);
|
|
2531
|
+
return Promise.resolve();
|
|
2532
|
+
}
|
|
2533
|
+
return Promise.resolve().then(() => prepend()).then((data) => {
|
|
2534
|
+
if (data === null || data === void 0) {
|
|
2535
|
+
controller.enqueue(`{"${resultKey}":`);
|
|
2536
|
+
return;
|
|
2537
|
+
}
|
|
2538
|
+
ok(
|
|
2539
|
+
isPlainObject(data),
|
|
2540
|
+
"prepend result expected to be plain object"
|
|
2541
|
+
);
|
|
2542
|
+
const dataPart = instance.stringify(data).slice(0, -1);
|
|
2543
|
+
if (dataPart === "{") {
|
|
2544
|
+
controller.enqueue(`{"${resultKey}":`);
|
|
2545
|
+
return;
|
|
2546
|
+
}
|
|
2547
|
+
controller.enqueue(`${dataPart}${sep}"${resultKey}":`);
|
|
2548
|
+
});
|
|
2549
|
+
},
|
|
2550
|
+
onFlush(controller) {
|
|
2551
|
+
if (!append) {
|
|
2552
|
+
controller.enqueue("}");
|
|
2553
|
+
return Promise.resolve();
|
|
2554
|
+
}
|
|
2555
|
+
return Promise.resolve().then(() => append()).then((data) => {
|
|
2556
|
+
if (data === null || data === void 0) {
|
|
2557
|
+
controller.enqueue("}");
|
|
2558
|
+
return;
|
|
2559
|
+
}
|
|
2560
|
+
ok(
|
|
2561
|
+
isPlainObject(data),
|
|
2562
|
+
"prepend result expected to be plain object"
|
|
2563
|
+
);
|
|
2564
|
+
const dataPart = instance.stringify(data).slice(1);
|
|
2565
|
+
if (dataPart === "}") {
|
|
2566
|
+
controller.enqueue(`}`);
|
|
2567
|
+
return;
|
|
2568
|
+
}
|
|
2569
|
+
controller.enqueue(`${sep}${dataPart}`);
|
|
2570
|
+
});
|
|
2571
|
+
}
|
|
2572
|
+
});
|
|
2573
|
+
return stream;
|
|
2574
|
+
}
|
|
2575
|
+
function getOptions(options) {
|
|
2576
|
+
const { ejson = instance, cl = "]", op = "[", sep = "," } = options;
|
|
2577
|
+
return {
|
|
2578
|
+
cl,
|
|
2579
|
+
ejson,
|
|
2580
|
+
op,
|
|
2581
|
+
sep
|
|
2582
|
+
};
|
|
2583
|
+
}
|
|
2584
|
+
|
|
2585
|
+
const objectKeys = /* @__PURE__ */ new WeakMap();
|
|
2586
|
+
const BSON_TYPES = Object.freeze(/* @__PURE__ */ new Set(["ObjectID", "ObjectId"]));
|
|
2587
|
+
const SYM_WITH_CACHE = Symbol();
|
|
2588
|
+
const argToKey = (value, options = { objectStrategy: "ref" }) => {
|
|
2589
|
+
let result = "";
|
|
2590
|
+
if (isObject(value)) {
|
|
2591
|
+
if (BSON_TYPES.has(value?._bsontype)) {
|
|
2592
|
+
return String(value);
|
|
2593
|
+
}
|
|
2594
|
+
let key;
|
|
2595
|
+
if (options.objectStrategy === "json") {
|
|
2596
|
+
key = instance.stringify(value);
|
|
2597
|
+
} else {
|
|
2598
|
+
key = objectKeys.get(value);
|
|
2599
|
+
if (!key) {
|
|
2600
|
+
key = createRadomKey();
|
|
2601
|
+
objectKeys.set(value, key);
|
|
2602
|
+
}
|
|
2603
|
+
}
|
|
2604
|
+
return key;
|
|
2605
|
+
} else if (Array.isArray(value)) {
|
|
2606
|
+
result += value.map((v) => argToKey(v, options)).join("/");
|
|
2607
|
+
} else {
|
|
2608
|
+
result = String(value);
|
|
2609
|
+
}
|
|
2610
|
+
return result;
|
|
2611
|
+
};
|
|
2612
|
+
function createRadomKey() {
|
|
2613
|
+
return Date.now() + "_" + randomString(16);
|
|
2614
|
+
}
|
|
2615
|
+
|
|
2616
|
+
function createWithCache({
|
|
2617
|
+
fn,
|
|
2618
|
+
getPointer,
|
|
2619
|
+
getBucket,
|
|
2620
|
+
objectStrategy = "ref"
|
|
2621
|
+
}) {
|
|
2622
|
+
const isAsync = fn.constructor.name === "AsyncFunction";
|
|
2623
|
+
const argToKeyOptions = { objectStrategy };
|
|
2624
|
+
const $cache = {
|
|
2625
|
+
getBucket: () => getBucket(getPointer()),
|
|
2626
|
+
getPointer,
|
|
2627
|
+
argToKeyOptions
|
|
2628
|
+
};
|
|
2629
|
+
const wrapFn = function(...args) {
|
|
2630
|
+
const storage = getBucket(getPointer());
|
|
2631
|
+
const cacheKey = args.map((v) => argToKey(v, argToKeyOptions)).join("_");
|
|
2632
|
+
if (storage.has(cacheKey)) {
|
|
2633
|
+
const value = storage.get(cacheKey);
|
|
2634
|
+
return isAsync ? Promise.resolve(value) : value;
|
|
2635
|
+
}
|
|
2636
|
+
const newValue = fn.apply(this, args);
|
|
2637
|
+
if (isPromise(newValue)) {
|
|
2638
|
+
return newValue.then((value) => {
|
|
2639
|
+
storage.set(cacheKey, value);
|
|
2640
|
+
return value;
|
|
2641
|
+
});
|
|
2642
|
+
}
|
|
2643
|
+
storage.set(cacheKey, newValue);
|
|
2644
|
+
return newValue;
|
|
2645
|
+
};
|
|
2646
|
+
wrapFn.$cache = $cache;
|
|
2647
|
+
def(wrapFn, SYM_WITH_CACHE, true);
|
|
2648
|
+
return wrapFn;
|
|
2649
|
+
}
|
|
2650
|
+
function isWithCache(value) {
|
|
2651
|
+
return !!value && value[SYM_WITH_CACHE] === true;
|
|
2652
|
+
}
|
|
2653
|
+
|
|
2654
|
+
const cache = /* @__PURE__ */ new WeakMap();
|
|
2655
|
+
function withCache(...args) {
|
|
2656
|
+
let options = {};
|
|
2657
|
+
let fn = noop;
|
|
2658
|
+
if (isFunction(args[0])) {
|
|
2659
|
+
fn = args[0];
|
|
2660
|
+
} else if (isFunction(args[1])) {
|
|
2661
|
+
options = args[0] || {};
|
|
2662
|
+
fn = args[1];
|
|
2663
|
+
}
|
|
2664
|
+
const pointer = options.cachePointer || fn;
|
|
2665
|
+
const getPointer = () => pointer;
|
|
2666
|
+
const getBucket = (pointer2) => {
|
|
2667
|
+
let fnCache = cache.get(pointer2);
|
|
2668
|
+
if (!fnCache) {
|
|
2669
|
+
fnCache = /* @__PURE__ */ new Map();
|
|
2670
|
+
cache.set(pointer2, fnCache);
|
|
1838
2671
|
}
|
|
1839
2672
|
return fnCache;
|
|
1840
2673
|
};
|
|
@@ -2448,15 +3281,6 @@ function captureStackTrace(till) {
|
|
|
2448
3281
|
return (err.stack || "").slice(6);
|
|
2449
3282
|
}
|
|
2450
3283
|
|
|
2451
|
-
function toError(value, unknownMessage = "Unknown error") {
|
|
2452
|
-
if (isError(value)) {
|
|
2453
|
-
return value;
|
|
2454
|
-
}
|
|
2455
|
-
const error = new Error(unknownMessage, { cause: value });
|
|
2456
|
-
Error.captureStackTrace(error, toError);
|
|
2457
|
-
return error;
|
|
2458
|
-
}
|
|
2459
|
-
|
|
2460
3284
|
function catchError(fn) {
|
|
2461
3285
|
try {
|
|
2462
3286
|
const res = fn();
|
|
@@ -3406,678 +4230,317 @@ var TABLE = new Int32Array([
|
|
|
3406
4230
|
755167117
|
|
3407
4231
|
]);
|
|
3408
4232
|
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");
|
|
4233
|
+
if (isString(value)) {
|
|
4234
|
+
return crc32(textEncoder.encode(value), seed);
|
|
3600
4235
|
}
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
}
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
fromValue = isDate(dt) ? dt.getTime() : 0;
|
|
4236
|
+
var crc = seed === 0 ? 0 : ~~seed ^ -1;
|
|
4237
|
+
if (value instanceof Uint8Array) {
|
|
4238
|
+
for (var index = 0; index < value.length; index++) {
|
|
4239
|
+
crc = TABLE[(crc ^ value[index]) & 255] ^ crc >>> 8;
|
|
4240
|
+
}
|
|
4241
|
+
} else {
|
|
4242
|
+
for (var current of value) {
|
|
4243
|
+
for (var index = 0; index < current.length; index++) {
|
|
4244
|
+
crc = TABLE[(crc ^ current[index]) & 255] ^ crc >>> 8;
|
|
4245
|
+
}
|
|
4246
|
+
}
|
|
3613
4247
|
}
|
|
3614
|
-
return
|
|
3615
|
-
}
|
|
3616
|
-
|
|
3617
|
-
function dateInDays(days, fromValue = Date.now()) {
|
|
3618
|
-
return new Date(timestampMs(fromValue) + days * 60 * 60 * 24 * 1e3);
|
|
4248
|
+
return crc ^ -1;
|
|
3619
4249
|
}
|
|
3620
4250
|
|
|
3621
|
-
function
|
|
3622
|
-
return
|
|
4251
|
+
function isDateObject(value) {
|
|
4252
|
+
return has(value, ["year", "month", "date"]) && isNumber(value.year) && isNumber(value.month) && isNumber(value.date);
|
|
3623
4253
|
}
|
|
3624
4254
|
|
|
3625
|
-
function
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
if (h === startTime.h) {
|
|
3631
|
-
return { h, m: getRandomInt(startTime.m, 59) };
|
|
4255
|
+
function createDateObject(value, returnsNullWhenInvalid = false) {
|
|
4256
|
+
let result = null;
|
|
4257
|
+
let inputValue = value;
|
|
4258
|
+
if (isNumber(inputValue) || isString(inputValue)) {
|
|
4259
|
+
inputValue = new Date(inputValue);
|
|
3632
4260
|
}
|
|
3633
|
-
if (
|
|
3634
|
-
|
|
4261
|
+
if (isDate(inputValue)) {
|
|
4262
|
+
result = {
|
|
4263
|
+
year: inputValue.getFullYear(),
|
|
4264
|
+
month: inputValue.getMonth() + 1,
|
|
4265
|
+
date: inputValue.getDate()
|
|
4266
|
+
};
|
|
4267
|
+
} else if (isDateObject(inputValue)) {
|
|
4268
|
+
result = { ...inputValue };
|
|
3635
4269
|
}
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
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;
|
|
4270
|
+
ok(
|
|
4271
|
+
returnsNullWhenInvalid || !!result,
|
|
4272
|
+
`Failed to date parse: ${value}.`
|
|
4273
|
+
);
|
|
4274
|
+
return result;
|
|
3661
4275
|
}
|
|
3662
4276
|
|
|
3663
|
-
function
|
|
3664
|
-
|
|
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);
|
|
4277
|
+
function isTimeObject(value) {
|
|
4278
|
+
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
4279
|
}
|
|
3670
4280
|
|
|
3671
|
-
function
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
if (value === 0) {
|
|
3680
|
-
return { h: 0, m: 0 };
|
|
3681
|
-
}
|
|
3682
|
-
value = value % 1440;
|
|
3683
|
-
if (value < 0) {
|
|
3684
|
-
value += 1440;
|
|
4281
|
+
function createTimeObject(value, returnsNullWhenInvalid = false) {
|
|
4282
|
+
let result = null;
|
|
4283
|
+
let inputValue = value;
|
|
4284
|
+
if (isNumber(inputValue)) {
|
|
4285
|
+
inputValue = new Date(inputValue);
|
|
4286
|
+
} else if (isString(inputValue)) {
|
|
4287
|
+
const [h, m] = inputValue.split(":").map((v) => v.trim().padStart(2, "0")).map((v) => parseInt(v));
|
|
4288
|
+
inputValue = { h, m };
|
|
3685
4289
|
}
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
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;
|
|
4290
|
+
if (isDate(inputValue)) {
|
|
4291
|
+
result = {
|
|
4292
|
+
h: inputValue.getHours(),
|
|
4293
|
+
m: inputValue.getMinutes()
|
|
4294
|
+
};
|
|
4295
|
+
} else if (isTimeObject(inputValue)) {
|
|
4296
|
+
result = { ...inputValue };
|
|
3704
4297
|
}
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
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;
|
|
4298
|
+
ok(
|
|
4299
|
+
returnsNullWhenInvalid || !!result,
|
|
4300
|
+
`Failed to time parse: ${value}.`
|
|
4301
|
+
);
|
|
4302
|
+
return result;
|
|
3720
4303
|
}
|
|
3721
4304
|
|
|
3722
|
-
const
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
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
|
-
}
|
|
4305
|
+
const UNIT_TO_MS = {
|
|
4306
|
+
ms: 1,
|
|
4307
|
+
s: 1e3,
|
|
4308
|
+
m: 1e3 * 60,
|
|
4309
|
+
h: 1e3 * 60 * 60,
|
|
4310
|
+
d: 1e3 * 60 * 60 * 24,
|
|
4311
|
+
w: 1e3 * 60 * 60 * 24 * 7
|
|
3793
4312
|
};
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
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);
|
|
4313
|
+
class TimeSpan {
|
|
4314
|
+
constructor(value, unit) {
|
|
4315
|
+
this.value = value;
|
|
4316
|
+
this.unit = unit;
|
|
3808
4317
|
}
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
4318
|
+
/**
|
|
4319
|
+
* The numeric value of the time span
|
|
4320
|
+
*/
|
|
4321
|
+
value;
|
|
4322
|
+
/**
|
|
4323
|
+
* The unit of the time span.
|
|
4324
|
+
*/
|
|
4325
|
+
unit;
|
|
4326
|
+
/**
|
|
4327
|
+
* Converts the time span to milliseconds.
|
|
4328
|
+
*
|
|
4329
|
+
* @returns {number} The equivalent time span in milliseconds.
|
|
4330
|
+
* @example
|
|
4331
|
+
* const ts = new TimeSpan(2, 'h');
|
|
4332
|
+
* ts.milliseconds(); // Returns 7200000
|
|
4333
|
+
*/
|
|
4334
|
+
milliseconds() {
|
|
4335
|
+
const multiplier = UNIT_TO_MS[this.unit];
|
|
4336
|
+
return this.value * multiplier;
|
|
3823
4337
|
}
|
|
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
4338
|
/**
|
|
3839
|
-
*
|
|
4339
|
+
* Converts the time span to seconds.
|
|
4340
|
+
*
|
|
4341
|
+
* @returns {number} The equivalent time span in seconds.
|
|
4342
|
+
* @example
|
|
4343
|
+
* const ts = new TimeSpan(2, 'm');
|
|
4344
|
+
* ts.seconds(); // Returns 120
|
|
3840
4345
|
*/
|
|
3841
|
-
|
|
3842
|
-
|
|
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
|
-
};
|
|
4346
|
+
seconds() {
|
|
4347
|
+
return this.milliseconds() / UNIT_TO_MS.s;
|
|
3857
4348
|
}
|
|
3858
4349
|
/**
|
|
3859
|
-
*
|
|
3860
|
-
*
|
|
4350
|
+
* Converts the time span to minutes.
|
|
4351
|
+
*
|
|
4352
|
+
* @returns {number} The equivalent time span in minutes.
|
|
4353
|
+
* @example
|
|
4354
|
+
* const ts = new TimeSpan(120, 's');
|
|
4355
|
+
* ts.minutes(); // Returns 2
|
|
3861
4356
|
*/
|
|
3862
|
-
|
|
3863
|
-
return this.
|
|
4357
|
+
minutes() {
|
|
4358
|
+
return this.milliseconds() / UNIT_TO_MS.m;
|
|
3864
4359
|
}
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
4360
|
+
/**
|
|
4361
|
+
* Converts the time span to hours.
|
|
4362
|
+
*
|
|
4363
|
+
* @returns {number} The equivalent time span in hours.
|
|
4364
|
+
* @example
|
|
4365
|
+
* const ts = new TimeSpan(120, 'm');
|
|
4366
|
+
* ts.hours(); // Returns 2
|
|
4367
|
+
*/
|
|
4368
|
+
hours() {
|
|
4369
|
+
return this.milliseconds() / UNIT_TO_MS.h;
|
|
3873
4370
|
}
|
|
3874
4371
|
/**
|
|
3875
|
-
*
|
|
3876
|
-
*
|
|
4372
|
+
* Converts the time span to days.
|
|
4373
|
+
*
|
|
4374
|
+
* @returns {number} The equivalent time span in days.
|
|
4375
|
+
* @example
|
|
4376
|
+
* const ts = new TimeSpan(48, 'h');
|
|
4377
|
+
* ts.days(); // Returns 2
|
|
3877
4378
|
*/
|
|
3878
|
-
|
|
3879
|
-
|
|
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;
|
|
4379
|
+
days() {
|
|
4380
|
+
return this.milliseconds() / UNIT_TO_MS.d;
|
|
3890
4381
|
}
|
|
3891
4382
|
/**
|
|
3892
|
-
*
|
|
3893
|
-
*
|
|
3894
|
-
* @
|
|
3895
|
-
* @
|
|
4383
|
+
* Converts the time span to weeks.
|
|
4384
|
+
*
|
|
4385
|
+
* @returns {number} The equivalent time span in weeks.
|
|
4386
|
+
* @example
|
|
4387
|
+
* const ts = new TimeSpan(14, 'd');
|
|
4388
|
+
* ts.weeks(); // Returns 2
|
|
3896
4389
|
*/
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
return JSON.stringify(value, void 0, space);
|
|
3900
|
-
}
|
|
3901
|
-
return JSON.stringify(this.encode(value), void 0, space);
|
|
4390
|
+
weeks() {
|
|
4391
|
+
return this.milliseconds() / UNIT_TO_MS.w;
|
|
3902
4392
|
}
|
|
3903
4393
|
/**
|
|
3904
|
-
*
|
|
3905
|
-
*
|
|
3906
|
-
*
|
|
4394
|
+
* Adds a specified value and unit to the current time span.
|
|
4395
|
+
*
|
|
4396
|
+
* Returns new instance.
|
|
4397
|
+
*
|
|
4398
|
+
* @param {number} value - The value to add.
|
|
4399
|
+
* @param {TimeSpanUnit} [unit='ms'] - The unit of the value to add (default is milliseconds).
|
|
4400
|
+
* @returns {TimeSpan} A new TimeSpan instance with the added value.
|
|
4401
|
+
* @example
|
|
4402
|
+
* const ts = new TimeSpan(1, 'h');
|
|
4403
|
+
* ts.add(30, 'm'); // Represents 1.5 hours
|
|
3907
4404
|
*/
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
}
|
|
3912
|
-
return JSON.parse(value, this.reviewerReady);
|
|
4405
|
+
add(value, unit = "ms") {
|
|
4406
|
+
const multiplier = UNIT_TO_MS[unit];
|
|
4407
|
+
return new TimeSpan(this.milliseconds() + value * multiplier, "ms");
|
|
3913
4408
|
}
|
|
3914
|
-
/**
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
4409
|
+
/**
|
|
4410
|
+
* Subtracts a specified value and unit from the current time span.
|
|
4411
|
+
*
|
|
4412
|
+
* Returns new instance.
|
|
4413
|
+
*
|
|
4414
|
+
* @param {number} value - The value to subtract.
|
|
4415
|
+
* @param {TimeSpanUnit} [unit='ms'] - The unit of the value to subtract (default is milliseconds).
|
|
4416
|
+
* @returns {TimeSpan} A new TimeSpan instance with the subtracted value.
|
|
4417
|
+
* @example
|
|
4418
|
+
* const ts = new TimeSpan(1, 'h');
|
|
4419
|
+
* ts.subtract(30, 'm'); // Represents 30 minutes less than 1 hour
|
|
4420
|
+
*/
|
|
4421
|
+
subtract(value, unit = "ms") {
|
|
4422
|
+
const multiplier = UNIT_TO_MS[unit];
|
|
4423
|
+
return new TimeSpan(this.milliseconds() - value * multiplier, "ms");
|
|
3928
4424
|
}
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
4425
|
+
}
|
|
4426
|
+
|
|
4427
|
+
function createTimeSpan(value, unit = "ms") {
|
|
4428
|
+
return new TimeSpan(value, unit);
|
|
4429
|
+
}
|
|
4430
|
+
|
|
4431
|
+
function timestampMs(fromValue = Date.now()) {
|
|
4432
|
+
if (isDate(fromValue)) {
|
|
4433
|
+
fromValue = fromValue.getTime();
|
|
4434
|
+
} else if (isString(fromValue)) {
|
|
4435
|
+
const dt = new Date(fromValue);
|
|
4436
|
+
fromValue = isDate(dt) ? dt.getTime() : 0;
|
|
3938
4437
|
}
|
|
4438
|
+
return isNumber(fromValue) ? fromValue : 0;
|
|
3939
4439
|
}
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
4440
|
+
|
|
4441
|
+
function dateInDays(days, fromValue = Date.now()) {
|
|
4442
|
+
return new Date(timestampMs(fromValue) + days * 60 * 60 * 24 * 1e3);
|
|
4443
|
+
}
|
|
4444
|
+
|
|
4445
|
+
function dateInSeconds(seconds, fromValue = Date.now()) {
|
|
4446
|
+
return new Date(timestampMs(fromValue) + seconds * 1e3);
|
|
4447
|
+
}
|
|
4448
|
+
|
|
4449
|
+
function getRandomTime(startTime = { h: 0, m: 0 }, endTime = { h: 23, m: 59 }) {
|
|
4450
|
+
const h = getRandomInt(startTime.h, endTime.h);
|
|
4451
|
+
if (startTime.h === endTime.h) {
|
|
4452
|
+
return { h, m: getRandomInt(startTime.m, endTime.m) };
|
|
3944
4453
|
}
|
|
3945
|
-
|
|
4454
|
+
if (h === startTime.h) {
|
|
4455
|
+
return { h, m: getRandomInt(startTime.m, 59) };
|
|
4456
|
+
}
|
|
4457
|
+
if (h === endTime.h) {
|
|
4458
|
+
return { h, m: getRandomInt(0, endTime.m) };
|
|
4459
|
+
}
|
|
4460
|
+
return { h, m: getRandomInt(0, 59) };
|
|
4461
|
+
}
|
|
4462
|
+
|
|
4463
|
+
function hmToSeconds(hm) {
|
|
4464
|
+
hm = Number(hm);
|
|
4465
|
+
number$1(hm, "expected number value");
|
|
4466
|
+
const h = Math.floor(hm);
|
|
4467
|
+
const m = round2digits(hm - h) * 100;
|
|
4468
|
+
return h * 3600 + m * 60;
|
|
4469
|
+
}
|
|
4470
|
+
|
|
4471
|
+
function isTimeString(value) {
|
|
4472
|
+
if (!isString(value)) return false;
|
|
4473
|
+
const parts = value.split(":").map(Number);
|
|
4474
|
+
if (parts.length !== 2) return false;
|
|
4475
|
+
const [h, m] = parts;
|
|
4476
|
+
return h >= 0 && h < 24 && m >= 0 && m < 60;
|
|
3946
4477
|
}
|
|
3947
4478
|
|
|
3948
|
-
function
|
|
3949
|
-
|
|
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;
|
|
4479
|
+
function isTimeValue(value) {
|
|
4480
|
+
return isTimeString(value) || isTimeObject(value);
|
|
3960
4481
|
}
|
|
3961
4482
|
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
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;
|
|
4483
|
+
function isValidWeekDay(value) {
|
|
4484
|
+
return isNumber(value) && Number.isInteger(value) && value >= 1 && value <= 7;
|
|
4485
|
+
}
|
|
4486
|
+
|
|
4487
|
+
function secondsToHm(seconds) {
|
|
4488
|
+
const value = Number(seconds);
|
|
4489
|
+
number$1(value, "expected number value");
|
|
4490
|
+
const h = Math.floor(value / 3600);
|
|
4491
|
+
const m = Math.floor(value % 3600 / 60);
|
|
4492
|
+
return round2digits(h + m / 100, 2);
|
|
4493
|
+
}
|
|
4494
|
+
|
|
4495
|
+
function timeFromMinutes(value, returnsNullWhenInvalid = false) {
|
|
4496
|
+
if (!isNumber(value)) {
|
|
4497
|
+
ok(
|
|
4498
|
+
returnsNullWhenInvalid,
|
|
4499
|
+
"Failed to time parse from minutes: " + value
|
|
4500
|
+
);
|
|
4501
|
+
return null;
|
|
3993
4502
|
}
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
* If null, defaults to 'application/json'.
|
|
3997
|
-
*/
|
|
3998
|
-
get vendorName() {
|
|
3999
|
-
return this.ejson.vendorName;
|
|
4503
|
+
if (value === 0) {
|
|
4504
|
+
return { h: 0, m: 0 };
|
|
4000
4505
|
}
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
get mimetype() {
|
|
4005
|
-
return this.ejson.mimetype;
|
|
4506
|
+
value = value % 1440;
|
|
4507
|
+
if (value < 0) {
|
|
4508
|
+
value += 1440;
|
|
4006
4509
|
}
|
|
4510
|
+
const h = Math.floor(value / 60);
|
|
4511
|
+
const m = value % 60;
|
|
4512
|
+
return { h, m };
|
|
4007
4513
|
}
|
|
4008
4514
|
|
|
4009
|
-
|
|
4515
|
+
function timestampToDate(value) {
|
|
4516
|
+
if (!isNumber(value)) return null;
|
|
4517
|
+
return new Date(value * 1e3);
|
|
4518
|
+
}
|
|
4010
4519
|
|
|
4011
|
-
function
|
|
4012
|
-
|
|
4013
|
-
|
|
4520
|
+
function timeStringify(value, returnsNullWhenInvalid = false) {
|
|
4521
|
+
const timeObject = createTimeObject(value, true);
|
|
4522
|
+
if (!timeObject) {
|
|
4523
|
+
ok(
|
|
4524
|
+
returnsNullWhenInvalid,
|
|
4525
|
+
"Failed to stringify time from: " + JSON.stringify(value)
|
|
4526
|
+
);
|
|
4527
|
+
return null;
|
|
4014
4528
|
}
|
|
4015
|
-
|
|
4529
|
+
let { h, m } = timeObject;
|
|
4530
|
+
const hStr = Math.ceil(h).toString().padStart(2, "0").slice(-2);
|
|
4531
|
+
const mStr = Math.ceil(m).toString().padStart(2, "0").slice(-2);
|
|
4532
|
+
return `${hStr}:${mStr}`;
|
|
4016
4533
|
}
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
const
|
|
4020
|
-
|
|
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;
|
|
4534
|
+
|
|
4535
|
+
function timeToMinutes(value) {
|
|
4536
|
+
const time = createTimeObject(value);
|
|
4537
|
+
return time.h * 60 + time.m;
|
|
4072
4538
|
}
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
op,
|
|
4079
|
-
sep
|
|
4080
|
-
};
|
|
4539
|
+
|
|
4540
|
+
function weeksInYear(year) {
|
|
4541
|
+
const target = new Date(Date.UTC(year + 1, 0, 1));
|
|
4542
|
+
const dayNumber = target.getDay();
|
|
4543
|
+
return dayNumber < 4 ? 52 : 53;
|
|
4081
4544
|
}
|
|
4082
4545
|
|
|
4083
4546
|
const env = (() => {
|
|
@@ -4142,7 +4605,7 @@ function createEnvParser(targetObject) {
|
|
|
4142
4605
|
return defaultValue;
|
|
4143
4606
|
}
|
|
4144
4607
|
try {
|
|
4145
|
-
return
|
|
4608
|
+
return instance.parse(targetObject[key]);
|
|
4146
4609
|
} catch (err) {
|
|
4147
4610
|
console.warn("Failed to parse json env variable", key);
|
|
4148
4611
|
return defaultValue;
|
|
@@ -4750,28 +5213,6 @@ const logger = (...baseArgs) => {
|
|
|
4750
5213
|
return instance;
|
|
4751
5214
|
};
|
|
4752
5215
|
|
|
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
5216
|
function nextTickIteration(amount, delay = "tick") {
|
|
4776
5217
|
let counter = 0;
|
|
4777
5218
|
const tickInterval = delay === "tick";
|
|
@@ -4791,6 +5232,45 @@ function nextTickIteration(amount, delay = "tick") {
|
|
|
4791
5232
|
};
|
|
4792
5233
|
}
|
|
4793
5234
|
|
|
5235
|
+
function asyncFilter(array, predicate, { concurrency = 1 } = {}) {
|
|
5236
|
+
concurrency = Math.max(concurrency, 1);
|
|
5237
|
+
if (array.length === 0) {
|
|
5238
|
+
return Promise.resolve([]);
|
|
5239
|
+
}
|
|
5240
|
+
var result = [];
|
|
5241
|
+
var currentIndex = 0;
|
|
5242
|
+
var completed = 0;
|
|
5243
|
+
var hasError = false;
|
|
5244
|
+
var cooldown = nextTickIteration(10);
|
|
5245
|
+
return new Promise((resolve, reject) => {
|
|
5246
|
+
var processItem = (index) => {
|
|
5247
|
+
if (hasError || index >= array.length) return;
|
|
5248
|
+
cooldown().then(() => predicate(array[index], index, array)).then((include) => {
|
|
5249
|
+
if (hasError) return;
|
|
5250
|
+
if (include) {
|
|
5251
|
+
result.push(index);
|
|
5252
|
+
}
|
|
5253
|
+
completed++;
|
|
5254
|
+
if (completed >= array.length) {
|
|
5255
|
+
resolve(result.toSorted((a, b) => a - b).map((idx) => array[idx]));
|
|
5256
|
+
} else {
|
|
5257
|
+
if (currentIndex < array.length) {
|
|
5258
|
+
processItem(currentIndex++);
|
|
5259
|
+
}
|
|
5260
|
+
}
|
|
5261
|
+
}).catch((error) => {
|
|
5262
|
+
if (!hasError) {
|
|
5263
|
+
hasError = true;
|
|
5264
|
+
reject(error);
|
|
5265
|
+
}
|
|
5266
|
+
});
|
|
5267
|
+
};
|
|
5268
|
+
for (; currentIndex < concurrency; currentIndex++) {
|
|
5269
|
+
processItem(currentIndex);
|
|
5270
|
+
}
|
|
5271
|
+
});
|
|
5272
|
+
}
|
|
5273
|
+
|
|
4794
5274
|
function asyncFind(array, callbackfn) {
|
|
4795
5275
|
var i = 0;
|
|
4796
5276
|
var cooldown = nextTickIteration(10);
|
|
@@ -4815,35 +5295,36 @@ function asyncFind(array, callbackfn) {
|
|
|
4815
5295
|
|
|
4816
5296
|
function asyncForEach(array, callbackfn, { concurrency = 1 } = {}) {
|
|
4817
5297
|
concurrency = Math.max(concurrency, 1);
|
|
4818
|
-
|
|
5298
|
+
if (array.length === 0) {
|
|
5299
|
+
return Promise.resolve();
|
|
5300
|
+
}
|
|
5301
|
+
var hasError = false;
|
|
5302
|
+
var completed = 0;
|
|
5303
|
+
var currentIndex = 0;
|
|
4819
5304
|
var cooldown = nextTickIteration(10);
|
|
4820
|
-
var tasks = Array(concurrency);
|
|
4821
5305
|
return new Promise((resolve, reject) => {
|
|
4822
|
-
var
|
|
4823
|
-
if (
|
|
4824
|
-
|
|
4825
|
-
return;
|
|
4826
|
-
|
|
4827
|
-
|
|
4828
|
-
|
|
4829
|
-
|
|
4830
|
-
if (
|
|
4831
|
-
|
|
4832
|
-
(itemIndex) => callbackfn(array[itemIndex], itemIndex, array)
|
|
4833
|
-
);
|
|
5306
|
+
var processItem = (index) => {
|
|
5307
|
+
if (hasError || index >= array.length) return;
|
|
5308
|
+
cooldown().then(() => callbackfn(array[index], index, array)).then((transformed) => {
|
|
5309
|
+
if (hasError) return;
|
|
5310
|
+
completed++;
|
|
5311
|
+
if (completed >= array.length) {
|
|
5312
|
+
resolve();
|
|
5313
|
+
} else {
|
|
5314
|
+
if (currentIndex < array.length) {
|
|
5315
|
+
processItem(currentIndex++);
|
|
4834
5316
|
}
|
|
4835
|
-
i++;
|
|
4836
5317
|
}
|
|
4837
|
-
|
|
4838
|
-
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
} else {
|
|
4842
|
-
resolve();
|
|
5318
|
+
}).catch((error) => {
|
|
5319
|
+
if (!hasError) {
|
|
5320
|
+
hasError = true;
|
|
5321
|
+
reject(error);
|
|
4843
5322
|
}
|
|
4844
|
-
})
|
|
5323
|
+
});
|
|
4845
5324
|
};
|
|
4846
|
-
|
|
5325
|
+
for (; currentIndex < concurrency; currentIndex++) {
|
|
5326
|
+
processItem(currentIndex);
|
|
5327
|
+
}
|
|
4847
5328
|
});
|
|
4848
5329
|
}
|
|
4849
5330
|
|
|
@@ -4984,38 +5465,38 @@ class AsyncIterableQueue {
|
|
|
4984
5465
|
|
|
4985
5466
|
function asyncMap(array, callbackfn, { concurrency = 1 } = {}) {
|
|
4986
5467
|
concurrency = Math.max(concurrency, 1);
|
|
4987
|
-
|
|
4988
|
-
|
|
5468
|
+
if (array.length === 0) {
|
|
5469
|
+
return Promise.resolve([]);
|
|
5470
|
+
}
|
|
5471
|
+
var hasError = false;
|
|
5472
|
+
var result = Array(array.length);
|
|
5473
|
+
var completed = 0;
|
|
5474
|
+
var currentIndex = 0;
|
|
4989
5475
|
var cooldown = nextTickIteration(10);
|
|
4990
|
-
var tasks = Array(concurrency);
|
|
4991
5476
|
return new Promise((resolve, reject) => {
|
|
4992
|
-
var
|
|
4993
|
-
if (
|
|
4994
|
-
|
|
4995
|
-
|
|
4996
|
-
|
|
4997
|
-
|
|
4998
|
-
|
|
4999
|
-
|
|
5000
|
-
|
|
5001
|
-
|
|
5002
|
-
|
|
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);
|
|
5477
|
+
var processItem = (index) => {
|
|
5478
|
+
if (hasError || index >= array.length) return;
|
|
5479
|
+
cooldown().then(() => callbackfn(array[index], index, array)).then((transformed) => {
|
|
5480
|
+
if (hasError) return;
|
|
5481
|
+
result[index] = transformed;
|
|
5482
|
+
completed++;
|
|
5483
|
+
if (completed >= array.length) {
|
|
5484
|
+
resolve(result);
|
|
5485
|
+
} else {
|
|
5486
|
+
if (currentIndex < array.length) {
|
|
5487
|
+
processItem(currentIndex++);
|
|
5014
5488
|
}
|
|
5015
|
-
}
|
|
5016
|
-
}
|
|
5489
|
+
}
|
|
5490
|
+
}).catch((error) => {
|
|
5491
|
+
if (!hasError) {
|
|
5492
|
+
hasError = true;
|
|
5493
|
+
reject(error);
|
|
5494
|
+
}
|
|
5495
|
+
});
|
|
5017
5496
|
};
|
|
5018
|
-
|
|
5497
|
+
for (; currentIndex < concurrency; currentIndex++) {
|
|
5498
|
+
processItem(currentIndex);
|
|
5499
|
+
}
|
|
5019
5500
|
});
|
|
5020
5501
|
}
|
|
5021
5502
|
|
|
@@ -5459,5 +5940,59 @@ function timeout(ms, promiseOrCallback, timeoutError = new AppError(408)) {
|
|
|
5459
5940
|
});
|
|
5460
5941
|
}
|
|
5461
5942
|
|
|
5462
|
-
|
|
5943
|
+
const stringifyArgs = (...args) => {
|
|
5944
|
+
return args.map((v) => argToKey(v, { objectStrategy: "json" })).join("_");
|
|
5945
|
+
};
|
|
5946
|
+
function withResolve(fn, getCacheKey) {
|
|
5947
|
+
const cache = /* @__PURE__ */ new Map();
|
|
5948
|
+
const cacheKeyVariants = arrayable(getCacheKey);
|
|
5949
|
+
return function(...args) {
|
|
5950
|
+
let cacheKey = stringifyArgs(...args);
|
|
5951
|
+
if (cacheKeyVariants?.length) {
|
|
5952
|
+
for (const getCacheKey2 of cacheKeyVariants) {
|
|
5953
|
+
const newCacheKey = getCacheKey2(args, stringifyArgs);
|
|
5954
|
+
if (newCacheKey === null) {
|
|
5955
|
+
cacheKey = Symbol();
|
|
5956
|
+
break;
|
|
5957
|
+
} else if (isString(newCacheKey) && cache.has(newCacheKey)) {
|
|
5958
|
+
cacheKey = newCacheKey;
|
|
5959
|
+
break;
|
|
5960
|
+
}
|
|
5961
|
+
}
|
|
5962
|
+
}
|
|
5963
|
+
const defers = cache.get(cacheKey) || [];
|
|
5964
|
+
const size = defers.length;
|
|
5965
|
+
const q = defer();
|
|
5966
|
+
defers.push(q);
|
|
5967
|
+
cache.set(cacheKey, defers);
|
|
5968
|
+
if (size) {
|
|
5969
|
+
return q.promise;
|
|
5970
|
+
}
|
|
5971
|
+
resolver(this, cacheKey, args);
|
|
5972
|
+
return q.promise;
|
|
5973
|
+
};
|
|
5974
|
+
function resolver(self, cacheKey, args) {
|
|
5975
|
+
const onSuccess = (r) => {
|
|
5976
|
+
const defers = cache.get(cacheKey) || [];
|
|
5977
|
+
for (const q of defers) {
|
|
5978
|
+
q.resolve(r);
|
|
5979
|
+
}
|
|
5980
|
+
cache.delete(cacheKey);
|
|
5981
|
+
};
|
|
5982
|
+
const onError = (r) => {
|
|
5983
|
+
const defers = cache.get(cacheKey) || [];
|
|
5984
|
+
for (const q of defers) {
|
|
5985
|
+
q.reject(r);
|
|
5986
|
+
}
|
|
5987
|
+
cache.delete(cacheKey);
|
|
5988
|
+
};
|
|
5989
|
+
try {
|
|
5990
|
+
fn.apply(self, args).then(onSuccess).catch(onError);
|
|
5991
|
+
} catch (err) {
|
|
5992
|
+
onError(err);
|
|
5993
|
+
}
|
|
5994
|
+
}
|
|
5995
|
+
}
|
|
5996
|
+
|
|
5997
|
+
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, bitPack, bitUnpack, 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, createFunction, 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
5998
|
//# sourceMappingURL=index.mjs.map
|