@yume-chan/struct 0.0.19 → 0.0.21

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 (54) hide show
  1. package/CHANGELOG.json +27 -0
  2. package/CHANGELOG.md +16 -1
  3. package/README.md +126 -143
  4. package/esm/basic/definition.d.ts +3 -3
  5. package/esm/basic/definition.d.ts.map +1 -1
  6. package/esm/basic/definition.js.map +1 -1
  7. package/esm/basic/field-value.d.ts.map +1 -1
  8. package/esm/basic/field-value.js.map +1 -1
  9. package/esm/basic/stream.d.ts +11 -6
  10. package/esm/basic/stream.d.ts.map +1 -1
  11. package/esm/basic/stream.js +7 -1
  12. package/esm/basic/stream.js.map +1 -1
  13. package/esm/basic/struct-value.d.ts.map +1 -1
  14. package/esm/basic/struct-value.js.map +1 -1
  15. package/esm/index.d.ts +1 -0
  16. package/esm/index.d.ts.map +1 -1
  17. package/esm/index.js +1 -0
  18. package/esm/index.js.map +1 -1
  19. package/esm/struct.d.ts +19 -12
  20. package/esm/struct.d.ts.map +1 -1
  21. package/esm/struct.js +70 -38
  22. package/esm/struct.js.map +1 -1
  23. package/esm/sync-promise.js +12 -12
  24. package/esm/sync-promise.js.map +1 -1
  25. package/esm/types/bigint.d.ts +3 -3
  26. package/esm/types/bigint.d.ts.map +1 -1
  27. package/esm/types/bigint.js +2 -3
  28. package/esm/types/bigint.js.map +1 -1
  29. package/esm/types/buffer/base.d.ts +3 -3
  30. package/esm/types/buffer/base.d.ts.map +1 -1
  31. package/esm/types/buffer/base.js +3 -5
  32. package/esm/types/buffer/base.js.map +1 -1
  33. package/esm/types/buffer/fixed-length.d.ts.map +1 -1
  34. package/esm/types/buffer/fixed-length.js.map +1 -1
  35. package/esm/types/buffer/variable-length.d.ts.map +1 -1
  36. package/esm/types/buffer/variable-length.js.map +1 -1
  37. package/esm/types/number.d.ts +3 -3
  38. package/esm/types/number.d.ts.map +1 -1
  39. package/esm/types/number.js +15 -17
  40. package/esm/types/number.js.map +1 -1
  41. package/package.json +8 -8
  42. package/src/basic/definition.ts +15 -18
  43. package/src/basic/field-value.ts +11 -11
  44. package/src/basic/stream.ts +17 -6
  45. package/src/basic/struct-value.ts +4 -4
  46. package/src/index.ts +1 -0
  47. package/src/struct.ts +166 -133
  48. package/src/sync-promise.ts +25 -25
  49. package/src/types/bigint.ts +33 -41
  50. package/src/types/buffer/base.ts +38 -38
  51. package/src/types/buffer/fixed-length.ts +4 -3
  52. package/src/types/buffer/variable-length.ts +22 -20
  53. package/src/types/number.ts +40 -44
  54. package/tsconfig.build.tsbuildinfo +1 -1
package/src/struct.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  import type {
2
- StructAsyncDeserializeStream,
3
- StructDeserializeStream,
2
+ AsyncExactReadable,
3
+ ExactReadable,
4
4
  StructFieldDefinition,
5
5
  StructFieldValue,
6
6
  StructOptions,
7
7
  } from "./basic/index.js";
