es-toolkit 1.52.0-dev.2095 → 1.52.0-dev.2096
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/browser.global.js +4 -4
- package/dist/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -0
- package/dist/index.mjs +2 -1
- package/dist/util/hash/browser.d.mts +26 -0
- package/dist/util/hash/browser.d.ts +26 -0
- package/dist/util/hash/browser.js +31 -0
- package/dist/util/hash/browser.mjs +30 -0
- package/dist/util/hash/node.d.mts +26 -0
- package/dist/util/hash/node.d.ts +26 -0
- package/dist/util/hash/node.js +494 -0
- package/dist/util/hash/node.mjs +493 -0
- package/dist/util/hash/sha256.js +158 -0
- package/dist/util/hash/sha256.mjs +158 -0
- package/dist/util/index.d.mts +2 -1
- package/dist/util/index.d.ts +2 -1
- package/dist/util/index.js +2 -0
- package/dist/util/index.mjs +2 -1
- package/dist/util/serialize/compareValues.js +23 -0
- package/dist/util/serialize/compareValues.mjs +23 -0
- package/dist/util/serialize/serialize.d.mts +44 -0
- package/dist/util/serialize/serialize.d.ts +44 -0
- package/dist/util/serialize/serialize.js +64 -0
- package/dist/util/serialize/serialize.mjs +63 -0
- package/dist/util/serialize/serializeBigInt.js +15 -0
- package/dist/util/serialize/serializeBigInt.mjs +15 -0
- package/dist/util/serialize/serializeFunction.js +26 -0
- package/dist/util/serialize/serializeFunction.mjs +26 -0
- package/dist/util/serialize/serializeNumber.js +21 -0
- package/dist/util/serialize/serializeNumber.mjs +21 -0
- package/dist/util/serialize/serializeObject.js +85 -0
- package/dist/util/serialize/serializeObject.mjs +85 -0
- package/dist/util/serialize/serializePlainObject.js +31 -0
- package/dist/util/serialize/serializePlainObject.mjs +31 -0
- package/dist/util/serialize/serializeString.js +18 -0
- package/dist/util/serialize/serializeString.mjs +18 -0
- package/dist/util/serialize/serializeSymbol.js +23 -0
- package/dist/util/serialize/serializeSymbol.mjs +23 -0
- package/package.json +47 -1
- package/util/hash.d.ts +1 -0
- package/util/hash.js +1 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
//#region src/util/hash/sha256.ts
|
|
2
|
+
const K = new Int32Array([
|
|
3
|
+
1116352408,
|
|
4
|
+
1899447441,
|
|
5
|
+
3049323471,
|
|
6
|
+
3921009573,
|
|
7
|
+
961987163,
|
|
8
|
+
1508970993,
|
|
9
|
+
2453635748,
|
|
10
|
+
2870763221,
|
|
11
|
+
3624381080,
|
|
12
|
+
310598401,
|
|
13
|
+
607225278,
|
|
14
|
+
1426881987,
|
|
15
|
+
1925078388,
|
|
16
|
+
2162078206,
|
|
17
|
+
2614888103,
|
|
18
|
+
3248222580,
|
|
19
|
+
3835390401,
|
|
20
|
+
4022224774,
|
|
21
|
+
264347078,
|
|
22
|
+
604807628,
|
|
23
|
+
770255983,
|
|
24
|
+
1249150122,
|
|
25
|
+
1555081692,
|
|
26
|
+
1996064986,
|
|
27
|
+
2554220882,
|
|
28
|
+
2821834349,
|
|
29
|
+
2952996808,
|
|
30
|
+
3210313671,
|
|
31
|
+
3336571891,
|
|
32
|
+
3584528711,
|
|
33
|
+
113926993,
|
|
34
|
+
338241895,
|
|
35
|
+
666307205,
|
|
36
|
+
773529912,
|
|
37
|
+
1294757372,
|
|
38
|
+
1396182291,
|
|
39
|
+
1695183700,
|
|
40
|
+
1986661051,
|
|
41
|
+
2177026350,
|
|
42
|
+
2456956037,
|
|
43
|
+
2730485921,
|
|
44
|
+
2820302411,
|
|
45
|
+
3259730800,
|
|
46
|
+
3345764771,
|
|
47
|
+
3516065817,
|
|
48
|
+
3600352804,
|
|
49
|
+
4094571909,
|
|
50
|
+
275423344,
|
|
51
|
+
430227734,
|
|
52
|
+
506948616,
|
|
53
|
+
659060556,
|
|
54
|
+
883997877,
|
|
55
|
+
958139571,
|
|
56
|
+
1322822218,
|
|
57
|
+
1537002063,
|
|
58
|
+
1747873779,
|
|
59
|
+
1955562222,
|
|
60
|
+
2024104815,
|
|
61
|
+
2227730452,
|
|
62
|
+
2361852424,
|
|
63
|
+
2428436474,
|
|
64
|
+
2756734187,
|
|
65
|
+
3204031479,
|
|
66
|
+
3329325298
|
|
67
|
+
]);
|
|
68
|
+
const BASE64_URL_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
69
|
+
/**
|
|
70
|
+
* Computes the SHA-256 digest of a string and encodes it in Base64URL
|
|
71
|
+
* format without padding.
|
|
72
|
+
*
|
|
73
|
+
* The output is byte-identical to
|
|
74
|
+
* `crypto.hash('sha256', data, 'base64url')` in Node.js.
|
|
75
|
+
*
|
|
76
|
+
* @param data - The string to hash. Encoded as UTF-8 before hashing.
|
|
77
|
+
* @returns The 43-character Base64URL-encoded digest.
|
|
78
|
+
*/
|
|
79
|
+
function sha256(data) {
|
|
80
|
+
const bytes = new TextEncoder().encode(data);
|
|
81
|
+
const byteLength = bytes.length;
|
|
82
|
+
const paddedLength = ((byteLength + 8 >> 6) + 1) * 64;
|
|
83
|
+
const padded = new Uint8Array(paddedLength);
|
|
84
|
+
padded.set(bytes);
|
|
85
|
+
padded[byteLength] = 128;
|
|
86
|
+
const view = new DataView(padded.buffer);
|
|
87
|
+
view.setUint32(paddedLength - 8, Math.floor(byteLength / 536870912));
|
|
88
|
+
view.setUint32(paddedLength - 4, byteLength << 3 >>> 0);
|
|
89
|
+
let h0 = 1779033703;
|
|
90
|
+
let h1 = -1150833019;
|
|
91
|
+
let h2 = 1013904242;
|
|
92
|
+
let h3 = -1521486534;
|
|
93
|
+
let h4 = 1359893119;
|
|
94
|
+
let h5 = -1694144372;
|
|
95
|
+
let h6 = 528734635;
|
|
96
|
+
let h7 = 1541459225;
|
|
97
|
+
const w = new Int32Array(64);
|
|
98
|
+
for (let offset = 0; offset < paddedLength; offset += 64) {
|
|
99
|
+
for (let i = 0; i < 16; i++) w[i] = view.getUint32(offset + i * 4) | 0;
|
|
100
|
+
for (let i = 16; i < 64; i++) {
|
|
101
|
+
const x = w[i - 15];
|
|
102
|
+
const y = w[i - 2];
|
|
103
|
+
const sigma0 = (x >>> 7 | x << 25) ^ (x >>> 18 | x << 14) ^ x >>> 3 | 0;
|
|
104
|
+
const sigma1 = (y >>> 17 | y << 15) ^ (y >>> 19 | y << 13) ^ y >>> 10 | 0;
|
|
105
|
+
w[i] = w[i - 16] + sigma0 + w[i - 7] + sigma1 | 0;
|
|
106
|
+
}
|
|
107
|
+
let a = h0;
|
|
108
|
+
let b = h1;
|
|
109
|
+
let c = h2;
|
|
110
|
+
let d = h3;
|
|
111
|
+
let e = h4;
|
|
112
|
+
let f = h5;
|
|
113
|
+
let g = h6;
|
|
114
|
+
let h = h7;
|
|
115
|
+
for (let i = 0; i < 64; i++) {
|
|
116
|
+
const bigSigma1 = (e >>> 6 | e << 26) ^ (e >>> 11 | e << 21) ^ (e >>> 25 | e << 7);
|
|
117
|
+
const ch = e & f ^ ~e & g;
|
|
118
|
+
const t1 = h + bigSigma1 + ch + K[i] + w[i] | 0;
|
|
119
|
+
const t2 = ((a >>> 2 | a << 30) ^ (a >>> 13 | a << 19) ^ (a >>> 22 | a << 10)) + (a & b ^ a & c ^ b & c) | 0;
|
|
120
|
+
h = g;
|
|
121
|
+
g = f;
|
|
122
|
+
f = e;
|
|
123
|
+
e = d + t1 | 0;
|
|
124
|
+
d = c;
|
|
125
|
+
c = b;
|
|
126
|
+
b = a;
|
|
127
|
+
a = t1 + t2 | 0;
|
|
128
|
+
}
|
|
129
|
+
h0 = h0 + a | 0;
|
|
130
|
+
h1 = h1 + b | 0;
|
|
131
|
+
h2 = h2 + c | 0;
|
|
132
|
+
h3 = h3 + d | 0;
|
|
133
|
+
h4 = h4 + e | 0;
|
|
134
|
+
h5 = h5 + f | 0;
|
|
135
|
+
h6 = h6 + g | 0;
|
|
136
|
+
h7 = h7 + h | 0;
|
|
137
|
+
}
|
|
138
|
+
const digest = new Uint8Array(32);
|
|
139
|
+
const digestView = new DataView(digest.buffer);
|
|
140
|
+
digestView.setInt32(0, h0);
|
|
141
|
+
digestView.setInt32(4, h1);
|
|
142
|
+
digestView.setInt32(8, h2);
|
|
143
|
+
digestView.setInt32(12, h3);
|
|
144
|
+
digestView.setInt32(16, h4);
|
|
145
|
+
digestView.setInt32(20, h5);
|
|
146
|
+
digestView.setInt32(24, h6);
|
|
147
|
+
digestView.setInt32(28, h7);
|
|
148
|
+
let result = "";
|
|
149
|
+
for (let i = 0; i < 30; i += 3) {
|
|
150
|
+
const n = digest[i] << 16 | digest[i + 1] << 8 | digest[i + 2];
|
|
151
|
+
result += BASE64_URL_ALPHABET[n >>> 18 & 63] + BASE64_URL_ALPHABET[n >>> 12 & 63] + BASE64_URL_ALPHABET[n >>> 6 & 63] + BASE64_URL_ALPHABET[n & 63];
|
|
152
|
+
}
|
|
153
|
+
const n = digest[30] << 8 | digest[31];
|
|
154
|
+
result += BASE64_URL_ALPHABET[n >>> 10 & 63] + BASE64_URL_ALPHABET[n >>> 4 & 63] + BASE64_URL_ALPHABET[n << 2 & 63];
|
|
155
|
+
return result;
|
|
156
|
+
}
|
|
157
|
+
//#endregion
|
|
158
|
+
export { sha256 };
|
package/dist/util/index.d.mts
CHANGED
|
@@ -3,4 +3,5 @@ import { attemptAsync } from "./attemptAsync.mjs";
|
|
|
3
3
|
import { defer } from "./defer.mjs";
|
|
4
4
|
import { deferAsync } from "./deferAsync.mjs";
|
|
5
5
|
import { invariant } from "./invariant.mjs";
|
|
6
|
-
|
|
6
|
+
import { serialize } from "./serialize/serialize.mjs";
|
|
7
|
+
export { invariant as assert, attempt, attemptAsync, defer, deferAsync, invariant, serialize };
|
package/dist/util/index.d.ts
CHANGED
|
@@ -3,4 +3,5 @@ import { attemptAsync } from "./attemptAsync.js";
|
|
|
3
3
|
import { defer } from "./defer.js";
|
|
4
4
|
import { deferAsync } from "./deferAsync.js";
|
|
5
5
|
import { invariant } from "./invariant.js";
|
|
6
|
-
|
|
6
|
+
import { serialize } from "./serialize/serialize.js";
|
|
7
|
+
export { invariant as assert, attempt, attemptAsync, defer, deferAsync, invariant, serialize };
|
package/dist/util/index.js
CHANGED
|
@@ -4,9 +4,11 @@ const require_attemptAsync = require("./attemptAsync.js");
|
|
|
4
4
|
const require_defer = require("./defer.js");
|
|
5
5
|
const require_deferAsync = require("./deferAsync.js");
|
|
6
6
|
const require_invariant = require("./invariant.js");
|
|
7
|
+
const require_serialize = require("./serialize/serialize.js");
|
|
7
8
|
exports.assert = require_invariant.invariant;
|
|
8
9
|
exports.attempt = require_attempt.attempt;
|
|
9
10
|
exports.attemptAsync = require_attemptAsync.attemptAsync;
|
|
10
11
|
exports.defer = require_defer.defer;
|
|
11
12
|
exports.deferAsync = require_deferAsync.deferAsync;
|
|
12
13
|
exports.invariant = require_invariant.invariant;
|
|
14
|
+
exports.serialize = require_serialize.serialize;
|
package/dist/util/index.mjs
CHANGED
|
@@ -3,4 +3,5 @@ import { attemptAsync } from "./attemptAsync.mjs";
|
|
|
3
3
|
import { defer } from "./defer.mjs";
|
|
4
4
|
import { deferAsync } from "./deferAsync.mjs";
|
|
5
5
|
import { invariant } from "./invariant.mjs";
|
|
6
|
-
|
|
6
|
+
import { serialize } from "./serialize/serialize.mjs";
|
|
7
|
+
export { invariant as assert, attempt, attemptAsync, defer, deferAsync, invariant, serialize };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const require_serialize = require("./serialize.js");
|
|
2
|
+
//#region src/util/serialize/compareValues.ts
|
|
3
|
+
/**
|
|
4
|
+
* Compares two values for sorting `Set` values and `Map` keys.
|
|
5
|
+
*
|
|
6
|
+
* Numbers are compared numerically and strings by code unit. Any other
|
|
7
|
+
* combination is compared by the code unit order of the serialized values.
|
|
8
|
+
*
|
|
9
|
+
* @param a - The first value to compare.
|
|
10
|
+
* @param b - The second value to compare.
|
|
11
|
+
* @param refs - The circular reference context shared with the surrounding serialization.
|
|
12
|
+
* @returns A negative number if `a` sorts before `b`, a positive number if
|
|
13
|
+
* `a` sorts after `b`, and `0` if they are equal.
|
|
14
|
+
*/
|
|
15
|
+
function compareValues(a, b, refs) {
|
|
16
|
+
if (typeof a === "number" && typeof b === "number") return a - b;
|
|
17
|
+
const serializedA = typeof a === "string" && typeof b === "string" ? a : require_serialize.serializeValue(a, refs);
|
|
18
|
+
const serializedB = typeof a === "string" && typeof b === "string" ? b : require_serialize.serializeValue(b, refs);
|
|
19
|
+
if (serializedA === serializedB) return 0;
|
|
20
|
+
return serializedA < serializedB ? -1 : 1;
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
exports.compareValues = compareValues;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { serializeValue } from "./serialize.mjs";
|
|
2
|
+
//#region src/util/serialize/compareValues.ts
|
|
3
|
+
/**
|
|
4
|
+
* Compares two values for sorting `Set` values and `Map` keys.
|
|
5
|
+
*
|
|
6
|
+
* Numbers are compared numerically and strings by code unit. Any other
|
|
7
|
+
* combination is compared by the code unit order of the serialized values.
|
|
8
|
+
*
|
|
9
|
+
* @param a - The first value to compare.
|
|
10
|
+
* @param b - The second value to compare.
|
|
11
|
+
* @param refs - The circular reference context shared with the surrounding serialization.
|
|
12
|
+
* @returns A negative number if `a` sorts before `b`, a positive number if
|
|
13
|
+
* `a` sorts after `b`, and `0` if they are equal.
|
|
14
|
+
*/
|
|
15
|
+
function compareValues(a, b, refs) {
|
|
16
|
+
if (typeof a === "number" && typeof b === "number") return a - b;
|
|
17
|
+
const serializedA = typeof a === "string" && typeof b === "string" ? a : serializeValue(a, refs);
|
|
18
|
+
const serializedB = typeof a === "string" && typeof b === "string" ? b : serializeValue(b, refs);
|
|
19
|
+
if (serializedA === serializedB) return 0;
|
|
20
|
+
return serializedA < serializedB ? -1 : 1;
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
export { compareValues };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
//#region src/util/serialize/serialize.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Serializes any value into a stable string.
|
|
4
|
+
*
|
|
5
|
+
* Two values with the same structure always serialize to the same string,
|
|
6
|
+
* regardless of key insertion order, so the output is suitable for hashing,
|
|
7
|
+
* cache keys, and change detection. It is not designed for security purposes;
|
|
8
|
+
* intentional collisions can be crafted from user input.
|
|
9
|
+
*
|
|
10
|
+
* Plain object keys, `Map` keys, and `Set` values are sorted, so the output
|
|
11
|
+
* does not depend on insertion order. String keys are always quoted, so a
|
|
12
|
+
* string key never collides with a key of another type. Circular references
|
|
13
|
+
* are serialized as `#ref{n}` back-references, where `n` is the order in
|
|
14
|
+
* which the object was first visited.
|
|
15
|
+
*
|
|
16
|
+
* Objects that cannot be serialized meaningfully, such as `Promise`, `WeakMap`,
|
|
17
|
+
* or `Blob`, throw a `TypeError`.
|
|
18
|
+
*
|
|
19
|
+
* @param value - The value to serialize.
|
|
20
|
+
* @returns The serialized string.
|
|
21
|
+
* @throws {TypeError} If the value contains an object that cannot be serialized.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* serialize({ b: 2, a: 1 }); // "{'a':1,'b':2}"
|
|
25
|
+
* serialize([1, 2n, 'a', { k: 1 }]); // "[1,2n,'a',{'k':1}]"
|
|
26
|
+
* serialize(new Set([3, 1, 2])); // "Set[1,2,3]"
|
|
27
|
+
* serialize(new Date(0)); // "Date('1970-01-01T00:00:00.000Z')"
|
|
28
|
+
*
|
|
29
|
+
* const obj = {};
|
|
30
|
+
* obj.self = obj;
|
|
31
|
+
* serialize(obj); // "{'self':#ref0}"
|
|
32
|
+
*/
|
|
33
|
+
declare function serialize(value: unknown): string;
|
|
34
|
+
/**
|
|
35
|
+
* Serializes a value with a shared circular reference context.
|
|
36
|
+
*
|
|
37
|
+
* @param value - The value to serialize.
|
|
38
|
+
* @param refs - Objects that are being serialized or have been serialized,
|
|
39
|
+
* mapped to their back-reference placeholder or completed serialization.
|
|
40
|
+
* @returns The serialized string.
|
|
41
|
+
*/
|
|
42
|
+
declare function serializeValue(value: unknown, refs: Map<object, string>): string;
|
|
43
|
+
//#endregion
|
|
44
|
+
export { serialize };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
//#region src/util/serialize/serialize.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Serializes any value into a stable string.
|
|
4
|
+
*
|
|
5
|
+
* Two values with the same structure always serialize to the same string,
|
|
6
|
+
* regardless of key insertion order, so the output is suitable for hashing,
|
|
7
|
+
* cache keys, and change detection. It is not designed for security purposes;
|
|
8
|
+
* intentional collisions can be crafted from user input.
|
|
9
|
+
*
|
|
10
|
+
* Plain object keys, `Map` keys, and `Set` values are sorted, so the output
|
|
11
|
+
* does not depend on insertion order. String keys are always quoted, so a
|
|
12
|
+
* string key never collides with a key of another type. Circular references
|
|
13
|
+
* are serialized as `#ref{n}` back-references, where `n` is the order in
|
|
14
|
+
* which the object was first visited.
|
|
15
|
+
*
|
|
16
|
+
* Objects that cannot be serialized meaningfully, such as `Promise`, `WeakMap`,
|
|
17
|
+
* or `Blob`, throw a `TypeError`.
|
|
18
|
+
*
|
|
19
|
+
* @param value - The value to serialize.
|
|
20
|
+
* @returns The serialized string.
|
|
21
|
+
* @throws {TypeError} If the value contains an object that cannot be serialized.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* serialize({ b: 2, a: 1 }); // "{'a':1,'b':2}"
|
|
25
|
+
* serialize([1, 2n, 'a', { k: 1 }]); // "[1,2n,'a',{'k':1}]"
|
|
26
|
+
* serialize(new Set([3, 1, 2])); // "Set[1,2,3]"
|
|
27
|
+
* serialize(new Date(0)); // "Date('1970-01-01T00:00:00.000Z')"
|
|
28
|
+
*
|
|
29
|
+
* const obj = {};
|
|
30
|
+
* obj.self = obj;
|
|
31
|
+
* serialize(obj); // "{'self':#ref0}"
|
|
32
|
+
*/
|
|
33
|
+
declare function serialize(value: unknown): string;
|
|
34
|
+
/**
|
|
35
|
+
* Serializes a value with a shared circular reference context.
|
|
36
|
+
*
|
|
37
|
+
* @param value - The value to serialize.
|
|
38
|
+
* @param refs - Objects that are being serialized or have been serialized,
|
|
39
|
+
* mapped to their back-reference placeholder or completed serialization.
|
|
40
|
+
* @returns The serialized string.
|
|
41
|
+
*/
|
|
42
|
+
declare function serializeValue(value: unknown, refs: Map<object, string>): string;
|
|
43
|
+
//#endregion
|
|
44
|
+
export { serialize };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
const require_serializeBigInt = require("./serializeBigInt.js");
|
|
2
|
+
const require_serializeFunction = require("./serializeFunction.js");
|
|
3
|
+
const require_serializeNumber = require("./serializeNumber.js");
|
|
4
|
+
const require_serializeString = require("./serializeString.js");
|
|
5
|
+
const require_serializeObject = require("./serializeObject.js");
|
|
6
|
+
const require_serializeSymbol = require("./serializeSymbol.js");
|
|
7
|
+
//#region src/util/serialize/serialize.ts
|
|
8
|
+
/**
|
|
9
|
+
* Serializes any value into a stable string.
|
|
10
|
+
*
|
|
11
|
+
* Two values with the same structure always serialize to the same string,
|
|
12
|
+
* regardless of key insertion order, so the output is suitable for hashing,
|
|
13
|
+
* cache keys, and change detection. It is not designed for security purposes;
|
|
14
|
+
* intentional collisions can be crafted from user input.
|
|
15
|
+
*
|
|
16
|
+
* Plain object keys, `Map` keys, and `Set` values are sorted, so the output
|
|
17
|
+
* does not depend on insertion order. String keys are always quoted, so a
|
|
18
|
+
* string key never collides with a key of another type. Circular references
|
|
19
|
+
* are serialized as `#ref{n}` back-references, where `n` is the order in
|
|
20
|
+
* which the object was first visited.
|
|
21
|
+
*
|
|
22
|
+
* Objects that cannot be serialized meaningfully, such as `Promise`, `WeakMap`,
|
|
23
|
+
* or `Blob`, throw a `TypeError`.
|
|
24
|
+
*
|
|
25
|
+
* @param value - The value to serialize.
|
|
26
|
+
* @returns The serialized string.
|
|
27
|
+
* @throws {TypeError} If the value contains an object that cannot be serialized.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* serialize({ b: 2, a: 1 }); // "{'a':1,'b':2}"
|
|
31
|
+
* serialize([1, 2n, 'a', { k: 1 }]); // "[1,2n,'a',{'k':1}]"
|
|
32
|
+
* serialize(new Set([3, 1, 2])); // "Set[1,2,3]"
|
|
33
|
+
* serialize(new Date(0)); // "Date('1970-01-01T00:00:00.000Z')"
|
|
34
|
+
*
|
|
35
|
+
* const obj = {};
|
|
36
|
+
* obj.self = obj;
|
|
37
|
+
* serialize(obj); // "{'self':#ref0}"
|
|
38
|
+
*/
|
|
39
|
+
function serialize(value) {
|
|
40
|
+
return serializeValue(value, /* @__PURE__ */ new Map());
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Serializes a value with a shared circular reference context.
|
|
44
|
+
*
|
|
45
|
+
* @param value - The value to serialize.
|
|
46
|
+
* @param refs - Objects that are being serialized or have been serialized,
|
|
47
|
+
* mapped to their back-reference placeholder or completed serialization.
|
|
48
|
+
* @returns The serialized string.
|
|
49
|
+
*/
|
|
50
|
+
function serializeValue(value, refs) {
|
|
51
|
+
switch (typeof value) {
|
|
52
|
+
case "string": return require_serializeString.serializeString(value);
|
|
53
|
+
case "number": return require_serializeNumber.serializeNumber(value);
|
|
54
|
+
case "bigint": return require_serializeBigInt.serializeBigInt(value);
|
|
55
|
+
case "symbol": return require_serializeSymbol.serializeSymbol(value);
|
|
56
|
+
case "function": return require_serializeFunction.serializeFunction(value);
|
|
57
|
+
case "object": return require_serializeObject.serializeObject(value, refs);
|
|
58
|
+
case "boolean": return String(value);
|
|
59
|
+
case "undefined": return "undefined";
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
63
|
+
exports.serialize = serialize;
|
|
64
|
+
exports.serializeValue = serializeValue;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { serializeBigInt } from "./serializeBigInt.mjs";
|
|
2
|
+
import { serializeFunction } from "./serializeFunction.mjs";
|
|
3
|
+
import { serializeNumber } from "./serializeNumber.mjs";
|
|
4
|
+
import { serializeString } from "./serializeString.mjs";
|
|
5
|
+
import { serializeObject } from "./serializeObject.mjs";
|
|
6
|
+
import { serializeSymbol } from "./serializeSymbol.mjs";
|
|
7
|
+
//#region src/util/serialize/serialize.ts
|
|
8
|
+
/**
|
|
9
|
+
* Serializes any value into a stable string.
|
|
10
|
+
*
|
|
11
|
+
* Two values with the same structure always serialize to the same string,
|
|
12
|
+
* regardless of key insertion order, so the output is suitable for hashing,
|
|
13
|
+
* cache keys, and change detection. It is not designed for security purposes;
|
|
14
|
+
* intentional collisions can be crafted from user input.
|
|
15
|
+
*
|
|
16
|
+
* Plain object keys, `Map` keys, and `Set` values are sorted, so the output
|
|
17
|
+
* does not depend on insertion order. String keys are always quoted, so a
|
|
18
|
+
* string key never collides with a key of another type. Circular references
|
|
19
|
+
* are serialized as `#ref{n}` back-references, where `n` is the order in
|
|
20
|
+
* which the object was first visited.
|
|
21
|
+
*
|
|
22
|
+
* Objects that cannot be serialized meaningfully, such as `Promise`, `WeakMap`,
|
|
23
|
+
* or `Blob`, throw a `TypeError`.
|
|
24
|
+
*
|
|
25
|
+
* @param value - The value to serialize.
|
|
26
|
+
* @returns The serialized string.
|
|
27
|
+
* @throws {TypeError} If the value contains an object that cannot be serialized.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* serialize({ b: 2, a: 1 }); // "{'a':1,'b':2}"
|
|
31
|
+
* serialize([1, 2n, 'a', { k: 1 }]); // "[1,2n,'a',{'k':1}]"
|
|
32
|
+
* serialize(new Set([3, 1, 2])); // "Set[1,2,3]"
|
|
33
|
+
* serialize(new Date(0)); // "Date('1970-01-01T00:00:00.000Z')"
|
|
34
|
+
*
|
|
35
|
+
* const obj = {};
|
|
36
|
+
* obj.self = obj;
|
|
37
|
+
* serialize(obj); // "{'self':#ref0}"
|
|
38
|
+
*/
|
|
39
|
+
function serialize(value) {
|
|
40
|
+
return serializeValue(value, /* @__PURE__ */ new Map());
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Serializes a value with a shared circular reference context.
|
|
44
|
+
*
|
|
45
|
+
* @param value - The value to serialize.
|
|
46
|
+
* @param refs - Objects that are being serialized or have been serialized,
|
|
47
|
+
* mapped to their back-reference placeholder or completed serialization.
|
|
48
|
+
* @returns The serialized string.
|
|
49
|
+
*/
|
|
50
|
+
function serializeValue(value, refs) {
|
|
51
|
+
switch (typeof value) {
|
|
52
|
+
case "string": return serializeString(value);
|
|
53
|
+
case "number": return serializeNumber(value);
|
|
54
|
+
case "bigint": return serializeBigInt(value);
|
|
55
|
+
case "symbol": return serializeSymbol(value);
|
|
56
|
+
case "function": return serializeFunction(value);
|
|
57
|
+
case "object": return serializeObject(value, refs);
|
|
58
|
+
case "boolean": return String(value);
|
|
59
|
+
case "undefined": return "undefined";
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
63
|
+
export { serialize, serializeValue };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/util/serialize/serializeBigInt.ts
|
|
2
|
+
/**
|
|
3
|
+
* Serializes a bigint into a string with an `n` suffix, like a bigint literal.
|
|
4
|
+
*
|
|
5
|
+
* @param value - The bigint to serialize.
|
|
6
|
+
* @returns The serialized string.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* serializeBigInt(123n); // "123n"
|
|
10
|
+
*/
|
|
11
|
+
function serializeBigInt(value) {
|
|
12
|
+
return `${value}n`;
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
exports.serializeBigInt = serializeBigInt;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/util/serialize/serializeBigInt.ts
|
|
2
|
+
/**
|
|
3
|
+
* Serializes a bigint into a string with an `n` suffix, like a bigint literal.
|
|
4
|
+
*
|
|
5
|
+
* @param value - The bigint to serialize.
|
|
6
|
+
* @returns The serialized string.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* serializeBigInt(123n); // "123n"
|
|
10
|
+
*/
|
|
11
|
+
function serializeBigInt(value) {
|
|
12
|
+
return `${value}n`;
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
export { serializeBigInt };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/util/serialize/serializeFunction.ts
|
|
2
|
+
/**
|
|
3
|
+
* Serializes a function into a string of the form `name:source`.
|
|
4
|
+
*
|
|
5
|
+
* Native functions have no meaningful source, so they are serialized as
|
|
6
|
+
* `name:[native]`. For other functions, newlines and their surrounding
|
|
7
|
+
* whitespace are collapsed so that formatting differences do not change
|
|
8
|
+
* the output.
|
|
9
|
+
*
|
|
10
|
+
* @param value - The function to serialize.
|
|
11
|
+
* @returns The serialized string.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* function sum(a, b) {
|
|
15
|
+
* return a + b;
|
|
16
|
+
* }
|
|
17
|
+
* serializeFunction(sum); // "sum:function sum(a, b) {return a + b;}"
|
|
18
|
+
* serializeFunction(Math.max); // "max:[native]"
|
|
19
|
+
*/
|
|
20
|
+
function serializeFunction(value) {
|
|
21
|
+
const source = Function.prototype.toString.call(value);
|
|
22
|
+
if (source.endsWith("[native code] }")) return `${value.name}:[native]`;
|
|
23
|
+
return `${value.name}:${source.replace(/\s*\n\s*/g, "")}`;
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
exports.serializeFunction = serializeFunction;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/util/serialize/serializeFunction.ts
|
|
2
|
+
/**
|
|
3
|
+
* Serializes a function into a string of the form `name:source`.
|
|
4
|
+
*
|
|
5
|
+
* Native functions have no meaningful source, so they are serialized as
|
|
6
|
+
* `name:[native]`. For other functions, newlines and their surrounding
|
|
7
|
+
* whitespace are collapsed so that formatting differences do not change
|
|
8
|
+
* the output.
|
|
9
|
+
*
|
|
10
|
+
* @param value - The function to serialize.
|
|
11
|
+
* @returns The serialized string.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* function sum(a, b) {
|
|
15
|
+
* return a + b;
|
|
16
|
+
* }
|
|
17
|
+
* serializeFunction(sum); // "sum:function sum(a, b) {return a + b;}"
|
|
18
|
+
* serializeFunction(Math.max); // "max:[native]"
|
|
19
|
+
*/
|
|
20
|
+
function serializeFunction(value) {
|
|
21
|
+
const source = Function.prototype.toString.call(value);
|
|
22
|
+
if (source.endsWith("[native code] }")) return `${value.name}:[native]`;
|
|
23
|
+
return `${value.name}:${source.replace(/\s*\n\s*/g, "")}`;
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
export { serializeFunction };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//#region src/util/serialize/serializeNumber.ts
|
|
2
|
+
/**
|
|
3
|
+
* Serializes a number into a string.
|
|
4
|
+
*
|
|
5
|
+
* `-0` is serialized as `0`, and `NaN` and `Infinity` are serialized
|
|
6
|
+
* as their string representations.
|
|
7
|
+
*
|
|
8
|
+
* @param value - The number to serialize.
|
|
9
|
+
* @returns The serialized string.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* serializeNumber(1); // "1"
|
|
13
|
+
* serializeNumber(-0); // "0"
|
|
14
|
+
* serializeNumber(NaN); // "NaN"
|
|
15
|
+
* serializeNumber(Infinity); // "Infinity"
|
|
16
|
+
*/
|
|
17
|
+
function serializeNumber(value) {
|
|
18
|
+
return String(value);
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
exports.serializeNumber = serializeNumber;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//#region src/util/serialize/serializeNumber.ts
|
|
2
|
+
/**
|
|
3
|
+
* Serializes a number into a string.
|
|
4
|
+
*
|
|
5
|
+
* `-0` is serialized as `0`, and `NaN` and `Infinity` are serialized
|
|
6
|
+
* as their string representations.
|
|
7
|
+
*
|
|
8
|
+
* @param value - The number to serialize.
|
|
9
|
+
* @returns The serialized string.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* serializeNumber(1); // "1"
|
|
13
|
+
* serializeNumber(-0); // "0"
|
|
14
|
+
* serializeNumber(NaN); // "NaN"
|
|
15
|
+
* serializeNumber(Infinity); // "Infinity"
|
|
16
|
+
*/
|
|
17
|
+
function serializeNumber(value) {
|
|
18
|
+
return String(value);
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
export { serializeNumber };
|