@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.cjs
CHANGED
|
@@ -180,6 +180,9 @@ const primitiveTypeofSet = Object.freeze(
|
|
|
180
180
|
const isPrimitive = (value) => {
|
|
181
181
|
return value === null || primitiveTypeofSet.has(typeof value);
|
|
182
182
|
};
|
|
183
|
+
function isNode() {
|
|
184
|
+
return typeof globalThis?.process !== "undefined" && process?.versions?.node != null;
|
|
185
|
+
}
|
|
183
186
|
|
|
184
187
|
function arrayable(value) {
|
|
185
188
|
const result = Array.isArray(value) ? value : value === null ? [] : value === void 0 ? [] : isString(value) ? value.split(",").map((v) => v.trim()).filter(Boolean) : [value];
|
|
@@ -291,13 +294,50 @@ function groupBy(array, keyBy, objectMode) {
|
|
|
291
294
|
|
|
292
295
|
function intersection(...arrays) {
|
|
293
296
|
if (arrays.length === 0) return [];
|
|
294
|
-
if (arrays.length === 1) return arrays[0];
|
|
297
|
+
if (arrays.length === 1) return [...arrays[0]];
|
|
295
298
|
return arrays.reduce((acc, curr) => {
|
|
296
299
|
const set = new Set(curr);
|
|
297
300
|
return acc.filter((item) => set.has(item));
|
|
298
301
|
});
|
|
299
302
|
}
|
|
300
303
|
|
|
304
|
+
function intersectionBy(keyBy, ...arrays) {
|
|
305
|
+
var arraysLength = arrays.length;
|
|
306
|
+
if (arraysLength === 0) return [];
|
|
307
|
+
if (arraysLength === 1) return [...arrays[0]];
|
|
308
|
+
var getItemKey = isFunction(keyBy) ? keyBy : (item) => item?.[keyBy];
|
|
309
|
+
arrays = arrays.toSorted((a, b) => a.length - b.length);
|
|
310
|
+
var arrayLengths = [arraysLength];
|
|
311
|
+
var arrayIndices = [0];
|
|
312
|
+
var arraySets = [/* @__PURE__ */ new Set()];
|
|
313
|
+
var key1, key2;
|
|
314
|
+
var i;
|
|
315
|
+
for (i = 1; i < arraysLength; i++) {
|
|
316
|
+
arrayLengths[i] = arrays[i].length;
|
|
317
|
+
arrayIndices[i] = 0;
|
|
318
|
+
arraySets[i] = /* @__PURE__ */ new Set();
|
|
319
|
+
}
|
|
320
|
+
return arrays[0].filter((item) => {
|
|
321
|
+
key1 = getItemKey(item);
|
|
322
|
+
if (arraySets[0].has(key1)) return false;
|
|
323
|
+
arraySets[0].add(key1);
|
|
324
|
+
loop: for (i = 1; i < arraysLength; i++) {
|
|
325
|
+
if (arraySets[i].has(key1)) {
|
|
326
|
+
continue loop;
|
|
327
|
+
}
|
|
328
|
+
for (; arrayIndices[i] < arrayLengths[i]; arrayIndices[i]++) {
|
|
329
|
+
key2 = getItemKey(arrays[i][arrayIndices[i]]);
|
|
330
|
+
arraySets[i].add(key2);
|
|
331
|
+
if (Object.is(key1, key2)) {
|
|
332
|
+
continue loop;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return false;
|
|
336
|
+
}
|
|
337
|
+
return true;
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
|
|
301
341
|
function keyBy(array, keyBy2, objectMode) {
|
|
302
342
|
const getItemKey = isFunction(keyBy2) ? keyBy2 : (item) => item?.[keyBy2];
|
|
303
343
|
if (objectMode === true) {
|
|
@@ -824,9 +864,14 @@ class BrowserAssertionError extends Error {
|
|
|
824
864
|
}
|
|
825
865
|
|
|
826
866
|
let AssertionError = BrowserAssertionError;
|
|
827
|
-
if (
|
|
828
|
-
|
|
829
|
-
|
|
867
|
+
if (isNode()) {
|
|
868
|
+
try {
|
|
869
|
+
const assert = require("node:assert");
|
|
870
|
+
if (assert.AssertionError) {
|
|
871
|
+
AssertionError = assert.AssertionError;
|
|
872
|
+
}
|
|
873
|
+
} catch {
|
|
874
|
+
}
|
|
830
875
|
}
|
|
831
876
|
|
|
832
877
|
function ok(value, message) {
|
|
@@ -896,7 +941,7 @@ function fn(value, message) {
|
|
|
896
941
|
}
|
|
897
942
|
}
|
|
898
943
|
function greaterThan(value, target, message) {
|
|
899
|
-
if (!isNumber(value) || value
|
|
944
|
+
if (!isNumber(value) || value <= target) {
|
|
900
945
|
throw toError$1(
|
|
901
946
|
greaterThan,
|
|
902
947
|
value,
|
|
@@ -1688,6 +1733,433 @@ function bigIntFromBytes(bytes) {
|
|
|
1688
1733
|
return decoded;
|
|
1689
1734
|
}
|
|
1690
1735
|
|
|
1736
|
+
function toError(value, unknownMessage = "Unknown error") {
|
|
1737
|
+
if (isError(value)) {
|
|
1738
|
+
return value;
|
|
1739
|
+
}
|
|
1740
|
+
const error = new Error(unknownMessage, { cause: value });
|
|
1741
|
+
Error.captureStackTrace(error, toError);
|
|
1742
|
+
return error;
|
|
1743
|
+
}
|
|
1744
|
+
|
|
1745
|
+
function createFunction(fnName, code, ...args) {
|
|
1746
|
+
try {
|
|
1747
|
+
const fn = new Function(...args, code);
|
|
1748
|
+
fn.code = code;
|
|
1749
|
+
return fn;
|
|
1750
|
+
} catch (err) {
|
|
1751
|
+
throw new Error(
|
|
1752
|
+
`failed to create bitPack.${fnName}()
|
|
1753
|
+
Error: ${toError(err).message}
|
|
1754
|
+
-- CODE START --
|
|
1755
|
+
${code}
|
|
1756
|
+
-- CODE END--`
|
|
1757
|
+
);
|
|
1758
|
+
}
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
function bitPack(options) {
|
|
1762
|
+
notEmpty(options.fields, "fields cannot be empty");
|
|
1763
|
+
greaterThan(options.totalBits, 0, "totalBits must be greater than 0");
|
|
1764
|
+
const fields = buildFieldsInfo$1(options.fields, options.totalBits);
|
|
1765
|
+
const plan = buildPlan(fields);
|
|
1766
|
+
const containersCount = Math.ceil(options.totalBits / 32);
|
|
1767
|
+
const buf = new Uint8Array(containersCount * 4);
|
|
1768
|
+
const baseCode = [
|
|
1769
|
+
"\n// Field init",
|
|
1770
|
+
initFields(fields),
|
|
1771
|
+
"\n// Plan",
|
|
1772
|
+
compilePlan(plan, options.optimize)
|
|
1773
|
+
];
|
|
1774
|
+
const fnBufferCode = [
|
|
1775
|
+
...baseCode,
|
|
1776
|
+
"\n// Return result",
|
|
1777
|
+
buildBufferResult(containersCount)
|
|
1778
|
+
].join("\n");
|
|
1779
|
+
const fnBuffer = createFunction(
|
|
1780
|
+
"buffer",
|
|
1781
|
+
fnBufferCode,
|
|
1782
|
+
"data"
|
|
1783
|
+
);
|
|
1784
|
+
const fnBigIntCode = [
|
|
1785
|
+
...baseCode,
|
|
1786
|
+
"\n// Return result",
|
|
1787
|
+
buildBigIntResult(containersCount)
|
|
1788
|
+
].join("\n");
|
|
1789
|
+
const fnBigInt = createFunction(
|
|
1790
|
+
"bigint",
|
|
1791
|
+
fnBigIntCode,
|
|
1792
|
+
"data"
|
|
1793
|
+
);
|
|
1794
|
+
const fnNumberCode = [
|
|
1795
|
+
...baseCode,
|
|
1796
|
+
"\n// Return result",
|
|
1797
|
+
buildNumberResult()
|
|
1798
|
+
].join("\n");
|
|
1799
|
+
const fnNumber = createFunction(
|
|
1800
|
+
"number",
|
|
1801
|
+
fnNumberCode,
|
|
1802
|
+
"data"
|
|
1803
|
+
);
|
|
1804
|
+
const fnBitsCode = [
|
|
1805
|
+
...baseCode,
|
|
1806
|
+
"\n// Return result",
|
|
1807
|
+
buildBitsResult(containersCount, options.totalBits)
|
|
1808
|
+
].join("\n");
|
|
1809
|
+
const fnBits = createFunction("bits", fnBitsCode, "data");
|
|
1810
|
+
if (!options.debug) {
|
|
1811
|
+
def(fnBuffer, "code", void 0);
|
|
1812
|
+
def(fnBigInt, "code", void 0);
|
|
1813
|
+
def(fnNumber, "code", void 0);
|
|
1814
|
+
def(fnBits, "code", void 0);
|
|
1815
|
+
}
|
|
1816
|
+
return {
|
|
1817
|
+
buffer: fnBuffer,
|
|
1818
|
+
bigint: fnBigInt,
|
|
1819
|
+
number: fnNumber,
|
|
1820
|
+
bits: fnBits,
|
|
1821
|
+
plan: options.debug ? plan : void 0,
|
|
1822
|
+
__buf: buf
|
|
1823
|
+
};
|
|
1824
|
+
}
|
|
1825
|
+
function initFields(fields) {
|
|
1826
|
+
return fields.map((field) => {
|
|
1827
|
+
if (field.bits > 32) {
|
|
1828
|
+
return [
|
|
1829
|
+
`var ${field.id}_high = (data['${field.name}'] / 0x100000000) | 0;`,
|
|
1830
|
+
`var ${field.id}_low = (data['${field.name}'] >>> 0);`
|
|
1831
|
+
].join("\n");
|
|
1832
|
+
}
|
|
1833
|
+
if (field.take === "high") {
|
|
1834
|
+
return `var ${field.id} = (data['${field.name}'] / 0x100000000) | 0;`;
|
|
1835
|
+
}
|
|
1836
|
+
return `var ${field.id} = (data['${field.name}'] & 0x${field.mask.toString(16)}) >>> 0;`;
|
|
1837
|
+
}).join("\n");
|
|
1838
|
+
}
|
|
1839
|
+
function buildBufferResult(containersCount) {
|
|
1840
|
+
const lines = [`var buf = this.__buf;`];
|
|
1841
|
+
for (let i = 0; i < containersCount; i++) {
|
|
1842
|
+
const containerIndex = containersCount - 1 - i;
|
|
1843
|
+
lines.push(
|
|
1844
|
+
`buf[${i * 4}] = c_${containerIndex} >>> 24;`,
|
|
1845
|
+
`buf[${i * 4 + 1}] = c_${containerIndex} >>> 16;`,
|
|
1846
|
+
`buf[${i * 4 + 2}] = c_${containerIndex} >>> 8;`,
|
|
1847
|
+
`buf[${i * 4 + 3}] = c_${containerIndex};`
|
|
1848
|
+
);
|
|
1849
|
+
}
|
|
1850
|
+
lines.push("return buf;");
|
|
1851
|
+
return lines.join("\n");
|
|
1852
|
+
}
|
|
1853
|
+
function buildBigIntResult(containersCount) {
|
|
1854
|
+
const parts = [];
|
|
1855
|
+
for (let i = 0; i < containersCount; i++) {
|
|
1856
|
+
const containerIndex = containersCount - 1 - i;
|
|
1857
|
+
if (containerIndex > 0) {
|
|
1858
|
+
parts.push(
|
|
1859
|
+
`(BigInt(c_${containerIndex} >>> 0) << ${containerIndex * 32}n)`
|
|
1860
|
+
);
|
|
1861
|
+
} else {
|
|
1862
|
+
parts.push(`BigInt(c_${containerIndex} >>> 0)`);
|
|
1863
|
+
}
|
|
1864
|
+
}
|
|
1865
|
+
return `return (
|
|
1866
|
+
${parts.join(" |\n ")}
|
|
1867
|
+
);`;
|
|
1868
|
+
}
|
|
1869
|
+
function buildNumberResult(containersCount) {
|
|
1870
|
+
return `return c_0;`;
|
|
1871
|
+
}
|
|
1872
|
+
function buildBitsResult(containersCount, totalBits) {
|
|
1873
|
+
const parts = [];
|
|
1874
|
+
for (let i = 0; i < containersCount; i++) {
|
|
1875
|
+
const containerIndex = containersCount - 1 - i;
|
|
1876
|
+
if (containerIndex > 0) {
|
|
1877
|
+
parts.push(
|
|
1878
|
+
`(BigInt(c_${containerIndex} >>> 0) << ${containerIndex * 32}n)`
|
|
1879
|
+
);
|
|
1880
|
+
} else {
|
|
1881
|
+
parts.push(`BigInt(c_${containerIndex} >>> 0)`);
|
|
1882
|
+
}
|
|
1883
|
+
}
|
|
1884
|
+
return `return (
|
|
1885
|
+
${parts.join(" |\n ")}
|
|
1886
|
+
).toString(2).padStart(${totalBits}, '0');`;
|
|
1887
|
+
}
|
|
1888
|
+
function compilePlan(plan, optimize) {
|
|
1889
|
+
if (optimize) {
|
|
1890
|
+
plan = optimizePlan(plan);
|
|
1891
|
+
}
|
|
1892
|
+
const assigned = /* @__PURE__ */ new Set();
|
|
1893
|
+
return plan.map((item) => compilePlanItem(item, assigned)).join("\n");
|
|
1894
|
+
}
|
|
1895
|
+
function optimizePlan(plan) {
|
|
1896
|
+
return plan.reduce((result, item) => {
|
|
1897
|
+
const prev = result.at(-1);
|
|
1898
|
+
if (canMergeSetOperations(prev, item)) {
|
|
1899
|
+
result.pop();
|
|
1900
|
+
result.push({
|
|
1901
|
+
object: "set",
|
|
1902
|
+
container: item.container,
|
|
1903
|
+
child: {
|
|
1904
|
+
object: "value",
|
|
1905
|
+
value: [
|
|
1906
|
+
compilePlanItem(prev.child),
|
|
1907
|
+
compilePlanItem(item.child)
|
|
1908
|
+
].join(" |\n ")
|
|
1909
|
+
}
|
|
1910
|
+
});
|
|
1911
|
+
} else {
|
|
1912
|
+
result.push(item);
|
|
1913
|
+
}
|
|
1914
|
+
return result;
|
|
1915
|
+
}, []);
|
|
1916
|
+
}
|
|
1917
|
+
function canMergeSetOperations(prev, current) {
|
|
1918
|
+
return prev?.object === "set" && current.object === "set" && prev.container === current.container;
|
|
1919
|
+
}
|
|
1920
|
+
function compilePlanItem(plan, assigned) {
|
|
1921
|
+
switch (plan.object) {
|
|
1922
|
+
case "set":
|
|
1923
|
+
if (assigned && !assigned.has(plan.container)) {
|
|
1924
|
+
assigned.add(plan.container);
|
|
1925
|
+
return `var c_${plan.container} = ${compilePlanItem(plan.child)};`;
|
|
1926
|
+
}
|
|
1927
|
+
return `c_${plan.container} |= ${compilePlanItem(plan.child)};`;
|
|
1928
|
+
case "value":
|
|
1929
|
+
const offset = plan.offset ?? 0;
|
|
1930
|
+
return offset > 0 ? `(${plan.value}) << ${offset}` : `(${plan.value})`;
|
|
1931
|
+
default:
|
|
1932
|
+
throw new Error(`Unknown plan object: ${plan.object}`);
|
|
1933
|
+
}
|
|
1934
|
+
}
|
|
1935
|
+
function buildPlan(fields) {
|
|
1936
|
+
const result = [];
|
|
1937
|
+
for (const field of fields) {
|
|
1938
|
+
const startContainer = Math.floor(field.startBit / 32);
|
|
1939
|
+
const endContainer = Math.floor(field.endBit / 32);
|
|
1940
|
+
if (startContainer === endContainer) {
|
|
1941
|
+
addSingleContainerField(field, result);
|
|
1942
|
+
} else if (field.bits <= 32) {
|
|
1943
|
+
addSpanningField(field, result);
|
|
1944
|
+
} else {
|
|
1945
|
+
addLargeField(field, result);
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1948
|
+
return result;
|
|
1949
|
+
}
|
|
1950
|
+
function addSingleContainerField(field, result) {
|
|
1951
|
+
result.push({
|
|
1952
|
+
object: "set",
|
|
1953
|
+
container: Math.floor(field.startBit / 32),
|
|
1954
|
+
child: {
|
|
1955
|
+
object: "value",
|
|
1956
|
+
offset: field.startBit % 32,
|
|
1957
|
+
value: field.id
|
|
1958
|
+
}
|
|
1959
|
+
});
|
|
1960
|
+
}
|
|
1961
|
+
function addSpanningField(field, result) {
|
|
1962
|
+
const startContainer = Math.floor(field.startBit / 32);
|
|
1963
|
+
const endContainer = Math.floor(field.endBit / 32);
|
|
1964
|
+
const firstContainerBits = 32 - field.startBit % 32;
|
|
1965
|
+
result.push({
|
|
1966
|
+
object: "set",
|
|
1967
|
+
container: startContainer,
|
|
1968
|
+
child: {
|
|
1969
|
+
object: "value",
|
|
1970
|
+
offset: field.startBit % 32,
|
|
1971
|
+
value: `(${field.id}) & ${(1 << firstContainerBits) - 1}`
|
|
1972
|
+
}
|
|
1973
|
+
});
|
|
1974
|
+
result.push({
|
|
1975
|
+
object: "set",
|
|
1976
|
+
container: endContainer,
|
|
1977
|
+
child: {
|
|
1978
|
+
object: "value",
|
|
1979
|
+
value: `(${field.id}) >>> ${firstContainerBits}`
|
|
1980
|
+
}
|
|
1981
|
+
});
|
|
1982
|
+
}
|
|
1983
|
+
function addLargeField(field, result) {
|
|
1984
|
+
const startContainer = Math.floor(field.startBit / 32);
|
|
1985
|
+
const endContainer = Math.floor(field.endBit / 32);
|
|
1986
|
+
const startOffset = field.startBit % 32;
|
|
1987
|
+
ok(
|
|
1988
|
+
startContainer !== endContainer,
|
|
1989
|
+
`Large field ${field.name} fits in single container - logic error`
|
|
1990
|
+
);
|
|
1991
|
+
ok(
|
|
1992
|
+
endContainer - startContainer === 1,
|
|
1993
|
+
`Fields spanning more than 2 containers (${field.bits} bits) not yet supported`
|
|
1994
|
+
);
|
|
1995
|
+
const bitsInLowerContainer = 32 - startOffset;
|
|
1996
|
+
result.push({
|
|
1997
|
+
object: "set",
|
|
1998
|
+
container: endContainer,
|
|
1999
|
+
child: {
|
|
2000
|
+
object: "value",
|
|
2001
|
+
offset: startOffset,
|
|
2002
|
+
value: `${field.id}_high`
|
|
2003
|
+
}
|
|
2004
|
+
});
|
|
2005
|
+
if (bitsInLowerContainer < 32) {
|
|
2006
|
+
result.push({
|
|
2007
|
+
object: "set",
|
|
2008
|
+
container: endContainer,
|
|
2009
|
+
child: {
|
|
2010
|
+
object: "value",
|
|
2011
|
+
value: `${field.id}_low >>> ${bitsInLowerContainer}`
|
|
2012
|
+
}
|
|
2013
|
+
});
|
|
2014
|
+
}
|
|
2015
|
+
if (field.bits > 32) {
|
|
2016
|
+
result.push({
|
|
2017
|
+
object: "set",
|
|
2018
|
+
container: startContainer,
|
|
2019
|
+
child: {
|
|
2020
|
+
object: "value",
|
|
2021
|
+
offset: startOffset,
|
|
2022
|
+
value: `${field.id}_low`
|
|
2023
|
+
}
|
|
2024
|
+
});
|
|
2025
|
+
}
|
|
2026
|
+
}
|
|
2027
|
+
function buildFieldsInfo$1(fields, totalBits) {
|
|
2028
|
+
const result = [];
|
|
2029
|
+
let currentBitPosition = totalBits;
|
|
2030
|
+
fields.forEach((field, idx) => {
|
|
2031
|
+
const startBit = currentBitPosition - field.bits;
|
|
2032
|
+
const endBit = currentBitPosition - 1;
|
|
2033
|
+
result.push({
|
|
2034
|
+
id: `f_${idx}`,
|
|
2035
|
+
...field,
|
|
2036
|
+
startBit,
|
|
2037
|
+
endBit,
|
|
2038
|
+
mask: Math.pow(2, field.bits) - 1
|
|
2039
|
+
});
|
|
2040
|
+
currentBitPosition -= field.bits;
|
|
2041
|
+
});
|
|
2042
|
+
return result;
|
|
2043
|
+
}
|
|
2044
|
+
|
|
2045
|
+
function bitUnpack(options) {
|
|
2046
|
+
notEmpty(options.fields, "fields cannot be empty");
|
|
2047
|
+
greaterThan(options.totalBits, 0, "totalBits must be greater than 0");
|
|
2048
|
+
const fields = buildFieldsInfo(options.fields, options.totalBits);
|
|
2049
|
+
const fnBigIntCode = [`return ${compileFields(fields)};`].join("\n");
|
|
2050
|
+
const fnBigInt = createFunction(
|
|
2051
|
+
"bigint",
|
|
2052
|
+
fnBigIntCode,
|
|
2053
|
+
"data"
|
|
2054
|
+
);
|
|
2055
|
+
const fnNumberCode = [
|
|
2056
|
+
"\n// Extract container from number",
|
|
2057
|
+
"data = BigInt(data);",
|
|
2058
|
+
"\n// Return result",
|
|
2059
|
+
`return ${compileFields(fields)};`
|
|
2060
|
+
].join("\n");
|
|
2061
|
+
const fnNumber = createFunction(
|
|
2062
|
+
"number",
|
|
2063
|
+
fnNumberCode,
|
|
2064
|
+
"data"
|
|
2065
|
+
);
|
|
2066
|
+
const fnBufferCode = [
|
|
2067
|
+
"\n// Extract bytes from buffer (big-endian)",
|
|
2068
|
+
extractBigIntFromBuffer(options.totalBits),
|
|
2069
|
+
"\n// Return result",
|
|
2070
|
+
`return ${compileFields(fields)};`
|
|
2071
|
+
].join("\n");
|
|
2072
|
+
const fnBuffer = createFunction(
|
|
2073
|
+
"buffer",
|
|
2074
|
+
fnBufferCode,
|
|
2075
|
+
"data"
|
|
2076
|
+
);
|
|
2077
|
+
const fnBitsCode = [
|
|
2078
|
+
"\n// Convert bits string to bigint",
|
|
2079
|
+
'var data = BigInt("0b" + bits);',
|
|
2080
|
+
"\n// Return result",
|
|
2081
|
+
`return ${compileFields(fields)};`
|
|
2082
|
+
].join("\n");
|
|
2083
|
+
const fnBits = createFunction("bits", fnBitsCode, "bits");
|
|
2084
|
+
if (!options.debug) {
|
|
2085
|
+
def(fnBuffer, "code", void 0);
|
|
2086
|
+
def(fnBigInt, "code", void 0);
|
|
2087
|
+
def(fnNumber, "code", void 0);
|
|
2088
|
+
def(fnBits, "code", void 0);
|
|
2089
|
+
}
|
|
2090
|
+
return {
|
|
2091
|
+
buffer: fnBuffer,
|
|
2092
|
+
bigint: fnBigInt,
|
|
2093
|
+
number: fnNumber,
|
|
2094
|
+
bits: fnBits
|
|
2095
|
+
};
|
|
2096
|
+
}
|
|
2097
|
+
function compileFields(fields) {
|
|
2098
|
+
const lines = ["{"];
|
|
2099
|
+
for (const field of fields) {
|
|
2100
|
+
if (field.startBit === 0) {
|
|
2101
|
+
lines.push(
|
|
2102
|
+
` ['${field.name}']: Number(data & 0x${field.mask.toString(16)}n),`
|
|
2103
|
+
);
|
|
2104
|
+
} else {
|
|
2105
|
+
lines.push(
|
|
2106
|
+
` ['${field.name}']: Number((data >> ${field.startBit}n) & 0x${field.mask.toString(16)}n),`
|
|
2107
|
+
);
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2110
|
+
lines.push("}");
|
|
2111
|
+
return lines.join("\n");
|
|
2112
|
+
}
|
|
2113
|
+
function extractBigIntFromBuffer(totalBits) {
|
|
2114
|
+
const totalBytes = Math.ceil(totalBits / 8);
|
|
2115
|
+
const chunks = [];
|
|
2116
|
+
let byteIndex = 0;
|
|
2117
|
+
let remainingBytes = totalBytes;
|
|
2118
|
+
while (remainingBytes > 0) {
|
|
2119
|
+
if (remainingBytes >= 4) {
|
|
2120
|
+
const shift = (remainingBytes - 4) * 8;
|
|
2121
|
+
const chunk = `((data[${byteIndex}] << 24) | (data[${byteIndex + 1}] << 16) | (data[${byteIndex + 2}] << 8) | data[${byteIndex + 3}]) >>> 0`;
|
|
2122
|
+
if (shift === 0) {
|
|
2123
|
+
chunks.push(`BigInt(${chunk})`);
|
|
2124
|
+
} else {
|
|
2125
|
+
chunks.push(`(BigInt(${chunk}) << ${shift}n)`);
|
|
2126
|
+
}
|
|
2127
|
+
byteIndex += 4;
|
|
2128
|
+
remainingBytes -= 4;
|
|
2129
|
+
} else {
|
|
2130
|
+
let chunk;
|
|
2131
|
+
if (remainingBytes === 3) {
|
|
2132
|
+
chunk = `(data[${byteIndex}] << 16) | (data[${byteIndex + 1}] << 8) | data[${byteIndex + 2}]`;
|
|
2133
|
+
} else if (remainingBytes === 2) {
|
|
2134
|
+
chunk = `(data[${byteIndex}] << 8) | data[${byteIndex + 1}]`;
|
|
2135
|
+
} else {
|
|
2136
|
+
chunk = `data[${byteIndex}]`;
|
|
2137
|
+
}
|
|
2138
|
+
chunks.push(`BigInt(${chunk})`);
|
|
2139
|
+
remainingBytes = 0;
|
|
2140
|
+
}
|
|
2141
|
+
}
|
|
2142
|
+
return `data =
|
|
2143
|
+
${chunks.join("\n | ")};`;
|
|
2144
|
+
}
|
|
2145
|
+
function buildFieldsInfo(fields, totalBits) {
|
|
2146
|
+
const result = [];
|
|
2147
|
+
let currentBitPosition = totalBits;
|
|
2148
|
+
fields.forEach((field, idx) => {
|
|
2149
|
+
const startBit = currentBitPosition - field.bits;
|
|
2150
|
+
const endBit = currentBitPosition - 1;
|
|
2151
|
+
result.push({
|
|
2152
|
+
id: `f_${idx}`,
|
|
2153
|
+
...field,
|
|
2154
|
+
mask: (1n << BigInt(field.bits)) - 1n,
|
|
2155
|
+
startBit,
|
|
2156
|
+
endBit
|
|
2157
|
+
});
|
|
2158
|
+
currentBitPosition -= field.bits;
|
|
2159
|
+
});
|
|
2160
|
+
return result;
|
|
2161
|
+
}
|
|
2162
|
+
|
|
1691
2163
|
function bytesToBase64(data, { encoding = "base64", padding } = {}) {
|
|
1692
2164
|
if (encoding === "base64") {
|
|
1693
2165
|
return base64.encode(data, { includePadding: padding ?? true });
|
|
@@ -1760,92 +2232,453 @@ function uint8ToUint32(value) {
|
|
|
1760
2232
|
return uint32Array;
|
|
1761
2233
|
}
|
|
1762
2234
|
|
|
1763
|
-
const
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
if (isObject(value)) {
|
|
1769
|
-
if (BSON_TYPES.has(value?._bsontype)) {
|
|
1770
|
-
return String(value);
|
|
2235
|
+
const DateType = {
|
|
2236
|
+
placeholder: "$date",
|
|
2237
|
+
encode: (value) => {
|
|
2238
|
+
if (value instanceof Date) {
|
|
2239
|
+
return value.getTime();
|
|
1771
2240
|
}
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
2241
|
+
},
|
|
2242
|
+
decode(value) {
|
|
2243
|
+
return new Date(value);
|
|
2244
|
+
}
|
|
2245
|
+
};
|
|
2246
|
+
const BinaryType = {
|
|
2247
|
+
placeholder: "$binary",
|
|
2248
|
+
encode: (value) => {
|
|
2249
|
+
if (value instanceof Uint8Array) {
|
|
2250
|
+
return base64.encode(value, { includePadding: true });
|
|
2251
|
+
} else if (value instanceof Uint16Array) {
|
|
2252
|
+
return {
|
|
2253
|
+
value: base64.encode(uint16ToUint8(value), { includePadding: true }),
|
|
2254
|
+
bit: 16
|
|
2255
|
+
};
|
|
2256
|
+
} else if (value instanceof Uint32Array) {
|
|
2257
|
+
return {
|
|
2258
|
+
value: base64.encode(uint32ToUint8(value), { includePadding: true }),
|
|
2259
|
+
bit: 32
|
|
2260
|
+
};
|
|
1781
2261
|
}
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
2262
|
+
},
|
|
2263
|
+
decode(value) {
|
|
2264
|
+
if (typeof value === "string") {
|
|
2265
|
+
return base64.decode(value, { strict: true });
|
|
2266
|
+
} else if (value.bit === 16) {
|
|
2267
|
+
return uint8ToUint16(base64.decode(value.value, { strict: true }));
|
|
2268
|
+
} else if (value.bit === 32) {
|
|
2269
|
+
return uint8ToUint32(base64.decode(value.value, { strict: true }));
|
|
2270
|
+
}
|
|
2271
|
+
throw new Error("Unexpected $binary bit value: " + value.bit);
|
|
1787
2272
|
}
|
|
1788
|
-
return result;
|
|
1789
2273
|
};
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
fn,
|
|
1796
|
-
getPointer,
|
|
1797
|
-
getBucket,
|
|
1798
|
-
objectStrategy = "ref"
|
|
1799
|
-
}) {
|
|
1800
|
-
const isAsync = fn.constructor.name === "AsyncFunction";
|
|
1801
|
-
const argToKeyOptions = { objectStrategy };
|
|
1802
|
-
const $cache = {
|
|
1803
|
-
getBucket: () => getBucket(getPointer()),
|
|
1804
|
-
getPointer,
|
|
1805
|
-
argToKeyOptions
|
|
1806
|
-
};
|
|
1807
|
-
const wrapFn = function(...args) {
|
|
1808
|
-
const storage = getBucket(getPointer());
|
|
1809
|
-
const cacheKey = args.map((v) => argToKey(v, argToKeyOptions)).join("_");
|
|
1810
|
-
if (storage.has(cacheKey)) {
|
|
1811
|
-
const value = storage.get(cacheKey);
|
|
1812
|
-
return isAsync ? Promise.resolve(value) : value;
|
|
2274
|
+
const BigIntType = {
|
|
2275
|
+
placeholder: "$bigint",
|
|
2276
|
+
encode: (value) => {
|
|
2277
|
+
if (typeof value === "bigint") {
|
|
2278
|
+
return base64.encode(bigIntBytes(value), { includePadding: false });
|
|
1813
2279
|
}
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
2280
|
+
},
|
|
2281
|
+
decode(value) {
|
|
2282
|
+
return bigIntFromBytes(base64.decode(value, { strict: false }));
|
|
2283
|
+
}
|
|
2284
|
+
};
|
|
2285
|
+
const MapType = {
|
|
2286
|
+
placeholder: "$map",
|
|
2287
|
+
encode: (value, encode) => {
|
|
2288
|
+
if (value instanceof Map) {
|
|
2289
|
+
return encode(Array.from(value.entries()));
|
|
1820
2290
|
}
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
wrapFn.$cache = $cache;
|
|
1825
|
-
def(wrapFn, SYM_WITH_CACHE, true);
|
|
1826
|
-
return wrapFn;
|
|
1827
|
-
}
|
|
1828
|
-
function isWithCache(value) {
|
|
1829
|
-
return !!value && value[SYM_WITH_CACHE] === true;
|
|
1830
|
-
}
|
|
1831
|
-
|
|
1832
|
-
const cache = /* @__PURE__ */ new WeakMap();
|
|
1833
|
-
function withCache(...args) {
|
|
1834
|
-
let options = {};
|
|
1835
|
-
let fn = noop;
|
|
1836
|
-
if (isFunction(args[0])) {
|
|
1837
|
-
fn = args[0];
|
|
1838
|
-
} else if (isFunction(args[1])) {
|
|
1839
|
-
options = args[0] || {};
|
|
1840
|
-
fn = args[1];
|
|
2291
|
+
},
|
|
2292
|
+
decode(value) {
|
|
2293
|
+
return new Map(value);
|
|
1841
2294
|
}
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
if (
|
|
1847
|
-
|
|
1848
|
-
|
|
2295
|
+
};
|
|
2296
|
+
const SetType = {
|
|
2297
|
+
placeholder: "$set",
|
|
2298
|
+
encode: (value, encode) => {
|
|
2299
|
+
if (value instanceof Set) {
|
|
2300
|
+
return encode(Array.from(value.values()));
|
|
2301
|
+
}
|
|
2302
|
+
},
|
|
2303
|
+
decode(value) {
|
|
2304
|
+
return new Set(value);
|
|
2305
|
+
}
|
|
2306
|
+
};
|
|
2307
|
+
const RegexType = {
|
|
2308
|
+
placeholder: "$regex",
|
|
2309
|
+
encode: (value, encode) => {
|
|
2310
|
+
if (value instanceof RegExp) {
|
|
2311
|
+
const regStr = value.toString();
|
|
2312
|
+
const patternStart = regStr.lastIndexOf("/");
|
|
2313
|
+
return {
|
|
2314
|
+
pattern: value.toString().slice(1, patternStart),
|
|
2315
|
+
flags: regStr.slice(patternStart + 1)
|
|
2316
|
+
};
|
|
2317
|
+
}
|
|
2318
|
+
},
|
|
2319
|
+
decode(value) {
|
|
2320
|
+
return new RegExp(value.pattern, value.flags);
|
|
2321
|
+
}
|
|
2322
|
+
};
|
|
2323
|
+
const InfinityType = {
|
|
2324
|
+
placeholder: "$inf",
|
|
2325
|
+
encode: (value, encode) => {
|
|
2326
|
+
if (value === Infinity) {
|
|
2327
|
+
return 1;
|
|
2328
|
+
} else if (value === -Infinity) {
|
|
2329
|
+
return -1;
|
|
2330
|
+
}
|
|
2331
|
+
},
|
|
2332
|
+
decode(value) {
|
|
2333
|
+
if (value === 1) return Infinity;
|
|
2334
|
+
if (value === -1) return -Infinity;
|
|
2335
|
+
throw new Error("Unexpected $inf value: " + value);
|
|
2336
|
+
}
|
|
2337
|
+
};
|
|
2338
|
+
|
|
2339
|
+
class EJSON {
|
|
2340
|
+
/** @internal */
|
|
2341
|
+
typeHandlers = /* @__PURE__ */ new Map();
|
|
2342
|
+
/** @internal */
|
|
2343
|
+
replacerReady;
|
|
2344
|
+
/** @internal */
|
|
2345
|
+
encode;
|
|
2346
|
+
/** @internal */
|
|
2347
|
+
reviewerReady;
|
|
2348
|
+
/** @internal */
|
|
2349
|
+
pure = true;
|
|
2350
|
+
_vendorName = null;
|
|
2351
|
+
/**
|
|
2352
|
+
* MIME type based on the provided vendor name or defaults to 'application/json'.
|
|
2353
|
+
*/
|
|
2354
|
+
mimetype = "application/json";
|
|
2355
|
+
Type = {
|
|
2356
|
+
Date: DateType,
|
|
2357
|
+
Map: MapType,
|
|
2358
|
+
Set: SetType,
|
|
2359
|
+
RegExp: RegexType,
|
|
2360
|
+
Infinity: InfinityType,
|
|
2361
|
+
BigInt: BigIntType,
|
|
2362
|
+
Binary: BinaryType
|
|
2363
|
+
};
|
|
2364
|
+
constructor() {
|
|
2365
|
+
this.replacerReady = this._replacer.bind(this);
|
|
2366
|
+
this.reviewerReady = this._reviewer.bind(this);
|
|
2367
|
+
this.encode = (value) => {
|
|
2368
|
+
return deepCloneWith(value, this.replacerReady);
|
|
2369
|
+
};
|
|
2370
|
+
}
|
|
2371
|
+
/**
|
|
2372
|
+
* The vendor name used for the custom MIME type definition.
|
|
2373
|
+
* If null, defaults to 'application/json'.
|
|
2374
|
+
*/
|
|
2375
|
+
get vendorName() {
|
|
2376
|
+
return this._vendorName;
|
|
2377
|
+
}
|
|
2378
|
+
set vendorName(value) {
|
|
2379
|
+
this._vendorName = value;
|
|
2380
|
+
if (!value) {
|
|
2381
|
+
this.mimetype = "application/json";
|
|
2382
|
+
} else {
|
|
2383
|
+
const vendorName = value.split(" ").map((v) => v.toLowerCase()).join(".").replace(/\.\.+/g, ".").replace(/\.$/, "");
|
|
2384
|
+
this.mimetype = `application/vnd.${vendorName}+json`;
|
|
2385
|
+
}
|
|
2386
|
+
}
|
|
2387
|
+
/**
|
|
2388
|
+
* Adds a custom type handler for encoding/decoding logic.
|
|
2389
|
+
* Ensures type placeholders are unique and adhere to conventions.
|
|
2390
|
+
*/
|
|
2391
|
+
addType(type) {
|
|
2392
|
+
ok(
|
|
2393
|
+
!this.typeHandlers.has(type.placeholder),
|
|
2394
|
+
`type with ${type.placeholder} already taken.`
|
|
2395
|
+
);
|
|
2396
|
+
ok(
|
|
2397
|
+
type.placeholder.startsWith("$"),
|
|
2398
|
+
"type placeholder must starts with $ symbol."
|
|
2399
|
+
);
|
|
2400
|
+
this.pure = false;
|
|
2401
|
+
this.typeHandlers.set(type.placeholder, type);
|
|
2402
|
+
return this;
|
|
2403
|
+
}
|
|
2404
|
+
/**
|
|
2405
|
+
* Stringifies a JavaScript value using custom encoding logic.
|
|
2406
|
+
* @param {any} value - The value to encode and stringify.
|
|
2407
|
+
* @param {string | number} [space] - Optional space for pretty-printing.
|
|
2408
|
+
* @returns {string} - The JSON stringified value.
|
|
2409
|
+
*/
|
|
2410
|
+
stringify(value, space) {
|
|
2411
|
+
if (this.pure) {
|
|
2412
|
+
return JSON.stringify(value, void 0, space);
|
|
2413
|
+
}
|
|
2414
|
+
return JSON.stringify(this.encode(value), void 0, space);
|
|
2415
|
+
}
|
|
2416
|
+
/**
|
|
2417
|
+
* Parses a JSON string using custom decoding logic.
|
|
2418
|
+
* @param {string} value - The JSON string to parse.
|
|
2419
|
+
* @returns {any} - The decoded JavaScript object.
|
|
2420
|
+
*/
|
|
2421
|
+
parse(value) {
|
|
2422
|
+
if (this.pure) {
|
|
2423
|
+
return JSON.parse(value);
|
|
2424
|
+
}
|
|
2425
|
+
return JSON.parse(value, this.reviewerReady);
|
|
2426
|
+
}
|
|
2427
|
+
/** @internal */
|
|
2428
|
+
_replacer(value, key) {
|
|
2429
|
+
if (isPlainObject(value)) return;
|
|
2430
|
+
if (Array.isArray(value)) return;
|
|
2431
|
+
if (!isInfinity(value) && !isBigInt(value)) {
|
|
2432
|
+
if (isPrimitive(value)) return;
|
|
2433
|
+
}
|
|
2434
|
+
for (const type of this.typeHandlers.values()) {
|
|
2435
|
+
const res = type.encode(value, this.encode);
|
|
2436
|
+
if (res !== void 0) {
|
|
2437
|
+
return type.encodeInline ? res : { [type.placeholder]: res };
|
|
2438
|
+
}
|
|
2439
|
+
}
|
|
2440
|
+
return value;
|
|
2441
|
+
}
|
|
2442
|
+
/** @internal */
|
|
2443
|
+
_reviewer(_, value) {
|
|
2444
|
+
const key = firstKey(value);
|
|
2445
|
+
if (!key || key[0] !== "$") return value;
|
|
2446
|
+
const type = this.typeHandlers.get(key);
|
|
2447
|
+
if (type) {
|
|
2448
|
+
return type.decode(value[key]);
|
|
2449
|
+
}
|
|
2450
|
+
return value;
|
|
2451
|
+
}
|
|
2452
|
+
}
|
|
2453
|
+
function firstKey(value) {
|
|
2454
|
+
if (!isObject(value)) return null;
|
|
2455
|
+
for (const key in value) {
|
|
2456
|
+
return key;
|
|
2457
|
+
}
|
|
2458
|
+
return null;
|
|
2459
|
+
}
|
|
2460
|
+
|
|
2461
|
+
function createEJSON(withBasicTypes = false) {
|
|
2462
|
+
const ejson = new EJSON();
|
|
2463
|
+
if (withBasicTypes) {
|
|
2464
|
+
ejson.addType(MapType);
|
|
2465
|
+
ejson.addType(SetType);
|
|
2466
|
+
ejson.addType(DateType);
|
|
2467
|
+
ejson.addType(InfinityType);
|
|
2468
|
+
ejson.addType(BigIntType);
|
|
2469
|
+
ejson.addType(BinaryType);
|
|
2470
|
+
ejson.addType(RegexType);
|
|
2471
|
+
}
|
|
2472
|
+
return ejson;
|
|
2473
|
+
}
|
|
2474
|
+
|
|
2475
|
+
class EJSONStream extends TransformStream {
|
|
2476
|
+
ejson;
|
|
2477
|
+
constructor({ ejson, cl, op, sep, onFlush, onStart }) {
|
|
2478
|
+
let firstChunk = true;
|
|
2479
|
+
super({
|
|
2480
|
+
start(controller) {
|
|
2481
|
+
return Promise.resolve().then(() => {
|
|
2482
|
+
if (onStart) {
|
|
2483
|
+
return onStart(controller);
|
|
2484
|
+
}
|
|
2485
|
+
}).then(() => {
|
|
2486
|
+
controller.enqueue(op);
|
|
2487
|
+
});
|
|
2488
|
+
},
|
|
2489
|
+
transform(chunk, controller) {
|
|
2490
|
+
const jsonString = ejson.stringify(chunk);
|
|
2491
|
+
if (firstChunk) {
|
|
2492
|
+
firstChunk = false;
|
|
2493
|
+
} else {
|
|
2494
|
+
controller.enqueue(sep);
|
|
2495
|
+
}
|
|
2496
|
+
controller.enqueue(jsonString);
|
|
2497
|
+
},
|
|
2498
|
+
flush(controller) {
|
|
2499
|
+
controller.enqueue(cl);
|
|
2500
|
+
if (onFlush) {
|
|
2501
|
+
return onFlush(controller);
|
|
2502
|
+
}
|
|
2503
|
+
}
|
|
2504
|
+
});
|
|
2505
|
+
this.ejson = ejson;
|
|
2506
|
+
}
|
|
2507
|
+
/**
|
|
2508
|
+
* The vendor name used for the custom MIME type definition.
|
|
2509
|
+
* If null, defaults to 'application/json'.
|
|
2510
|
+
*/
|
|
2511
|
+
get vendorName() {
|
|
2512
|
+
return this.ejson.vendorName;
|
|
2513
|
+
}
|
|
2514
|
+
/**
|
|
2515
|
+
* MIME type based on the provided vendor name or defaults to 'application/json'.
|
|
2516
|
+
*/
|
|
2517
|
+
get mimetype() {
|
|
2518
|
+
return this.ejson.mimetype;
|
|
2519
|
+
}
|
|
2520
|
+
}
|
|
2521
|
+
|
|
2522
|
+
const instance = createEJSON(true);
|
|
2523
|
+
|
|
2524
|
+
function createEJSONStream(options = {}) {
|
|
2525
|
+
if (options.resultKey || options.append || options.prepend) {
|
|
2526
|
+
return createEJSONStreamPayload(options);
|
|
2527
|
+
}
|
|
2528
|
+
return new EJSONStream(getOptions(options));
|
|
2529
|
+
}
|
|
2530
|
+
function createEJSONStreamPayload(options) {
|
|
2531
|
+
let { cl, ejson, op, sep } = getOptions(options);
|
|
2532
|
+
const { append, prepend, resultKey } = options;
|
|
2533
|
+
notEmptyString(resultKey, "resultKey required.");
|
|
2534
|
+
const stream = new EJSONStream({
|
|
2535
|
+
ejson,
|
|
2536
|
+
cl,
|
|
2537
|
+
op,
|
|
2538
|
+
sep,
|
|
2539
|
+
onStart(controller) {
|
|
2540
|
+
if (!prepend) {
|
|
2541
|
+
controller.enqueue(`{"${resultKey}":`);
|
|
2542
|
+
return Promise.resolve();
|
|
2543
|
+
}
|
|
2544
|
+
return Promise.resolve().then(() => prepend()).then((data) => {
|
|
2545
|
+
if (data === null || data === void 0) {
|
|
2546
|
+
controller.enqueue(`{"${resultKey}":`);
|
|
2547
|
+
return;
|
|
2548
|
+
}
|
|
2549
|
+
ok(
|
|
2550
|
+
isPlainObject(data),
|
|
2551
|
+
"prepend result expected to be plain object"
|
|
2552
|
+
);
|
|
2553
|
+
const dataPart = instance.stringify(data).slice(0, -1);
|
|
2554
|
+
if (dataPart === "{") {
|
|
2555
|
+
controller.enqueue(`{"${resultKey}":`);
|
|
2556
|
+
return;
|
|
2557
|
+
}
|
|
2558
|
+
controller.enqueue(`${dataPart}${sep}"${resultKey}":`);
|
|
2559
|
+
});
|
|
2560
|
+
},
|
|
2561
|
+
onFlush(controller) {
|
|
2562
|
+
if (!append) {
|
|
2563
|
+
controller.enqueue("}");
|
|
2564
|
+
return Promise.resolve();
|
|
2565
|
+
}
|
|
2566
|
+
return Promise.resolve().then(() => append()).then((data) => {
|
|
2567
|
+
if (data === null || data === void 0) {
|
|
2568
|
+
controller.enqueue("}");
|
|
2569
|
+
return;
|
|
2570
|
+
}
|
|
2571
|
+
ok(
|
|
2572
|
+
isPlainObject(data),
|
|
2573
|
+
"prepend result expected to be plain object"
|
|
2574
|
+
);
|
|
2575
|
+
const dataPart = instance.stringify(data).slice(1);
|
|
2576
|
+
if (dataPart === "}") {
|
|
2577
|
+
controller.enqueue(`}`);
|
|
2578
|
+
return;
|
|
2579
|
+
}
|
|
2580
|
+
controller.enqueue(`${sep}${dataPart}`);
|
|
2581
|
+
});
|
|
2582
|
+
}
|
|
2583
|
+
});
|
|
2584
|
+
return stream;
|
|
2585
|
+
}
|
|
2586
|
+
function getOptions(options) {
|
|
2587
|
+
const { ejson = instance, cl = "]", op = "[", sep = "," } = options;
|
|
2588
|
+
return {
|
|
2589
|
+
cl,
|
|
2590
|
+
ejson,
|
|
2591
|
+
op,
|
|
2592
|
+
sep
|
|
2593
|
+
};
|
|
2594
|
+
}
|
|
2595
|
+
|
|
2596
|
+
const objectKeys = /* @__PURE__ */ new WeakMap();
|
|
2597
|
+
const BSON_TYPES = Object.freeze(/* @__PURE__ */ new Set(["ObjectID", "ObjectId"]));
|
|
2598
|
+
const SYM_WITH_CACHE = Symbol();
|
|
2599
|
+
const argToKey = (value, options = { objectStrategy: "ref" }) => {
|
|
2600
|
+
let result = "";
|
|
2601
|
+
if (isObject(value)) {
|
|
2602
|
+
if (BSON_TYPES.has(value?._bsontype)) {
|
|
2603
|
+
return String(value);
|
|
2604
|
+
}
|
|
2605
|
+
let key;
|
|
2606
|
+
if (options.objectStrategy === "json") {
|
|
2607
|
+
key = instance.stringify(value);
|
|
2608
|
+
} else {
|
|
2609
|
+
key = objectKeys.get(value);
|
|
2610
|
+
if (!key) {
|
|
2611
|
+
key = createRadomKey();
|
|
2612
|
+
objectKeys.set(value, key);
|
|
2613
|
+
}
|
|
2614
|
+
}
|
|
2615
|
+
return key;
|
|
2616
|
+
} else if (Array.isArray(value)) {
|
|
2617
|
+
result += value.map((v) => argToKey(v, options)).join("/");
|
|
2618
|
+
} else {
|
|
2619
|
+
result = String(value);
|
|
2620
|
+
}
|
|
2621
|
+
return result;
|
|
2622
|
+
};
|
|
2623
|
+
function createRadomKey() {
|
|
2624
|
+
return Date.now() + "_" + randomString(16);
|
|
2625
|
+
}
|
|
2626
|
+
|
|
2627
|
+
function createWithCache({
|
|
2628
|
+
fn,
|
|
2629
|
+
getPointer,
|
|
2630
|
+
getBucket,
|
|
2631
|
+
objectStrategy = "ref"
|
|
2632
|
+
}) {
|
|
2633
|
+
const isAsync = fn.constructor.name === "AsyncFunction";
|
|
2634
|
+
const argToKeyOptions = { objectStrategy };
|
|
2635
|
+
const $cache = {
|
|
2636
|
+
getBucket: () => getBucket(getPointer()),
|
|
2637
|
+
getPointer,
|
|
2638
|
+
argToKeyOptions
|
|
2639
|
+
};
|
|
2640
|
+
const wrapFn = function(...args) {
|
|
2641
|
+
const storage = getBucket(getPointer());
|
|
2642
|
+
const cacheKey = args.map((v) => argToKey(v, argToKeyOptions)).join("_");
|
|
2643
|
+
if (storage.has(cacheKey)) {
|
|
2644
|
+
const value = storage.get(cacheKey);
|
|
2645
|
+
return isAsync ? Promise.resolve(value) : value;
|
|
2646
|
+
}
|
|
2647
|
+
const newValue = fn.apply(this, args);
|
|
2648
|
+
if (isPromise(newValue)) {
|
|
2649
|
+
return newValue.then((value) => {
|
|
2650
|
+
storage.set(cacheKey, value);
|
|
2651
|
+
return value;
|
|
2652
|
+
});
|
|
2653
|
+
}
|
|
2654
|
+
storage.set(cacheKey, newValue);
|
|
2655
|
+
return newValue;
|
|
2656
|
+
};
|
|
2657
|
+
wrapFn.$cache = $cache;
|
|
2658
|
+
def(wrapFn, SYM_WITH_CACHE, true);
|
|
2659
|
+
return wrapFn;
|
|
2660
|
+
}
|
|
2661
|
+
function isWithCache(value) {
|
|
2662
|
+
return !!value && value[SYM_WITH_CACHE] === true;
|
|
2663
|
+
}
|
|
2664
|
+
|
|
2665
|
+
const cache = /* @__PURE__ */ new WeakMap();
|
|
2666
|
+
function withCache(...args) {
|
|
2667
|
+
let options = {};
|
|
2668
|
+
let fn = noop;
|
|
2669
|
+
if (isFunction(args[0])) {
|
|
2670
|
+
fn = args[0];
|
|
2671
|
+
} else if (isFunction(args[1])) {
|
|
2672
|
+
options = args[0] || {};
|
|
2673
|
+
fn = args[1];
|
|
2674
|
+
}
|
|
2675
|
+
const pointer = options.cachePointer || fn;
|
|
2676
|
+
const getPointer = () => pointer;
|
|
2677
|
+
const getBucket = (pointer2) => {
|
|
2678
|
+
let fnCache = cache.get(pointer2);
|
|
2679
|
+
if (!fnCache) {
|
|
2680
|
+
fnCache = /* @__PURE__ */ new Map();
|
|
2681
|
+
cache.set(pointer2, fnCache);
|
|
1849
2682
|
}
|
|
1850
2683
|
return fnCache;
|
|
1851
2684
|
};
|
|
@@ -2459,15 +3292,6 @@ function captureStackTrace(till) {
|
|
|
2459
3292
|
return (err.stack || "").slice(6);
|
|
2460
3293
|
}
|
|
2461
3294
|
|
|
2462
|
-
function toError(value, unknownMessage = "Unknown error") {
|
|
2463
|
-
if (isError(value)) {
|
|
2464
|
-
return value;
|
|
2465
|
-
}
|
|
2466
|
-
const error = new Error(unknownMessage, { cause: value });
|
|
2467
|
-
Error.captureStackTrace(error, toError);
|
|
2468
|
-
return error;
|
|
2469
|
-
}
|
|
2470
|
-
|
|
2471
3295
|
function catchError(fn) {
|
|
2472
3296
|
try {
|
|
2473
3297
|
const res = fn();
|
|
@@ -3417,678 +4241,317 @@ var TABLE = new Int32Array([
|
|
|
3417
4241
|
755167117
|
|
3418
4242
|
]);
|
|
3419
4243
|
function crc32(value, seed) {
|
|
3420
|
-
if (isString(value)) {
|
|
3421
|
-
return crc32(textEncoder.encode(value), seed);
|
|
3422
|
-
}
|
|
3423
|
-
var crc = seed === 0 ? 0 : ~~seed ^ -1;
|
|
3424
|
-
if (value instanceof Uint8Array) {
|
|
3425
|
-
for (var index = 0; index < value.length; index++) {
|
|
3426
|
-
crc = TABLE[(crc ^ value[index]) & 255] ^ crc >>> 8;
|
|
3427
|
-
}
|
|
3428
|
-
} else {
|
|
3429
|
-
for (var current of value) {
|
|
3430
|
-
for (var index = 0; index < current.length; index++) {
|
|
3431
|
-
crc = TABLE[(crc ^ current[index]) & 255] ^ crc >>> 8;
|
|
3432
|
-
}
|
|
3433
|
-
}
|
|
3434
|
-
}
|
|
3435
|
-
return crc ^ -1;
|
|
3436
|
-
}
|
|
3437
|
-
|
|
3438
|
-
function isDateObject(value) {
|
|
3439
|
-
return has(value, ["year", "month", "date"]) && isNumber(value.year) && isNumber(value.month) && isNumber(value.date);
|
|
3440
|
-
}
|
|
3441
|
-
|
|
3442
|
-
function createDateObject(value, returnsNullWhenInvalid = false) {
|
|
3443
|
-
let result = null;
|
|
3444
|
-
let inputValue = value;
|
|
3445
|
-
if (isNumber(inputValue) || isString(inputValue)) {
|
|
3446
|
-
inputValue = new Date(inputValue);
|
|
3447
|
-
}
|
|
3448
|
-
if (isDate(inputValue)) {
|
|
3449
|
-
result = {
|
|
3450
|
-
year: inputValue.getFullYear(),
|
|
3451
|
-
month: inputValue.getMonth() + 1,
|
|
3452
|
-
date: inputValue.getDate()
|
|
3453
|
-
};
|
|
3454
|
-
} else if (isDateObject(inputValue)) {
|
|
3455
|
-
result = { ...inputValue };
|
|
3456
|
-
}
|
|
3457
|
-
ok(
|
|
3458
|
-
returnsNullWhenInvalid || !!result,
|
|
3459
|
-
`Failed to date parse: ${value}.`
|
|
3460
|
-
);
|
|
3461
|
-
return result;
|
|
3462
|
-
}
|
|
3463
|
-
|
|
3464
|
-
function isTimeObject(value) {
|
|
3465
|
-
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;
|
|
3466
|
-
}
|
|
3467
|
-
|
|
3468
|
-
function createTimeObject(value, returnsNullWhenInvalid = false) {
|
|
3469
|
-
let result = null;
|
|
3470
|
-
let inputValue = value;
|
|
3471
|
-
if (isNumber(inputValue)) {
|
|
3472
|
-
inputValue = new Date(inputValue);
|
|
3473
|
-
} else if (isString(inputValue)) {
|
|
3474
|
-
const [h, m] = inputValue.split(":").map((v) => v.trim().padStart(2, "0")).map((v) => parseInt(v));
|
|
3475
|
-
inputValue = { h, m };
|
|
3476
|
-
}
|
|
3477
|
-
if (isDate(inputValue)) {
|
|
3478
|
-
result = {
|
|
3479
|
-
h: inputValue.getHours(),
|
|
3480
|
-
m: inputValue.getMinutes()
|
|
3481
|
-
};
|
|
3482
|
-
} else if (isTimeObject(inputValue)) {
|
|
3483
|
-
result = { ...inputValue };
|
|
3484
|
-
}
|
|
3485
|
-
ok(
|
|
3486
|
-
returnsNullWhenInvalid || !!result,
|
|
3487
|
-
`Failed to time parse: ${value}.`
|
|
3488
|
-
);
|
|
3489
|
-
return result;
|
|
3490
|
-
}
|
|
3491
|
-
|
|
3492
|
-
const UNIT_TO_MS = {
|
|
3493
|
-
ms: 1,
|
|
3494
|
-
s: 1e3,
|
|
3495
|
-
m: 1e3 * 60,
|
|
3496
|
-
h: 1e3 * 60 * 60,
|
|
3497
|
-
d: 1e3 * 60 * 60 * 24,
|
|
3498
|
-
w: 1e3 * 60 * 60 * 24 * 7
|
|
3499
|
-
};
|
|
3500
|
-
class TimeSpan {
|
|
3501
|
-
constructor(value, unit) {
|
|
3502
|
-
this.value = value;
|
|
3503
|
-
this.unit = unit;
|
|
3504
|
-
}
|
|
3505
|
-
/**
|
|
3506
|
-
* The numeric value of the time span
|
|
3507
|
-
*/
|
|
3508
|
-
value;
|
|
3509
|
-
/**
|
|
3510
|
-
* The unit of the time span.
|
|
3511
|
-
*/
|
|
3512
|
-
unit;
|
|
3513
|
-
/**
|
|
3514
|
-
* Converts the time span to milliseconds.
|
|
3515
|
-
*
|
|
3516
|
-
* @returns {number} The equivalent time span in milliseconds.
|
|
3517
|
-
* @example
|
|
3518
|
-
* const ts = new TimeSpan(2, 'h');
|
|
3519
|
-
* ts.milliseconds(); // Returns 7200000
|
|
3520
|
-
*/
|
|
3521
|
-
milliseconds() {
|
|
3522
|
-
const multiplier = UNIT_TO_MS[this.unit];
|
|
3523
|
-
return this.value * multiplier;
|
|
3524
|
-
}
|
|
3525
|
-
/**
|
|
3526
|
-
* Converts the time span to seconds.
|
|
3527
|
-
*
|
|
3528
|
-
* @returns {number} The equivalent time span in seconds.
|
|
3529
|
-
* @example
|
|
3530
|
-
* const ts = new TimeSpan(2, 'm');
|
|
3531
|
-
* ts.seconds(); // Returns 120
|
|
3532
|
-
*/
|
|
3533
|
-
seconds() {
|
|
3534
|
-
return this.milliseconds() / UNIT_TO_MS.s;
|
|
3535
|
-
}
|
|
3536
|
-
/**
|
|
3537
|
-
* Converts the time span to minutes.
|
|
3538
|
-
*
|
|
3539
|
-
* @returns {number} The equivalent time span in minutes.
|
|
3540
|
-
* @example
|
|
3541
|
-
* const ts = new TimeSpan(120, 's');
|
|
3542
|
-
* ts.minutes(); // Returns 2
|
|
3543
|
-
*/
|
|
3544
|
-
minutes() {
|
|
3545
|
-
return this.milliseconds() / UNIT_TO_MS.m;
|
|
3546
|
-
}
|
|
3547
|
-
/**
|
|
3548
|
-
* Converts the time span to hours.
|
|
3549
|
-
*
|
|
3550
|
-
* @returns {number} The equivalent time span in hours.
|
|
3551
|
-
* @example
|
|
3552
|
-
* const ts = new TimeSpan(120, 'm');
|
|
3553
|
-
* ts.hours(); // Returns 2
|
|
3554
|
-
*/
|
|
3555
|
-
hours() {
|
|
3556
|
-
return this.milliseconds() / UNIT_TO_MS.h;
|
|
3557
|
-
}
|
|
3558
|
-
/**
|
|
3559
|
-
* Converts the time span to days.
|
|
3560
|
-
*
|
|
3561
|
-
* @returns {number} The equivalent time span in days.
|
|
3562
|
-
* @example
|
|
3563
|
-
* const ts = new TimeSpan(48, 'h');
|
|
3564
|
-
* ts.days(); // Returns 2
|
|
3565
|
-
*/
|
|
3566
|
-
days() {
|
|
3567
|
-
return this.milliseconds() / UNIT_TO_MS.d;
|
|
3568
|
-
}
|
|
3569
|
-
/**
|
|
3570
|
-
* Converts the time span to weeks.
|
|
3571
|
-
*
|
|
3572
|
-
* @returns {number} The equivalent time span in weeks.
|
|
3573
|
-
* @example
|
|
3574
|
-
* const ts = new TimeSpan(14, 'd');
|
|
3575
|
-
* ts.weeks(); // Returns 2
|
|
3576
|
-
*/
|
|
3577
|
-
weeks() {
|
|
3578
|
-
return this.milliseconds() / UNIT_TO_MS.w;
|
|
3579
|
-
}
|
|
3580
|
-
/**
|
|
3581
|
-
* Adds a specified value and unit to the current time span.
|
|
3582
|
-
*
|
|
3583
|
-
* Returns new instance.
|
|
3584
|
-
*
|
|
3585
|
-
* @param {number} value - The value to add.
|
|
3586
|
-
* @param {TimeSpanUnit} [unit='ms'] - The unit of the value to add (default is milliseconds).
|
|
3587
|
-
* @returns {TimeSpan} A new TimeSpan instance with the added value.
|
|
3588
|
-
* @example
|
|
3589
|
-
* const ts = new TimeSpan(1, 'h');
|
|
3590
|
-
* ts.add(30, 'm'); // Represents 1.5 hours
|
|
3591
|
-
*/
|
|
3592
|
-
add(value, unit = "ms") {
|
|
3593
|
-
const multiplier = UNIT_TO_MS[unit];
|
|
3594
|
-
return new TimeSpan(this.milliseconds() + value * multiplier, "ms");
|
|
3595
|
-
}
|
|
3596
|
-
/**
|
|
3597
|
-
* Subtracts a specified value and unit from the current time span.
|
|
3598
|
-
*
|
|
3599
|
-
* Returns new instance.
|
|
3600
|
-
*
|
|
3601
|
-
* @param {number} value - The value to subtract.
|
|
3602
|
-
* @param {TimeSpanUnit} [unit='ms'] - The unit of the value to subtract (default is milliseconds).
|
|
3603
|
-
* @returns {TimeSpan} A new TimeSpan instance with the subtracted value.
|
|
3604
|
-
* @example
|
|
3605
|
-
* const ts = new TimeSpan(1, 'h');
|
|
3606
|
-
* ts.subtract(30, 'm'); // Represents 30 minutes less than 1 hour
|
|
3607
|
-
*/
|
|
3608
|
-
subtract(value, unit = "ms") {
|
|
3609
|
-
const multiplier = UNIT_TO_MS[unit];
|
|
3610
|
-
return new TimeSpan(this.milliseconds() - value * multiplier, "ms");
|
|
4244
|
+
if (isString(value)) {
|
|
4245
|
+
return crc32(textEncoder.encode(value), seed);
|
|
3611
4246
|
}
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
}
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
fromValue = isDate(dt) ? dt.getTime() : 0;
|
|
4247
|
+
var crc = seed === 0 ? 0 : ~~seed ^ -1;
|
|
4248
|
+
if (value instanceof Uint8Array) {
|
|
4249
|
+
for (var index = 0; index < value.length; index++) {
|
|
4250
|
+
crc = TABLE[(crc ^ value[index]) & 255] ^ crc >>> 8;
|
|
4251
|
+
}
|
|
4252
|
+
} else {
|
|
4253
|
+
for (var current of value) {
|
|
4254
|
+
for (var index = 0; index < current.length; index++) {
|
|
4255
|
+
crc = TABLE[(crc ^ current[index]) & 255] ^ crc >>> 8;
|
|
4256
|
+
}
|
|
4257
|
+
}
|
|
3624
4258
|
}
|
|
3625
|
-
return
|
|
3626
|
-
}
|
|
3627
|
-
|
|
3628
|
-
function dateInDays(days, fromValue = Date.now()) {
|
|
3629
|
-
return new Date(timestampMs(fromValue) + days * 60 * 60 * 24 * 1e3);
|
|
4259
|
+
return crc ^ -1;
|
|
3630
4260
|
}
|
|
3631
4261
|
|
|
3632
|
-
function
|
|
3633
|
-
return
|
|
4262
|
+
function isDateObject(value) {
|
|
4263
|
+
return has(value, ["year", "month", "date"]) && isNumber(value.year) && isNumber(value.month) && isNumber(value.date);
|
|
3634
4264
|
}
|
|
3635
4265
|
|
|
3636
|
-
function
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
if (h === startTime.h) {
|
|
3642
|
-
return { h, m: getRandomInt(startTime.m, 59) };
|
|
4266
|
+
function createDateObject(value, returnsNullWhenInvalid = false) {
|
|
4267
|
+
let result = null;
|
|
4268
|
+
let inputValue = value;
|
|
4269
|
+
if (isNumber(inputValue) || isString(inputValue)) {
|
|
4270
|
+
inputValue = new Date(inputValue);
|
|
3643
4271
|
}
|
|
3644
|
-
if (
|
|
3645
|
-
|
|
4272
|
+
if (isDate(inputValue)) {
|
|
4273
|
+
result = {
|
|
4274
|
+
year: inputValue.getFullYear(),
|
|
4275
|
+
month: inputValue.getMonth() + 1,
|
|
4276
|
+
date: inputValue.getDate()
|
|
4277
|
+
};
|
|
4278
|
+
} else if (isDateObject(inputValue)) {
|
|
4279
|
+
result = { ...inputValue };
|
|
3646
4280
|
}
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
number$1(hm, "expected number value");
|
|
3653
|
-
const h = Math.floor(hm);
|
|
3654
|
-
const m = round2digits(hm - h) * 100;
|
|
3655
|
-
return h * 3600 + m * 60;
|
|
3656
|
-
}
|
|
3657
|
-
|
|
3658
|
-
function isTimeString(value) {
|
|
3659
|
-
if (!isString(value)) return false;
|
|
3660
|
-
const parts = value.split(":").map(Number);
|
|
3661
|
-
if (parts.length !== 2) return false;
|
|
3662
|
-
const [h, m] = parts;
|
|
3663
|
-
return h >= 0 && h < 24 && m >= 0 && m < 60;
|
|
3664
|
-
}
|
|
3665
|
-
|
|
3666
|
-
function isTimeValue(value) {
|
|
3667
|
-
return isTimeString(value) || isTimeObject(value);
|
|
3668
|
-
}
|
|
3669
|
-
|
|
3670
|
-
function isValidWeekDay(value) {
|
|
3671
|
-
return isNumber(value) && Number.isInteger(value) && value >= 1 && value <= 7;
|
|
4281
|
+
ok(
|
|
4282
|
+
returnsNullWhenInvalid || !!result,
|
|
4283
|
+
`Failed to date parse: ${value}.`
|
|
4284
|
+
);
|
|
4285
|
+
return result;
|
|
3672
4286
|
}
|
|
3673
4287
|
|
|
3674
|
-
function
|
|
3675
|
-
|
|
3676
|
-
number$1(value, "expected number value");
|
|
3677
|
-
const h = Math.floor(value / 3600);
|
|
3678
|
-
const m = Math.floor(value % 3600 / 60);
|
|
3679
|
-
return round2digits(h + m / 100, 2);
|
|
4288
|
+
function isTimeObject(value) {
|
|
4289
|
+
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;
|
|
3680
4290
|
}
|
|
3681
4291
|
|
|
3682
|
-
function
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
if (value === 0) {
|
|
3691
|
-
return { h: 0, m: 0 };
|
|
3692
|
-
}
|
|
3693
|
-
value = value % 1440;
|
|
3694
|
-
if (value < 0) {
|
|
3695
|
-
value += 1440;
|
|
4292
|
+
function createTimeObject(value, returnsNullWhenInvalid = false) {
|
|
4293
|
+
let result = null;
|
|
4294
|
+
let inputValue = value;
|
|
4295
|
+
if (isNumber(inputValue)) {
|
|
4296
|
+
inputValue = new Date(inputValue);
|
|
4297
|
+
} else if (isString(inputValue)) {
|
|
4298
|
+
const [h, m] = inputValue.split(":").map((v) => v.trim().padStart(2, "0")).map((v) => parseInt(v));
|
|
4299
|
+
inputValue = { h, m };
|
|
3696
4300
|
}
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
return new Date(value * 1e3);
|
|
3705
|
-
}
|
|
3706
|
-
|
|
3707
|
-
function timeStringify(value, returnsNullWhenInvalid = false) {
|
|
3708
|
-
const timeObject = createTimeObject(value, true);
|
|
3709
|
-
if (!timeObject) {
|
|
3710
|
-
ok(
|
|
3711
|
-
returnsNullWhenInvalid,
|
|
3712
|
-
"Failed to stringify time from: " + JSON.stringify(value)
|
|
3713
|
-
);
|
|
3714
|
-
return null;
|
|
4301
|
+
if (isDate(inputValue)) {
|
|
4302
|
+
result = {
|
|
4303
|
+
h: inputValue.getHours(),
|
|
4304
|
+
m: inputValue.getMinutes()
|
|
4305
|
+
};
|
|
4306
|
+
} else if (isTimeObject(inputValue)) {
|
|
4307
|
+
result = { ...inputValue };
|
|
3715
4308
|
}
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
function timeToMinutes(value) {
|
|
3723
|
-
const time = createTimeObject(value);
|
|
3724
|
-
return time.h * 60 + time.m;
|
|
3725
|
-
}
|
|
3726
|
-
|
|
3727
|
-
function weeksInYear(year) {
|
|
3728
|
-
const target = new Date(Date.UTC(year + 1, 0, 1));
|
|
3729
|
-
const dayNumber = target.getDay();
|
|
3730
|
-
return dayNumber < 4 ? 52 : 53;
|
|
4309
|
+
ok(
|
|
4310
|
+
returnsNullWhenInvalid || !!result,
|
|
4311
|
+
`Failed to time parse: ${value}.`
|
|
4312
|
+
);
|
|
4313
|
+
return result;
|
|
3731
4314
|
}
|
|
3732
4315
|
|
|
3733
|
-
const
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
decode(value) {
|
|
3741
|
-
return new Date(value);
|
|
3742
|
-
}
|
|
3743
|
-
};
|
|
3744
|
-
const BinaryType = {
|
|
3745
|
-
placeholder: "$binary",
|
|
3746
|
-
encode: (value) => {
|
|
3747
|
-
if (value instanceof Uint8Array) {
|
|
3748
|
-
return base64.encode(value, { includePadding: true });
|
|
3749
|
-
} else if (value instanceof Uint16Array) {
|
|
3750
|
-
return {
|
|
3751
|
-
value: base64.encode(uint16ToUint8(value), { includePadding: true }),
|
|
3752
|
-
bit: 16
|
|
3753
|
-
};
|
|
3754
|
-
} else if (value instanceof Uint32Array) {
|
|
3755
|
-
return {
|
|
3756
|
-
value: base64.encode(uint32ToUint8(value), { includePadding: true }),
|
|
3757
|
-
bit: 32
|
|
3758
|
-
};
|
|
3759
|
-
}
|
|
3760
|
-
},
|
|
3761
|
-
decode(value) {
|
|
3762
|
-
if (typeof value === "string") {
|
|
3763
|
-
return base64.decode(value, { strict: true });
|
|
3764
|
-
} else if (value.bit === 16) {
|
|
3765
|
-
return uint8ToUint16(base64.decode(value.value, { strict: true }));
|
|
3766
|
-
} else if (value.bit === 32) {
|
|
3767
|
-
return uint8ToUint32(base64.decode(value.value, { strict: true }));
|
|
3768
|
-
}
|
|
3769
|
-
throw new Error("Unexpected $binary bit value: " + value.bit);
|
|
3770
|
-
}
|
|
3771
|
-
};
|
|
3772
|
-
const BigIntType = {
|
|
3773
|
-
placeholder: "$bigint",
|
|
3774
|
-
encode: (value) => {
|
|
3775
|
-
if (typeof value === "bigint") {
|
|
3776
|
-
return base64.encode(bigIntBytes(value), { includePadding: false });
|
|
3777
|
-
}
|
|
3778
|
-
},
|
|
3779
|
-
decode(value) {
|
|
3780
|
-
return bigIntFromBytes(base64.decode(value, { strict: false }));
|
|
3781
|
-
}
|
|
3782
|
-
};
|
|
3783
|
-
const MapType = {
|
|
3784
|
-
placeholder: "$map",
|
|
3785
|
-
encode: (value, encode) => {
|
|
3786
|
-
if (value instanceof Map) {
|
|
3787
|
-
return encode(Array.from(value.entries()));
|
|
3788
|
-
}
|
|
3789
|
-
},
|
|
3790
|
-
decode(value) {
|
|
3791
|
-
return new Map(value);
|
|
3792
|
-
}
|
|
3793
|
-
};
|
|
3794
|
-
const SetType = {
|
|
3795
|
-
placeholder: "$set",
|
|
3796
|
-
encode: (value, encode) => {
|
|
3797
|
-
if (value instanceof Set) {
|
|
3798
|
-
return encode(Array.from(value.values()));
|
|
3799
|
-
}
|
|
3800
|
-
},
|
|
3801
|
-
decode(value) {
|
|
3802
|
-
return new Set(value);
|
|
3803
|
-
}
|
|
4316
|
+
const UNIT_TO_MS = {
|
|
4317
|
+
ms: 1,
|
|
4318
|
+
s: 1e3,
|
|
4319
|
+
m: 1e3 * 60,
|
|
4320
|
+
h: 1e3 * 60 * 60,
|
|
4321
|
+
d: 1e3 * 60 * 60 * 24,
|
|
4322
|
+
w: 1e3 * 60 * 60 * 24 * 7
|
|
3804
4323
|
};
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
const regStr = value.toString();
|
|
3810
|
-
const patternStart = regStr.lastIndexOf("/");
|
|
3811
|
-
return {
|
|
3812
|
-
pattern: value.toString().slice(1, patternStart),
|
|
3813
|
-
flags: regStr.slice(patternStart + 1)
|
|
3814
|
-
};
|
|
3815
|
-
}
|
|
3816
|
-
},
|
|
3817
|
-
decode(value) {
|
|
3818
|
-
return new RegExp(value.pattern, value.flags);
|
|
4324
|
+
class TimeSpan {
|
|
4325
|
+
constructor(value, unit) {
|
|
4326
|
+
this.value = value;
|
|
4327
|
+
this.unit = unit;
|
|
3819
4328
|
}
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
4329
|
+
/**
|
|
4330
|
+
* The numeric value of the time span
|
|
4331
|
+
*/
|
|
4332
|
+
value;
|
|
4333
|
+
/**
|
|
4334
|
+
* The unit of the time span.
|
|
4335
|
+
*/
|
|
4336
|
+
unit;
|
|
4337
|
+
/**
|
|
4338
|
+
* Converts the time span to milliseconds.
|
|
4339
|
+
*
|
|
4340
|
+
* @returns {number} The equivalent time span in milliseconds.
|
|
4341
|
+
* @example
|
|
4342
|
+
* const ts = new TimeSpan(2, 'h');
|
|
4343
|
+
* ts.milliseconds(); // Returns 7200000
|
|
4344
|
+
*/
|
|
4345
|
+
milliseconds() {
|
|
4346
|
+
const multiplier = UNIT_TO_MS[this.unit];
|
|
4347
|
+
return this.value * multiplier;
|
|
3834
4348
|
}
|
|
3835
|
-
};
|
|
3836
|
-
|
|
3837
|
-
class EJSON {
|
|
3838
|
-
/** @internal */
|
|
3839
|
-
typeHandlers = /* @__PURE__ */ new Map();
|
|
3840
|
-
/** @internal */
|
|
3841
|
-
replacerReady;
|
|
3842
|
-
/** @internal */
|
|
3843
|
-
encode;
|
|
3844
|
-
/** @internal */
|
|
3845
|
-
reviewerReady;
|
|
3846
|
-
/** @internal */
|
|
3847
|
-
pure = true;
|
|
3848
|
-
_vendorName = null;
|
|
3849
4349
|
/**
|
|
3850
|
-
*
|
|
4350
|
+
* Converts the time span to seconds.
|
|
4351
|
+
*
|
|
4352
|
+
* @returns {number} The equivalent time span in seconds.
|
|
4353
|
+
* @example
|
|
4354
|
+
* const ts = new TimeSpan(2, 'm');
|
|
4355
|
+
* ts.seconds(); // Returns 120
|
|
3851
4356
|
*/
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
Date: DateType,
|
|
3855
|
-
Map: MapType,
|
|
3856
|
-
Set: SetType,
|
|
3857
|
-
RegExp: RegexType,
|
|
3858
|
-
Infinity: InfinityType,
|
|
3859
|
-
BigInt: BigIntType,
|
|
3860
|
-
Binary: BinaryType
|
|
3861
|
-
};
|
|
3862
|
-
constructor() {
|
|
3863
|
-
this.replacerReady = this._replacer.bind(this);
|
|
3864
|
-
this.reviewerReady = this._reviewer.bind(this);
|
|
3865
|
-
this.encode = (value) => {
|
|
3866
|
-
return deepCloneWith(value, this.replacerReady);
|
|
3867
|
-
};
|
|
4357
|
+
seconds() {
|
|
4358
|
+
return this.milliseconds() / UNIT_TO_MS.s;
|
|
3868
4359
|
}
|
|
3869
4360
|
/**
|
|
3870
|
-
*
|
|
3871
|
-
*
|
|
4361
|
+
* Converts the time span to minutes.
|
|
4362
|
+
*
|
|
4363
|
+
* @returns {number} The equivalent time span in minutes.
|
|
4364
|
+
* @example
|
|
4365
|
+
* const ts = new TimeSpan(120, 's');
|
|
4366
|
+
* ts.minutes(); // Returns 2
|
|
3872
4367
|
*/
|
|
3873
|
-
|
|
3874
|
-
return this.
|
|
4368
|
+
minutes() {
|
|
4369
|
+
return this.milliseconds() / UNIT_TO_MS.m;
|
|
3875
4370
|
}
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
4371
|
+
/**
|
|
4372
|
+
* Converts the time span to hours.
|
|
4373
|
+
*
|
|
4374
|
+
* @returns {number} The equivalent time span in hours.
|
|
4375
|
+
* @example
|
|
4376
|
+
* const ts = new TimeSpan(120, 'm');
|
|
4377
|
+
* ts.hours(); // Returns 2
|
|
4378
|
+
*/
|
|
4379
|
+
hours() {
|
|
4380
|
+
return this.milliseconds() / UNIT_TO_MS.h;
|
|
3884
4381
|
}
|
|
3885
4382
|
/**
|
|
3886
|
-
*
|
|
3887
|
-
*
|
|
4383
|
+
* Converts the time span to days.
|
|
4384
|
+
*
|
|
4385
|
+
* @returns {number} The equivalent time span in days.
|
|
4386
|
+
* @example
|
|
4387
|
+
* const ts = new TimeSpan(48, 'h');
|
|
4388
|
+
* ts.days(); // Returns 2
|
|
3888
4389
|
*/
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
!this.typeHandlers.has(type.placeholder),
|
|
3892
|
-
`type with ${type.placeholder} already taken.`
|
|
3893
|
-
);
|
|
3894
|
-
ok(
|
|
3895
|
-
type.placeholder.startsWith("$"),
|
|
3896
|
-
"type placeholder must starts with $ symbol."
|
|
3897
|
-
);
|
|
3898
|
-
this.pure = false;
|
|
3899
|
-
this.typeHandlers.set(type.placeholder, type);
|
|
3900
|
-
return this;
|
|
4390
|
+
days() {
|
|
4391
|
+
return this.milliseconds() / UNIT_TO_MS.d;
|
|
3901
4392
|
}
|
|
3902
4393
|
/**
|
|
3903
|
-
*
|
|
3904
|
-
*
|
|
3905
|
-
* @
|
|
3906
|
-
* @
|
|
4394
|
+
* Converts the time span to weeks.
|
|
4395
|
+
*
|
|
4396
|
+
* @returns {number} The equivalent time span in weeks.
|
|
4397
|
+
* @example
|
|
4398
|
+
* const ts = new TimeSpan(14, 'd');
|
|
4399
|
+
* ts.weeks(); // Returns 2
|
|
3907
4400
|
*/
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
return JSON.stringify(value, void 0, space);
|
|
3911
|
-
}
|
|
3912
|
-
return JSON.stringify(this.encode(value), void 0, space);
|
|
4401
|
+
weeks() {
|
|
4402
|
+
return this.milliseconds() / UNIT_TO_MS.w;
|
|
3913
4403
|
}
|
|
3914
4404
|
/**
|
|
3915
|
-
*
|
|
3916
|
-
*
|
|
3917
|
-
*
|
|
4405
|
+
* Adds a specified value and unit to the current time span.
|
|
4406
|
+
*
|
|
4407
|
+
* Returns new instance.
|
|
4408
|
+
*
|
|
4409
|
+
* @param {number} value - The value to add.
|
|
4410
|
+
* @param {TimeSpanUnit} [unit='ms'] - The unit of the value to add (default is milliseconds).
|
|
4411
|
+
* @returns {TimeSpan} A new TimeSpan instance with the added value.
|
|
4412
|
+
* @example
|
|
4413
|
+
* const ts = new TimeSpan(1, 'h');
|
|
4414
|
+
* ts.add(30, 'm'); // Represents 1.5 hours
|
|
3918
4415
|
*/
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
}
|
|
3923
|
-
return JSON.parse(value, this.reviewerReady);
|
|
4416
|
+
add(value, unit = "ms") {
|
|
4417
|
+
const multiplier = UNIT_TO_MS[unit];
|
|
4418
|
+
return new TimeSpan(this.milliseconds() + value * multiplier, "ms");
|
|
3924
4419
|
}
|
|
3925
|
-
/**
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
4420
|
+
/**
|
|
4421
|
+
* Subtracts a specified value and unit from the current time span.
|
|
4422
|
+
*
|
|
4423
|
+
* Returns new instance.
|
|
4424
|
+
*
|
|
4425
|
+
* @param {number} value - The value to subtract.
|
|
4426
|
+
* @param {TimeSpanUnit} [unit='ms'] - The unit of the value to subtract (default is milliseconds).
|
|
4427
|
+
* @returns {TimeSpan} A new TimeSpan instance with the subtracted value.
|
|
4428
|
+
* @example
|
|
4429
|
+
* const ts = new TimeSpan(1, 'h');
|
|
4430
|
+
* ts.subtract(30, 'm'); // Represents 30 minutes less than 1 hour
|
|
4431
|
+
*/
|
|
4432
|
+
subtract(value, unit = "ms") {
|
|
4433
|
+
const multiplier = UNIT_TO_MS[unit];
|
|
4434
|
+
return new TimeSpan(this.milliseconds() - value * multiplier, "ms");
|
|
3939
4435
|
}
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
4436
|
+
}
|
|
4437
|
+
|
|
4438
|
+
function createTimeSpan(value, unit = "ms") {
|
|
4439
|
+
return new TimeSpan(value, unit);
|
|
4440
|
+
}
|
|
4441
|
+
|
|
4442
|
+
function timestampMs(fromValue = Date.now()) {
|
|
4443
|
+
if (isDate(fromValue)) {
|
|
4444
|
+
fromValue = fromValue.getTime();
|
|
4445
|
+
} else if (isString(fromValue)) {
|
|
4446
|
+
const dt = new Date(fromValue);
|
|
4447
|
+
fromValue = isDate(dt) ? dt.getTime() : 0;
|
|
3949
4448
|
}
|
|
4449
|
+
return isNumber(fromValue) ? fromValue : 0;
|
|
3950
4450
|
}
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
4451
|
+
|
|
4452
|
+
function dateInDays(days, fromValue = Date.now()) {
|
|
4453
|
+
return new Date(timestampMs(fromValue) + days * 60 * 60 * 24 * 1e3);
|
|
4454
|
+
}
|
|
4455
|
+
|
|
4456
|
+
function dateInSeconds(seconds, fromValue = Date.now()) {
|
|
4457
|
+
return new Date(timestampMs(fromValue) + seconds * 1e3);
|
|
4458
|
+
}
|
|
4459
|
+
|
|
4460
|
+
function getRandomTime(startTime = { h: 0, m: 0 }, endTime = { h: 23, m: 59 }) {
|
|
4461
|
+
const h = getRandomInt(startTime.h, endTime.h);
|
|
4462
|
+
if (startTime.h === endTime.h) {
|
|
4463
|
+
return { h, m: getRandomInt(startTime.m, endTime.m) };
|
|
3955
4464
|
}
|
|
3956
|
-
|
|
4465
|
+
if (h === startTime.h) {
|
|
4466
|
+
return { h, m: getRandomInt(startTime.m, 59) };
|
|
4467
|
+
}
|
|
4468
|
+
if (h === endTime.h) {
|
|
4469
|
+
return { h, m: getRandomInt(0, endTime.m) };
|
|
4470
|
+
}
|
|
4471
|
+
return { h, m: getRandomInt(0, 59) };
|
|
4472
|
+
}
|
|
4473
|
+
|
|
4474
|
+
function hmToSeconds(hm) {
|
|
4475
|
+
hm = Number(hm);
|
|
4476
|
+
number$1(hm, "expected number value");
|
|
4477
|
+
const h = Math.floor(hm);
|
|
4478
|
+
const m = round2digits(hm - h) * 100;
|
|
4479
|
+
return h * 3600 + m * 60;
|
|
4480
|
+
}
|
|
4481
|
+
|
|
4482
|
+
function isTimeString(value) {
|
|
4483
|
+
if (!isString(value)) return false;
|
|
4484
|
+
const parts = value.split(":").map(Number);
|
|
4485
|
+
if (parts.length !== 2) return false;
|
|
4486
|
+
const [h, m] = parts;
|
|
4487
|
+
return h >= 0 && h < 24 && m >= 0 && m < 60;
|
|
3957
4488
|
}
|
|
3958
4489
|
|
|
3959
|
-
function
|
|
3960
|
-
|
|
3961
|
-
if (withBasicTypes) {
|
|
3962
|
-
ejson.addType(MapType);
|
|
3963
|
-
ejson.addType(SetType);
|
|
3964
|
-
ejson.addType(DateType);
|
|
3965
|
-
ejson.addType(InfinityType);
|
|
3966
|
-
ejson.addType(BigIntType);
|
|
3967
|
-
ejson.addType(BinaryType);
|
|
3968
|
-
ejson.addType(RegexType);
|
|
3969
|
-
}
|
|
3970
|
-
return ejson;
|
|
4490
|
+
function isTimeValue(value) {
|
|
4491
|
+
return isTimeString(value) || isTimeObject(value);
|
|
3971
4492
|
}
|
|
3972
4493
|
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
controller.enqueue(sep);
|
|
3993
|
-
}
|
|
3994
|
-
controller.enqueue(jsonString);
|
|
3995
|
-
},
|
|
3996
|
-
flush(controller) {
|
|
3997
|
-
controller.enqueue(cl);
|
|
3998
|
-
if (onFlush) {
|
|
3999
|
-
return onFlush(controller);
|
|
4000
|
-
}
|
|
4001
|
-
}
|
|
4002
|
-
});
|
|
4003
|
-
this.ejson = ejson;
|
|
4494
|
+
function isValidWeekDay(value) {
|
|
4495
|
+
return isNumber(value) && Number.isInteger(value) && value >= 1 && value <= 7;
|
|
4496
|
+
}
|
|
4497
|
+
|
|
4498
|
+
function secondsToHm(seconds) {
|
|
4499
|
+
const value = Number(seconds);
|
|
4500
|
+
number$1(value, "expected number value");
|
|
4501
|
+
const h = Math.floor(value / 3600);
|
|
4502
|
+
const m = Math.floor(value % 3600 / 60);
|
|
4503
|
+
return round2digits(h + m / 100, 2);
|
|
4504
|
+
}
|
|
4505
|
+
|
|
4506
|
+
function timeFromMinutes(value, returnsNullWhenInvalid = false) {
|
|
4507
|
+
if (!isNumber(value)) {
|
|
4508
|
+
ok(
|
|
4509
|
+
returnsNullWhenInvalid,
|
|
4510
|
+
"Failed to time parse from minutes: " + value
|
|
4511
|
+
);
|
|
4512
|
+
return null;
|
|
4004
4513
|
}
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
* If null, defaults to 'application/json'.
|
|
4008
|
-
*/
|
|
4009
|
-
get vendorName() {
|
|
4010
|
-
return this.ejson.vendorName;
|
|
4514
|
+
if (value === 0) {
|
|
4515
|
+
return { h: 0, m: 0 };
|
|
4011
4516
|
}
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
get mimetype() {
|
|
4016
|
-
return this.ejson.mimetype;
|
|
4517
|
+
value = value % 1440;
|
|
4518
|
+
if (value < 0) {
|
|
4519
|
+
value += 1440;
|
|
4017
4520
|
}
|
|
4521
|
+
const h = Math.floor(value / 60);
|
|
4522
|
+
const m = value % 60;
|
|
4523
|
+
return { h, m };
|
|
4018
4524
|
}
|
|
4019
4525
|
|
|
4020
|
-
|
|
4526
|
+
function timestampToDate(value) {
|
|
4527
|
+
if (!isNumber(value)) return null;
|
|
4528
|
+
return new Date(value * 1e3);
|
|
4529
|
+
}
|
|
4021
4530
|
|
|
4022
|
-
function
|
|
4023
|
-
|
|
4024
|
-
|
|
4531
|
+
function timeStringify(value, returnsNullWhenInvalid = false) {
|
|
4532
|
+
const timeObject = createTimeObject(value, true);
|
|
4533
|
+
if (!timeObject) {
|
|
4534
|
+
ok(
|
|
4535
|
+
returnsNullWhenInvalid,
|
|
4536
|
+
"Failed to stringify time from: " + JSON.stringify(value)
|
|
4537
|
+
);
|
|
4538
|
+
return null;
|
|
4025
4539
|
}
|
|
4026
|
-
|
|
4540
|
+
let { h, m } = timeObject;
|
|
4541
|
+
const hStr = Math.ceil(h).toString().padStart(2, "0").slice(-2);
|
|
4542
|
+
const mStr = Math.ceil(m).toString().padStart(2, "0").slice(-2);
|
|
4543
|
+
return `${hStr}:${mStr}`;
|
|
4027
4544
|
}
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
const
|
|
4031
|
-
|
|
4032
|
-
const stream = new EJSONStream({
|
|
4033
|
-
ejson,
|
|
4034
|
-
cl,
|
|
4035
|
-
op,
|
|
4036
|
-
sep,
|
|
4037
|
-
onStart(controller) {
|
|
4038
|
-
if (!prepend) {
|
|
4039
|
-
controller.enqueue(`{"${resultKey}":`);
|
|
4040
|
-
return Promise.resolve();
|
|
4041
|
-
}
|
|
4042
|
-
return Promise.resolve().then(() => prepend()).then((data) => {
|
|
4043
|
-
if (data === null || data === void 0) {
|
|
4044
|
-
controller.enqueue(`{"${resultKey}":`);
|
|
4045
|
-
return;
|
|
4046
|
-
}
|
|
4047
|
-
ok(
|
|
4048
|
-
isPlainObject(data),
|
|
4049
|
-
"prepend result expected to be plain object"
|
|
4050
|
-
);
|
|
4051
|
-
const dataPart = instance.stringify(data).slice(0, -1);
|
|
4052
|
-
if (dataPart === "{") {
|
|
4053
|
-
controller.enqueue(`{"${resultKey}":`);
|
|
4054
|
-
return;
|
|
4055
|
-
}
|
|
4056
|
-
controller.enqueue(`${dataPart}${sep}"${resultKey}":`);
|
|
4057
|
-
});
|
|
4058
|
-
},
|
|
4059
|
-
onFlush(controller) {
|
|
4060
|
-
if (!append) {
|
|
4061
|
-
controller.enqueue("}");
|
|
4062
|
-
return Promise.resolve();
|
|
4063
|
-
}
|
|
4064
|
-
return Promise.resolve().then(() => append()).then((data) => {
|
|
4065
|
-
if (data === null || data === void 0) {
|
|
4066
|
-
controller.enqueue("}");
|
|
4067
|
-
return;
|
|
4068
|
-
}
|
|
4069
|
-
ok(
|
|
4070
|
-
isPlainObject(data),
|
|
4071
|
-
"prepend result expected to be plain object"
|
|
4072
|
-
);
|
|
4073
|
-
const dataPart = instance.stringify(data).slice(1);
|
|
4074
|
-
if (dataPart === "}") {
|
|
4075
|
-
controller.enqueue(`}`);
|
|
4076
|
-
return;
|
|
4077
|
-
}
|
|
4078
|
-
controller.enqueue(`${sep}${dataPart}`);
|
|
4079
|
-
});
|
|
4080
|
-
}
|
|
4081
|
-
});
|
|
4082
|
-
return stream;
|
|
4545
|
+
|
|
4546
|
+
function timeToMinutes(value) {
|
|
4547
|
+
const time = createTimeObject(value);
|
|
4548
|
+
return time.h * 60 + time.m;
|
|
4083
4549
|
}
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
op,
|
|
4090
|
-
sep
|
|
4091
|
-
};
|
|
4550
|
+
|
|
4551
|
+
function weeksInYear(year) {
|
|
4552
|
+
const target = new Date(Date.UTC(year + 1, 0, 1));
|
|
4553
|
+
const dayNumber = target.getDay();
|
|
4554
|
+
return dayNumber < 4 ? 52 : 53;
|
|
4092
4555
|
}
|
|
4093
4556
|
|
|
4094
4557
|
const env = (() => {
|
|
@@ -4153,7 +4616,7 @@ function createEnvParser(targetObject) {
|
|
|
4153
4616
|
return defaultValue;
|
|
4154
4617
|
}
|
|
4155
4618
|
try {
|
|
4156
|
-
return
|
|
4619
|
+
return instance.parse(targetObject[key]);
|
|
4157
4620
|
} catch (err) {
|
|
4158
4621
|
console.warn("Failed to parse json env variable", key);
|
|
4159
4622
|
return defaultValue;
|
|
@@ -4761,28 +5224,6 @@ const logger = (...baseArgs) => {
|
|
|
4761
5224
|
return instance;
|
|
4762
5225
|
};
|
|
4763
5226
|
|
|
4764
|
-
function asyncFilter(array, predicate) {
|
|
4765
|
-
var i = 0;
|
|
4766
|
-
var result = [];
|
|
4767
|
-
var cooldown = nextTickIteration(10);
|
|
4768
|
-
return new Promise((resolve, reject) => {
|
|
4769
|
-
var processNextBatch = () => {
|
|
4770
|
-
if (i < array.length) {
|
|
4771
|
-
cooldown().then(() => predicate(array[i], i, array)).then((valid) => {
|
|
4772
|
-
if (Boolean(valid)) {
|
|
4773
|
-
result.push(array[i]);
|
|
4774
|
-
}
|
|
4775
|
-
i++;
|
|
4776
|
-
setTimeout(processNextBatch, 0);
|
|
4777
|
-
}).catch(reject);
|
|
4778
|
-
} else {
|
|
4779
|
-
resolve(result);
|
|
4780
|
-
}
|
|
4781
|
-
};
|
|
4782
|
-
processNextBatch();
|
|
4783
|
-
});
|
|
4784
|
-
}
|
|
4785
|
-
|
|
4786
5227
|
function nextTickIteration(amount, delay = "tick") {
|
|
4787
5228
|
let counter = 0;
|
|
4788
5229
|
const tickInterval = delay === "tick";
|
|
@@ -4802,6 +5243,45 @@ function nextTickIteration(amount, delay = "tick") {
|
|
|
4802
5243
|
};
|
|
4803
5244
|
}
|
|
4804
5245
|
|
|
5246
|
+
function asyncFilter(array, predicate, { concurrency = 1 } = {}) {
|
|
5247
|
+
concurrency = Math.max(concurrency, 1);
|
|
5248
|
+
if (array.length === 0) {
|
|
5249
|
+
return Promise.resolve([]);
|
|
5250
|
+
}
|
|
5251
|
+
var result = [];
|
|
5252
|
+
var currentIndex = 0;
|
|
5253
|
+
var completed = 0;
|
|
5254
|
+
var hasError = false;
|
|
5255
|
+
var cooldown = nextTickIteration(10);
|
|
5256
|
+
return new Promise((resolve, reject) => {
|
|
5257
|
+
var processItem = (index) => {
|
|
5258
|
+
if (hasError || index >= array.length) return;
|
|
5259
|
+
cooldown().then(() => predicate(array[index], index, array)).then((include) => {
|
|
5260
|
+
if (hasError) return;
|
|
5261
|
+
if (include) {
|
|
5262
|
+
result.push(index);
|
|
5263
|
+
}
|
|
5264
|
+
completed++;
|
|
5265
|
+
if (completed >= array.length) {
|
|
5266
|
+
resolve(result.toSorted((a, b) => a - b).map((idx) => array[idx]));
|
|
5267
|
+
} else {
|
|
5268
|
+
if (currentIndex < array.length) {
|
|
5269
|
+
processItem(currentIndex++);
|
|
5270
|
+
}
|
|
5271
|
+
}
|
|
5272
|
+
}).catch((error) => {
|
|
5273
|
+
if (!hasError) {
|
|
5274
|
+
hasError = true;
|
|
5275
|
+
reject(error);
|
|
5276
|
+
}
|
|
5277
|
+
});
|
|
5278
|
+
};
|
|
5279
|
+
for (; currentIndex < concurrency; currentIndex++) {
|
|
5280
|
+
processItem(currentIndex);
|
|
5281
|
+
}
|
|
5282
|
+
});
|
|
5283
|
+
}
|
|
5284
|
+
|
|
4805
5285
|
function asyncFind(array, callbackfn) {
|
|
4806
5286
|
var i = 0;
|
|
4807
5287
|
var cooldown = nextTickIteration(10);
|
|
@@ -4826,35 +5306,36 @@ function asyncFind(array, callbackfn) {
|
|
|
4826
5306
|
|
|
4827
5307
|
function asyncForEach(array, callbackfn, { concurrency = 1 } = {}) {
|
|
4828
5308
|
concurrency = Math.max(concurrency, 1);
|
|
4829
|
-
|
|
5309
|
+
if (array.length === 0) {
|
|
5310
|
+
return Promise.resolve();
|
|
5311
|
+
}
|
|
5312
|
+
var hasError = false;
|
|
5313
|
+
var completed = 0;
|
|
5314
|
+
var currentIndex = 0;
|
|
4830
5315
|
var cooldown = nextTickIteration(10);
|
|
4831
|
-
var tasks = Array(concurrency);
|
|
4832
5316
|
return new Promise((resolve, reject) => {
|
|
4833
|
-
var
|
|
4834
|
-
if (
|
|
4835
|
-
|
|
4836
|
-
return;
|
|
4837
|
-
|
|
4838
|
-
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
if (
|
|
4842
|
-
|
|
4843
|
-
(itemIndex) => callbackfn(array[itemIndex], itemIndex, array)
|
|
4844
|
-
);
|
|
5317
|
+
var processItem = (index) => {
|
|
5318
|
+
if (hasError || index >= array.length) return;
|
|
5319
|
+
cooldown().then(() => callbackfn(array[index], index, array)).then((transformed) => {
|
|
5320
|
+
if (hasError) return;
|
|
5321
|
+
completed++;
|
|
5322
|
+
if (completed >= array.length) {
|
|
5323
|
+
resolve();
|
|
5324
|
+
} else {
|
|
5325
|
+
if (currentIndex < array.length) {
|
|
5326
|
+
processItem(currentIndex++);
|
|
4845
5327
|
}
|
|
4846
|
-
i++;
|
|
4847
5328
|
}
|
|
4848
|
-
|
|
4849
|
-
|
|
4850
|
-
|
|
4851
|
-
|
|
4852
|
-
} else {
|
|
4853
|
-
resolve();
|
|
5329
|
+
}).catch((error) => {
|
|
5330
|
+
if (!hasError) {
|
|
5331
|
+
hasError = true;
|
|
5332
|
+
reject(error);
|
|
4854
5333
|
}
|
|
4855
|
-
})
|
|
5334
|
+
});
|
|
4856
5335
|
};
|
|
4857
|
-
|
|
5336
|
+
for (; currentIndex < concurrency; currentIndex++) {
|
|
5337
|
+
processItem(currentIndex);
|
|
5338
|
+
}
|
|
4858
5339
|
});
|
|
4859
5340
|
}
|
|
4860
5341
|
|
|
@@ -4995,38 +5476,38 @@ class AsyncIterableQueue {
|
|
|
4995
5476
|
|
|
4996
5477
|
function asyncMap(array, callbackfn, { concurrency = 1 } = {}) {
|
|
4997
5478
|
concurrency = Math.max(concurrency, 1);
|
|
4998
|
-
|
|
4999
|
-
|
|
5479
|
+
if (array.length === 0) {
|
|
5480
|
+
return Promise.resolve([]);
|
|
5481
|
+
}
|
|
5482
|
+
var hasError = false;
|
|
5483
|
+
var result = Array(array.length);
|
|
5484
|
+
var completed = 0;
|
|
5485
|
+
var currentIndex = 0;
|
|
5000
5486
|
var cooldown = nextTickIteration(10);
|
|
5001
|
-
var tasks = Array(concurrency);
|
|
5002
5487
|
return new Promise((resolve, reject) => {
|
|
5003
|
-
var
|
|
5004
|
-
if (
|
|
5005
|
-
|
|
5006
|
-
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
|
|
5014
|
-
result.push(transformed);
|
|
5015
|
-
});
|
|
5016
|
-
}
|
|
5017
|
-
i++;
|
|
5018
|
-
}
|
|
5019
|
-
return Promise.all(tasks);
|
|
5020
|
-
}).then(() => {
|
|
5021
|
-
if (i < array.length) {
|
|
5022
|
-
setTimeout(processNextBatch, 0);
|
|
5023
|
-
} else {
|
|
5024
|
-
resolve(result);
|
|
5488
|
+
var processItem = (index) => {
|
|
5489
|
+
if (hasError || index >= array.length) return;
|
|
5490
|
+
cooldown().then(() => callbackfn(array[index], index, array)).then((transformed) => {
|
|
5491
|
+
if (hasError) return;
|
|
5492
|
+
result[index] = transformed;
|
|
5493
|
+
completed++;
|
|
5494
|
+
if (completed >= array.length) {
|
|
5495
|
+
resolve(result);
|
|
5496
|
+
} else {
|
|
5497
|
+
if (currentIndex < array.length) {
|
|
5498
|
+
processItem(currentIndex++);
|
|
5025
5499
|
}
|
|
5026
|
-
}
|
|
5027
|
-
}
|
|
5500
|
+
}
|
|
5501
|
+
}).catch((error) => {
|
|
5502
|
+
if (!hasError) {
|
|
5503
|
+
hasError = true;
|
|
5504
|
+
reject(error);
|
|
5505
|
+
}
|
|
5506
|
+
});
|
|
5028
5507
|
};
|
|
5029
|
-
|
|
5508
|
+
for (; currentIndex < concurrency; currentIndex++) {
|
|
5509
|
+
processItem(currentIndex);
|
|
5510
|
+
}
|
|
5030
5511
|
});
|
|
5031
5512
|
}
|
|
5032
5513
|
|
|
@@ -5470,6 +5951,60 @@ function timeout(ms, promiseOrCallback, timeoutError = new AppError(408)) {
|
|
|
5470
5951
|
});
|
|
5471
5952
|
}
|
|
5472
5953
|
|
|
5954
|
+
const stringifyArgs = (...args) => {
|
|
5955
|
+
return args.map((v) => argToKey(v, { objectStrategy: "json" })).join("_");
|
|
5956
|
+
};
|
|
5957
|
+
function withResolve(fn, getCacheKey) {
|
|
5958
|
+
const cache = /* @__PURE__ */ new Map();
|
|
5959
|
+
const cacheKeyVariants = arrayable(getCacheKey);
|
|
5960
|
+
return function(...args) {
|
|
5961
|
+
let cacheKey = stringifyArgs(...args);
|
|
5962
|
+
if (cacheKeyVariants?.length) {
|
|
5963
|
+
for (const getCacheKey2 of cacheKeyVariants) {
|
|
5964
|
+
const newCacheKey = getCacheKey2(args, stringifyArgs);
|
|
5965
|
+
if (newCacheKey === null) {
|
|
5966
|
+
cacheKey = Symbol();
|
|
5967
|
+
break;
|
|
5968
|
+
} else if (isString(newCacheKey) && cache.has(newCacheKey)) {
|
|
5969
|
+
cacheKey = newCacheKey;
|
|
5970
|
+
break;
|
|
5971
|
+
}
|
|
5972
|
+
}
|
|
5973
|
+
}
|
|
5974
|
+
const defers = cache.get(cacheKey) || [];
|
|
5975
|
+
const size = defers.length;
|
|
5976
|
+
const q = defer();
|
|
5977
|
+
defers.push(q);
|
|
5978
|
+
cache.set(cacheKey, defers);
|
|
5979
|
+
if (size) {
|
|
5980
|
+
return q.promise;
|
|
5981
|
+
}
|
|
5982
|
+
resolver(this, cacheKey, args);
|
|
5983
|
+
return q.promise;
|
|
5984
|
+
};
|
|
5985
|
+
function resolver(self, cacheKey, args) {
|
|
5986
|
+
const onSuccess = (r) => {
|
|
5987
|
+
const defers = cache.get(cacheKey) || [];
|
|
5988
|
+
for (const q of defers) {
|
|
5989
|
+
q.resolve(r);
|
|
5990
|
+
}
|
|
5991
|
+
cache.delete(cacheKey);
|
|
5992
|
+
};
|
|
5993
|
+
const onError = (r) => {
|
|
5994
|
+
const defers = cache.get(cacheKey) || [];
|
|
5995
|
+
for (const q of defers) {
|
|
5996
|
+
q.reject(r);
|
|
5997
|
+
}
|
|
5998
|
+
cache.delete(cacheKey);
|
|
5999
|
+
};
|
|
6000
|
+
try {
|
|
6001
|
+
fn.apply(self, args).then(onSuccess).catch(onError);
|
|
6002
|
+
} catch (err) {
|
|
6003
|
+
onError(err);
|
|
6004
|
+
}
|
|
6005
|
+
}
|
|
6006
|
+
}
|
|
6007
|
+
|
|
5473
6008
|
exports.AppError = AppError;
|
|
5474
6009
|
exports.AsyncIterableQueue = AsyncIterableQueue;
|
|
5475
6010
|
exports.BrowserAssertionError = BrowserAssertionError;
|
|
@@ -5506,6 +6041,8 @@ exports.base64url = base64url;
|
|
|
5506
6041
|
exports.basex = basex;
|
|
5507
6042
|
exports.bigIntBytes = bigIntBytes;
|
|
5508
6043
|
exports.bigIntFromBytes = bigIntFromBytes;
|
|
6044
|
+
exports.bitPack = bitPack;
|
|
6045
|
+
exports.bitUnpack = bitUnpack;
|
|
5509
6046
|
exports.blendColors = blendColors;
|
|
5510
6047
|
exports.buildCssColor = buildCssColor;
|
|
5511
6048
|
exports.bytesToBase64 = bytesToBase64;
|
|
@@ -5539,6 +6076,7 @@ exports.createDeepCloneWith = createDeepCloneWith;
|
|
|
5539
6076
|
exports.createEJSON = createEJSON;
|
|
5540
6077
|
exports.createEJSONStream = createEJSONStream;
|
|
5541
6078
|
exports.createEnvParser = createEnvParser;
|
|
6079
|
+
exports.createFunction = createFunction;
|
|
5542
6080
|
exports.createRandomizer = createRandomizer;
|
|
5543
6081
|
exports.createSecureCustomizer = createSecureCustomizer;
|
|
5544
6082
|
exports.createTimeObject = createTimeObject;
|
|
@@ -5590,6 +6128,7 @@ exports.humanFileSize = humanFileSize;
|
|
|
5590
6128
|
exports.humanize = humanize;
|
|
5591
6129
|
exports.interpolateColor = interpolateColor;
|
|
5592
6130
|
exports.intersection = intersection;
|
|
6131
|
+
exports.intersectionBy = intersectionBy;
|
|
5593
6132
|
exports.isBigInt = isBigInt;
|
|
5594
6133
|
exports.isBoolean = isBoolean;
|
|
5595
6134
|
exports.isCached = isCached;
|
|
@@ -5605,6 +6144,7 @@ exports.isError = isError;
|
|
|
5605
6144
|
exports.isFunction = isFunction;
|
|
5606
6145
|
exports.isInfinity = isInfinity;
|
|
5607
6146
|
exports.isMap = isMap;
|
|
6147
|
+
exports.isNode = isNode;
|
|
5608
6148
|
exports.isNullOrUndefined = isNullOrUndefined;
|
|
5609
6149
|
exports.isNumber = isNumber;
|
|
5610
6150
|
exports.isObject = isObject;
|
|
@@ -5695,5 +6235,6 @@ exports.withCacheFixed = withCacheFixed;
|
|
|
5695
6235
|
exports.withCacheLRU = withCacheLRU;
|
|
5696
6236
|
exports.withDeepClone = withDeepClone;
|
|
5697
6237
|
exports.withPointerCache = withPointerCache;
|
|
6238
|
+
exports.withResolve = withResolve;
|
|
5698
6239
|
exports.wrapText = wrapText;
|
|
5699
6240
|
//# sourceMappingURL=index.cjs.map
|