@yume-chan/struct 0.0.10 → 0.0.14

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 (122) hide show
  1. package/CHANGELOG.json +48 -0
  2. package/CHANGELOG.md +29 -1
  3. package/LICENSE +1 -1
  4. package/README.md +102 -53
  5. package/{dts → esm}/basic/definition.d.ts +9 -13
  6. package/esm/basic/definition.d.ts.map +1 -0
  7. package/esm/basic/definition.js +13 -9
  8. package/esm/basic/definition.js.map +1 -1
  9. package/{dts → esm}/basic/field-value.d.ts +8 -8
  10. package/esm/basic/field-value.d.ts.map +1 -0
  11. package/esm/basic/field-value.js +12 -5
  12. package/esm/basic/field-value.js.map +1 -1
  13. package/esm/basic/index.d.ts +6 -0
  14. package/esm/basic/index.d.ts.map +1 -0
  15. package/esm/basic/index.js +5 -4
  16. package/esm/basic/index.js.map +1 -1
  17. package/esm/basic/options.d.ts +10 -0
  18. package/esm/basic/options.d.ts.map +1 -0
  19. package/esm/basic/{context.js → options.js} +1 -1
  20. package/esm/basic/options.js.map +1 -0
  21. package/esm/basic/stream.d.ts +19 -0
  22. package/esm/basic/stream.d.ts.map +1 -0
  23. package/esm/basic/stream.js +2 -0
  24. package/esm/basic/stream.js.map +1 -0
  25. package/{dts → esm}/basic/struct-value.d.ts +3 -3
  26. package/esm/basic/struct-value.d.ts.map +1 -0
  27. package/esm/basic/struct-value.js +7 -9
  28. package/esm/basic/struct-value.js.map +1 -1
  29. package/esm/index.d.ts +14 -0
  30. package/esm/index.d.ts.map +1 -0
  31. package/esm/index.js +5 -5
  32. package/esm/index.js.map +1 -1
  33. package/{dts → esm}/struct.d.ts +16 -12
  34. package/esm/struct.d.ts.map +1 -0
  35. package/esm/struct.js +67 -54
  36. package/esm/struct.js.map +1 -1
  37. package/esm/syncbird.d.ts +65 -0
  38. package/esm/syncbird.d.ts.map +1 -0
  39. package/esm/syncbird.js +17 -4
  40. package/esm/syncbird.js.map +1 -1
  41. package/esm/types/bigint.d.ts +25 -0
  42. package/esm/types/bigint.d.ts.map +1 -0
  43. package/esm/types/bigint.js +45 -0
  44. package/esm/types/bigint.js.map +1 -0
  45. package/esm/types/buffer/base.d.ts +63 -0
  46. package/esm/types/buffer/base.d.ts.map +1 -0
  47. package/esm/types/buffer/base.js +100 -0
  48. package/esm/types/buffer/base.js.map +1 -0
  49. package/esm/types/buffer/fixed-length.d.ts +8 -0
  50. package/esm/types/buffer/fixed-length.d.ts.map +1 -0
  51. package/esm/types/buffer/fixed-length.js +8 -0
  52. package/esm/types/buffer/fixed-length.js.map +1 -0
  53. package/esm/types/buffer/index.d.ts +4 -0
  54. package/esm/types/buffer/index.d.ts.map +1 -0
  55. package/esm/types/buffer/index.js +4 -0
  56. package/esm/types/buffer/index.js.map +1 -0
  57. package/esm/types/buffer/variable-length.d.ts +43 -0
  58. package/esm/types/buffer/variable-length.d.ts.map +1 -0
  59. package/esm/types/buffer/variable-length.js +76 -0
  60. package/esm/types/buffer/variable-length.js.map +1 -0
  61. package/esm/types/index.d.ts +4 -0
  62. package/esm/types/index.d.ts.map +1 -0
  63. package/esm/types/index.js +3 -4
  64. package/esm/types/index.js.map +1 -1
  65. package/{dts → esm}/types/number.d.ts +10 -12
  66. package/esm/types/number.d.ts.map +1 -0
  67. package/esm/types/number.js +21 -14
  68. package/esm/types/number.js.map +1 -1
  69. package/{dts → esm}/utils.d.ts +2 -2
  70. package/{dts → esm}/utils.d.ts.map +1 -1
  71. package/esm/utils.js +9 -3
  72. package/esm/utils.js.map +1 -1
  73. package/package.json +47 -47
  74. package/src/basic/definition.ts +11 -13
  75. package/src/basic/field-value.ts +8 -8
  76. package/src/basic/index.ts +5 -4
  77. package/src/basic/options.ts +19 -0
  78. package/src/basic/stream.ts +19 -0
  79. package/src/basic/struct-value.ts +4 -4
  80. package/src/index.ts +17 -5
  81. package/src/struct.ts +89 -75
  82. package/src/syncbird.ts +88 -10
  83. package/src/types/bigint.ts +102 -0
  84. package/src/types/buffer/base.ts +176 -0
  85. package/src/types/buffer/fixed-length.ts +17 -0
  86. package/src/types/buffer/index.ts +3 -0
  87. package/src/types/buffer/variable-length.ts +156 -0
  88. package/src/types/index.ts +3 -4
  89. package/src/types/number.ts +27 -26
  90. package/src/utils.ts +13 -5
  91. package/dts/basic/context.d.ts +0 -28
  92. package/dts/basic/context.d.ts.map +0 -1
  93. package/dts/basic/definition.d.ts.map +0 -1
  94. package/dts/basic/field-value.d.ts.map +0 -1
  95. package/dts/basic/index.d.ts +0 -5
  96. package/dts/basic/index.d.ts.map +0 -1
  97. package/dts/basic/struct-value.d.ts.map +0 -1
  98. package/dts/index.d.ts +0 -6
  99. package/dts/index.d.ts.map +0 -1
  100. package/dts/struct.d.ts.map +0 -1
  101. package/dts/syncbird.d.ts +0 -20
  102. package/dts/syncbird.d.ts.map +0 -1
  103. package/dts/types/array-buffer.d.ts +0 -71
  104. package/dts/types/array-buffer.d.ts.map +0 -1
  105. package/dts/types/fixed-length-array-buffer.d.ts +0 -8
  106. package/dts/types/fixed-length-array-buffer.d.ts.map +0 -1
  107. package/dts/types/index.d.ts +0 -5
  108. package/dts/types/index.d.ts.map +0 -1
  109. package/dts/types/number.d.ts.map +0 -1
  110. package/dts/types/variable-length-array-buffer.d.ts +0 -32
  111. package/dts/types/variable-length-array-buffer.d.ts.map +0 -1
  112. package/esm/basic/context.js.map +0 -1
  113. package/esm/types/array-buffer.js +0 -110
  114. package/esm/types/array-buffer.js.map +0 -1
  115. package/esm/types/fixed-length-array-buffer.js +0 -8
  116. package/esm/types/fixed-length-array-buffer.js.map +0 -1
  117. package/esm/types/variable-length-array-buffer.js +0 -71
  118. package/esm/types/variable-length-array-buffer.js.map +0 -1
  119. package/src/basic/context.ts +0 -32
  120. package/src/types/array-buffer.ts +0 -194
  121. package/src/types/fixed-length-array-buffer.ts +0 -17
  122. package/src/types/variable-length-array-buffer.ts +0 -142
