@cloudpss/ubjson 0.5.37 → 0.5.39

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.
Files changed (91) hide show
  1. package/dist/base/decoder.d.ts +12 -0
  2. package/dist/base/decoder.js +26 -0
  3. package/dist/base/decoder.js.map +1 -0
  4. package/dist/{common → base}/encoder.d.ts +2 -6
  5. package/dist/{common → base}/encoder.js +71 -121
  6. package/dist/base/encoder.js.map +1 -0
  7. package/dist/decoder.d.ts +1 -2
  8. package/dist/decoder.js +1 -1
  9. package/dist/decoder.js.map +1 -1
  10. package/dist/encoder.d.ts +1 -1
  11. package/dist/encoder.js +11 -11
  12. package/dist/encoder.js.map +1 -1
  13. package/dist/{common → helper}/constants.js.map +1 -1
  14. package/dist/helper/decode.d.ts +49 -0
  15. package/dist/helper/decode.js +344 -0
  16. package/dist/helper/decode.js.map +1 -0
  17. package/dist/helper/encode.d.ts +20 -0
  18. package/dist/helper/encode.js +84 -0
  19. package/dist/helper/encode.js.map +1 -0
  20. package/dist/{common → helper}/errors.d.ts +4 -0
  21. package/dist/{common → helper}/errors.js +10 -2
  22. package/dist/helper/errors.js.map +1 -0
  23. package/dist/{common → helper}/string-decoder.js +1 -1
  24. package/dist/{common → helper}/string-decoder.js.map +1 -1
  25. package/dist/{common → helper}/string-encoder.js.map +1 -1
  26. package/dist/{utils.d.ts → helper/utils.d.ts} +0 -4
  27. package/dist/{utils.js → helper/utils.js} +0 -6
  28. package/dist/helper/utils.js.map +1 -0
  29. package/dist/index.d.ts +3 -5
  30. package/dist/index.js +5 -5
  31. package/dist/index.js.map +1 -1
  32. package/dist/rxjs/decoder.js +1 -1
  33. package/dist/rxjs/decoder.js.map +1 -1
  34. package/dist/rxjs/index.d.ts +1 -1
  35. package/dist/rxjs/index.js +1 -1
  36. package/dist/rxjs/index.js.map +1 -1
  37. package/dist/stream/index.d.ts +2 -2
  38. package/dist/stream/index.js +2 -2
  39. package/dist/stream/index.js.map +1 -1
  40. package/dist/stream-helper/decoder.d.ts +2 -3
  41. package/dist/stream-helper/decoder.js +3 -6
  42. package/dist/stream-helper/decoder.js.map +1 -1
  43. package/dist/stream-helper/encoder.d.ts +1 -1
  44. package/dist/stream-helper/encoder.js +15 -15
  45. package/dist/stream-helper/encoder.js.map +1 -1
  46. package/package.json +4 -4
  47. package/src/base/decoder.ts +27 -0
  48. package/src/{common → base}/encoder.ts +72 -116
  49. package/src/decoder.ts +1 -2
  50. package/src/encoder.ts +11 -11
  51. package/src/helper/decode.ts +362 -0
  52. package/src/helper/encode.ts +89 -0
  53. package/src/{common → helper}/errors.ts +12 -2
  54. package/src/{common → helper}/string-decoder.ts +1 -1
  55. package/src/{utils.ts → helper/utils.ts} +0 -7
  56. package/src/index.ts +6 -8
  57. package/src/rxjs/decoder.ts +1 -1
  58. package/src/rxjs/index.ts +1 -1
  59. package/src/stream/index.ts +3 -3
  60. package/src/stream-helper/decoder.ts +3 -6
  61. package/src/stream-helper/encoder.ts +16 -16
  62. package/tests/.utils.js +6 -4
  63. package/tests/decode.js +0 -18
  64. package/tests/e2e/no-encode-into.js +1 -1
  65. package/tests/encode.js +1 -1
  66. package/tests/huge-string.js +1 -0
  67. package/tests/rxjs/decode.js +14 -13
  68. package/tests/rxjs/encode.js +13 -12
  69. package/tests/stream/decode.js +15 -13
  70. package/tests/stream/encode.js +9 -8
  71. package/tests/stream/many.js +2 -1
  72. package/tests/string-encoding.js +4 -6
  73. package/benchmark-small.js +0 -81
  74. package/benchmark-string-decode.js +0 -41
  75. package/benchmark-string-encode.js +0 -32
  76. package/benchmark-string-size-caculation.js +0 -50
  77. package/benchmark.js +0 -50
  78. package/dist/common/decoder.d.ts +0 -45
  79. package/dist/common/decoder.js +0 -348
  80. package/dist/common/decoder.js.map +0 -1
  81. package/dist/common/encoder.js.map +0 -1
  82. package/dist/common/errors.js.map +0 -1
  83. package/dist/utils.js.map +0 -1
  84. package/src/common/decoder.ts +0 -356
  85. /package/dist/{common → helper}/constants.d.ts +0 -0
  86. /package/dist/{common → helper}/constants.js +0 -0
  87. /package/dist/{common → helper}/string-decoder.d.ts +0 -0
  88. /package/dist/{common → helper}/string-encoder.d.ts +0 -0
  89. /package/dist/{common → helper}/string-encoder.js +0 -0
  90. /package/src/{common → helper}/constants.ts +0 -0
  91. /package/src/{common → helper}/string-encoder.ts +0 -0
