@cloudpss/ubjson 0.6.0-alpha.8 → 0.6.0-alpha.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudpss/ubjson",
3
- "version": "0.6.0-alpha.8",
3
+ "version": "0.6.0-alpha.9",
4
4
  "author": "CloudPSS",
5
5
  "license": "MIT",
6
6
  "keywords": [
package/tests/.utils.ts CHANGED
@@ -7,7 +7,7 @@ import '../dist/options.js';
7
7
  /**
8
8
  * 重设所有环境
9
9
  */
10
- export function resetEnv() {
10
+ export function resetEnv(): void {
11
11
  resetDecoderEnv();
12
12
  resetEncoderEnv();
13
13
  resetEncoder();
@@ -15,25 +15,26 @@ export function resetEnv() {
15
15
 
16
16
  /**
17
17
  * 输入转为数字数组以便比较
18
- * @param {[ArrayBuffer] | [Uint8Array] | (number | string)[]} args 输入
19
- * @returns {number[]} 数字数组
18
+ * @param args 输入
19
+ * @returns 数字数组
20
20
  */
21
- export function toArray(...args) {
21
+ export function toArray(...args: [ArrayBuffer] | [Uint8Array] | Array<number | string>): number[] {
22
22
  if (args[0] instanceof ArrayBuffer) {
23
23
  return Array.from(new Uint8Array(args[0]));
24
24
  }
25
25
  if (args[0] instanceof Uint8Array) {
26
26
  return Array.from(args[0]);
27
27
  }
28
- return args.map((x) => (typeof x == 'number' ? x : /** @type {string} */ (x).charCodeAt(0)));
28
+ // eslint-disable-next-line unicorn/prefer-code-point
29
+ return args.map((x) => (typeof x == 'number' ? x : (x as string).charCodeAt(0)));
29
30
  }
30
31
 
31
32
  /**
32
33
  * 将数字或字符串转换为 Uint8Array
33
- * @param {...string | number} args 数字或 char 的数组
34
- * @returns {Uint8Array} Uint8Array
34
+ * @param args 数字或 char 的数组
35
+ * @returns Uint8Array
35
36
  */
36
- export function toBuffer(...args) {
37
+ export function toBuffer(...args: Array<string | number>): Uint8Array<ArrayBuffer> {
37
38
  const data = [];
38
39
  for (const x of args) {
39
40
  if (typeof x == 'number') {
package/tests/decode.ts CHANGED
@@ -141,6 +141,7 @@ test('decode huge string (unexpected eof) [error]', () => {
141
141
 
142
142
  test('decode ascii string', () => {
143
143
  const header = toBuffer('S', 'I', 0x3f, 0xff);
144
+ // eslint-disable-next-line unicorn/prefer-code-point
144
145
  const payload = new Uint8Array(0x3fff + header.byteLength).fill('a'.charCodeAt(0));
145
146
  payload.set(header);
146
147
  expect(decode(payload)).toBe('a'.repeat(0x3fff));
@@ -148,6 +149,7 @@ test('decode ascii string', () => {
148
149
 
149
150
  test('decode ascii string [huge]', () => {
150
151
  const header = toBuffer('S', 'I', 0x7f, 0xff);
152
+ // eslint-disable-next-line unicorn/prefer-code-point
151
153
  const payload = new Uint8Array(0x7fff + header.byteLength).fill('a'.charCodeAt(0));
152
154
  payload.set(header);
153
155
  expect(decode(payload)).toBe('a'.repeat(0x7fff));
@@ -507,19 +509,16 @@ test('decode (eof at key)', () => {
507
509
 
508
510
  describe('proto poisoning attack', () => {
509
511
  it('should remove __proto__ key', () => {
510
- const obj = /** @type {Record<string, unknown>} */ decode(
512
+ const obj = decode(
511
513
  toBuffer('{', 'i', 9, '__proto__', '{', 'i', 1, 'a', 'S', 'i', 3, 'abc', '}', '}'),
512
- );
514
+ ) as Record<string, unknown>;
513
515
  expect(Object.hasOwn(obj, '__proto__')).toBe(false);
514
516
  expect(obj['__proto__']).toBe(Object.prototype);
515
517
  });
516
518
  it('should allow __proto__ key', () => {
517
- const obj = /** @type {Record<string, unknown>} */ decode(
518
- toBuffer('{', 'i', 9, '__proto__', '{', 'i', 1, 'a', 'S', 'i', 3, 'abc', '}', '}'),
519
- {
520
- protoAction: 'allow',
521
- },
522
- );
519
+ const obj = decode(toBuffer('{', 'i', 9, '__proto__', '{', 'i', 1, 'a', 'S', 'i', 3, 'abc', '}', '}'), {
520
+ protoAction: 'allow',
521
+ }) as Record<string, unknown>;
523
522
  expect(Object.hasOwn(obj, '__proto__')).toBe(true);
524
523
  expect(obj['__proto__']).toEqual({ a: 'abc' });
525
524
  });
@@ -534,19 +533,16 @@ describe('proto poisoning attack', () => {
534
533
 
535
534
  describe('constructor poisoning attack', () => {
536
535
  it('should remove constructor key', () => {
537
- const obj = /** @type {Record<string, unknown>} */ decode(
538
- toBuffer('{', 'i', 11, 'constructor', '{', 'i', 1, 'a', 'S', 'i', 3, 'abc', '}', '}'),
539
- {
540
- constructorAction: 'remove',
541
- },
542
- );
536
+ const obj = decode(toBuffer('{', 'i', 11, 'constructor', '{', 'i', 1, 'a', 'S', 'i', 3, 'abc', '}', '}'), {
537
+ constructorAction: 'remove',
538
+ }) as Record<string, unknown>;
543
539
  expect(Object.hasOwn(obj, 'constructor')).toBe(false);
544
540
  expect(obj.constructor).toBe(Object);
545
541
  });
546
542
  it('should allow constructor key', () => {
547
- const obj = /** @type {Record<string, unknown>} */ decode(
543
+ const obj = decode(
548
544
  toBuffer('{', 'i', 11, 'constructor', '{', 'i', 1, 'a', 'S', 'i', 3, 'abc', '}', '}'),
549
- );
545
+ ) as Record<string, unknown>;
550
546
  expect(Object.hasOwn(obj, 'constructor')).toBe(true);
551
547
  expect(obj.constructor).toEqual({ a: 'abc' });
552
548
  });
@@ -8,15 +8,15 @@ describe('stream', () => {
8
8
  const expected = EXPECTED[name] ?? input;
9
9
  if (expected instanceof Error) {
10
10
  await expect(async () => {
11
- const encoded = await Readable.fromWeb(/** @type {any} */ encodeStream(input)).toArray();
11
+ const encoded = await Readable.fromWeb(encodeStream(input) as never).toArray();
12
12
  const decoded = await decodeStream(
13
- /** @type {ReadableStream<Uint8Array>} */ Readable.toWeb(Readable.from(encoded)),
13
+ Readable.toWeb(Readable.from(encoded)) as ReadableStream<Uint8Array<ArrayBuffer>>,
14
14
  );
15
15
  expect(decoded).toEqual(expected);
16
16
  }).rejects.toThrow(expected);
17
17
  } else {
18
- const encoded = await Readable.fromWeb(/** @type {any} */ encodeStream(input)).toArray();
19
- const data = encoded.flatMap((/** @type {Buffer} */ chunk) => {
18
+ const encoded = await Readable.fromWeb(encodeStream(input) as never).toArray();
19
+ const data = encoded.flatMap((chunk: Buffer<ArrayBuffer>) => {
20
20
  if (chunk.length < 2) return [chunk];
21
21
  // split to random chunks
22
22
  const chunks = [];
@@ -29,7 +29,7 @@ describe('stream', () => {
29
29
  return chunks;
30
30
  });
31
31
  const decoded = await decodeStream(
32
- /** @type {ReadableStream<Uint8Array>} */ Readable.toWeb(Readable.from(data)),
32
+ Readable.toWeb(Readable.from(data)) as ReadableStream<Uint8Array<ArrayBuffer>>,
33
33
  );
34
34
  expect(decoded).toEqual(expected);
35
35
  }
package/tests/encode.ts CHANGED
@@ -7,7 +7,7 @@ import { getEncoder } from '../dist/encoder.js';
7
7
  import { toArray } from './.utils.ts';
8
8
 
9
9
  // @ts-expect-error Access private property
10
- const poolInit = getEncoder().pool;
10
+ const poolInit = getEncoder().pool as Uint8Array<ArrayBuffer>;
11
11
 
12
12
  test('encode function', () => {
13
13
  expect(() =>
@@ -444,10 +444,10 @@ test('encode object (only null values)', () => {
444
444
  });
445
445
 
446
446
  test('encode object (skip prototype)', () => {
447
- const obj = Object.create({ a: 2, x: 'xx' });
448
- obj.a = 1;
449
- obj.b = 'a';
450
- obj.c = true;
447
+ const obj = Object.create({ a: 2, x: 'xx' }) as Record<string, unknown>;
448
+ obj['a'] = 1;
449
+ obj['b'] = 'a';
450
+ obj['c'] = true;
451
451
  expect(toArray(encode(obj))).toEqual(
452
452
  toArray('{', 'i', 1, 'a', 'U', 1, 'i', 1, 'b', 'C', 'a', 'i', 1, 'c', 'T', '}'),
453
453
  );
@@ -6,11 +6,8 @@ const STR_BYTE_LENGTH = 128 * 1024 * 1024 - 20;
6
6
 
7
7
  /**
8
8
  * 构造测试字符串
9
- * @param {string} char 使用的字符
10
- * @param {number} byteLength 需要的长度
11
- * @returns {[Uint8Array, string]}
12
9
  */
13
- function makeString(char, byteLength) {
10
+ function makeString(char: string, byteLength: number): [Uint8Array<ArrayBuffer>, string] {
14
11
  const encoded = new TextEncoder().encode(char);
15
12
  return [encoded, char.repeat(byteLength / encoded.byteLength)];
16
13
  }
@@ -2,28 +2,24 @@
2
2
  * Tests from https://bitbucket.org/shelacek/ubjson
3
3
  */
4
4
  import { jest } from '@jest/globals';
5
- import { firstValueFrom, of, Subject } from 'rxjs';
5
+ import { firstValueFrom, type Observable, of, Subject } from 'rxjs';
6
6
  import { decode as decodePipe } from '../../dist/rxjs/index.js';
7
7
  import { toBuffer } from '../.utils.ts';
8
8
  import { UnexpectedEofError as UnexpectedEof } from '../../dist/helper/errors.js';
9
9
 
10
10
  /**
11
11
  * 包装为 promise
12
- * @param {Uint8Array} data ubjson 数据
13
- * @returns {Promise<unknown>}
14
12
  */
15
- async function decode(data) {
13
+ async function decode(data: BufferSource): Promise<unknown> {
16
14
  const readable = of(data);
17
15
  return firstValueFrom(readable.pipe(decodePipe()), { defaultValue: undefined });
18
16
  }
19
17
 
20
18
  /**
21
19
  * 包装为 promise
22
- * @param {import("rxjs").Observable<Uint8Array>} observable ubjson 数据流
23
- * @param {(data: unknown) => void} onData 数据回调
24
20
  */
25
- async function decodeStream(observable, onData) {
26
- return /** @type {Promise<void>} */ new Promise((resolve, reject) => {
21
+ async function decodeStream(observable: Observable<BufferSource>, onData: (data: unknown) => void) {
22
+ return new Promise<void>((resolve, reject) => {
27
23
  observable.pipe(decodePipe()).subscribe({
28
24
  next: onData,
29
25
  error: reject,
@@ -115,6 +111,7 @@ test('decode string (unexpected eof) [error]', async () => {
115
111
 
116
112
  test('decode ascii string', async () => {
117
113
  const header = toBuffer('S', 'I', 0x3f, 0xff);
114
+ // eslint-disable-next-line unicorn/prefer-code-point
118
115
  const payload = new Uint8Array(0x3fff + header.byteLength).fill('a'.charCodeAt(0));
119
116
  payload.set(header);
120
117
  expect(await decode(payload)).toBe('a'.repeat(0x3fff));
@@ -123,6 +120,7 @@ test('decode ascii string', async () => {
123
120
  test('decode ascii string 32kiB [huge]', async () => {
124
121
  const size = 0x7fff;
125
122
  const header = toBuffer('S', 'I', 0x7f, 0xff);
123
+ // eslint-disable-next-line unicorn/prefer-code-point
126
124
  const payload = new Uint8Array(size + header.byteLength).fill('a'.charCodeAt(0));
127
125
  payload.set(header);
128
126
  expect(await decode(payload)).toBe('a'.repeat(size));
@@ -131,6 +129,7 @@ test('decode ascii string 32kiB [huge]', async () => {
131
129
  test('decode ascii string 64MB [huge]', async () => {
132
130
  const size = 0x03d0_9000;
133
131
  const header = toBuffer('S', 'l', 0x03, 0xd0, 0x90, 0x00);
132
+ // eslint-disable-next-line unicorn/prefer-code-point
134
133
  const payload = new Uint8Array(size + header.byteLength).fill('a'.charCodeAt(0));
135
134
  payload.set(header);
136
135
  expect(await decode(payload)).toBe('a'.repeat(size));
@@ -467,7 +466,7 @@ test('decode object (empty key, optimized)', async () => {
467
466
  });
468
467
 
469
468
  test('decode stream', async () => {
470
- const stream = new Subject();
469
+ const stream = new Subject<BufferSource>();
471
470
  // while decoding streaming, N will be regarded as a no-op, rather than an undefined value
472
471
  const onData = jest.fn();
473
472
  const result = decodeStream(stream, onData);
@@ -485,7 +484,7 @@ test('decode stream', async () => {
485
484
  });
486
485
 
487
486
  test('decode bad stream [error]', async () => {
488
- const stream = new Subject();
487
+ const stream = new Subject<BufferSource>();
489
488
  // while decoding streaming, N will be regarded as a no-op, rather than an undefined value
490
489
  const onData = jest.fn();
491
490
  const result = decodeStream(stream, onData);
@@ -504,7 +503,7 @@ test('decode bad stream [error]', async () => {
504
503
  });
505
504
 
506
505
  test('decode partial stream [error]', async () => {
507
- const stream = new Subject();
506
+ const stream = new Subject<BufferSource>();
508
507
  // while decoding streaming, N will be regarded as a no-op, rather than an undefined value
509
508
  const onData = jest.fn();
510
509
  const result = decodeStream(stream, onData);
@@ -520,7 +519,7 @@ test('decode partial stream [error]', async () => {
520
519
  });
521
520
 
522
521
  test('decode error stream [error]', async () => {
523
- const stream = new Subject();
522
+ const stream = new Subject<BufferSource>();
524
523
  // while decoding streaming, N will be regarded as a no-op, rather than an undefined value
525
524
  const onData = jest.fn();
526
525
  const result = decodeStream(stream, onData);
@@ -8,10 +8,8 @@ import { toArray } from '../.utils.ts';
8
8
 
9
9
  /**
10
10
  * 包装为 promise
11
- * @param {unknown} value 要编码的值
12
- * @returns {Promise<Buffer>}
13
11
  */
14
- async function encodeAsync(value) {
12
+ async function encodeAsync(value: unknown): Promise<Buffer<ArrayBuffer>> {
15
13
  return firstValueFrom(
16
14
  of(value).pipe(
17
15
  encode(),
@@ -304,7 +302,7 @@ test('encode object (only null values)', async () => {
304
302
  });
305
303
 
306
304
  test('encode object (skip prototype)', async () => {
307
- const obj = /** @type {Record<string, unknown>} */ Object.create({ a: 2, x: 'xx' });
305
+ const obj = Object.create({ a: 2, x: 'xx' }) as Record<string, unknown>;
308
306
  obj['a'] = 1;
309
307
  obj['b'] = 'a';
310
308
  obj['c'] = true;
@@ -9,20 +9,16 @@ import { UnexpectedEofError as UnexpectedEof } from '../../dist/helper/errors.js
9
9
 
10
10
  /**
11
11
  * 包装为 promise
12
- * @param {Uint8Array} data ubjson 数据
13
- * @returns {Promise<unknown>}
14
12
  */
15
- async function decode(data) {
13
+ async function decode(data: Uint8Array<ArrayBuffer>): Promise<unknown> {
16
14
  const readable = Readable.from([data], { objectMode: false });
17
- return decodeAsync(/** @type {ReadableStream<Uint8Array>} */ Readable.toWeb(readable));
15
+ return decodeAsync(Readable.toWeb(readable) as ReadableStream<Uint8Array<ArrayBuffer>>);
18
16
  }
19
17
 
20
18
  /**
21
19
  * 包装为 promise
22
- * @param {import("stream").Readable} stream ubjson 流
23
- * @returns {Promise<void>}
24
20
  */
25
- async function eos(stream) {
21
+ async function eos(stream: Readable): Promise<void> {
26
22
  return new Promise((resolve, reject) => {
27
23
  stream.on('error', reject);
28
24
  stream.on('end', resolve);
@@ -113,6 +109,7 @@ test('decode string (unexpected eof) [error]', async () => {
113
109
 
114
110
  test('decode ascii string', async () => {
115
111
  const header = toBuffer('S', 'I', 0x3f, 0xff);
112
+ // eslint-disable-next-line unicorn/prefer-code-point
116
113
  const payload = new Uint8Array(0x3fff + header.byteLength).fill('a'.charCodeAt(0));
117
114
  payload.set(header);
118
115
  expect(await decode(payload)).toBe('a'.repeat(0x3fff));
@@ -120,6 +117,7 @@ test('decode ascii string', async () => {
120
117
 
121
118
  test('decode ascii string [huge]', async () => {
122
119
  const header = toBuffer('S', 'I', 0x7f, 0xff);
120
+ // eslint-disable-next-line unicorn/prefer-code-point
123
121
  const payload = new Uint8Array(0x7fff + header.byteLength).fill('a'.charCodeAt(0));
124
122
  payload.set(header);
125
123
  expect(await decode(payload)).toBe('a'.repeat(0x7fff));
@@ -456,7 +454,7 @@ test('decode object (empty key, optimized)', async () => {
456
454
  });
457
455
 
458
456
  test('decode stream', async () => {
459
- const stream = Transform.fromWeb(/** @type {any} */ decodeStream(), { objectMode: true });
457
+ const stream = Transform.fromWeb(decodeStream() as never, { objectMode: true });
460
458
  // while decoding streaming, N will be regarded as a no-op, rather than an undefined value
461
459
  const onData = jest.fn();
462
460
  stream.on('data', onData);
@@ -499,7 +497,7 @@ test('decode bad stream [error]', async () => {
499
497
  });
500
498
 
501
499
  test('decode partial stream [error]', async () => {
502
- const stream = Transform.fromWeb(/** @type {any} */ decodeStream(), { objectMode: true });
500
+ const stream = Transform.fromWeb(decodeStream() as never, { objectMode: true });
503
501
  // while decoding streaming, N will be regarded as a no-op, rather than an undefined value
504
502
  const onData = jest.fn();
505
503
  stream.on('data', onData);
@@ -9,11 +9,9 @@ import { Transform } from 'node:stream';
9
9
 
10
10
  /**
11
11
  * 包装为 promise
12
- * @param {unknown} value 值
13
- * @returns {Promise<Buffer>} 返回值
14
12
  */
15
- async function encodeAsync(value) {
16
- return buffer(encode(value));
13
+ async function encodeAsync(value: unknown): Promise<Buffer<ArrayBuffer>> {
14
+ return (await buffer(encode(value))) as Buffer<ArrayBuffer>;
17
15
  }
18
16
 
19
17
  test('encode function', async () => {
@@ -299,10 +297,10 @@ test('encode object (only null values)', async () => {
299
297
  });
300
298
 
301
299
  test('encode object (skip prototype)', async () => {
302
- const obj = Object.create({ a: 2, x: 'xx' });
303
- obj.a = 1;
304
- obj.b = 'a';
305
- obj.c = true;
300
+ const obj = Object.create({ a: 2, x: 'xx' }) as Record<string, unknown>;
301
+ obj['a'] = 1;
302
+ obj['b'] = 'a';
303
+ obj['c'] = true;
306
304
  expect(toArray(await encodeAsync(obj))).toEqual(
307
305
  toArray('{', 'i', 1, 'a', 'U', 1, 'i', 1, 'b', 'C', 'a', 'i', 1, 'c', 'T', '}'),
308
306
  );
@@ -364,7 +362,7 @@ test('encode huge data (~128M)', async () => {
364
362
  });
365
363
 
366
364
  test('encode stream', async () => {
367
- const stream = Transform.fromWeb(/** @type {any} */ encoder(), { objectMode: true });
365
+ const stream = Transform.fromWeb(encoder() as never, { objectMode: true });
368
366
  stream.write(undefined);
369
367
  stream.write(true);
370
368
  stream.write(false);
@@ -1,15 +1,13 @@
1
1
  import { Readable } from 'node:stream';
2
+ import type { ReadableStream as ReadableStream2 } from 'node:stream/web';
2
3
  import { encodeMany, decodeMany } from '../../dist/stream/index.js';
3
4
  import { buffer } from 'node:stream/consumers';
4
5
  import { finished } from 'node:stream/promises';
5
6
 
6
7
  /**
7
8
  * iterableToAsyncIterable
8
- * @template T
9
- * @param {Iterable<T>} iterable - iterable
10
- * @returns {AsyncIterable<T>} async iterable
11
9
  */
12
- function iterableToAsyncIterable(iterable) {
10
+ function iterableToAsyncIterable<T>(iterable: Iterable<T>): AsyncIterable<T> {
13
11
  return {
14
12
  [Symbol.asyncIterator]: () => {
15
13
  const iterator = iterable[Symbol.iterator]();
@@ -23,12 +21,9 @@ function iterableToAsyncIterable(iterable) {
23
21
 
24
22
  /**
25
23
  * asyncIterableToArray
26
- * @template T
27
- * @param {AsyncIterable<T>} asyncIterable - async iterable
28
- * @returns {Promise<Array<T>>} array
29
24
  */
30
- async function asyncIterableToArray(asyncIterable) {
31
- const array = [];
25
+ async function asyncIterableToArray<T>(asyncIterable: AsyncIterable<T>): Promise<T[]> {
26
+ const array: T[] = [];
32
27
  for await (const item of asyncIterable) {
33
28
  array.push(item);
34
29
  }
@@ -53,7 +48,7 @@ test('encode/decode many', async () => {
53
48
  ];
54
49
  const encoded = await buffer(encodeMany(iterableToAsyncIterable(data)));
55
50
  const decoded = await asyncIterableToArray(
56
- decodeMany(/** @type {ReadableStream<Uint8Array>} */ (Readable.toWeb(Readable.from([encoded])))),
51
+ decodeMany(Readable.toWeb(Readable.from([encoded])) as ReadableStream<Uint8Array<ArrayBuffer>>),
57
52
  );
58
53
  expect(decoded).toEqual([
59
54
  {
@@ -74,7 +69,7 @@ test('encode/decode many', async () => {
74
69
 
75
70
  test('encode/decode many with invalid value', async () => {
76
71
  await expect(async () => {
77
- const readable = Readable.fromWeb(/** @type {any} */ (encodeMany(iterableToAsyncIterable([1, () => 1]))));
72
+ const readable = Readable.fromWeb(encodeMany(iterableToAsyncIterable([1, () => 1])) as ReadableStream2);
78
73
  const f = finished(readable);
79
74
  readable.resume();
80
75
  await f;
@@ -82,31 +77,25 @@ test('encode/decode many with invalid value', async () => {
82
77
  });
83
78
 
84
79
  test('encode/decode many with error', async () => {
85
- // await expect(async () => {
86
- // try {
87
- // const stream = encodeMany(
88
- // (async function* () {
89
- // yield 1;
90
- // await Promise.resolve();
91
- // // throw new Error('xx');
92
- // })(),
93
- // );
94
- // const f = finished(/** @type {any} */ (stream));
95
- // for await (const _ of stream) {
96
- // //
97
- // }
98
- // await f;
99
- // } catch (ex) {
100
- // console.log(ex);
101
- // }
102
- // }).rejects.toThrow('xx');
80
+ await expect(async () => {
81
+ const stream = encodeMany(
82
+ (async function* () {
83
+ yield 1;
84
+ await Promise.resolve();
85
+ throw new Error('test error');
86
+ })(),
87
+ );
88
+ for await (const _ of stream) {
89
+ //
90
+ }
91
+ }).rejects.toThrow('test error');
103
92
  });
104
93
 
105
94
  test('encode/decode many with undefined', async () => {
106
95
  const data = [1, null, undefined, [undefined]];
107
96
  const encoded = await buffer(encodeMany(iterableToAsyncIterable(data)));
108
97
  const decoded = await asyncIterableToArray(
109
- decodeMany(/** @type {ReadableStream<Uint8Array>} */ (Readable.toWeb(Readable.from([encoded])))),
98
+ decodeMany(Readable.toWeb(Readable.from([encoded])) as ReadableStream<Uint8Array<ArrayBuffer>>),
110
99
  );
111
100
  expect(decoded).toEqual([
112
101
  1,
@@ -2,11 +2,9 @@ import { Encoder } from '../dist/encoder.js';
2
2
  import { decode, jsDecode } from '../dist/helper/string-decoder.js';
3
3
 
4
4
  /**
5
- * 测试编码
6
- * @param {Pick<TextEncoder, 'encode'>} encoder encoder
7
- * @param {Pick<TextDecoder, 'decode'>} decoder decoder
5
+ * 测试编码器和解码器
8
6
  */
9
- function testEncoding(encoder, decoder) {
7
+ function testEncoding(encoder: Pick<TextEncoder, 'encode'>, decoder: Pick<TextDecoder, 'decode'>) {
10
8
  expect(decoder.decode(encoder.encode(''))).toEqual('');
11
9
  expect(decoder.decode(encoder.encode('a'))).toEqual('a');
12
10
  expect(decoder.decode(encoder.encode('p4'))).toEqual('p4');
@@ -46,6 +44,7 @@ function testEncoding(encoder, decoder) {
46
44
  bad.fill(0xff);
47
45
  expect(decoder.decode(bad)).toEqual('\uFFFD'.repeat(length));
48
46
 
47
+ // eslint-disable-next-line unicorn/prefer-code-point
49
48
  bad.fill('a'.charCodeAt(0), 0, length - 1);
50
49
  expect(decoder.decode(bad)).toEqual('a'.repeat(length - 1) + '\uFFFD');
51
50
  }
@@ -55,6 +54,7 @@ function testEncoding(encoder, decoder) {
55
54
  for (let index = 0; index < 0xffff; index++) {
56
55
  // 跳过 Surrogate
57
56
  if (index >= 0xd800 && index <= 0xdfff) continue;
57
+ // eslint-disable-next-line unicorn/prefer-code-point
58
58
  const expected = String.fromCharCode(index);
59
59
  const encoded = encoder.encode(expected);
60
60
  const actual = decoder.decode(encoded);
@@ -77,6 +77,7 @@ function testEncoding(encoder, decoder) {
77
77
  // 检查所有 2 字节 ASCII
78
78
  for (let index = 0; index < 0x80; index++) {
79
79
  for (let index2 = 0; index2 < 0x80; index2++) {
80
+ // eslint-disable-next-line unicorn/prefer-code-point
80
81
  const expected = String.fromCharCode(index, index2);
81
82
  const actual = decoder.decode(encoder.encode(expected));
82
83
  if (expected !== actual) expect(actual).toEqual(expected);
@@ -121,6 +122,8 @@ test('decode string js', () => {
121
122
  });
122
123
 
123
124
  test('decode malformed', () => {
125
+ // eslint-disable-next-line unicorn/prefer-code-point
124
126
  expect(decode(new Uint8Array([0xff, 'a'.charCodeAt(0)]), 0, 2)).toEqual('\uFFFDa');
127
+ // eslint-disable-next-line unicorn/prefer-code-point
125
128
  expect(jsDecode(new Uint8Array([0xff, 'a'.charCodeAt(0)]), 0, 2)).toEqual('\uFFFDa');
126
129
  });