@cloudpss/ubjson 0.4.15 → 0.4.16
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/benchmark-string-size-caculation.js +50 -0
- package/benchmark-string.js +3 -3
- package/benchmark.js +3 -3
- package/dist/common/decoder.js +3 -3
- package/dist/common/decoder.js.map +1 -1
- package/dist/common/encoder.d.ts +0 -1
- package/dist/common/encoder.js +26 -23
- package/dist/common/encoder.js.map +1 -1
- package/dist/common/string-decoder.js +3 -3
- package/dist/common/string-decoder.js.map +1 -1
- package/dist/common/string-encoder.d.ts +2 -0
- package/dist/common/string-encoder.js +51 -0
- package/dist/common/string-encoder.js.map +1 -1
- package/dist/decoder.d.ts +1 -2
- package/dist/decoder.js +1 -2
- package/dist/decoder.js.map +1 -1
- package/dist/encoder.js.map +1 -1
- package/dist/stream-helper/decoder.d.ts +2 -2
- package/dist/stream-helper/decoder.js +2 -2
- package/dist/stream-helper/decoder.js.map +1 -1
- package/dist/utils.js +3 -0
- package/dist/utils.js.map +1 -1
- package/package.json +2 -2
- package/src/common/decoder.ts +3 -3
- package/src/common/encoder.ts +27 -25
- package/src/common/string-decoder.ts +3 -4
- package/src/common/string-encoder.ts +63 -0
- package/src/decoder.ts +1 -3
- package/src/encoder.ts +2 -4
- package/src/stream-helper/decoder.ts +3 -3
- package/src/utils.ts +3 -0
- package/tests/decode.js +12 -44
- package/tests/e2e.js +20 -21
- package/tests/encode.js +31 -53
- package/tests/huge-string.js +122 -0
- package/tests/rxjs/decode.js +18 -50
- package/tests/rxjs/encode.js +17 -61
- package/tests/stream/decode.js +17 -49
- package/tests/stream/encode.js +17 -61
- package/tests/string-encoding.js +4 -7
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { encode } from '../dist/index.js';
|
|
2
|
+
import { toArray } from './.utils.js';
|
|
3
|
+
|
|
4
|
+
const STR_BYTE_LENGTH = 128 * 1024 * 1024 - 20;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 构造测试字符串
|
|
8
|
+
* @param {string} char 使用的字符
|
|
9
|
+
* @param {number} byteLength 需要的长度
|
|
10
|
+
*/
|
|
11
|
+
function makeString(char, byteLength) {
|
|
12
|
+
const encoded = new TextEncoder().encode(char);
|
|
13
|
+
return [encoded, char.repeat(byteLength / encoded.byteLength)];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const [str1Data, str1] = makeString('a', STR_BYTE_LENGTH);
|
|
17
|
+
// \u04d2 = Ӓ, 2 bytes in utf-8
|
|
18
|
+
const [str2Data, str2] = makeString('Ӓ', STR_BYTE_LENGTH);
|
|
19
|
+
// \u6c34 = 水, 3 bytes in utf-8
|
|
20
|
+
const [str3Data, str3] = makeString('水', STR_BYTE_LENGTH);
|
|
21
|
+
// \u1f600 = 😀, 4 bytes in utf-8 (0xF0 0x9F 0x98 0x80)
|
|
22
|
+
const [str4Data, str4] = makeString('😀', STR_BYTE_LENGTH);
|
|
23
|
+
// bad surrogate pair
|
|
24
|
+
const [strXData, strX] = makeString('😀'[0], STR_BYTE_LENGTH);
|
|
25
|
+
|
|
26
|
+
const strErr = 'a'.repeat(128 * 1024 * 1024);
|
|
27
|
+
|
|
28
|
+
const ENCODED_PREFIX_LENGTH = 6;
|
|
29
|
+
|
|
30
|
+
describe(`encode huge string`, () => {
|
|
31
|
+
describe(`with node buffer`, () => {
|
|
32
|
+
it(`~128M [1]`, () => {
|
|
33
|
+
const encoded = encode(str1);
|
|
34
|
+
expect(encoded.length).toBe(STR_BYTE_LENGTH + ENCODED_PREFIX_LENGTH);
|
|
35
|
+
expect(toArray(encoded.slice(0, ENCODED_PREFIX_LENGTH + str1Data.length * 2))).toEqual(
|
|
36
|
+
toArray('S', 'l', 0x7, 0xff, 0xff, 0xec, ...str1Data, ...str1Data),
|
|
37
|
+
);
|
|
38
|
+
});
|
|
39
|
+
it(`~128M [2]`, () => {
|
|
40
|
+
const encoded = encode(str2);
|
|
41
|
+
expect(encoded.length).toBe(STR_BYTE_LENGTH + ENCODED_PREFIX_LENGTH);
|
|
42
|
+
expect(toArray(encoded.slice(0, ENCODED_PREFIX_LENGTH + str2Data.length * 2))).toEqual(
|
|
43
|
+
toArray('S', 'l', 0x7, 0xff, 0xff, 0xec, ...str2Data, ...str2Data),
|
|
44
|
+
);
|
|
45
|
+
});
|
|
46
|
+
it(`~128M [3]`, () => {
|
|
47
|
+
const encoded = encode(str3);
|
|
48
|
+
expect(encoded.length).toBe(STR_BYTE_LENGTH + ENCODED_PREFIX_LENGTH);
|
|
49
|
+
expect(toArray(encoded.slice(0, ENCODED_PREFIX_LENGTH + str3Data.length * 2))).toEqual(
|
|
50
|
+
toArray('S', 'l', 0x7, 0xff, 0xff, 0xec, ...str3Data, ...str3Data),
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
it(`~128M [4]`, () => {
|
|
54
|
+
const encoded = encode(str4);
|
|
55
|
+
expect(encoded.length).toBe(STR_BYTE_LENGTH + ENCODED_PREFIX_LENGTH);
|
|
56
|
+
expect(toArray(encoded.slice(0, ENCODED_PREFIX_LENGTH + str4Data.length * 2))).toEqual(
|
|
57
|
+
toArray('S', 'l', 0x7, 0xff, 0xff, 0xec, ...str4Data, ...str4Data),
|
|
58
|
+
);
|
|
59
|
+
});
|
|
60
|
+
it(`~128M [bad surrogate pair]`, () => {
|
|
61
|
+
const encoded = encode(strX);
|
|
62
|
+
expect(encoded.length).toBe(STR_BYTE_LENGTH + ENCODED_PREFIX_LENGTH);
|
|
63
|
+
expect(toArray(encoded.slice(0, ENCODED_PREFIX_LENGTH + strXData.length * 2))).toEqual(
|
|
64
|
+
toArray('S', 'l', 0x7, 0xff, 0xff, 0xec, ...strXData, ...strXData),
|
|
65
|
+
);
|
|
66
|
+
});
|
|
67
|
+
it(`128M [error]`, () => {
|
|
68
|
+
expect(() => encode(strErr)).toThrow(/Buffer has exceed max size/);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
describe(`without node buffer`, () => {
|
|
72
|
+
let buffer = Buffer;
|
|
73
|
+
beforeAll(() => {
|
|
74
|
+
buffer = global.Buffer;
|
|
75
|
+
// @ts-expect-error remove buffer
|
|
76
|
+
global.Buffer = undefined;
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
afterAll(() => {
|
|
80
|
+
global.Buffer = buffer;
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it(`~128M [1]`, () => {
|
|
84
|
+
const encoded = encode(str1);
|
|
85
|
+
expect(encoded.length).toBe(STR_BYTE_LENGTH + ENCODED_PREFIX_LENGTH);
|
|
86
|
+
expect(toArray(encoded.slice(0, ENCODED_PREFIX_LENGTH + str1Data.length * 2))).toEqual(
|
|
87
|
+
toArray('S', 'l', 0x7, 0xff, 0xff, 0xec, ...str1Data, ...str1Data),
|
|
88
|
+
);
|
|
89
|
+
});
|
|
90
|
+
it(`~128M [2]`, () => {
|
|
91
|
+
const encoded = encode(str2);
|
|
92
|
+
expect(encoded.length).toBe(STR_BYTE_LENGTH + ENCODED_PREFIX_LENGTH);
|
|
93
|
+
expect(toArray(encoded.slice(0, ENCODED_PREFIX_LENGTH + str2Data.length * 2))).toEqual(
|
|
94
|
+
toArray('S', 'l', 0x7, 0xff, 0xff, 0xec, ...str2Data, ...str2Data),
|
|
95
|
+
);
|
|
96
|
+
});
|
|
97
|
+
it(`~128M [3]`, () => {
|
|
98
|
+
const encoded = encode(str3);
|
|
99
|
+
expect(encoded.length).toBe(STR_BYTE_LENGTH + ENCODED_PREFIX_LENGTH);
|
|
100
|
+
expect(toArray(encoded.slice(0, ENCODED_PREFIX_LENGTH + str3Data.length * 2))).toEqual(
|
|
101
|
+
toArray('S', 'l', 0x7, 0xff, 0xff, 0xec, ...str3Data, ...str3Data),
|
|
102
|
+
);
|
|
103
|
+
});
|
|
104
|
+
it(`~128M [4]`, () => {
|
|
105
|
+
const encoded = encode(str4);
|
|
106
|
+
expect(encoded.length).toBe(STR_BYTE_LENGTH + ENCODED_PREFIX_LENGTH);
|
|
107
|
+
expect(toArray(encoded.slice(0, ENCODED_PREFIX_LENGTH + str4Data.length * 2))).toEqual(
|
|
108
|
+
toArray('S', 'l', 0x7, 0xff, 0xff, 0xec, ...str4Data, ...str4Data),
|
|
109
|
+
);
|
|
110
|
+
});
|
|
111
|
+
it(`~128M [bad surrogate pair]`, () => {
|
|
112
|
+
const encoded = encode(strX);
|
|
113
|
+
expect(encoded.length).toBe(STR_BYTE_LENGTH + ENCODED_PREFIX_LENGTH);
|
|
114
|
+
expect(toArray(encoded.slice(0, ENCODED_PREFIX_LENGTH + strXData.length * 2))).toEqual(
|
|
115
|
+
toArray('S', 'l', 0x7, 0xff, 0xff, 0xec, ...strXData, ...strXData),
|
|
116
|
+
);
|
|
117
|
+
});
|
|
118
|
+
it(`128M [error]`, () => {
|
|
119
|
+
expect(() => encode(strErr)).toThrow(/Buffer has exceed max size/);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
});
|
package/tests/rxjs/decode.js
CHANGED
|
@@ -8,7 +8,6 @@ import { toBuffer } from '../.utils.js';
|
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* 包装为 promise
|
|
11
|
-
*
|
|
12
11
|
* @param {Uint8Array} data ubjson 数据
|
|
13
12
|
*/
|
|
14
13
|
async function decode(data) {
|
|
@@ -18,7 +17,6 @@ async function decode(data) {
|
|
|
18
17
|
|
|
19
18
|
/**
|
|
20
19
|
* 包装为 promise
|
|
21
|
-
*
|
|
22
20
|
* @param {import("rxjs").Observable<Uint8Array>} observable ubjson 数据流
|
|
23
21
|
* @param {(data: unknown) => void} onData 数据回调
|
|
24
22
|
*/
|
|
@@ -75,7 +73,7 @@ test('decode int16', async () => {
|
|
|
75
73
|
});
|
|
76
74
|
|
|
77
75
|
test('decode int32', async () => {
|
|
78
|
-
expect(await decode(toBuffer('l', 0x12, 0x34, 0x56, 0x78))).toBe(
|
|
76
|
+
expect(await decode(toBuffer('l', 0x12, 0x34, 0x56, 0x78))).toBe(0x1234_5678);
|
|
79
77
|
});
|
|
80
78
|
|
|
81
79
|
test('decode int64 [error]', async () => {
|
|
@@ -83,11 +81,11 @@ test('decode int64 [error]', async () => {
|
|
|
83
81
|
});
|
|
84
82
|
|
|
85
83
|
test('decode float32', async () => {
|
|
86
|
-
expect(await decode(toBuffer('d', 0x3f, 0x80, 0x80, 0x00))).toBe(1.
|
|
84
|
+
expect(await decode(toBuffer('d', 0x3f, 0x80, 0x80, 0x00))).toBe(1.003_906_25);
|
|
87
85
|
});
|
|
88
86
|
|
|
89
87
|
test('decode float64', async () => {
|
|
90
|
-
expect(await decode(toBuffer('D', 0x40, 0xf8, 0x6a, 0x00, 0x10, 0x00, 0x00, 0x00))).toBe(
|
|
88
|
+
expect(await decode(toBuffer('D', 0x40, 0xf8, 0x6a, 0x00, 0x10, 0x00, 0x00, 0x00))).toBe(100_000.003_906_25);
|
|
91
89
|
});
|
|
92
90
|
|
|
93
91
|
test('decode high-precision number [error]', async () => {
|
|
@@ -130,7 +128,7 @@ test('decode ascii string 32kiB [huge]', async () => {
|
|
|
130
128
|
});
|
|
131
129
|
|
|
132
130
|
test('decode ascii string 64MB [huge]', async () => {
|
|
133
|
-
const size =
|
|
131
|
+
const size = 0x03d0_9000;
|
|
134
132
|
const header = toBuffer('S', 'l', 0x03, 0xd0, 0x90, 0x00);
|
|
135
133
|
const payload = new Uint8Array(size + header.byteLength).fill('a'.charCodeAt(0));
|
|
136
134
|
payload.set(header);
|
|
@@ -142,9 +140,7 @@ test('decode huge string', async () => {
|
|
|
142
140
|
});
|
|
143
141
|
|
|
144
142
|
test('decode huge string [error]', async () => {
|
|
145
|
-
await expect(() => decode(toBuffer('S', 'L', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 'x'))).rejects.toThrow(
|
|
146
|
-
/Unsupported type int64/,
|
|
147
|
-
);
|
|
143
|
+
await expect(() => decode(toBuffer('S', 'L', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 'x'))).rejects.toThrow(/Unsupported type int64/);
|
|
148
144
|
});
|
|
149
145
|
|
|
150
146
|
test('decode array', async () => {
|
|
@@ -180,11 +176,10 @@ test('decode array (strongly typed, empty, optimized)', async () => {
|
|
|
180
176
|
});
|
|
181
177
|
|
|
182
178
|
test('decode N-D array (strongly typed, optimized)', async () => {
|
|
183
|
-
expect(
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
).toEqual([new Int8Array([1, 2, 3]), new Int8Array([4, 5, 6])]);
|
|
179
|
+
expect(await decode(toBuffer('[', '$', '[', '#', 'i', 2, '$', 'i', '#', 'i', 3, 1, 2, 3, '$', 'i', '#', 'i', 3, 4, 5, 6))).toEqual([
|
|
180
|
+
new Int8Array([1, 2, 3]),
|
|
181
|
+
new Int8Array([4, 5, 6]),
|
|
182
|
+
]);
|
|
188
183
|
});
|
|
189
184
|
|
|
190
185
|
test('decode array of objects (optimized)', async () => {
|
|
@@ -356,13 +351,11 @@ test('decode array (int16, strongly typed, optimized) [use typed array]', async
|
|
|
356
351
|
test('decode array (int32, strongly typed, optimized) [use typed array]', async () => {
|
|
357
352
|
const actual = await decode(toBuffer('[', '$', 'l', '#', 'i', 2, 0x12, 0x34, 0x56, 0x78, 0xfe, 0xdc, 0xba, 0x98));
|
|
358
353
|
expect(actual).toBeInstanceOf(Int32Array);
|
|
359
|
-
expect(actual).toEqual(Int32Array.from([
|
|
354
|
+
expect(actual).toEqual(Int32Array.from([305_419_896, -19_088_744]));
|
|
360
355
|
});
|
|
361
356
|
|
|
362
357
|
test('decode array (int64, strongly typed, optimized) [use typed array]', async () => {
|
|
363
|
-
await expect(() =>
|
|
364
|
-
decode(toBuffer('[', '$', 'L', '#', 'i', 1, 0x12, 0x34, 0x56, 0x78, 0xfe, 0xdc, 0xba, 0x98)),
|
|
365
|
-
).rejects.toThrow();
|
|
358
|
+
await expect(() => decode(toBuffer('[', '$', 'L', '#', 'i', 1, 0x12, 0x34, 0x56, 0x78, 0xfe, 0xdc, 0xba, 0x98))).rejects.toThrow();
|
|
366
359
|
});
|
|
367
360
|
|
|
368
361
|
test('decode array (float32, strongly typed, optimized) [use typed array]', async () => {
|
|
@@ -373,30 +366,7 @@ test('decode array (float32, strongly typed, optimized) [use typed array]', asyn
|
|
|
373
366
|
|
|
374
367
|
test('decode array (float64, strongly typed, optimized) [use typed array]', async () => {
|
|
375
368
|
const actual = await decode(
|
|
376
|
-
toBuffer(
|
|
377
|
-
'[',
|
|
378
|
-
'$',
|
|
379
|
-
'D',
|
|
380
|
-
'#',
|
|
381
|
-
'i',
|
|
382
|
-
2,
|
|
383
|
-
0x3f,
|
|
384
|
-
0xd0,
|
|
385
|
-
0x00,
|
|
386
|
-
0x00,
|
|
387
|
-
0x00,
|
|
388
|
-
0x00,
|
|
389
|
-
0x00,
|
|
390
|
-
0x00,
|
|
391
|
-
0x3f,
|
|
392
|
-
0xc0,
|
|
393
|
-
0x00,
|
|
394
|
-
0x00,
|
|
395
|
-
0x00,
|
|
396
|
-
0x00,
|
|
397
|
-
0x00,
|
|
398
|
-
0x00,
|
|
399
|
-
),
|
|
369
|
+
toBuffer('[', '$', 'D', '#', 'i', 2, 0x3f, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
|
|
400
370
|
);
|
|
401
371
|
expect(actual).toBeInstanceOf(Float64Array);
|
|
402
372
|
expect(actual).toEqual(Float64Array.from([0.25, 0.125]));
|
|
@@ -411,11 +381,11 @@ test('decode object', async () => {
|
|
|
411
381
|
});
|
|
412
382
|
|
|
413
383
|
test('decode object (with no-op)', async () => {
|
|
414
|
-
expect(
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
384
|
+
expect(await decode(toBuffer('N', '{', 'N', 'i', 1, 'a', 'i', 1, 'i', 1, 'b', 'N', 'i', 2, 'i', 1, 'c', 'i', 3, 'N', '}', 'N'))).toEqual({
|
|
385
|
+
a: 1,
|
|
386
|
+
b: 2,
|
|
387
|
+
c: 3,
|
|
388
|
+
});
|
|
419
389
|
});
|
|
420
390
|
|
|
421
391
|
test('decode array (empty, optimized)', async () => {
|
|
@@ -423,9 +393,7 @@ test('decode array (empty, optimized)', async () => {
|
|
|
423
393
|
});
|
|
424
394
|
|
|
425
395
|
test('decode object (mixed, optimized)', async () => {
|
|
426
|
-
expect(
|
|
427
|
-
await decode(toBuffer('{', '#', 'i', 3, 'i', 1, 'a', 'i', 1, 'i', 1, 'b', 'C', 'a', 'i', 1, 'c', 'T')),
|
|
428
|
-
).toEqual({
|
|
396
|
+
expect(await decode(toBuffer('{', '#', 'i', 3, 'i', 1, 'a', 'i', 1, 'i', 1, 'b', 'C', 'a', 'i', 1, 'c', 'T'))).toEqual({
|
|
429
397
|
a: 1,
|
|
430
398
|
b: 'a',
|
|
431
399
|
c: true,
|
package/tests/rxjs/encode.js
CHANGED
|
@@ -8,7 +8,6 @@ import { toArray } from '../.utils.js';
|
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* 包装为 promise
|
|
11
|
-
*
|
|
12
11
|
* @param {unknown} value 要编码的值
|
|
13
12
|
*/
|
|
14
13
|
function encodeAsync(value) {
|
|
@@ -65,21 +64,19 @@ test('encode int16', async () => {
|
|
|
65
64
|
});
|
|
66
65
|
|
|
67
66
|
test('encode int32', async () => {
|
|
68
|
-
expect(toArray(await encodeAsync(
|
|
67
|
+
expect(toArray(await encodeAsync(0x1234_5678))).toEqual(toArray('l', 0x12, 0x34, 0x56, 0x78));
|
|
69
68
|
});
|
|
70
69
|
|
|
71
70
|
test('encode float32', async () => {
|
|
72
|
-
expect(toArray(await encodeAsync(1.
|
|
71
|
+
expect(toArray(await encodeAsync(1.003_906_25))).toEqual(toArray('d', 0x3f, 0x80, 0x80, 0x00));
|
|
73
72
|
});
|
|
74
73
|
|
|
75
74
|
test('encode float32 (too large integer)', async () => {
|
|
76
|
-
expect(toArray(await encodeAsync(
|
|
75
|
+
expect(toArray(await encodeAsync(2_147_483_648))).toEqual(toArray('d', 0x4f, 0x00, 0x00, 0x00));
|
|
77
76
|
});
|
|
78
77
|
|
|
79
78
|
test('encode float64', async () => {
|
|
80
|
-
expect(toArray(await encodeAsync(
|
|
81
|
-
toArray('D', 0x40, 0xf8, 0x6a, 0x00, 0x10, 0x00, 0x00, 0x00),
|
|
82
|
-
);
|
|
79
|
+
expect(toArray(await encodeAsync(100_000.003_906_25))).toEqual(toArray('D', 0x40, 0xf8, 0x6a, 0x00, 0x10, 0x00, 0x00, 0x00));
|
|
83
80
|
});
|
|
84
81
|
|
|
85
82
|
test('encode char', async () => {
|
|
@@ -87,7 +84,7 @@ test('encode char', async () => {
|
|
|
87
84
|
});
|
|
88
85
|
|
|
89
86
|
test('encode char 128', async () => {
|
|
90
|
-
expect(toArray(await encodeAsync('\
|
|
87
|
+
expect(toArray(await encodeAsync('\u00CC'))).toEqual(toArray('C', '\u00CC'));
|
|
91
88
|
});
|
|
92
89
|
|
|
93
90
|
test('encode char 257', async () => {
|
|
@@ -131,7 +128,7 @@ test('encode array (undefined)', async () => {
|
|
|
131
128
|
});
|
|
132
129
|
|
|
133
130
|
test('encode array (spares)', async () => {
|
|
134
|
-
const array =
|
|
131
|
+
const array = Array.from({ length: 3 });
|
|
135
132
|
array[1] = true;
|
|
136
133
|
expect(toArray(await encodeAsync(array))).toEqual(toArray('[', 'Z', 'T', 'Z', ']'));
|
|
137
134
|
});
|
|
@@ -195,25 +192,19 @@ test('encode array of objects of arrays', async () => {
|
|
|
195
192
|
});
|
|
196
193
|
|
|
197
194
|
test('encode array (int8 typed array)', async () => {
|
|
198
|
-
expect(toArray(await encodeAsync(Int8Array.from([18, -2])))).toEqual(
|
|
199
|
-
toArray('[', '$', 'i', '#', 'i', 2, 0x12, 0xfe),
|
|
200
|
-
);
|
|
195
|
+
expect(toArray(await encodeAsync(Int8Array.from([18, -2])))).toEqual(toArray('[', '$', 'i', '#', 'i', 2, 0x12, 0xfe));
|
|
201
196
|
});
|
|
202
197
|
|
|
203
198
|
test('encode array (uint8 typed array)', async () => {
|
|
204
|
-
expect(toArray(await encodeAsync(Uint8Array.from([18, 254])))).toEqual(
|
|
205
|
-
toArray('[', '$', 'U', '#', 'i', 2, 0x12, 0xfe),
|
|
206
|
-
);
|
|
199
|
+
expect(toArray(await encodeAsync(Uint8Array.from([18, 254])))).toEqual(toArray('[', '$', 'U', '#', 'i', 2, 0x12, 0xfe));
|
|
207
200
|
});
|
|
208
201
|
|
|
209
202
|
test('encode array (int16 typed array)', async () => {
|
|
210
|
-
expect(toArray(await encodeAsync(Int16Array.from([4660, -292])))).toEqual(
|
|
211
|
-
toArray('[', '$', 'I', '#', 'i', 2, 0x12, 0x34, 0xfe, 0xdc),
|
|
212
|
-
);
|
|
203
|
+
expect(toArray(await encodeAsync(Int16Array.from([4660, -292])))).toEqual(toArray('[', '$', 'I', '#', 'i', 2, 0x12, 0x34, 0xfe, 0xdc));
|
|
213
204
|
});
|
|
214
205
|
|
|
215
206
|
test('encode array (int32 typed array)', async () => {
|
|
216
|
-
expect(toArray(await encodeAsync(Int32Array.from([
|
|
207
|
+
expect(toArray(await encodeAsync(Int32Array.from([305_419_896, -19_088_744])))).toEqual(
|
|
217
208
|
toArray('[', '$', 'l', '#', 'i', 2, 0x12, 0x34, 0x56, 0x78, 0xfe, 0xdc, 0xba, 0x98),
|
|
218
209
|
);
|
|
219
210
|
});
|
|
@@ -226,30 +217,7 @@ test('encode array (float32 typed array)', async () => {
|
|
|
226
217
|
|
|
227
218
|
test('encode array (float64 typed array)', async () => {
|
|
228
219
|
expect(toArray(await encodeAsync(Float64Array.from([0.25, 0.125])))).toEqual(
|
|
229
|
-
toArray(
|
|
230
|
-
'[',
|
|
231
|
-
'$',
|
|
232
|
-
'D',
|
|
233
|
-
'#',
|
|
234
|
-
'i',
|
|
235
|
-
2,
|
|
236
|
-
0x3f,
|
|
237
|
-
0xd0,
|
|
238
|
-
0x00,
|
|
239
|
-
0x00,
|
|
240
|
-
0x00,
|
|
241
|
-
0x00,
|
|
242
|
-
0x00,
|
|
243
|
-
0x00,
|
|
244
|
-
0x3f,
|
|
245
|
-
0xc0,
|
|
246
|
-
0x00,
|
|
247
|
-
0x00,
|
|
248
|
-
0x00,
|
|
249
|
-
0x00,
|
|
250
|
-
0x00,
|
|
251
|
-
0x00,
|
|
252
|
-
),
|
|
220
|
+
toArray('[', '$', 'D', '#', 'i', 2, 0x3f, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
|
|
253
221
|
);
|
|
254
222
|
});
|
|
255
223
|
|
|
@@ -274,9 +242,7 @@ test('encode array (int64 typed array)', async () => {
|
|
|
274
242
|
});
|
|
275
243
|
|
|
276
244
|
test('encode object', async () => {
|
|
277
|
-
expect(toArray(await encodeAsync({ a: 1, b: 2, c: 3 }))).toEqual(
|
|
278
|
-
toArray('{', 'i', 1, 'a', 'U', 1, 'i', 1, 'b', 'U', 2, 'i', 1, 'c', 'U', 3, '}'),
|
|
279
|
-
);
|
|
245
|
+
expect(toArray(await encodeAsync({ a: 1, b: 2, c: 3 }))).toEqual(toArray('{', 'i', 1, 'a', 'U', 1, 'i', 1, 'b', 'U', 2, 'i', 1, 'c', 'U', 3, '}'));
|
|
280
246
|
});
|
|
281
247
|
|
|
282
248
|
test('encode object (empty)', async () => {
|
|
@@ -288,15 +254,11 @@ test('encode object (empty key)', async () => {
|
|
|
288
254
|
});
|
|
289
255
|
|
|
290
256
|
test('encode object (mixed)', async () => {
|
|
291
|
-
expect(toArray(await encodeAsync({ a: 1, b: 'a', c: true }))).toEqual(
|
|
292
|
-
toArray('{', 'i', 1, 'a', 'U', 1, 'i', 1, 'b', 'C', 'a', 'i', 1, 'c', 'T', '}'),
|
|
293
|
-
);
|
|
257
|
+
expect(toArray(await encodeAsync({ a: 1, b: 'a', c: true }))).toEqual(toArray('{', 'i', 1, 'a', 'U', 1, 'i', 1, 'b', 'C', 'a', 'i', 1, 'c', 'T', '}'));
|
|
294
258
|
});
|
|
295
259
|
|
|
296
260
|
test('encode object (only null values)', async () => {
|
|
297
|
-
expect(toArray(await encodeAsync({ a: null, b: null, c: null }))).toEqual(
|
|
298
|
-
toArray('{', 'i', 1, 'a', 'Z', 'i', 1, 'b', 'Z', 'i', 1, 'c', 'Z', '}'),
|
|
299
|
-
);
|
|
261
|
+
expect(toArray(await encodeAsync({ a: null, b: null, c: null }))).toEqual(toArray('{', 'i', 1, 'a', 'Z', 'i', 1, 'b', 'Z', 'i', 1, 'c', 'Z', '}'));
|
|
300
262
|
});
|
|
301
263
|
|
|
302
264
|
test('encode object (skip prototype)', async () => {
|
|
@@ -304,9 +266,7 @@ test('encode object (skip prototype)', async () => {
|
|
|
304
266
|
obj.a = 1;
|
|
305
267
|
obj.b = 'a';
|
|
306
268
|
obj.c = true;
|
|
307
|
-
expect(toArray(await encodeAsync(obj))).toEqual(
|
|
308
|
-
toArray('{', 'i', 1, 'a', 'U', 1, 'i', 1, 'b', 'C', 'a', 'i', 1, 'c', 'T', '}'),
|
|
309
|
-
);
|
|
269
|
+
expect(toArray(await encodeAsync(obj))).toEqual(toArray('{', 'i', 1, 'a', 'U', 1, 'i', 1, 'b', 'C', 'a', 'i', 1, 'c', 'T', '}'));
|
|
310
270
|
});
|
|
311
271
|
|
|
312
272
|
test('encode object (skip symbol)', async () => {
|
|
@@ -352,9 +312,7 @@ test('encode huge typed array (16K)', async () => {
|
|
|
352
312
|
|
|
353
313
|
test('encode huge typed array (~128M)', async () => {
|
|
354
314
|
const obj = new Uint8Array(128 * 1024 * 1024 - 10);
|
|
355
|
-
expect(toArray((await encodeAsync(obj)).slice(0, 10))).toEqual(
|
|
356
|
-
toArray('[', '$', 'U', '#', 'l', 0x7, 0xff, 0xff, 0xf6, 0),
|
|
357
|
-
);
|
|
315
|
+
expect(toArray((await encodeAsync(obj)).slice(0, 10))).toEqual(toArray('[', '$', 'U', '#', 'l', 0x7, 0xff, 0xff, 0xf6, 0));
|
|
358
316
|
});
|
|
359
317
|
|
|
360
318
|
test('encode huge typed array (256M + 1) [error]', async () => {
|
|
@@ -369,9 +327,7 @@ test('encode huge typed array (3G) [error]', async () => {
|
|
|
369
327
|
|
|
370
328
|
test('encode huge data (~128M)', async () => {
|
|
371
329
|
const obj = [new Uint8Array(128 * 1024 * 1024 - 20)];
|
|
372
|
-
expect(toArray((await encodeAsync(obj)).slice(0, 11))).toEqual(
|
|
373
|
-
toArray('[', '[', '$', 'U', '#', 'l', 0x7, 0xff, 0xff, 0xec, 0),
|
|
374
|
-
);
|
|
330
|
+
expect(toArray((await encodeAsync(obj)).slice(0, 11))).toEqual(toArray('[', '[', '$', 'U', '#', 'l', 0x7, 0xff, 0xff, 0xec, 0));
|
|
375
331
|
});
|
|
376
332
|
|
|
377
333
|
test('encode huge data (256M + 1) [error]', async () => {
|
package/tests/stream/decode.js
CHANGED
|
@@ -8,7 +8,6 @@ import { toBuffer } from '../.utils.js';
|
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* 包装为 promise
|
|
11
|
-
*
|
|
12
11
|
* @param {Uint8Array} data ubjson 数据
|
|
13
12
|
*/
|
|
14
13
|
async function decode(data) {
|
|
@@ -18,7 +17,6 @@ async function decode(data) {
|
|
|
18
17
|
|
|
19
18
|
/**
|
|
20
19
|
* 包装为 promise
|
|
21
|
-
*
|
|
22
20
|
* @param {import("stream").Transform} stream ubjson 流
|
|
23
21
|
*/
|
|
24
22
|
function eos(stream) {
|
|
@@ -70,7 +68,7 @@ test('decode int16', async () => {
|
|
|
70
68
|
});
|
|
71
69
|
|
|
72
70
|
test('decode int32', async () => {
|
|
73
|
-
expect(await decode(toBuffer('l', 0x12, 0x34, 0x56, 0x78))).toBe(
|
|
71
|
+
expect(await decode(toBuffer('l', 0x12, 0x34, 0x56, 0x78))).toBe(0x1234_5678);
|
|
74
72
|
});
|
|
75
73
|
|
|
76
74
|
test('decode int64 [error]', async () => {
|
|
@@ -78,11 +76,11 @@ test('decode int64 [error]', async () => {
|
|
|
78
76
|
});
|
|
79
77
|
|
|
80
78
|
test('decode float32', async () => {
|
|
81
|
-
expect(await decode(toBuffer('d', 0x3f, 0x80, 0x80, 0x00))).toBe(1.
|
|
79
|
+
expect(await decode(toBuffer('d', 0x3f, 0x80, 0x80, 0x00))).toBe(1.003_906_25);
|
|
82
80
|
});
|
|
83
81
|
|
|
84
82
|
test('decode float64', async () => {
|
|
85
|
-
expect(await decode(toBuffer('D', 0x40, 0xf8, 0x6a, 0x00, 0x10, 0x00, 0x00, 0x00))).toBe(
|
|
83
|
+
expect(await decode(toBuffer('D', 0x40, 0xf8, 0x6a, 0x00, 0x10, 0x00, 0x00, 0x00))).toBe(100_000.003_906_25);
|
|
86
84
|
});
|
|
87
85
|
|
|
88
86
|
test('decode high-precision number [error]', async () => {
|
|
@@ -128,9 +126,7 @@ test('decode huge string', async () => {
|
|
|
128
126
|
});
|
|
129
127
|
|
|
130
128
|
test('decode huge string [error]', async () => {
|
|
131
|
-
await expect(() => decode(toBuffer('S', 'L', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 'x'))).rejects.toThrow(
|
|
132
|
-
/Unsupported type int64/,
|
|
133
|
-
);
|
|
129
|
+
await expect(() => decode(toBuffer('S', 'L', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 'x'))).rejects.toThrow(/Unsupported type int64/);
|
|
134
130
|
});
|
|
135
131
|
|
|
136
132
|
test('decode array', async () => {
|
|
@@ -166,11 +162,10 @@ test('decode array (strongly typed, empty, optimized)', async () => {
|
|
|
166
162
|
});
|
|
167
163
|
|
|
168
164
|
test('decode N-D array (strongly typed, optimized)', async () => {
|
|
169
|
-
expect(
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
).toEqual([new Int8Array([1, 2, 3]), new Int8Array([4, 5, 6])]);
|
|
165
|
+
expect(await decode(toBuffer('[', '$', '[', '#', 'i', 2, '$', 'i', '#', 'i', 3, 1, 2, 3, '$', 'i', '#', 'i', 3, 4, 5, 6))).toEqual([
|
|
166
|
+
new Int8Array([1, 2, 3]),
|
|
167
|
+
new Int8Array([4, 5, 6]),
|
|
168
|
+
]);
|
|
174
169
|
});
|
|
175
170
|
|
|
176
171
|
test('decode array of objects (optimized)', async () => {
|
|
@@ -342,13 +337,11 @@ test('decode array (int16, strongly typed, optimized) [use typed array]', async
|
|
|
342
337
|
test('decode array (int32, strongly typed, optimized) [use typed array]', async () => {
|
|
343
338
|
const actual = await decode(toBuffer('[', '$', 'l', '#', 'i', 2, 0x12, 0x34, 0x56, 0x78, 0xfe, 0xdc, 0xba, 0x98));
|
|
344
339
|
expect(actual).toBeInstanceOf(Int32Array);
|
|
345
|
-
expect(actual).toEqual(Int32Array.from([
|
|
340
|
+
expect(actual).toEqual(Int32Array.from([305_419_896, -19_088_744]));
|
|
346
341
|
});
|
|
347
342
|
|
|
348
343
|
test('decode array (int64, strongly typed, optimized) [use typed array]', async () => {
|
|
349
|
-
await expect(() =>
|
|
350
|
-
decode(toBuffer('[', '$', 'L', '#', 'i', 1, 0x12, 0x34, 0x56, 0x78, 0xfe, 0xdc, 0xba, 0x98)),
|
|
351
|
-
).rejects.toThrow();
|
|
344
|
+
await expect(() => decode(toBuffer('[', '$', 'L', '#', 'i', 1, 0x12, 0x34, 0x56, 0x78, 0xfe, 0xdc, 0xba, 0x98))).rejects.toThrow();
|
|
352
345
|
});
|
|
353
346
|
|
|
354
347
|
test('decode array (float32, strongly typed, optimized) [use typed array]', async () => {
|
|
@@ -359,30 +352,7 @@ test('decode array (float32, strongly typed, optimized) [use typed array]', asyn
|
|
|
359
352
|
|
|
360
353
|
test('decode array (float64, strongly typed, optimized) [use typed array]', async () => {
|
|
361
354
|
const actual = await decode(
|
|
362
|
-
toBuffer(
|
|
363
|
-
'[',
|
|
364
|
-
'$',
|
|
365
|
-
'D',
|
|
366
|
-
'#',
|
|
367
|
-
'i',
|
|
368
|
-
2,
|
|
369
|
-
0x3f,
|
|
370
|
-
0xd0,
|
|
371
|
-
0x00,
|
|
372
|
-
0x00,
|
|
373
|
-
0x00,
|
|
374
|
-
0x00,
|
|
375
|
-
0x00,
|
|
376
|
-
0x00,
|
|
377
|
-
0x3f,
|
|
378
|
-
0xc0,
|
|
379
|
-
0x00,
|
|
380
|
-
0x00,
|
|
381
|
-
0x00,
|
|
382
|
-
0x00,
|
|
383
|
-
0x00,
|
|
384
|
-
0x00,
|
|
385
|
-
),
|
|
355
|
+
toBuffer('[', '$', 'D', '#', 'i', 2, 0x3f, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
|
|
386
356
|
);
|
|
387
357
|
expect(actual).toBeInstanceOf(Float64Array);
|
|
388
358
|
expect(actual).toEqual(Float64Array.from([0.25, 0.125]));
|
|
@@ -397,11 +367,11 @@ test('decode object', async () => {
|
|
|
397
367
|
});
|
|
398
368
|
|
|
399
369
|
test('decode object (with no-op)', async () => {
|
|
400
|
-
expect(
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
370
|
+
expect(await decode(toBuffer('N', '{', 'N', 'i', 1, 'a', 'i', 1, 'i', 1, 'b', 'N', 'i', 2, 'i', 1, 'c', 'i', 3, 'N', '}', 'N'))).toEqual({
|
|
371
|
+
a: 1,
|
|
372
|
+
b: 2,
|
|
373
|
+
c: 3,
|
|
374
|
+
});
|
|
405
375
|
});
|
|
406
376
|
|
|
407
377
|
test('decode array (empty, optimized)', async () => {
|
|
@@ -409,9 +379,7 @@ test('decode array (empty, optimized)', async () => {
|
|
|
409
379
|
});
|
|
410
380
|
|
|
411
381
|
test('decode object (mixed, optimized)', async () => {
|
|
412
|
-
expect(
|
|
413
|
-
await decode(toBuffer('{', '#', 'i', 3, 'i', 1, 'a', 'i', 1, 'i', 1, 'b', 'C', 'a', 'i', 1, 'c', 'T')),
|
|
414
|
-
).toEqual({
|
|
382
|
+
expect(await decode(toBuffer('{', '#', 'i', 3, 'i', 1, 'a', 'i', 1, 'i', 1, 'b', 'C', 'a', 'i', 1, 'c', 'T'))).toEqual({
|
|
415
383
|
a: 1,
|
|
416
384
|
b: 'a',
|
|
417
385
|
c: true,
|