package/tests/.utils.js CHANGED
@@ -1,7 +1,11 @@
1
- import { resetEnv as resetDecoderEnv } from '../dist/common/string-decoder.js';
2
- import { resetEnv as resetEncoderEnv } from '../dist/common/string-encoder.js';
1
+ import { resetEnv as resetDecoderEnv } from '../dist/helper/string-decoder.js';
2
+ import { resetEnv as resetEncoderEnv } from '../dist/helper/string-encoder.js';
3
3
  import { resetEncoder } from '../dist/encoder.js';
4
+ import '../dist/helper/constants.js';
4
5
 
6
+ /**
7
+ * 重设所有环境
8
+ */
5
9
  export function resetEnv() {
6
10
  resetDecoderEnv();
7
11
  resetEncoderEnv();
@@ -10,7 +14,6 @@ export function resetEnv() {
10
14
 
11
15
  /**
12
16
  * 输入转为数字数组以便比较
13
- *
14
17
  * @param {[ArrayBuffer] | [Uint8Array] | (number | string)[]} args 输入
15
18
  * @returns {number[]} 数字数组
16
19
  */
@@ -26,7 +29,6 @@ export function toArray(...args) {
26
29
 
27
30
  /**
28
31
  * 将数字或字符串转换为 Uint8Array
29
- *
30
32
  * @param {...string | number} args 数字或 char 的数组
31
33
  * @returns {Uint8Array} Uint8Array
32
34
  */
package/tests/decode.js CHANGED
@@ -202,24 +202,6 @@ test('decode N-D array (strongly typed, optimized)', () => {
202
202
  ).toEqual([new Int8Array([1, 2, 3]), new Int8Array([4, 5, 6])]);
203
203
  });
204
204
 
205
- test('decode N-D array (strongly typed, optimized, no alloc buffer)', () => {
206
- const buf = toBuffer('[', '$', '[', '#', 'i', 2, '$', 'i', '#', 'i', 3, 1, 2, 3, '$', 'U', '#', 'U', 3, 4, 5, 6);
207
-
208
- const decoded1 = /** @type {[Int8Array, Uint8Array]} */ (decode(buf));
209
- const decoded2 = /** @type {[Int8Array, Uint8Array]} */ (decode(buf, { noAllocBuffer: true }));
210
- // @ts-expect-error Falsy value
211
- const decoded3 = /** @type {[Int8Array, Uint8Array]} */ (decode(buf, { noAllocBuffer: 0 }));
212
- expect(decoded1).toEqual([new Int8Array([1, 2, 3]), new Uint8Array([4, 5, 6])]);
213
- expect(decoded2).toEqual([new Int8Array([1, 2, 3]), new Uint8Array([4, 5, 6])]);
214
- expect(decoded3).toEqual([new Int8Array([1, 2, 3]), new Uint8Array([4, 5, 6])]);
215
- expect(decoded1[0].buffer).not.toBe(buf.buffer);
216
- expect(decoded1[1].buffer).not.toBe(buf.buffer);
217
- expect(decoded2[0].buffer).not.toBe(buf.buffer);
218
- expect(decoded2[1].buffer).toBe(buf.buffer);
219
- expect(decoded3[0].buffer).not.toBe(buf.buffer);
220
- expect(decoded3[1].buffer).not.toBe(buf.buffer);
221
- });
222
-
223
205
  test('decode array of objects (optimized)', () => {
224
206
  expect(
225
207
  decode(
@@ -4,7 +4,7 @@ import { encode, decode } from '../../dist/index.js';
4
4
 
5
5
  describe('no encodeInto', () => {
6
6
  // eslint-disable-next-line @typescript-eslint/unbound-method
7
- const encodeInto = TextEncoder.prototype.encodeInto;
7
+ const { encodeInto } = TextEncoder.prototype;
8
8
  beforeAll(() => {
9
9
  // @ts-expect-error 移除 encodeInto 以测试兼容性
10
10
  TextEncoder.prototype.encodeInto = undefined;
package/tests/encode.js CHANGED
@@ -157,7 +157,7 @@ test('encode string (len = 180)', () => {
157
157
 
158
158
  test('encode string (no encodeInto)', () => {
159
159
  // eslint-disable-next-line @typescript-eslint/unbound-method
160
- const encodeInto = TextEncoder.prototype.encodeInto;
160
+ const { encodeInto } = TextEncoder.prototype;
161
161
  // @ts-expect-error 移除 encodeInto 以测试兼容性
162
162
  TextEncoder.prototype.encodeInto = undefined;
163
163
  expect(toArray(encode('ubjson'))).toEqual(toArray('S', 'i', 6, ...'ubjson'));
@@ -8,6 +8,7 @@ const STR_BYTE_LENGTH = 128 * 1024 * 1024 - 20;
8
8
  * 构造测试字符串
9
9
  * @param {string} char 使用的字符
10
10
  * @param {number} byteLength 需要的长度
11
+ * @returns {[Uint8Array, string]}
11
12
  */
12
13
  function makeString(char, byteLength) {
13
14
  const encoded = new TextEncoder().encode(char);
@@ -5,11 +5,12 @@ import { jest } from '@jest/globals';
5
5
  import { firstValueFrom, of, Subject } from 'rxjs';
6
6
  import { decode as decodePipe } from '../../dist/rxjs/index.js';
7
7
  import { toBuffer } from '../.utils.js';
8
- import { UnexpectedEof } from '../../dist/utils.js';
8
+ import { UnexpectedEofError as UnexpectedEof } from '../../dist/helper/errors.js';
9
9
 
10
10
  /**
11
11
  * 包装为 promise
12
12
  * @param {Uint8Array} data ubjson 数据
13
+ * @returns {Promise<unknown>}
13
14
  */
14
15
  async function decode(data) {
15
16
  const readable = of(data);
@@ -21,7 +22,7 @@ async function decode(data) {
21
22
  * @param {import("rxjs").Observable<Uint8Array>} observable ubjson 数据流
22
23
  * @param {(data: unknown) => void} onData 数据回调
23
24
  */
24
- function decodeStream(observable, onData) {
25
+ async function decodeStream(observable, onData) {
25
26
  return /** @type {Promise<void>} */ (
26
27
  new Promise((resolve, reject) => {
27
28
  observable.pipe(decodePipe()).subscribe({
@@ -34,7 +35,7 @@ function decodeStream(observable, onData) {
34
35
  }
35
36
 
36
37
  test('decode unsupported type', async () => {
37
- await expect(() => decode(toBuffer('!'))).rejects.toThrow();
38
+ await expect(async () => decode(toBuffer('!'))).rejects.toThrow();
38
39
  });
39
40
 
40
41
  test('decode undefined', async () => {
@@ -91,7 +92,7 @@ test('decode float64', async () => {
91
92
  });
92
93
 
93
94
  test('decode high-precision number [error]', async () => {
94
- await expect(() => decode(toBuffer('H', 'i', 3, '1', '.', '1'))).rejects.toThrow();
95
+ await expect(async () => decode(toBuffer('H', 'i', 3, '1', '.', '1'))).rejects.toThrow();
95
96
  });
96
97
 
97
98
  test('decode char', async () => {
@@ -107,11 +108,11 @@ test('decode empty string', async () => {
107
108
  });
108
109
 
109
110
  test('decode string (bad size) [error]', async () => {
110
- await expect(() => decode(toBuffer('S', 'i', 0xff, 'x'))).rejects.toThrow(/Invalid length/);
111
+ await expect(async () => decode(toBuffer('S', 'i', 0xff, 'x'))).rejects.toThrow(/Invalid length/);
111
112
  });
112
113
 
113
114
  test('decode string (unexpected eof) [error]', async () => {
114
- await expect(() => decode(toBuffer('S', 'i', 2, 'x'))).rejects.toThrow(UnexpectedEof);
115
+ await expect(async () => decode(toBuffer('S', 'i', 2, 'x'))).rejects.toThrow(UnexpectedEof);
115
116
  });
116
117
 
117
118
  test('decode ascii string', async () => {
@@ -143,9 +144,9 @@ test('decode huge string', async () => {
143
144
 
144
145
  test('decode huge string [int64 length]', async () => {
145
146
  expect(await decode(toBuffer('S', 'L', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 'x'))).toBe('x');
146
- await expect(() => decode(toBuffer('S', 'L', 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 'x'))).rejects.toThrow(
147
- /Invalid length/,
148
- );
147
+ await expect(async () =>
148
+ decode(toBuffer('S', 'L', 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 'x')),
149
+ ).rejects.toThrow(/Invalid length/);
149
150
  });
150
151
 
151
152
  test('decode array', async () => {
@@ -309,19 +310,19 @@ test('decode array of objects of arrays (optimized)', async () => {
309
310
  });
310
311
 
311
312
  test('decode array (strongly typed, unexpected eof, optimized)', async () => {
312
- await expect(() => decode(toBuffer('[', '$', 'i', '#', 'i', 3, 1, 2))).rejects.toThrow(UnexpectedEof);
313
+ await expect(async () => decode(toBuffer('[', '$', 'i', '#', 'i', 3, 1, 2))).rejects.toThrow(UnexpectedEof);
313
314
  });
314
315
 
315
316
  test('decode array (strongly typed, invalid length value, optimized)', async () => {
316
- await expect(() => decode(toBuffer('[', '$', 'i', '#', 'i', -1))).rejects.toThrow();
317
+ await expect(async () => decode(toBuffer('[', '$', 'i', '#', 'i', -1))).rejects.toThrow();
317
318
  });
318
319
 
319
320
  test('decode array (strongly typed, invalid length type, optimized)', async () => {
320
- await expect(() => decode(toBuffer('[', '$', 'i', '#', 'C', '0'))).rejects.toThrow();
321
+ await expect(async () => decode(toBuffer('[', '$', 'i', '#', 'C', '0'))).rejects.toThrow();
321
322
  });
322
323
 
323
324
  test('decode array (strongly typed, malformed, optimized)', async () => {
324
- await expect(() => decode(toBuffer('[', '$', 'i', 1, 2, 3, ']'))).rejects.toThrow();
325
+ await expect(async () => decode(toBuffer('[', '$', 'i', 1, 2, 3, ']'))).rejects.toThrow();
325
326
  });
326
327
 
327
328
  test('decode array (only null values, optimized)', async () => {
@@ -9,8 +9,9 @@ import { toArray } from '../.utils.js';
9
9
  /**
10
10
  * 包装为 promise
11
11
  * @param {unknown} value 要编码的值
12
+ * @returns {Promise<Buffer>}
12
13
  */
13
- function encodeAsync(value) {
14
+ async function encodeAsync(value) {
14
15
  return firstValueFrom(
15
16
  of(value).pipe(
16
17
  encode(),
@@ -21,7 +22,7 @@ function encodeAsync(value) {
21
22
  }
22
23
 
23
24
  test('encode function', async () => {
24
- await expect(() =>
25
+ await expect(async () =>
25
26
  encodeAsync(function () {
26
27
  // noop
27
28
  }),
@@ -37,7 +38,7 @@ test('encode bigint', async () => {
37
38
  });
38
39
 
39
40
  test('encode symbol', async () => {
40
- await expect(() => encodeAsync(Symbol('sym'))).rejects.toThrow();
41
+ await expect(async () => encodeAsync(Symbol('sym'))).rejects.toThrow();
41
42
  });
42
43
 
43
44
  test('encode undefined', async () => {
@@ -113,7 +114,7 @@ test('encode huge string', async () => {
113
114
 
114
115
  test('encode string (no encodeInto)', async () => {
115
116
  // eslint-disable-next-line @typescript-eslint/unbound-method
116
- const encodeInto = TextEncoder.prototype.encodeInto;
117
+ const { encodeInto } = TextEncoder.prototype;
117
118
  // @ts-expect-error 移除 encodeInto 以测试兼容性
118
119
  TextEncoder.prototype.encodeInto = undefined;
119
120
  expect(toArray(await encodeAsync('ubjson'))).toEqual(toArray('S', 'i', 6, 'u', 'b', 'j', 's', 'o', 'n'));
@@ -257,19 +258,19 @@ test('encode array (float64 typed array)', async () => {
257
258
  });
258
259
 
259
260
  test('encode array (uint8clamped typed array)', async () => {
260
- await expect(() => encodeAsync(new Uint8ClampedArray())).rejects.toThrow();
261
+ await expect(async () => encodeAsync(new Uint8ClampedArray())).rejects.toThrow();
261
262
  });
262
263
 
263
264
  test('encode array (uint16 typed array)', async () => {
264
- await expect(() => encodeAsync(new Uint16Array())).rejects.toThrow();
265
+ await expect(async () => encodeAsync(new Uint16Array())).rejects.toThrow();
265
266
  });
266
267
 
267
268
  test('encode array (uint32 typed array)', async () => {
268
- await expect(() => encodeAsync(new Uint32Array())).rejects.toThrow();
269
+ await expect(async () => encodeAsync(new Uint32Array())).rejects.toThrow();
269
270
  });
270
271
 
271
272
  test('encode array (uint64 typed array)', async () => {
272
- await expect(() => encodeAsync(new BigUint64Array())).rejects.toThrow();
273
+ await expect(async () => encodeAsync(new BigUint64Array())).rejects.toThrow();
273
274
  });
274
275
 
275
276
  test('encode array (int64 typed array)', async () => {
@@ -303,10 +304,10 @@ test('encode object (only null values)', async () => {
303
304
  });
304
305
 
305
306
  test('encode object (skip prototype)', async () => {
306
- const obj = Object.create({ a: 2, x: 'xx' });
307
- obj.a = 1;
308
- obj.b = 'a';
309
- obj.c = true;
307
+ const obj = /** @type {Record<string, unknown>} */ (Object.create({ a: 2, x: 'xx' }));
308
+ obj['a'] = 1;
309
+ obj['b'] = 'a';
310
+ obj['c'] = true;
310
311
  expect(toArray(await encodeAsync(obj))).toEqual(
311
312
  toArray('{', 'i', 1, 'a', 'U', 1, 'i', 1, 'b', 'C', 'a', 'i', 1, 'c', 'T', '}'),
312
313
  );
@@ -5,11 +5,12 @@ import { jest } from '@jest/globals';
5
5
  import { Readable } from 'node:stream';
6
6
  import { decoder as decodeStream, decode as decodeAsync } from '../../dist/stream/index.js';
7
7
  import { toBuffer } from '../.utils.js';
8
- import { UnexpectedEof } from '../../dist/utils.js';
8
+ import { UnexpectedEofError as UnexpectedEof } from '../../dist/helper/errors.js';
9
9
 
10
10
  /**
11
11
  * 包装为 promise
12
12
  * @param {Uint8Array} data ubjson 数据
13
+ * @returns {Promise<unknown>}
13
14
  */
14
15
  async function decode(data) {
15
16
  const readable = Readable.from([data], { objectMode: false });
@@ -19,8 +20,9 @@ async function decode(data) {
19
20
  /**
20
21
  * 包装为 promise
21
22
  * @param {import("stream").Transform} stream ubjson 流
23
+ * @returns {Promise<void>}
22
24
  */
23
- function eos(stream) {
25
+ async function eos(stream) {
24
26
  return new Promise((resolve, reject) => {
25
27
  stream.on('error', reject);
26
28
  stream.on('end', resolve);
@@ -28,7 +30,7 @@ function eos(stream) {
28
30
  }
29
31
 
30
32
  test('decode unsupported type', async () => {
31
- await expect(() => decode(toBuffer('!'))).rejects.toThrow();
33
+ await expect(async () => decode(toBuffer('!'))).rejects.toThrow();
32
34
  });
33
35
 
34
36
  test('decode undefined', async () => {
@@ -86,7 +88,7 @@ test('decode float64', async () => {
86
88
  });
87
89
 
88
90
  test('decode high-precision number [error]', async () => {
89
- await expect(() => decode(toBuffer('H', 'i', 3, '1', '.', '1'))).rejects.toThrow();
91
+ await expect(async () => decode(toBuffer('H', 'i', 3, '1', '.', '1'))).rejects.toThrow();
90
92
  });
91
93
 
92
94
  test('decode char', async () => {
@@ -102,11 +104,11 @@ test('decode empty string', async () => {
102
104
  });
103
105
 
104
106
  test('decode string (bad size) [error]', async () => {
105
- await expect(() => decode(toBuffer('S', 'i', 0xff, 'x'))).rejects.toThrow(/Invalid length/);
107
+ await expect(async () => decode(toBuffer('S', 'i', 0xff, 'x'))).rejects.toThrow(/Invalid length/);
106
108
  });
107
109
 
108
110
  test('decode string (unexpected eof) [error]', async () => {
109
- await expect(() => decode(toBuffer('S', 'i', 2, 'x'))).rejects.toThrow(UnexpectedEof);
111
+ await expect(async () => decode(toBuffer('S', 'i', 2, 'x'))).rejects.toThrow(UnexpectedEof);
110
112
  });
111
113
 
112
114
  test('decode ascii string', async () => {
@@ -129,9 +131,9 @@ test('decode huge string', async () => {
129
131
 
130
132
  test('decode huge string [int64 length]', async () => {
131
133
  expect(await decode(toBuffer('S', 'L', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 'x'))).toBe('x');
132
- await expect(() => decode(toBuffer('S', 'L', 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 'x'))).rejects.toThrow(
133
- /Invalid length/,
134
- );
134
+ await expect(async () =>
135
+ decode(toBuffer('S', 'L', 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 'x')),
136
+ ).rejects.toThrow(/Invalid length/);
135
137
  });
136
138
 
137
139
  test('decode array', async () => {
@@ -295,19 +297,19 @@ test('decode array of objects of arrays (optimized)', async () => {
295
297
  });
296
298
 
297
299
  test('decode array (strongly typed, unexpected eof, optimized)', async () => {
298
- await expect(() => decode(toBuffer('[', '$', 'i', '#', 'i', 3, 1, 2))).rejects.toThrow();
300
+ await expect(async () => decode(toBuffer('[', '$', 'i', '#', 'i', 3, 1, 2))).rejects.toThrow();
299
301
  });
300
302
 
301
303
  test('decode array (strongly typed, invalid length value, optimized)', async () => {
302
- await expect(() => decode(toBuffer('[', '$', 'i', '#', 'i', -1))).rejects.toThrow();
304
+ await expect(async () => decode(toBuffer('[', '$', 'i', '#', 'i', -1))).rejects.toThrow();
303
305
  });
304
306
 
305
307
  test('decode array (strongly typed, invalid length type, optimized)', async () => {
306
- await expect(() => decode(toBuffer('[', '$', 'i', '#', 'C', '0'))).rejects.toThrow();
308
+ await expect(async () => decode(toBuffer('[', '$', 'i', '#', 'C', '0'))).rejects.toThrow();
307
309
  });
308
310
 
309
311
  test('decode array (strongly typed, malformed, optimized)', async () => {
310
- await expect(() => decode(toBuffer('[', '$', 'i', 1, 2, 3, ']'))).rejects.toThrow();
312
+ await expect(async () => decode(toBuffer('[', '$', 'i', 1, 2, 3, ']'))).rejects.toThrow();
311
313
  });
312
314
 
313
315
  test('decode array (only null values, optimized)', async () => {
@@ -9,13 +9,14 @@ import { toArray } from '../.utils.js';
9
9
  /**
10
10
  * 包装为 promise
11
11
  * @param {unknown} value 值
12
+ * @returns {Promise<Buffer>} 返回值
12
13
  */
13
- function encodeAsync(value) {
14
+ async function encodeAsync(value) {
14
15
  return buffer(encode(value));
15
16
  }
16
17
 
17
18
  test('encode function', async () => {
18
- await expect(() =>
19
+ await expect(async () =>
19
20
  encodeAsync(function () {
20
21
  // noop
21
22
  }),
@@ -31,7 +32,7 @@ test('encode bigint', async () => {
31
32
  });
32
33
 
33
34
  test('encode symbol', async () => {
34
- await expect(() => encodeAsync(Symbol('sym'))).rejects.toThrow();
35
+ await expect(async () => encodeAsync(Symbol('sym'))).rejects.toThrow();
35
36
  });
36
37
 
37
38
  test('encode undefined', async () => {
@@ -107,7 +108,7 @@ test('encode huge string', async () => {
107
108
 
108
109
  test('encode string (no encodeInto)', async () => {
109
110
  // eslint-disable-next-line @typescript-eslint/unbound-method
110
- const encodeInto = TextEncoder.prototype.encodeInto;
111
+ const { encodeInto } = TextEncoder.prototype;
111
112
  // @ts-expect-error 移除 encodeInto 以测试兼容性
112
113
  TextEncoder.prototype.encodeInto = undefined;
113
114
  expect(toArray(await encodeAsync('ubjson'))).toEqual(toArray('S', 'i', 6, 'u', 'b', 'j', 's', 'o', 'n'));
@@ -251,19 +252,19 @@ test('encode array (float64 typed array)', async () => {
251
252
  });
252
253
 
253
254
  test('encode array (uint8clamped typed array)', async () => {
254
- await expect(() => encodeAsync(new Uint8ClampedArray())).rejects.toThrow();
255
+ await expect(async () => encodeAsync(new Uint8ClampedArray())).rejects.toThrow();
255
256
  });
256
257
 
257
258
  test('encode array (uint16 typed array)', async () => {
258
- await expect(() => encodeAsync(new Uint16Array())).rejects.toThrow();
259
+ await expect(async () => encodeAsync(new Uint16Array())).rejects.toThrow();
259
260
  });
260
261
 
261
262
  test('encode array (uint32 typed array)', async () => {
262
- await expect(() => encodeAsync(new Uint32Array())).rejects.toThrow();
263
+ await expect(async () => encodeAsync(new Uint32Array())).rejects.toThrow();
263
264
  });
264
265
 
265
266
  test('encode array (uint64 typed array)', async () => {
266
- await expect(() => encodeAsync(new BigUint64Array())).rejects.toThrow();
267
+ await expect(async () => encodeAsync(new BigUint64Array())).rejects.toThrow();
267
268
  });
268
269
 
269
270
  test('encode array (int64 typed array)', async () => {
@@ -14,7 +14,8 @@ function iterableToAsyncIterable(iterable) {
14
14
  [Symbol.asyncIterator]: () => {
15
15
  const iterator = iterable[Symbol.iterator]();
16
16
  return {
17
- next: () => Promise.resolve(iterator.next()),
17
+ // eslint-disable-next-line unicorn/no-useless-promise-resolve-reject
18
+ next: async () => Promise.resolve(iterator.next()),
18
19
  };
19
20
  },
20
21
  };
@@ -1,14 +1,12 @@
1
1
  import { Encoder } from '../dist/encoder.js';
2
- import { decode, decodeKey, jsDecode } from '../dist/common/string-decoder.js';
3
- import '../dist/common/constants.js';
2
+ import { decode, decodeKey, jsDecode } from '../dist/helper/string-decoder.js';
4
3
 
5
4
  /**
6
5
  * 测试编码
6
+ * @param {Pick<TextEncoder, 'encode'>} encoder encoder
7
+ * @param {Pick<TextDecoder, 'decode'>} decoder decoder
7
8
  */
8
- function testEncoding(
9
- /** @type {Pick<TextEncoder, 'encode'>} */ encoder,
10
- /** @type {Pick<TextDecoder, 'decode'>} */ decoder,
11
- ) {
9
+ function testEncoding(encoder, decoder) {
12
10
  expect(decoder.decode(encoder.encode(''))).toEqual('');
13
11
  expect(decoder.decode(encoder.encode('a'))).toEqual('a');
14
12
  expect(decoder.decode(encoder.encode('p4'))).toEqual('p4');
@@ -1,81 +0,0 @@
1
- import { load } from '@cloudpss/yaml';
2
- import { encode, decode } from './dist/index.js';
3
- import { encode as encodeAsync } from './dist/stream/index.js';
4
- import { encode as oldEncode, decode as oldDecode } from 'ref-impl';
5
- import { encode as oldEncodeAsync } from 'ref-impl/stream';
6
- import lodash from 'lodash';
7
-
8
- const LOOP = 100000;
9
- const WARM_UP = 10000;
10
-
11
- const t = (/** @type {number} */ time) => (time * 1_000_000).toFixed(2).padStart(6) + 'ns';
12
-
13
- /* eslint-disable no-console */
14
- const obj = decode(
15
- encode(
16
- load(`
17
- verb: create
18
- type: plot
19
- key: plot-0
20
- version: 1
21
- data: {title: 三台电机转速wr, traces: [{name: '#wr1:0', type: scatter, x: !!js/Float64Array +anx0k1iUD8AqvHSTWJgP/B+arx0k2g/8Knx0k1icD9oFK5H4Xp0P+B+arx0k3g/WOkmMQisfD/sqfHSTWKAPzzfT42XboI/jBSuR+F6hD8=, 'y': !!js/Float64Array AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8=}, {name: '#wr2:0', type: scatter, x: !!js/Float64Array +anx0k1iUD8AqvHSTWJgP/B+arx0k2g/8Knx0k1icD9oFK5H4Xp0P+B+arx0k3g/WOkmMQisfD/sqfHSTWKAPzzfT42XboI/jBSuR+F6hD8=, 'y': !!js/Float64Array AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8=}, {name: '#wr3:0', type: scatter, x: !!js/Float64Array +anx0k1iUD8AqvHSTWJgP/B+arx0k2g/8Knx0k1icD9oFK5H4Xp0P+B+arx0k3g/WOkmMQisfD/sqfHSTWKAPzzfT42XboI/jBSuR+F6hD8=, 'y': !!js/Float64Array AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8AAAAAAADwPwAAAAAAAPA/AAAAAAAA8D8=}]}
22
- `),
23
- ),
24
- );
25
-
26
- const impl = [
27
- ['REF', oldEncode, oldDecode, oldEncodeAsync],
28
- ['CURRENT', encode, decode, encodeAsync],
29
- ];
30
-
31
- async function run() {
32
- let encodeTime = {};
33
- let encodeAsyncTime = {};
34
- let decodeTime = {};
35
- let obj2 = {};
36
- for (const [name] of impl) {
37
- encodeTime[name] = 0;
38
- encodeAsyncTime[name] = 0;
39
- decodeTime[name] = 0;
40
- }
41
- for (let i = 0; i < WARM_UP; i++) {
42
- for (const [, encode, decode, encodeAsync] of impl) {
43
- const encoded = encode(obj);
44
- for await (const _piece of encodeAsync(obj)) {
45
- continue;
46
- }
47
- decode(encoded);
48
- }
49
- }
50
- for (let i = 0; i < LOOP; i++) {
51
- for (const [name, encode, decode, encodeAsync] of impl) {
52
- let start = performance.now();
53
- const encoded = encode(obj);
54
- encodeTime[name] += performance.now() - start;
55
-
56
- start = performance.now();
57
- for await (const _piece of encodeAsync(obj)) {
58
- continue;
59
- }
60
- encodeAsyncTime[name] += performance.now() - start;
61
-
62
- start = performance.now();
63
- obj2[name] = decode(encoded);
64
- decodeTime[name] += performance.now() - start;
65
- }
66
- }
67
- for (const [name] of impl) {
68
- console.assert(lodash.isEqual(obj, obj2[name]));
69
- }
70
- for (const [name] of impl) {
71
- console.log(
72
- `${name}\tencode: ${t(encodeTime[name] / LOOP)}\tencode stream: ${t(
73
- encodeAsyncTime[name] / LOOP,
74
- )}\tdecode: ${t(decodeTime[name] / LOOP)}`,
75
- );
76
- }
77
- }
78
-
79
- await run();
80
-
81
- console.log('');
@@ -1,41 +0,0 @@
1
- import { nativeDecode, decode, jsDecode } from './dist/common/string-decoder.js';
2
-
3
- const LOOP = 500000;
4
-
5
- const t = (/** @type {number} */ time) => time.toFixed(10) + 'ms';
6
-
7
- /** 测试数据 */
8
- function createTestData(/** @type {number} */ size) {
9
- return new Uint8Array(size).fill(50);
10
- }
11
-
12
- /* eslint-disable no-console */
13
-
14
- console.log(` Size\tTextDecoder MyStringDecoder my/sys%\tJsDecoder js/sys%`);
15
- for (let index = 10; index < 1000; index = Math.trunc(index * 1.2)) {
16
- const data = createTestData(index);
17
-
18
- let decodeTimeSystem = 0;
19
- let decodeTimeOptimal = 0;
20
- let decodeTimeJs = 0;
21
- for (let i = 0; i < LOOP; i++) {
22
- let start = performance.now();
23
- nativeDecode(data);
24
- decodeTimeSystem += performance.now() - start;
25
-
26
- start = performance.now();
27
- decode(data, 0, data.byteLength);
28
- decodeTimeOptimal += performance.now() - start;
29
-
30
- start = performance.now();
31
- jsDecode(data, 0, data.byteLength);
32
- decodeTimeJs += performance.now() - start;
33
- }
34
- const ratioOptimal = decodeTimeOptimal / decodeTimeSystem;
35
- const ratioJs = decodeTimeJs / decodeTimeSystem;
36
- console.log(
37
- `Data: ${data.byteLength} \t${t(decodeTimeSystem / LOOP)} ${t(decodeTimeOptimal / LOOP)} ${(
38
- ratioOptimal * 100
39
- ).toFixed(3)}%\t${t(decodeTimeJs / LOOP)} ${(ratioJs * 100).toFixed(3)}%`,
40
- );
41
- }
@@ -1,32 +0,0 @@
1
- import { jsEncodeInto, nativeEncodeInto } from './dist/common/string-encoder.js';
2
-
3
- const LOOP = 500000;
4
-
5
- const t = (/** @type {number} */ time) => time.toFixed(10) + 'ms';
6
-
7
- /** 测试数据 */
8
- function createTestData(/** @type {number} */ size) {
9
- return ['a'.repeat(size), 'Ӓ'.repeat(size / 2), '水'.repeat(size / 3), 'aӒ水'.repeat(size / 6)];
10
- }
11
-
12
- /* eslint-disable no-console */
13
-
14
- console.log(` Size\tnativeEncodeInto \tjsEncodeInto \tmy/sys%`);
15
- for (let index = 10; index < 1000; index = Math.trunc(index * 1.2)) {
16
- const data1 = createTestData(index)[0];
17
- const buf = new Uint8Array(index + 10);
18
-
19
- let encodeSystem = 0;
20
- let encodeJs = 0;
21
- for (let i = 0; i < LOOP; i++) {
22
- let start = performance.now();
23
- nativeEncodeInto(data1, buf, 1);
24
- encodeSystem += performance.now() - start;
25
-
26
- start = performance.now();
27
- jsEncodeInto(data1, buf, 1);
28
- encodeJs += performance.now() - start;
29
- }
30
- const ratioJs = encodeJs / encodeSystem;
31
- console.log(`Data: ${index} \t${t(encodeSystem / LOOP)} ${t(encodeJs / LOOP)} ${(ratioJs * 100).toFixed(3)}%`);
32
- }
@@ -1,50 +0,0 @@
1
- import prettyBytes from 'pretty-bytes';
2
- import { jsStringByteLength, nodeStringByteLength } from './dist/common/string-encoder.js';
3
-
4
- const LOOP = 100;
5
-
6
- const t = (/** @type {number} */ time) => time.toFixed(6) + 'ms';
7
- const pb = (/** @type {number} */ size) => prettyBytes(size, { binary: true });
8
-
9
- /** 测试数据 */
10
- function createTestData(/** @type {number} */ size) {
11
- return ['a'.repeat(size), 'Ӓ'.repeat(size / 2), '水'.repeat(size / 3), 'aӒ水'.repeat(size / 6)];
12
- }
13
-
14
- /* eslint-disable no-console */
15
-
16
- console.log(`Size \tTime1 \tTime2 \tTime3 \tTimeMixed`);
17
-
18
- for (const i of [8, 16, 32, 64, 256, 1024, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576]) {
19
- const [data1, data2, data3, dataMixed] = createTestData(i);
20
- for (const withBuffer of [true, false]) {
21
- const encode = withBuffer ? nodeStringByteLength : jsStringByteLength;
22
- let size;
23
- let time1 = 0,
24
- time2 = 0,
25
- time3 = 0,
26
- timeMixed = 0;
27
- for (let i = 0; i < LOOP; i++) {
28
- let start = performance.now();
29
- size = encode(data1);
30
- time1 += performance.now() - start;
31
-
32
- start = performance.now();
33
- size = encode(data2);
34
- time2 += performance.now() - start;
35
-
36
- start = performance.now();
37
- size = encode(data3);
38
- time3 += performance.now() - start;
39
-
40
- start = performance.now();
41
- size = encode(dataMixed);
42
- timeMixed += performance.now() - start;
43
- }
44
- console.log(
45
- `[${withBuffer ? 'w/ ' : 'w/o'} buffer] ${pb(size)}\t${t(time1 / LOOP)} \t${t(time2 / LOOP)} \t${t(
46
- time3 / LOOP,
47
- )} \t${t(timeMixed / LOOP)}`,
48
- );
49
- }
50
- }