package/src/struct.ts CHANGED
@@ -1,8 +1,10 @@
1
- import type { StructAsyncDeserializeStream, StructDeserializeStream, StructFieldDefinition, StructFieldValue, StructOptions } from './basic';
2
- import { StructDefaultOptions, StructValue } from './basic';
3
- import { Syncbird } from "./syncbird";
4
- import { ArrayBufferFieldType, ArrayBufferLikeFieldType, FixedLengthArrayBufferLikeFieldDefinition, FixedLengthArrayBufferLikeFieldOptions, LengthField, NumberFieldDefinition, NumberFieldType, StringFieldType, Uint8ClampedArrayFieldType, VariableLengthArrayBufferLikeFieldDefinition, VariableLengthArrayBufferLikeFieldOptions } from './types';
5
- import { Evaluate, Identity, Overwrite, ValueOrPromise } from "./utils";
1
+ // cspell: ignore Syncbird
2
+
3
+ import type { StructAsyncDeserializeStream, StructDeserializeStream, StructFieldDefinition, StructFieldValue, StructOptions } from './basic/index.js';
4
+ import { StructDefaultOptions, StructValue } from './basic/index.js';
5
+ import { Syncbird } from "./syncbird.js";
6
+ import { BigIntFieldDefinition, BigIntFieldType, BufferFieldSubType, FixedLengthBufferLikeFieldDefinition, NumberFieldDefinition, NumberFieldType, StringBufferFieldSubType, Uint8ArrayBufferFieldSubType, VariableLengthBufferLikeFieldDefinition, type FixedLengthBufferLikeFieldOptions, type LengthField, type VariableLengthBufferLikeFieldOptions } from './types/index.js';
7
+ import type { Evaluate, Identity, Overwrite, ValueOrPromise } from "./utils.js";
6
8
 