8
8
  import {
9
+ ExactReadableEndedError,
9
10
  STRUCT_VALUE_SYMBOL,
10
11
  StructDefaultOptions,
11
12
  StructValue,
@@ -30,9 +31,7 @@ import {
30
31
  import type { Evaluate, Identity, Overwrite, ValueOrPromise } from "./utils.js";
31
32
 
32
33
  export interface StructLike<TValue> {
33
- deserialize(
34
- stream: StructDeserializeStream | StructAsyncDeserializeStream
35
- ): Promise<TValue>;
34
+ deserialize(stream: ExactReadable | AsyncExactReadable): Promise<TValue>;
36
35
  }
37
36
 
38
37
  /**
@@ -51,7 +50,7 @@ type AddFieldDescriptor<
51
50
  TExtra extends object,
52
51
  TPostDeserialized,
53
52
  TFieldName extends PropertyKey,
54
- TDefinition extends StructFieldDefinition<any, any, any>
53
+ TDefinition extends StructFieldDefinition<any, any, any>,
55
54
  > = Identity<
56
55
  Struct<
57
56
  // Merge two types
@@ -71,7 +70,7 @@ interface ArrayBufferLikeFieldCreator<
71
70
  TFields extends object,
72
71
  TOmitInitKey extends PropertyKey,
73
72
  TExtra extends object,
74
- TPostDeserialized
73
+ TPostDeserialized,
75
74
  > {
76
75
  /**
77
76
  * Append a fixed-length array buffer like field to the `Struct`
@@ -85,12 +84,12 @@ interface ArrayBufferLikeFieldCreator<
85
84
  <
86
85
  TName extends PropertyKey,
87
86
  TType extends BufferFieldSubType<any, any>,
88
- TTypeScriptType = TType["TTypeScriptType"]
87
+ TTypeScriptType = TType["TTypeScriptType"],
89
88
  >(
90
89
  name: TName,
91
90
  type: TType,
92
91
  options: FixedLengthBufferLikeFieldOptions,
93
- typeScriptType?: TTypeScriptType
92
+ typeScriptType?: TTypeScriptType,
94
93
  ): AddFieldDescriptor<
95
94
  TFields,
96
95
  TOmitInitKey,
@@ -110,12 +109,12 @@ interface ArrayBufferLikeFieldCreator<
110
109
  TName extends PropertyKey,
111
110
  TType extends BufferFieldSubType<any, any>,
112
111
  TOptions extends VariableLengthBufferLikeFieldOptions<TFields>,
113
- TTypeScriptType = TType["TTypeScriptType"]
112
+ TTypeScriptType = TType["TTypeScriptType"],
114
113
  >(
115
114
  name: TName,
116
115
  type: TType,
117
116
  options: TOptions,
118
- typeScriptType?: TTypeScriptType
117
+ typeScriptType?: TTypeScriptType,
119
118
  ): AddFieldDescriptor<
120
119
  TFields,
121
120
  TOmitInitKey,
@@ -134,12 +133,12 @@ interface BoundArrayBufferLikeFieldDefinitionCreator<
134
133
  TOmitInitKey extends PropertyKey,
135
134
  TExtra extends object,
136
135
  TPostDeserialized,
137
- TType extends BufferFieldSubType<any, any>
136
+ TType extends BufferFieldSubType<any, any>,
138
137
  > {
139
138
  <TName extends PropertyKey, TTypeScriptType = TType["TTypeScriptType"]>(
140
139
  name: TName,
141
140
  options: FixedLengthBufferLikeFieldOptions,
142
- typeScriptType?: TTypeScriptType
141
+ typeScriptType?: TTypeScriptType,
143
142
  ): AddFieldDescriptor<
144
143
  TFields,
145
144
  TOmitInitKey,
@@ -160,11 +159,11 @@ interface BoundArrayBufferLikeFieldDefinitionCreator<
160
159
  TFields,
161
160
  TLengthField
162
161
  >,
163
- TTypeScriptType = TType["TTypeScriptType"]
162
+ TTypeScriptType = TType["TTypeScriptType"],
164
163
  >(
165
164
  name: TName,
166
165
  options: TOptions,
167
- typeScriptType?: TTypeScriptType
166
+ typeScriptType?: TTypeScriptType,
168
167
  ): AddFieldDescriptor<
169
168
  TFields,
170
169
  TOmitInitKey,
@@ -181,73 +180,100 @@ interface BoundArrayBufferLikeFieldDefinitionCreator<
181
180
 
182
181
  export type StructPostDeserialized<TFields, TPostDeserialized> = (
183
182
  this: TFields,
184
- object: TFields
183
+ object: TFields,
185
184
  ) => TPostDeserialized;
186
185
 
187
186
  export type StructDeserializedResult<
188
187
  TFields extends object,
189
188
  TExtra extends object,
190
- TPostDeserialized
189
+ TPostDeserialized,
191
190
  > = TPostDeserialized extends undefined
192
191
  ? Overwrite<TExtra, TFields>
193
192
  : TPostDeserialized;
194
193
 
194
+ export class StructDeserializeError extends Error {
195
+ constructor(message: string) {
196
+ super(message);
197
+ Object.setPrototypeOf(this, new.target.prototype);
198
+ }
199
+ }
200
+
201
+ export class StructNotEnoughDataError extends StructDeserializeError {
202
+ constructor() {
203
+ super(
204
+ "The underlying readable was ended before the struct was fully deserialized",
205
+ );
206
+ }
207
+ }
208
+
209
+ export class StructEmptyError extends StructDeserializeError {
210
+ constructor() {
211
+ super("The underlying readable doesn't contain any more struct");
212
+ }
213
+ }
214
+
195
215
  export class Struct<
196
216
  TFields extends object = Record<never, never>,
197
217
  TOmitInitKey extends PropertyKey = never,
198
218
  TExtra extends object = Record<never, never>,
199
- TPostDeserialized = undefined
219
+ TPostDeserialized = undefined,
200
220
  > implements
201
221
  StructLike<
202
222
  StructDeserializedResult<TFields, TExtra, TPostDeserialized>
203
223
  >
204
224
  {
205
- public readonly TFields!: TFields;
225
+ readonly TFields!: TFields;
206
226
 
207
- public readonly TOmitInitKey!: TOmitInitKey;
227
+ readonly TOmitInitKey!: TOmitInitKey;
208
228
 
209
- public readonly TExtra!: TExtra;
229
+ readonly TExtra!: TExtra;
210
230
 
211
- public readonly TInit!: Evaluate<Omit<TFields, TOmitInitKey>>;
231
+ readonly TInit!: Evaluate<Omit<TFields, TOmitInitKey>>;
212
232
 
213
- public readonly TDeserializeResult!: StructDeserializedResult<
233
+ readonly TDeserializeResult!: StructDeserializedResult<
214
234
  TFields,
215
235
  TExtra,
216
236
  TPostDeserialized
217
237
  >;
218
238
 
219
- public readonly options: Readonly<StructOptions>;
239
+ readonly options: Readonly<StructOptions>;
220
240
 
221
- private _size = 0;
241
+ #size = 0;
222
242
  /**
223
243
  * Gets the static size (exclude fields that can change size at runtime)
224
244
  */
225
- public get size() {
226
- return this._size;
245
+ get size() {
246
+ return this.#size;
227
247
  }
228
248
 
229
- private _fields: [
249
+ #fields: [
230
250
  name: PropertyKey,
231
- definition: StructFieldDefinition<any, any, any>
251
+ definition: StructFieldDefinition<any, any, any>,
232
252
  ][] = [];
253
+ get fields(): readonly [
254
+ name: PropertyKey,
255
+ definition: StructFieldDefinition<any, any, any>,
256
+ ][] {
257
+ return this.#fields;
258
+ }
233
259
 
234
- private _extra: Record<PropertyKey, unknown> = {};
260
+ #extra: Record<PropertyKey, unknown> = {};
235
261
 
236
- private _postDeserialized?: StructPostDeserialized<any, any> | undefined;
262
+ #postDeserialized?: StructPostDeserialized<any, any> | undefined;
237
263
 
238
- public constructor(options?: Partial<Readonly<StructOptions>>) {
264
+ constructor(options?: Partial<Readonly<StructOptions>>) {
239
265
  this.options = { ...StructDefaultOptions, ...options };
240
266
  }
241
267
 
242
268
  /**
243
269
  * Appends a `StructFieldDefinition` to the `Struct
244
270
  */
245
- public field<
271
+ field<
246
272
  TName extends PropertyKey,
247
- TDefinition extends StructFieldDefinition<any, any, any>
273
+ TDefinition extends StructFieldDefinition<any, any, any>,
248
274
  >(
249
275
  name: TName,
250
- definition: TDefinition
276
+ definition: TDefinition,
251
277
  ): AddFieldDescriptor<
252
278
  TFields,
253
279
  TOmitInitKey,
@@ -256,20 +282,20 @@ export class Struct<
256
282
  TName,
257
283
  TDefinition
258
284
  > {
259
- for (const field of this._fields) {
285
+ for (const field of this.#fields) {
260
286
  if (field[0] === name) {
287
+ // Convert Symbol to string
288
+ const nameString = String(name);
261
289
  throw new Error(
262
- `This struct already have a field with name '${String(
263
- name
264
- )}'`
290
+ `This struct already have a field with name '${nameString}'`,
265
291
  );
266
292
  }
267
293
  }
268
294
 
269
- this._fields.push([name, definition]);
295
+ this.#fields.push([name, definition]);
270
296
 
271
297
  const size = definition.getSize();
272
- this._size += size;
298
+ this.#size += size;
273
299
 
274
300
  // Force cast `this` to another type
275
301
  return this as any;
@@ -278,104 +304,104 @@ export class Struct<
278
304
  /**
279
305
  * Merges (flats) another `Struct`'s fields and extra fields into this one.
280
306
  */
281
- public fields<TOther extends Struct<any, any, any, any>>(
282
- other: TOther
307
+ concat<TOther extends Struct<any, any, any, any>>(
308
+ other: TOther,
283
309
  ): Struct<
284
310
  TFields & TOther["TFields"],
285
311
  TOmitInitKey | TOther["TOmitInitKey"],
286
312
  TExtra & TOther["TExtra"],
287
313
  TPostDeserialized
288
314
  > {
289
- for (const field of other._fields) {
290
- this._fields.push(field);
315
+ for (const field of other.#fields) {
316
+ this.#fields.push(field);
291
317
  }
292
- this._size += other._size;
318
+ this.#size += other.#size;
293
319
  Object.defineProperties(
294
- this._extra,
295
- Object.getOwnPropertyDescriptors(other._extra)
320
+ this.#extra,
321
+ Object.getOwnPropertyDescriptors(other.#extra),
296
322
  );
297
323
  return this as any;
298
324
  }
299
325
 
300
- private number<
326
+ #number<
301
327
  TName extends PropertyKey,
302
328
  TType extends NumberFieldType = NumberFieldType,
303
- TTypeScriptType = number
329
+ TTypeScriptType = number,
304
330
  >(name: TName, type: TType, typeScriptType?: TTypeScriptType) {
305
331
  return this.field(
306
332
  name,
307
- new NumberFieldDefinition(type, typeScriptType)
333
+ new NumberFieldDefinition(type, typeScriptType),
308
334
  );
309
335
  }
310
336
 
311
337
  /**
312
338
  * Appends an `int8` field to the `Struct`
313
339
  */
314
- public int8<TName extends PropertyKey, TTypeScriptType = number>(
340
+ int8<TName extends PropertyKey, TTypeScriptType = number>(
315
341
  name: TName,
316
- typeScriptType?: TTypeScriptType
342
+ typeScriptType?: TTypeScriptType,
317
343
  ) {
318
- return this.number(name, NumberFieldType.Int8, typeScriptType);
344
+ return this.#number(name, NumberFieldType.Int8, typeScriptType);
319
345
  }
320
346
 
321
347
  /**
322
348
  * Appends an `uint8` field to the `Struct`
323
349
  */
324
- public uint8<TName extends PropertyKey, TTypeScriptType = number>(
350
+ uint8<TName extends PropertyKey, TTypeScriptType = number>(
325
351
  name: TName,
326
- typeScriptType?: TTypeScriptType
352
+ typeScriptType?: TTypeScriptType,
327
353
  ) {
328
- return this.number(name, NumberFieldType.Uint8, typeScriptType);
354
+ return this.#number(name, NumberFieldType.Uint8, typeScriptType);
329
355
  }
330
356
 
331
357
  /**
332
358
  * Appends an `int16` field to the `Struct`
333
359
  */
334
- public int16<TName extends PropertyKey, TTypeScriptType = number>(
360
+ int16<TName extends PropertyKey, TTypeScriptType = number>(
335
361
  name: TName,
336
- typeScriptType?: TTypeScriptType
362
+ typeScriptType?: TTypeScriptType,
337
363
  ) {
338
- return this.number(name, NumberFieldType.Int16, typeScriptType);
364
+ return this.#number(name, NumberFieldType.Int16, typeScriptType);
339
365
  }
340
366
 
341
367
  /**
342
368
  * Appends an `uint16` field to the `Struct`
343
369
  */
344
- public uint16<TName extends PropertyKey, TTypeScriptType = number>(
370
+ uint16<TName extends PropertyKey, TTypeScriptType = number>(
345
371
  name: TName,
346
- typeScriptType?: TTypeScriptType
372
+ typeScriptType?: TTypeScriptType,
347
373
  ) {
348
- return this.number(name, NumberFieldType.Uint16, typeScriptType);
374
+ return this.#number(name, NumberFieldType.Uint16, typeScriptType);
349
375
  }
350
376
 
351
377
  /**
352
378
  * Appends an `int32` field to the `Struct`
353
379
  */
354
- public int32<TName extends PropertyKey, TTypeScriptType = number>(
380
+ int32<TName extends PropertyKey, TTypeScriptType = number>(
355
381
  name: TName,
356
- typeScriptType?: TTypeScriptType
382
+ typeScriptType?: TTypeScriptType,
357
383
  ) {
358
- return this.number(name, NumberFieldType.Int32, typeScriptType);
384
+ return this.#number(name, NumberFieldType.Int32, typeScriptType);
359
385
  }
360
386
 
361
387
  /**
362
388
  * Appends an `uint32` field to the `Struct`
363
389
  */
364
- public uint32<TName extends PropertyKey, TTypeScriptType = number>(
390
+ uint32<TName extends PropertyKey, TTypeScriptType = number>(
365
391
  name: TName,
366
- typeScriptType?: TTypeScriptType
392
+ typeScriptType?: TTypeScriptType,
367
393
  ) {
368
- return this.number(name, NumberFieldType.Uint32, typeScriptType);
394
+ return this.#number(name, NumberFieldType.Uint32, typeScriptType);
369
395
  }
370
396
 
371
- private bigint<
397
+ #bigint<
372
398
  TName extends PropertyKey,
373
399
  TType extends BigIntFieldType = BigIntFieldType,
374
- TTypeScriptType = TType["TTypeScriptType"]
400
+ TTypeScriptType = TType["TTypeScriptType"],
375
401
  >(name: TName, type: TType, typeScriptType?: TTypeScriptType) {
376
402
  return this.field(
377
403
  name,
378
- new BigIntFieldDefinition(type, typeScriptType)
404
+ new BigIntFieldDefinition(type, typeScriptType),
379
405
  );
380
406
  }
381
407
 
@@ -384,11 +410,11 @@ export class Struct<
384
410
  *
385
411
  * Requires native `BigInt` support
386
412
  */
387
- public int64<
413
+ int64<
388
414
  TName extends PropertyKey,
389
- TTypeScriptType = BigIntFieldType["TTypeScriptType"]
415
+ TTypeScriptType = BigIntFieldType["TTypeScriptType"],
390
416
  >(name: TName, typeScriptType?: TTypeScriptType) {
391
- return this.bigint(name, BigIntFieldType.Int64, typeScriptType);
417
+ return this.#bigint(name, BigIntFieldType.Int64, typeScriptType);
392
418
  }
393
419
 
394
420
  /**
@@ -396,14 +422,14 @@ export class Struct<
396
422
  *
397
423
  * Requires native `BigInt` support
398
424
  */
399
- public uint64<
425
+ uint64<
400
426
  TName extends PropertyKey,
401
- TTypeScriptType = BigIntFieldType["TTypeScriptType"]
427
+ TTypeScriptType = BigIntFieldType["TTypeScriptType"],
402
428
  >(name: TName, typeScriptType?: TTypeScriptType) {
403
- return this.bigint(name, BigIntFieldType.Uint64, typeScriptType);
429
+ return this.#bigint(name, BigIntFieldType.Uint64, typeScriptType);
404
430
  }
405
431
 
406
- private arrayBufferLike: ArrayBufferLikeFieldCreator<
432
+ #arrayBufferLike: ArrayBufferLikeFieldCreator<
407
433
  TFields,
408
434
  TOmitInitKey,
409
435
  TExtra,
@@ -413,48 +439,48 @@ export class Struct<
413
439
  type: BufferFieldSubType,
414
440
  options:
415
441
  | FixedLengthBufferLikeFieldOptions
416
- | VariableLengthBufferLikeFieldOptions
442
+ | VariableLengthBufferLikeFieldOptions,
417
443
  ): any => {
418
444
  if ("length" in options) {
419
445
  return this.field(
420
446
  name,
421
- new FixedLengthBufferLikeFieldDefinition(type, options)
447
+ new FixedLengthBufferLikeFieldDefinition(type, options),
422
448
  );
423
449
  } else {
424
450
  return this.field(
425
451
  name,
426
- new VariableLengthBufferLikeFieldDefinition(type, options)
452
+ new VariableLengthBufferLikeFieldDefinition(type, options),
427
453
  );
428
454
  }
429
455
  };
430
456
 
431
- public uint8Array: BoundArrayBufferLikeFieldDefinitionCreator<
457
+ uint8Array: BoundArrayBufferLikeFieldDefinitionCreator<
432
458
  TFields,
433
459
  TOmitInitKey,
434
460
  TExtra,
435
461
  TPostDeserialized,
436
462
  Uint8ArrayBufferFieldSubType
437
463
  > = (name: PropertyKey, options: any, typeScriptType: any): any => {
438
- return this.arrayBufferLike(
464
+ return this.#arrayBufferLike(
439
465
  name,
440
466
  Uint8ArrayBufferFieldSubType.Instance,
441
467
  options,
442
- typeScriptType
468
+ typeScriptType,
443
469
  );
444
470
  };
445
471
 
446
- public string: BoundArrayBufferLikeFieldDefinitionCreator<
472
+ string: BoundArrayBufferLikeFieldDefinitionCreator<
447
473
  TFields,
448
474
  TOmitInitKey,
449
475
  TExtra,
450
476
  TPostDeserialized,
451
477
  StringBufferFieldSubType
452
478
  > = (name: PropertyKey, options: any, typeScriptType: any): any => {
453
- return this.arrayBufferLike(
479
+ return this.#arrayBufferLike(
454
480
  name,
455
481
  StringBufferFieldSubType.Instance,
456
482
  options,
457
- typeScriptType
483
+ typeScriptType,
458
484
  );
459
485
  };
460
486
 
@@ -468,18 +494,18 @@ export class Struct<
468
494
  * @param value
469
495
  * An object containing properties to be added to the result value. Accessors and methods are also allowed.
470
496
  */
471
- public extra<
497
+ extra<
472
498
  T extends Record<
473
499
  // This trick disallows any keys that are already in `TValue`
474
500
  Exclude<keyof T, Exclude<keyof T, keyof TFields>>,
475
501
  never
476
- >
502
+ >,
477
503
  >(
478
- value: T & ThisType<Overwrite<Overwrite<TExtra, T>, TFields>>
504
+ value: T & ThisType<Overwrite<Overwrite<TExtra, T>, TFields>>,
479
505
  ): Struct<TFields, TOmitInitKey, Overwrite<TExtra, T>, TPostDeserialized> {
480
506
  Object.defineProperties(
481
- this._extra,
482
- Object.getOwnPropertyDescriptors(value)
507
+ this.#extra,
508
+ Object.getOwnPropertyDescriptors(value),
483
509
  );
484
510
  return this as any;
485
511
  }
@@ -490,8 +516,8 @@ export class Struct<
490
516
  * A callback returning `never` (always throw an error)
491
517
  * will also change the return type of `deserialize` to `never`.
492
518
  */
493
- public postDeserialize(
494
- callback: StructPostDeserialized<TFields, never>
519
+ postDeserialize(
520
+ callback: StructPostDeserialized<TFields, never>,
495
521
  ): Struct<TFields, TOmitInitKey, TExtra, never>;
496
522
  /**
497
523
  * Registers (or replaces) a custom callback to be run after deserialized.
@@ -499,8 +525,8 @@ export class Struct<
499
525
  * A callback returning `void` means it modify the result object in-place
500
526
  * (or doesn't modify it at all), so `deserialize` will still return the result object.
501
527
  */
502
- public postDeserialize(
503
- callback?: StructPostDeserialized<TFields, void>
528
+ postDeserialize(
529
+ callback?: StructPostDeserialized<TFields, void>,
504
530
  ): Struct<TFields, TOmitInitKey, TExtra, undefined>;
505
531
  /**
506
532
  * Registers (or replaces) a custom callback to be run after deserialized.
@@ -508,56 +534,63 @@ export class Struct<
508
534
  * A callback returning anything other than `undefined`
509
535
  * will `deserialize` to return that object instead.
510
536
  */
511
- public postDeserialize<TPostSerialize>(
512
- callback?: StructPostDeserialized<TFields, TPostSerialize>
537
+ postDeserialize<TPostSerialize>(
538
+ callback?: StructPostDeserialized<TFields, TPostSerialize>,
513
539
  ): Struct<TFields, TOmitInitKey, TExtra, TPostSerialize>;
514
- public postDeserialize(callback?: StructPostDeserialized<TFields, any>) {
515
- this._postDeserialized = callback;
540
+ postDeserialize(callback?: StructPostDeserialized<TFields, any>) {
541
+ this.#postDeserialized = callback;
516
542
  return this as any;
517
543
  }
518
544
 
519
545
  /**
520
546
  * Deserialize a struct value from `stream`.
521
547
  */
522
- public deserialize(
523
- stream: StructDeserializeStream
548
+ deserialize(
549
+ stream: ExactReadable,
524
550
  ): StructDeserializedResult<TFields, TExtra, TPostDeserialized>;
525
- public deserialize(
526
- stream: StructAsyncDeserializeStream
551
+ deserialize(
552
+ stream: AsyncExactReadable,
527
553
  ): Promise<StructDeserializedResult<TFields, TExtra, TPostDeserialized>>;
528
- public deserialize(
529
- stream: StructDeserializeStream | StructAsyncDeserializeStream
554
+ deserialize(
555
+ stream: ExactReadable | AsyncExactReadable,
530
556
  ): ValueOrPromise<
531
557
  StructDeserializedResult<TFields, TExtra, TPostDeserialized>
532
558
  > {
533
- const structValue = new StructValue(this._extra);
559
+ const structValue = new StructValue(this.#extra);
534
560
 
535
561
  let promise = SyncPromise.resolve();
536
562
 
537
- for (const [name, definition] of this._fields) {
563
+ const startPosition = stream.position;
564
+ for (const [name, definition] of this.#fields) {
538
565
  promise = promise
539
566
  .then(() =>
540
- definition.deserialize(
541
- this.options,
542
- stream as any,
543
- structValue
544
- )
567
+ definition.deserialize(this.options, stream, structValue),
545
568
  )
546
- .then((fieldValue) => {
547
- structValue.set(name, fieldValue);
548
- });
569
+ .then(
570
+ (fieldValue) => {
571
+ structValue.set(name, fieldValue);
572
+ },
573
+ (e) => {
574
+ if (!(e instanceof ExactReadableEndedError)) {
575
+ throw e;
576
+ }
577
+
578
+ if (stream.position === startPosition) {
579
+ throw new StructEmptyError();
580
+ } else {
581
+ throw new StructNotEnoughDataError();
582
+ }
583
+ },
584
+ );
549
585
  }
550
586
 
551
587
  return promise
552
588
  .then(() => {
553
- const object = structValue.value;
589
+ const value = structValue.value;
554
590
 
555
591
  // Run `postDeserialized`
556
- if (this._postDeserialized) {
557
- const override = this._postDeserialized.call(
558
- object,
559
- object
560
- );
592
+ if (this.#postDeserialized) {
593
+ const override = this.#postDeserialized.call(value, value);
561
594
  // If it returns a new value, use that as result
562
595
  // Otherwise it only inspects/mutates the object in place.
563
596
  if (override !== undefined) {
@@ -565,19 +598,19 @@ export class Struct<
565
598
  }
566
599
  }
567
600
 
568
- return object;
601
+ return value;
569
602
  })
570
603
  .valueOrPromise();
571
604
  }
572
605
 
573
- public serialize(init: Evaluate<Omit<TFields, TOmitInitKey>>): Uint8Array;
574
- public serialize(
606
+ serialize(init: Evaluate<Omit<TFields, TOmitInitKey>>): Uint8Array;
607
+ serialize(
575
608
  init: Evaluate<Omit<TFields, TOmitInitKey>>,
576
- output: Uint8Array
609
+ output: Uint8Array,
577
610
  ): number;
578
- public serialize(
611
+ serialize(
579
612
  init: Evaluate<Omit<TFields, TOmitInitKey>>,
580
- output?: Uint8Array
613
+ output?: Uint8Array,
581
614
  ): Uint8Array | number {
582
615
  let structValue: StructValue;
583
616
  if (STRUCT_VALUE_SYMBOL in init) {
@@ -590,11 +623,11 @@ export class Struct<
590
623
  }
591
624
  } else {
592
625
  structValue = new StructValue({});
593
- for (const [name, definition] of this._fields) {
626
+ for (const [name, definition] of this.#fields) {
594
627
  const fieldValue = definition.create(
595
628
  this.options,
596
629
  structValue,
597
- (init as any)[name]
630
+ (init as any)[name],
598
631
  );
599
632
  structValue.set(name, fieldValue);
600
633
  }
@@ -603,7 +636,7 @@ export class Struct<
603
636
  let structSize = 0;
604
637
  const fieldsInfo: { fieldValue: StructFieldValue; size: number }[] = [];
605
638
 
606
- for (const [name] of this._fields) {
639
+ for (const [name] of this.#fields) {
607
640
  const fieldValue = structValue.get(name);
608
641
  const size = fieldValue.getSize();
609
642
  fieldsInfo.push({ fieldValue, size });
@@ -619,7 +652,7 @@ export class Struct<
619
652
  const dataView = new DataView(
620
653
  output.buffer,
621
654
  output.byteOffset,
622
- output.byteLength
655
+ output.byteLength,
623
656
  );
624
657
  let offset = 0;
625
658
  for (const { fieldValue, size } of fieldsInfo) {