7
9
  export interface StructLike<TValue> {
8
10
  deserialize(stream: StructDeserializeStream | StructAsyncDeserializeStream): Promise<TValue>;
@@ -55,12 +57,12 @@ interface ArrayBufferLikeFieldCreator<
55
57
  */
56
58
  <
57
59
  TName extends PropertyKey,
58
- TType extends ArrayBufferLikeFieldType<any, any>,
60
+ TType extends BufferFieldSubType<any, any>,
59
61
  TTypeScriptType = TType['TTypeScriptType'],
60
62
  >(
61
63
  name: TName,
62
64
  type: TType,
63
- options: FixedLengthArrayBufferLikeFieldOptions,
65
+ options: FixedLengthBufferLikeFieldOptions,
64
66
  typescriptType?: TTypeScriptType,
65
67
  ): AddFieldDescriptor<
66
68
  TFields,
@@ -68,9 +70,9 @@ interface ArrayBufferLikeFieldCreator<
68
70
  TExtra,
69
71
  TPostDeserialized,
70
72
  TName,
71
- FixedLengthArrayBufferLikeFieldDefinition<
73
+ FixedLengthBufferLikeFieldDefinition<
72
74
  TType,
73
- FixedLengthArrayBufferLikeFieldOptions
75
+ FixedLengthBufferLikeFieldOptions
74
76
  >
75
77
  >;
76
78
 
@@ -79,8 +81,8 @@ interface ArrayBufferLikeFieldCreator<
79
81
  */
80
82
  <
81
83
  TName extends PropertyKey,
82
- TType extends ArrayBufferLikeFieldType<any, any>,
83
- TOptions extends VariableLengthArrayBufferLikeFieldOptions<TFields>,
84
+ TType extends BufferFieldSubType<any, any>,
85
+ TOptions extends VariableLengthBufferLikeFieldOptions<TFields>,
84
86
  TTypeScriptType = TType['TTypeScriptType'],
85
87
  >(
86
88
  name: TName,
@@ -93,7 +95,7 @@ interface ArrayBufferLikeFieldCreator<
93
95
  TExtra,
94
96
  TPostDeserialized,
95
97
  TName,
96
- VariableLengthArrayBufferLikeFieldDefinition<
98
+ VariableLengthBufferLikeFieldDefinition<
97
99
  TType,
98
100
  TOptions
99
101
  >
@@ -103,19 +105,19 @@ interface ArrayBufferLikeFieldCreator<
103
105
  /**
104
106
  * Similar to `ArrayBufferLikeFieldCreator`, but bind to `TType`
105
107
  */
106
- interface BindedArrayBufferLikeFieldDefinitionCreator<
108
+ interface BoundArrayBufferLikeFieldDefinitionCreator<
107
109
  TFields extends object,
108
110
  TOmitInitKey extends PropertyKey,
109
111
  TExtra extends object,
110
112
  TPostDeserialized,
111
- TType extends ArrayBufferLikeFieldType<any, any>
113
+ TType extends BufferFieldSubType<any, any>
112
114
  > {
113
115
  <
114
116
  TName extends PropertyKey,
115
117
  TTypeScriptType = TType['TTypeScriptType'],
116
118
  >(
117
119
  name: TName,
118
- options: FixedLengthArrayBufferLikeFieldOptions,
120
+ options: FixedLengthBufferLikeFieldOptions,
119
121
  typescriptType?: TTypeScriptType,
120
122
  ): AddFieldDescriptor<
121
123
  TFields,
@@ -123,16 +125,16 @@ interface BindedArrayBufferLikeFieldDefinitionCreator<
123
125
  TExtra,
124
126
  TPostDeserialized,
125
127
  TName,
126
- FixedLengthArrayBufferLikeFieldDefinition<
128
+ FixedLengthBufferLikeFieldDefinition<
127
129
  TType,
128
- FixedLengthArrayBufferLikeFieldOptions
130
+ FixedLengthBufferLikeFieldOptions
129
131
  >
130
132
  >;
131
133
 
132
134
  <
133
135
  TName extends PropertyKey,
134
136
  TLengthField extends LengthField<TFields>,
135
- TOptions extends VariableLengthArrayBufferLikeFieldOptions<TFields, TLengthField>,
137
+ TOptions extends VariableLengthBufferLikeFieldOptions<TFields, TLengthField>,
136
138
  TTypeScriptType = TType['TTypeScriptType'],
137
139
  >(
138
140
  name: TName,
@@ -144,7 +146,7 @@ interface BindedArrayBufferLikeFieldDefinitionCreator<
144
146
  TExtra,
145
147
  TPostDeserialized,
146
148
  TName,
147
- VariableLengthArrayBufferLikeFieldDefinition<
149
+ VariableLengthBufferLikeFieldDefinition<
148
150
  TType,
149
151
  TOptions
150
152
  >
@@ -185,7 +187,7 @@ export class Struct<
185
187
 
186
188
  private _extra: PropertyDescriptorMap = {};
187
189
 
188
- private _postDeserialized?: StructPostDeserialized<any, any>;
190
+ private _postDeserialized?: StructPostDeserialized<any, any> | undefined;
189
191
 
190
192
  public constructor(options?: Partial<Readonly<StructOptions>>) {
191
193
  this.options = { ...StructDefaultOptions, ...options };
@@ -210,7 +212,7 @@ export class Struct<
210
212
  > {
211
213
  for (const field of this._fields) {
212
214
  if (field[0] === name) {
213
- throw new Error(`This struct already have a field with name '${name}'`);
215
+ throw new Error(`This struct already have a field with name '${String(name)}'`);
214
216
  }
215
217
  }
216
218
 
@@ -359,6 +361,21 @@ export class Struct<
359
361
  );
360
362
  }
361
363
 
364
+ private bigint<
365
+ TName extends PropertyKey,
366
+ TType extends BigIntFieldType = BigIntFieldType,
367
+ TTypeScriptType = TType['TTypeScriptType']
368
+ >(
369
+ name: TName,
370
+ type: TType,
371
+ _typescriptType?: TTypeScriptType,
372
+ ) {
373
+ return this.field(
374
+ name,
375
+ new BigIntFieldDefinition(type, _typescriptType),
376
+ );
377
+ }
378
+
362
379
  /**
363
380
  * Appends an `int64` field to the `Struct`
364
381
  *
@@ -366,14 +383,14 @@ export class Struct<
366
383
  */
367
384
  public int64<
368
385
  TName extends PropertyKey,
369
- TTypeScriptType = (typeof NumberFieldType)['Int64']['TTypeScriptType']
386
+ TTypeScriptType = BigIntFieldType['TTypeScriptType']
370
387
  >(
371
388
  name: TName,
372
389
  _typescriptType?: TTypeScriptType,
373
390
  ) {
374
- return this.number(
391
+ return this.bigint(
375
392
  name,
376
- NumberFieldType.Int64,
393
+ BigIntFieldType.Int64,
377
394
  _typescriptType
378
395
  );
379
396
  }
@@ -385,14 +402,14 @@ export class Struct<
385
402
  */
386
403
  public uint64<
387
404
  TName extends PropertyKey,
388
- TTypeScriptType = (typeof NumberFieldType)['Uint64']['TTypeScriptType']
405
+ TTypeScriptType = BigIntFieldType['TTypeScriptType']
389
406
  >(
390
407
  name: TName,
391
408
  _typescriptType?: TTypeScriptType,
392
409
  ) {
393
- return this.number(
410
+ return this.bigint(
394
411
  name,
395
- NumberFieldType.Uint64,
412
+ BigIntFieldType.Uint64,
396
413
  _typescriptType
397
414
  );
398
415
  }
@@ -404,59 +421,46 @@ export class Struct<
404
421
  TPostDeserialized
405
422
  > = (
406
423
  name: PropertyKey,
407
- type: ArrayBufferLikeFieldType,
408
- options: FixedLengthArrayBufferLikeFieldOptions | VariableLengthArrayBufferLikeFieldOptions
424
+ type: BufferFieldSubType,
425
+ options: FixedLengthBufferLikeFieldOptions | VariableLengthBufferLikeFieldOptions
409
426
  ): any => {
410
427
  if ('length' in options) {
411
428
  return this.field(
412
429
  name,
413
- new FixedLengthArrayBufferLikeFieldDefinition(type, options),
430
+ new FixedLengthBufferLikeFieldDefinition(type, options),
414
431
  );
415
432
  } else {
416
433
  return this.field(
417
434
  name,
418
- new VariableLengthArrayBufferLikeFieldDefinition(type, options),
435
+ new VariableLengthBufferLikeFieldDefinition(type, options),
419
436
  );
420
437
  }
421
438
  };
422
439
 
423
- public arrayBuffer: BindedArrayBufferLikeFieldDefinitionCreator<
440
+ public uint8Array: BoundArrayBufferLikeFieldDefinitionCreator<
424
441
  TFields,
425
442
  TOmitInitKey,
426
443
  TExtra,
427
444
  TPostDeserialized,
428
- ArrayBufferFieldType
445
+ Uint8ArrayBufferFieldSubType
429
446
  > = (
430
447
  name: PropertyKey,
431
448
  options: any
432
449
  ): any => {
433
- return this.arrayBufferLike(name, ArrayBufferFieldType.instance, options);
450
+ return this.arrayBufferLike(name, Uint8ArrayBufferFieldSubType.Instance, options);
434
451
  };
435
452
 
436
- public uint8ClampedArray: BindedArrayBufferLikeFieldDefinitionCreator<
453
+ public string: BoundArrayBufferLikeFieldDefinitionCreator<
437
454
  TFields,
438
455
  TOmitInitKey,
439
456
  TExtra,
440
457
  TPostDeserialized,
441
- Uint8ClampedArrayFieldType
458
+ StringBufferFieldSubType
442
459
  > = (
443
460
  name: PropertyKey,
444
461
  options: any
445
462
  ): any => {
446
- return this.arrayBufferLike(name, Uint8ClampedArrayFieldType.instance, options);
447
- };
448
-
449
- public string: BindedArrayBufferLikeFieldDefinitionCreator<
450
- TFields,
451
- TOmitInitKey,
452
- TExtra,
453
- TPostDeserialized,
454
- StringFieldType
455
- > = (
456
- name: PropertyKey,
457
- options: any
458
- ): any => {
459
- return this.arrayBufferLike(name, StringFieldType.instance, options);
463
+ return this.arrayBufferLike(name, StringBufferFieldSubType.Instance, options);
460
464
  };
461
465
 
462
466
  /**
@@ -522,6 +526,9 @@ export class Struct<
522
526
  return this as any;
523
527
  }
524
528
 
529
+ /**
530
+ * Deserialize a struct value from `stream`.
531
+ */
525
532
  public deserialize(
526
533
  stream: StructDeserializeStream,
527
534
  ): StructDeserializedResult<TFields, TExtra, TPostDeserialized>;
@@ -534,37 +541,35 @@ export class Struct<
534
541
  const value = new StructValue();
535
542
  Object.defineProperties(value.value, this._extra);
536
543
 
537
- return Syncbird.try(() => {
538
- const iterator = this._fields[Symbol.iterator]();
539
- const iterate: () => StructValue | Syncbird<StructValue> = () => {
540
- const result = iterator.next();
541
- if (result.done) {
542
- return value;
543
- }
544
-
545
- const [name, definition] = result.value;
544
+ return Syncbird
545
+ .each(this._fields, ([name, definition]) => {
546
546
  return Syncbird.resolve(
547
547
  definition.deserialize(this.options, stream as any, value)
548
548
  ).then(fieldValue => {
549
549
  value.set(name, fieldValue);
550
- return iterate();
551
550
  });
552
- };
553
- return iterate();
554
- }).then(value => {
555
- if (this._postDeserialized) {
556
- const object = value.value as TFields;
557
- const result = this._postDeserialized.call(object, object);
558
- if (result) {
559
- return result;
551
+ })
552
+ .then(() => {
553
+ const object = value.value;
554
+
555
+ // Run `postDeserialized`
556
+ if (this._postDeserialized) {
557
+ const override = this._postDeserialized.call(object, object);
558
+ // If it returns a new value, use that as result
559
+ // Otherwise it only inspects/mutates the object in place.
560
+ if (override) {
561
+ return override;
562
+ }
560
563
  }
561
- }
562
564
 
563
- return value.value;
564
- }).valueOrPromise();
565
+ return object;
566
+ })
567
+ .valueOrPromise();
565
568
  }
566
569
 
567
- public serialize(init: Evaluate<Omit<TFields, TOmitInitKey>>): ArrayBuffer {
570
+ public serialize(init: Evaluate<Omit<TFields, TOmitInitKey>>): Uint8Array;
571
+ public serialize(init: Evaluate<Omit<TFields, TOmitInitKey>>, output: Uint8Array): number;
572
+ public serialize(init: Evaluate<Omit<TFields, TOmitInitKey>>, output?: Uint8Array): Uint8Array | number {
568
573
  const value = new StructValue();
569
574
 
570
575
  for (const [name, definition] of this._fields) {
@@ -582,14 +587,23 @@ export class Struct<
582
587
  structSize += size;
583
588
  }
584
589
 
585
- const buffer = new ArrayBuffer(structSize);
586
- const dataView = new DataView(buffer);
590
+ let outputType = 'number';
591
+ if (!output) {
592
+ output = new Uint8Array(structSize);
593
+ outputType = 'Uint8Array';
594
+ }
595
+
596
+ const dataView = new DataView(output.buffer, output.byteOffset, output.byteLength);
587
597
  let offset = 0;
588
598
  for (const { fieldValue, size } of fieldsInfo) {
589
599
  fieldValue.serialize(dataView, offset);
590
600
  offset += size;
591
601
  }
592
602
 
593
- return buffer;
603
+ if (outputType === 'number') {
604
+ return structSize;
605
+ } else {
606
+ return output;
607
+ }
594
608
  }
595
609
  }
package/src/syncbird.ts CHANGED
@@ -1,6 +1,9 @@
1
+ // cspell: ignore syncbird
2
+
1
3
  import Bluebird from 'bluebird';
2
4
 
3
- type Resolvable<R> = R | PromiseLike<R>;
5
+ export type Resolvable<R> = R | PromiseLike<R>;
6
+ export type IterateFunction<T, R> = (item: T, index: number, arrayLength: number) => Resolvable<R>;
4
7
 
5
8
  export interface Syncbird<R> extends Bluebird<R> {
6
9
  valueOrPromise(): R | PromiseLike<R>;
@@ -13,6 +16,39 @@ export interface Syncbird<R> extends Bluebird<R> {
13
16
  }
14
17
 
15
18
  interface SyncbirdStatic {
19
+ /**
20
+ * Iterate over an array, or a promise of an array,
21
+ * which contains promises (or a mix of promises and values) with the given iterator function with the signature `(item, index, value)`
22
+ * where item is the resolved value of a respective promise in the input array.
23
+ * Iteration happens serially. If any promise in the input array is rejected the returned promise is rejected as well.
24
+ *
25
+ * Resolves to the original array unmodified, this method is meant to be used for side effects.
26
+ * If the iterator function returns a promise or a thenable, the result for the promise is awaited for before continuing with next iteration.
27
+ */
28
+ each<R>(
29
+ values: Resolvable<Iterable<Resolvable<R>>>,
30
+ iterator: IterateFunction<R, any>
31
+ ): Syncbird<R[]>;
32
+
33
+ /**
34
+ * Reduce an array, or a promise of an array,
35
+ * which contains a promises (or a mix of promises and values) with the given `reducer` function with the signature `(total, current, index, arrayLength)`
36
+ * where `item` is the resolved value of a respective promise in the input array.
37
+ * If any promise in the input array is rejected the returned promise is rejected as well.
38
+ *
39
+ * If the reducer function returns a promise or a thenable, the result for the promise is awaited for before continuing with next iteration.
40
+ *
41
+ * *The original array is not modified. If no `initialValue` is given and the array doesn't contain at least 2 items,
42
+ * the callback will not be called and `undefined` is returned.
43
+ *
44
+ * If `initialValue` is given and the array doesn't have at least 1 item, `initialValue` is returned.*
45
+ */
46
+ reduce<R, U>(
47
+ values: Resolvable<Iterable<Resolvable<R>>>,
48
+ reducer: (total: U, current: R, index: number, arrayLength: number) => Resolvable<U>,
49
+ initialValue?: U
50
+ ): Syncbird<U>;
51
+
16
52
  /**
17
53
  * Create a promise that is resolved with the given `value`. If `value` is a thenable or promise, the returned promise will assume its state.
18
54
  */
@@ -22,25 +58,67 @@ interface SyncbirdStatic {
22
58
  try<R>(fn: () => Resolvable<R>): Syncbird<R>;
23
59
  attempt<R>(fn: () => Resolvable<R>): Syncbird<R>;
24
60
 
61
+ /**
62
+ * Configure long stack traces, warnings, monitoring and cancellation.
63
+ * Note that even though false is the default here, a development environment might be detected which automatically
64
+ * enables long stack traces and warnings.
65
+ */
66
+ config(options: {
67
+ /** Enable warnings */
68
+ warnings?: boolean | {
69
+ /** Enables all warnings except forgotten return statements. */
70
+ wForgottenReturn: boolean;
71
+ } | undefined;
72
+ /** Enable long stack traces */
73
+ longStackTraces?: boolean | undefined;
74
+ /** Enable cancellation */
75
+ cancellation?: boolean | undefined;
76
+ /** Enable monitoring */
77
+ monitoring?: boolean | undefined;
78
+ /** Enable async hooks */
79
+ asyncHooks?: boolean | undefined;
80
+ }): void;
81
+
25
82
  new <R>(callback: (resolve: (thenableOrResult?: Resolvable<R>) => void, reject: (error?: any) => void, onCancel?: (callback: () => void) => void) => void): Syncbird<R>;
26
83
  }
27
84
 
28
85
  export const Syncbird: SyncbirdStatic = Bluebird.getNewLibraryCopy() as any;
29
86
 
30
- const _then = Bluebird.prototype.then;
31
- Syncbird.prototype.then = function <T, TResult1 = T, TResult2 = never>(
32
- this: Bluebird<T>,
33
- onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null,
34
- onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null
35
- ): Syncbird<TResult1 | TResult2> {
87
+ Syncbird.config({
88
+ asyncHooks: false,
89
+ cancellation: false,
90
+ longStackTraces: false,
91
+ monitoring: false,
92
+ warnings: false,
93
+ });
94
+
95
+ // Bluebird uses `_then` internally.
96
+ const _then = (Syncbird.prototype as any)._then;
97
+ Syncbird.prototype._then = function <T, TResult1 = T, TResult2 = never>(
98
+ this: Syncbird<T>,
99
+ onfulfilled: ((value: T, internalData?: unknown) => unknown) | undefined | null,
100
+ onrejected: ((reason: any) => unknown) | undefined | null,
101
+ _: never,
102
+ receiver: unknown,
103
+ internalData: unknown,
104
+ ): Syncbird<unknown> {
36
105
  if (this.isFulfilled()) {
37
106
  if (!onfulfilled) {
38
- return this as unknown as Syncbird<TResult1>;
107
+ return this;
39
108
  } else {
40
- return Syncbird.resolve(onfulfilled(this.value())) as Syncbird<TResult1 | TResult2>;
109
+ // Synchronously call `onfulfilled`, and wrap the result in a new `Syncbird` object.
110
+ return Syncbird.resolve(
111
+ onfulfilled.call(
112
+ receiver,
113
+ this.value(),
114
+ // Some Bluebird internal methods (for example `reduce`) need this `internalData`
115
+ internalData
116
+ )
117
+ );
41
118
  }
42
119
  } else {
43
- return _then.call(this, onfulfilled, onrejected) as Syncbird<TResult1 | TResult2>;
120
+ // Forward to Bluebird's `_then` method.
121
+ return _then.call(this, onfulfilled, onrejected, _, receiver, internalData);
44
122
  }
45
123
  };
46
124
 
@@ -0,0 +1,102 @@
1
+ // cspell: ignore syncbird
2
+
3
+ import { getBigInt64, getBigUint64, setBigInt64, setBigUint64 } from '@yume-chan/dataview-bigint-polyfill/esm/fallback.js';
4
+ import { StructFieldDefinition, StructFieldValue, StructValue, type StructAsyncDeserializeStream, type StructDeserializeStream, type StructOptions } from "../basic/index.js";
5
+ import { Syncbird } from "../syncbird.js";
6
+ import type { ValueOrPromise } from "../utils.js";
7
+
8
+ type DataViewBigInt64Getter = (dataView: DataView, byteOffset: number, littleEndian: boolean | undefined) => bigint;
9
+
10
+ type DataViewBigInt64Setter = (dataView: DataView, byteOffset: number, value: bigint, littleEndian: boolean | undefined) => void;
11
+
12
+ export class BigIntFieldType {
13
+ public readonly TTypeScriptType!: bigint;
14
+
15
+ public readonly size: number;
16
+
17
+ public readonly getter: DataViewBigInt64Getter;
18
+
19
+ public readonly setter: DataViewBigInt64Setter;
20
+
21
+ public constructor(
22
+ size: number,
23
+ getter: DataViewBigInt64Getter,
24
+ setter: DataViewBigInt64Setter,
25
+ ) {
26
+ this.size = size;
27
+ this.getter = getter;
28
+ this.setter = setter;
29
+ }
30
+
31
+ public static readonly Int64 = new BigIntFieldType(8, getBigInt64, setBigInt64);
32
+
33
+ public static readonly Uint64 = new BigIntFieldType(8, getBigUint64, setBigUint64);
34
+ }
35
+
36
+ export class BigIntFieldDefinition<
37
+ TType extends BigIntFieldType = BigIntFieldType,
38
+ TTypeScriptType = TType["TTypeScriptType"],
39
+ > extends StructFieldDefinition<
40
+ void,
41
+ TTypeScriptType
42
+ > {
43
+ public readonly type: TType;
44
+
45
+ public constructor(type: TType, _typescriptType?: TTypeScriptType) {
46
+ super();
47
+ this.type = type;
48
+ }
49
+
50
+ public getSize(): number {
51
+ return this.type.size;
52
+ }
53
+
54
+ public create(
55
+ options: Readonly<StructOptions>,
56
+ struct: StructValue,
57
+ value: TTypeScriptType,
58
+ ): BigIntFieldValue<this> {
59
+ return new BigIntFieldValue(this, options, struct, value);
60
+ }
61
+
62
+ public override deserialize(
63
+ options: Readonly<StructOptions>,
64
+ stream: StructDeserializeStream,
65
+ struct: StructValue,
66
+ ): BigIntFieldValue<this>;
67
+ public override deserialize(
68
+ options: Readonly<StructOptions>,
69
+ stream: StructAsyncDeserializeStream,
70
+ struct: StructValue,
71
+ ): Promise<BigIntFieldValue<this>>;
72
+ public override deserialize(
73
+ options: Readonly<StructOptions>,
74
+ stream: StructDeserializeStream | StructAsyncDeserializeStream,
75
+ struct: StructValue,
76
+ ): ValueOrPromise<BigIntFieldValue<this>> {
77
+ return Syncbird.try(() => {
78
+ return stream.read(this.getSize());
79
+ }).then(array => {
80
+ const view = new DataView(array.buffer, array.byteOffset, array.byteLength);
81
+ const value = this.type.getter(
82
+ view,
83
+ 0,
84
+ options.littleEndian
85
+ );
86
+ return this.create(options, struct, value as any);
87
+ }).valueOrPromise();
88
+ }
89
+ }
90
+
91
+ export class BigIntFieldValue<
92
+ TDefinition extends BigIntFieldDefinition<BigIntFieldType, any>,
93
+ > extends StructFieldValue<TDefinition> {
94
+ public serialize(dataView: DataView, offset: number): void {
95
+ this.definition.type.setter(
96
+ dataView,
97
+ offset,
98
+ this.value!,
99
+ this.options.littleEndian
100
+ );
101
+ }
102
+ }