@yume-chan/struct 0.0.5 → 0.0.10
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/CHANGELOG.json +23 -0
- package/CHANGELOG.md +16 -0
- package/LICENSE +21 -21
- package/README.md +720 -643
- package/dts/basic/context.d.ts +10 -17
- package/dts/basic/context.d.ts.map +1 -1
- package/dts/basic/definition.d.ts +23 -23
- package/dts/basic/definition.d.ts.map +1 -1
- package/dts/basic/field-value.d.ts +38 -0
- package/dts/basic/field-value.d.ts.map +1 -0
- package/dts/basic/index.d.ts +2 -2
- package/dts/basic/index.d.ts.map +1 -1
- package/dts/basic/struct-value.d.ts +24 -0
- package/dts/basic/struct-value.d.ts.map +1 -0
- package/dts/index.d.ts +1 -0
- package/dts/index.d.ts.map +1 -1
- package/dts/struct.d.ts +44 -47
- package/dts/struct.d.ts.map +1 -1
- package/dts/syncbird.d.ts +20 -0
- package/dts/syncbird.d.ts.map +1 -0
- package/dts/types/array-buffer.d.ts +22 -20
- package/dts/types/array-buffer.d.ts.map +1 -1
- package/dts/types/fixed-length-array-buffer.d.ts +1 -3
- package/dts/types/fixed-length-array-buffer.d.ts.map +1 -1
- package/dts/types/index.d.ts +0 -1
- package/dts/types/index.d.ts.map +1 -1
- package/dts/types/number.d.ts +11 -10
- package/dts/types/number.d.ts.map +1 -1
- package/dts/types/variable-length-array-buffer.d.ts +21 -19
- package/dts/types/variable-length-array-buffer.d.ts.map +1 -1
- package/dts/{types/utils.d.ts → utils.d.ts} +3 -0
- package/dts/utils.d.ts.map +1 -0
- package/esm/basic/context.js +1 -1
- package/esm/basic/context.js.map +1 -1
- package/esm/basic/definition.js +9 -11
- package/esm/basic/definition.js.map +1 -1
- package/esm/basic/field-value.js +35 -0
- package/esm/basic/field-value.js.map +1 -0
- package/esm/basic/index.js +2 -2
- package/esm/basic/index.js.map +1 -1
- package/esm/basic/struct-value.js +36 -0
- package/esm/basic/struct-value.js.map +1 -0
- package/esm/index.js +1 -0
- package/esm/index.js.map +1 -1
- package/esm/struct.js +103 -176
- package/esm/struct.js.map +1 -1
- package/esm/syncbird.js +25 -0
- package/esm/syncbird.js.map +1 -0
- package/esm/types/array-buffer.js +83 -107
- package/esm/types/array-buffer.js.map +1 -1
- package/esm/types/fixed-length-array-buffer.js +5 -15
- package/esm/types/fixed-length-array-buffer.js.map +1 -1
- package/esm/types/index.js +0 -1
- package/esm/types/index.js.map +1 -1
- package/esm/types/number.js +35 -53
- package/esm/types/number.js.map +1 -1
- package/esm/types/variable-length-array-buffer.js +57 -68
- package/esm/types/variable-length-array-buffer.js.map +1 -1
- package/esm/utils.js +17 -0
- package/esm/utils.js.map +1 -0
- package/package.json +47 -50
- package/src/basic/context.ts +32 -40
- package/src/basic/definition.ts +72 -69
- package/src/basic/{runtime-value.ts → field-value.ts} +67 -72
- package/src/basic/index.ts +4 -4
- package/src/basic/struct-value.ts +39 -0
- package/src/index.ts +5 -4
- package/src/struct.ts +595 -579
- package/src/syncbird.ts +53 -0
- package/src/types/array-buffer.ts +194 -171
- package/src/types/fixed-length-array-buffer.ts +17 -27
- package/src/types/index.ts +4 -5
- package/src/types/number.ts +114 -101
- package/src/types/variable-length-array-buffer.ts +142 -121
- package/src/{types/utils.ts → utils.ts} +62 -47
- package/cjs/basic/context.js +0 -7
- package/cjs/basic/context.js.map +0 -1
- package/cjs/basic/definition.js +0 -26
- package/cjs/basic/definition.js.map +0 -1
- package/cjs/basic/index.js +0 -8
- package/cjs/basic/index.js.map +0 -1
- package/cjs/basic/runtime-object.js +0 -34
- package/cjs/basic/runtime-object.js.map +0 -1
- package/cjs/basic/runtime-value.js +0 -41
- package/cjs/basic/runtime-value.js.map +0 -1
- package/cjs/index.js +0 -10
- package/cjs/index.js.map +0 -1
- package/cjs/struct.js +0 -259
- package/cjs/struct.js.map +0 -1
- package/cjs/types/array-buffer.js +0 -137
- package/cjs/types/array-buffer.js.map +0 -1
- package/cjs/types/fixed-length-array-buffer.js +0 -21
- package/cjs/types/fixed-length-array-buffer.js.map +0 -1
- package/cjs/types/index.js +0 -9
- package/cjs/types/index.js.map +0 -1
- package/cjs/types/number.js +0 -68
- package/cjs/types/number.js.map +0 -1
- package/cjs/types/utils.js +0 -11
- package/cjs/types/utils.js.map +0 -1
- package/cjs/types/variable-length-array-buffer.js +0 -85
- package/cjs/types/variable-length-array-buffer.js.map +0 -1
- package/dts/basic/runtime-object.d.ts +0 -17
- package/dts/basic/runtime-object.d.ts.map +0 -1
- package/dts/basic/runtime-value.d.ts +0 -39
- package/dts/basic/runtime-value.d.ts.map +0 -1
- package/dts/types/utils.d.ts.map +0 -1
- package/esm/basic/runtime-object.js +0 -28
- package/esm/basic/runtime-object.js.map +0 -1
- package/esm/basic/runtime-value.js +0 -38
- package/esm/basic/runtime-value.js.map +0 -1
- package/esm/types/utils.js +0 -7
- package/esm/types/utils.js.map +0 -1
- package/src/basic/context.spec.ts +0 -9
- package/src/basic/definition.spec.ts +0 -26
- package/src/basic/runtime-object.spec.ts +0 -38
- package/src/basic/runtime-object.ts +0 -36
- package/src/basic/runtime-value.spec.ts +0 -71
- package/src/types/array-buffer.spec.ts +0 -88
- package/src/types/number.spec.ts +0 -262
- package/tsconfig.cjs.json +0 -11
- package/tsconfig.esm.json +0 -15
package/src/struct.ts
CHANGED
|
@@ -1,579 +1,595 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
*
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
Identity<Struct<
|
|
29
|
-
// Merge two types
|
|
30
|
-
// Evaluate immediately to optimize editor hover tooltip
|
|
31
|
-
Evaluate<TFields & Record<TFieldName, TDefinition['
|
|
32
|
-
// Merge two `
|
|
33
|
-
|
|
34
|
-
TExtra,
|
|
35
|
-
TPostDeserialized
|
|
36
|
-
>>;
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Overload methods to add an array buffer like field
|
|
40
|
-
*/
|
|
41
|
-
interface ArrayBufferLikeFieldCreator<
|
|
42
|
-
TFields extends object,
|
|
43
|
-
|
|
44
|
-
TExtra extends object,
|
|
45
|
-
TPostDeserialized
|
|
46
|
-
> {
|
|
47
|
-
/**
|
|
48
|
-
* Append a fixed-length array to the `Struct`
|
|
49
|
-
*
|
|
50
|
-
* @param name Name of the field
|
|
51
|
-
* @param type `Array.SubType.ArrayBuffer` or `Array.SubType.String`
|
|
52
|
-
* @param options Fixed-length array options
|
|
53
|
-
* @param typescriptType Type of the field in TypeScript.
|
|
54
|
-
* For example, if this field is a string, you can declare it as a string enum or literal union.
|
|
55
|
-
*/
|
|
56
|
-
<
|
|
57
|
-
TName extends PropertyKey,
|
|
58
|
-
TType extends ArrayBufferLikeFieldType,
|
|
59
|
-
TTypeScriptType = TType['
|
|
60
|
-
>(
|
|
61
|
-
name: TName,
|
|
62
|
-
type: TType,
|
|
63
|
-
options: FixedLengthArrayBufferLikeFieldOptions,
|
|
64
|
-
typescriptType?: TTypeScriptType,
|
|
65
|
-
): AddFieldDescriptor<
|
|
66
|
-
TFields,
|
|
67
|
-
|
|
68
|
-
TExtra,
|
|
69
|
-
TPostDeserialized,
|
|
70
|
-
TName,
|
|
71
|
-
FixedLengthArrayBufferLikeFieldDefinition<
|
|
72
|
-
TType,
|
|
73
|
-
FixedLengthArrayBufferLikeFieldOptions
|
|
74
|
-
>
|
|
75
|
-
>;
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Append a variable-length array to the `Struct`
|
|
79
|
-
*/
|
|
80
|
-
<
|
|
81
|
-
TName extends PropertyKey,
|
|
82
|
-
TType extends ArrayBufferLikeFieldType,
|
|
83
|
-
TOptions extends VariableLengthArrayBufferLikeFieldOptions<TFields>,
|
|
84
|
-
TTypeScriptType = TType['
|
|
85
|
-
>(
|
|
86
|
-
name: TName,
|
|
87
|
-
type: TType,
|
|
88
|
-
options: TOptions,
|
|
89
|
-
typescriptType?: TTypeScriptType,
|
|
90
|
-
): AddFieldDescriptor<
|
|
91
|
-
TFields,
|
|
92
|
-
|
|
93
|
-
TExtra,
|
|
94
|
-
TPostDeserialized,
|
|
95
|
-
TName,
|
|
96
|
-
VariableLengthArrayBufferLikeFieldDefinition<
|
|
97
|
-
TType,
|
|
98
|
-
TOptions
|
|
99
|
-
>
|
|
100
|
-
>;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Similar to `ArrayBufferLikeFieldCreator`, but bind to
|
|
105
|
-
*/
|
|
106
|
-
interface
|
|
107
|
-
TFields extends object,
|
|
108
|
-
|
|
109
|
-
TExtra extends object,
|
|
110
|
-
TPostDeserialized,
|
|
111
|
-
TType extends ArrayBufferLikeFieldType
|
|
112
|
-
> {
|
|
113
|
-
<
|
|
114
|
-
TName extends PropertyKey,
|
|
115
|
-
TTypeScriptType = TType['
|
|
116
|
-
>(
|
|
117
|
-
name: TName,
|
|
118
|
-
options: FixedLengthArrayBufferLikeFieldOptions,
|
|
119
|
-
typescriptType?: TTypeScriptType,
|
|
120
|
-
): AddFieldDescriptor<
|
|
121
|
-
TFields,
|
|
122
|
-
|
|
123
|
-
TExtra,
|
|
124
|
-
TPostDeserialized,
|
|
125
|
-
TName,
|
|
126
|
-
FixedLengthArrayBufferLikeFieldDefinition<
|
|
127
|
-
TType,
|
|
128
|
-
FixedLengthArrayBufferLikeFieldOptions
|
|
129
|
-
>
|
|
130
|
-
>;
|
|
131
|
-
|
|
132
|
-
<
|
|
133
|
-
TName extends PropertyKey,
|
|
134
|
-
TLengthField extends
|
|
135
|
-
TOptions extends VariableLengthArrayBufferLikeFieldOptions<TFields, TLengthField>,
|
|
136
|
-
TTypeScriptType = TType['
|
|
137
|
-
>(
|
|
138
|
-
name: TName,
|
|
139
|
-
options: TOptions,
|
|
140
|
-
typescriptType?: TTypeScriptType,
|
|
141
|
-
): AddFieldDescriptor<
|
|
142
|
-
TFields,
|
|
143
|
-
|
|
144
|
-
TExtra,
|
|
145
|
-
TPostDeserialized,
|
|
146
|
-
TName,
|
|
147
|
-
VariableLengthArrayBufferLikeFieldDefinition<
|
|
148
|
-
TType,
|
|
149
|
-
TOptions
|
|
150
|
-
>
|
|
151
|
-
>;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
export type StructPostDeserialized<
|
|
155
|
-
(this:
|
|
156
|
-
|
|
157
|
-
export type
|
|
158
|
-
TPostDeserialized extends undefined ? Overwrite<TExtra, TFields> : TPostDeserialized;
|
|
159
|
-
|
|
160
|
-
export class Struct<
|
|
161
|
-
TFields extends object = {},
|
|
162
|
-
|
|
163
|
-
TExtra extends object = {},
|
|
164
|
-
TPostDeserialized = undefined,
|
|
165
|
-
> implements StructLike<
|
|
166
|
-
public readonly
|
|
167
|
-
|
|
168
|
-
public readonly
|
|
169
|
-
|
|
170
|
-
public readonly
|
|
171
|
-
|
|
172
|
-
public readonly
|
|
173
|
-
|
|
174
|
-
public readonly
|
|
175
|
-
|
|
176
|
-
public readonly options: Readonly<StructOptions>;
|
|
177
|
-
|
|
178
|
-
private _size = 0;
|
|
179
|
-
/**
|
|
180
|
-
* Gets the static size (exclude fields that can change size at runtime)
|
|
181
|
-
*/
|
|
182
|
-
public get size() { return this._size; }
|
|
183
|
-
|
|
184
|
-
private _fields: [name: PropertyKey, definition:
|
|
185
|
-
|
|
186
|
-
private _extra: PropertyDescriptorMap = {};
|
|
187
|
-
|
|
188
|
-
private _postDeserialized?: StructPostDeserialized<any, any>;
|
|
189
|
-
|
|
190
|
-
public constructor(options?: Partial<StructOptions
|
|
191
|
-
this.options = { ...StructDefaultOptions, ...options };
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Appends a `
|
|
196
|
-
*/
|
|
197
|
-
public field<
|
|
198
|
-
TName extends PropertyKey,
|
|
199
|
-
TDefinition extends
|
|
200
|
-
>(
|
|
201
|
-
name: TName,
|
|
202
|
-
definition: TDefinition,
|
|
203
|
-
): AddFieldDescriptor<
|
|
204
|
-
TFields,
|
|
205
|
-
|
|
206
|
-
TExtra,
|
|
207
|
-
TPostDeserialized,
|
|
208
|
-
TName,
|
|
209
|
-
TDefinition
|
|
210
|
-
> {
|
|
211
|
-
this._fields
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
*
|
|
464
|
-
*
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
*
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
*
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
return
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
public
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
const
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
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";
|
|
6
|
+
|
|
7
|
+
export interface StructLike<TValue> {
|
|
8
|
+
deserialize(stream: StructDeserializeStream | StructAsyncDeserializeStream): Promise<TValue>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Extract the value type of the specified `Struct`
|
|
13
|
+
*/
|
|
14
|
+
export type StructValueType<T extends StructLike<any>> =
|
|
15
|
+
Awaited<ReturnType<T['deserialize']>>;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Create a new `Struct` type with `TDefinition` appended
|
|
19
|
+
*/
|
|
20
|
+
type AddFieldDescriptor<
|
|
21
|
+
TFields extends object,
|
|
22
|
+
TOmitInitKey extends PropertyKey,
|
|
23
|
+
TExtra extends object,
|
|
24
|
+
TPostDeserialized,
|
|
25
|
+
TFieldName extends PropertyKey,
|
|
26
|
+
TDefinition extends StructFieldDefinition<any, any, any>
|
|
27
|
+
> =
|
|
28
|
+
Identity<Struct<
|
|
29
|
+
// Merge two types
|
|
30
|
+
// Evaluate immediately to optimize editor hover tooltip
|
|
31
|
+
Evaluate<TFields & Record<TFieldName, TDefinition['TValue']>>,
|
|
32
|
+
// Merge two `TOmitInitKey`s
|
|
33
|
+
TOmitInitKey | TDefinition['TOmitInitKey'],
|
|
34
|
+
TExtra,
|
|
35
|
+
TPostDeserialized
|
|
36
|
+
>>;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Overload methods to add an array buffer like field
|
|
40
|
+
*/
|
|
41
|
+
interface ArrayBufferLikeFieldCreator<
|
|
42
|
+
TFields extends object,
|
|
43
|
+
TOmitInitKey extends PropertyKey,
|
|
44
|
+
TExtra extends object,
|
|
45
|
+
TPostDeserialized
|
|
46
|
+
> {
|
|
47
|
+
/**
|
|
48
|
+
* Append a fixed-length array buffer like field to the `Struct`
|
|
49
|
+
*
|
|
50
|
+
* @param name Name of the field
|
|
51
|
+
* @param type `Array.SubType.ArrayBuffer` or `Array.SubType.String`
|
|
52
|
+
* @param options Fixed-length array options
|
|
53
|
+
* @param typescriptType Type of the field in TypeScript.
|
|
54
|
+
* For example, if this field is a string, you can declare it as a string enum or literal union.
|
|
55
|
+
*/
|
|
56
|
+
<
|
|
57
|
+
TName extends PropertyKey,
|
|
58
|
+
TType extends ArrayBufferLikeFieldType<any, any>,
|
|
59
|
+
TTypeScriptType = TType['TTypeScriptType'],
|
|
60
|
+
>(
|
|
61
|
+
name: TName,
|
|
62
|
+
type: TType,
|
|
63
|
+
options: FixedLengthArrayBufferLikeFieldOptions,
|
|
64
|
+
typescriptType?: TTypeScriptType,
|
|
65
|
+
): AddFieldDescriptor<
|
|
66
|
+
TFields,
|
|
67
|
+
TOmitInitKey,
|
|
68
|
+
TExtra,
|
|
69
|
+
TPostDeserialized,
|
|
70
|
+
TName,
|
|
71
|
+
FixedLengthArrayBufferLikeFieldDefinition<
|
|
72
|
+
TType,
|
|
73
|
+
FixedLengthArrayBufferLikeFieldOptions
|
|
74
|
+
>
|
|
75
|
+
>;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Append a variable-length array buffer like field to the `Struct`
|
|
79
|
+
*/
|
|
80
|
+
<
|
|
81
|
+
TName extends PropertyKey,
|
|
82
|
+
TType extends ArrayBufferLikeFieldType<any, any>,
|
|
83
|
+
TOptions extends VariableLengthArrayBufferLikeFieldOptions<TFields>,
|
|
84
|
+
TTypeScriptType = TType['TTypeScriptType'],
|
|
85
|
+
>(
|
|
86
|
+
name: TName,
|
|
87
|
+
type: TType,
|
|
88
|
+
options: TOptions,
|
|
89
|
+
typescriptType?: TTypeScriptType,
|
|
90
|
+
): AddFieldDescriptor<
|
|
91
|
+
TFields,
|
|
92
|
+
TOmitInitKey,
|
|
93
|
+
TExtra,
|
|
94
|
+
TPostDeserialized,
|
|
95
|
+
TName,
|
|
96
|
+
VariableLengthArrayBufferLikeFieldDefinition<
|
|
97
|
+
TType,
|
|
98
|
+
TOptions
|
|
99
|
+
>
|
|
100
|
+
>;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Similar to `ArrayBufferLikeFieldCreator`, but bind to `TType`
|
|
105
|
+
*/
|
|
106
|
+
interface BindedArrayBufferLikeFieldDefinitionCreator<
|
|
107
|
+
TFields extends object,
|
|
108
|
+
TOmitInitKey extends PropertyKey,
|
|
109
|
+
TExtra extends object,
|
|
110
|
+
TPostDeserialized,
|
|
111
|
+
TType extends ArrayBufferLikeFieldType<any, any>
|
|
112
|
+
> {
|
|
113
|
+
<
|
|
114
|
+
TName extends PropertyKey,
|
|
115
|
+
TTypeScriptType = TType['TTypeScriptType'],
|
|
116
|
+
>(
|
|
117
|
+
name: TName,
|
|
118
|
+
options: FixedLengthArrayBufferLikeFieldOptions,
|
|
119
|
+
typescriptType?: TTypeScriptType,
|
|
120
|
+
): AddFieldDescriptor<
|
|
121
|
+
TFields,
|
|
122
|
+
TOmitInitKey,
|
|
123
|
+
TExtra,
|
|
124
|
+
TPostDeserialized,
|
|
125
|
+
TName,
|
|
126
|
+
FixedLengthArrayBufferLikeFieldDefinition<
|
|
127
|
+
TType,
|
|
128
|
+
FixedLengthArrayBufferLikeFieldOptions
|
|
129
|
+
>
|
|
130
|
+
>;
|
|
131
|
+
|
|
132
|
+
<
|
|
133
|
+
TName extends PropertyKey,
|
|
134
|
+
TLengthField extends LengthField<TFields>,
|
|
135
|
+
TOptions extends VariableLengthArrayBufferLikeFieldOptions<TFields, TLengthField>,
|
|
136
|
+
TTypeScriptType = TType['TTypeScriptType'],
|
|
137
|
+
>(
|
|
138
|
+
name: TName,
|
|
139
|
+
options: TOptions,
|
|
140
|
+
typescriptType?: TTypeScriptType,
|
|
141
|
+
): AddFieldDescriptor<
|
|
142
|
+
TFields,
|
|
143
|
+
TOmitInitKey,
|
|
144
|
+
TExtra,
|
|
145
|
+
TPostDeserialized,
|
|
146
|
+
TName,
|
|
147
|
+
VariableLengthArrayBufferLikeFieldDefinition<
|
|
148
|
+
TType,
|
|
149
|
+
TOptions
|
|
150
|
+
>
|
|
151
|
+
>;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export type StructPostDeserialized<TFields, TPostDeserialized> =
|
|
155
|
+
(this: TFields, object: TFields) => TPostDeserialized;
|
|
156
|
+
|
|
157
|
+
export type StructDeserializedResult<TFields extends object, TExtra extends object, TPostDeserialized> =
|
|
158
|
+
TPostDeserialized extends undefined ? Overwrite<TExtra, TFields> : TPostDeserialized;
|
|
159
|
+
|
|
160
|
+
export class Struct<
|
|
161
|
+
TFields extends object = {},
|
|
162
|
+
TOmitInitKey extends PropertyKey = never,
|
|
163
|
+
TExtra extends object = {},
|
|
164
|
+
TPostDeserialized = undefined,
|
|
165
|
+
> implements StructLike<StructDeserializedResult<TFields, TExtra, TPostDeserialized>>{
|
|
166
|
+
public readonly TFields!: TFields;
|
|
167
|
+
|
|
168
|
+
public readonly TOmitInitKey!: TOmitInitKey;
|
|
169
|
+
|
|
170
|
+
public readonly TExtra!: TExtra;
|
|
171
|
+
|
|
172
|
+
public readonly TInit!: Evaluate<Omit<TFields, TOmitInitKey>>;
|
|
173
|
+
|
|
174
|
+
public readonly TDeserializeResult!: StructDeserializedResult<TFields, TExtra, TPostDeserialized>;
|
|
175
|
+
|
|
176
|
+
public readonly options: Readonly<StructOptions>;
|
|
177
|
+
|
|
178
|
+
private _size = 0;
|
|
179
|
+
/**
|
|
180
|
+
* Gets the static size (exclude fields that can change size at runtime)
|
|
181
|
+
*/
|
|
182
|
+
public get size() { return this._size; }
|
|
183
|
+
|
|
184
|
+
private _fields: [name: PropertyKey, definition: StructFieldDefinition<any, any, any>][] = [];
|
|
185
|
+
|
|
186
|
+
private _extra: PropertyDescriptorMap = {};
|
|
187
|
+
|
|
188
|
+
private _postDeserialized?: StructPostDeserialized<any, any>;
|
|
189
|
+
|
|
190
|
+
public constructor(options?: Partial<Readonly<StructOptions>>) {
|
|
191
|
+
this.options = { ...StructDefaultOptions, ...options };
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Appends a `StructFieldDefinition` to the `Struct
|
|
196
|
+
*/
|
|
197
|
+
public field<
|
|
198
|
+
TName extends PropertyKey,
|
|
199
|
+
TDefinition extends StructFieldDefinition<any, any, any>
|
|
200
|
+
>(
|
|
201
|
+
name: TName,
|
|
202
|
+
definition: TDefinition,
|
|
203
|
+
): AddFieldDescriptor<
|
|
204
|
+
TFields,
|
|
205
|
+
TOmitInitKey,
|
|
206
|
+
TExtra,
|
|
207
|
+
TPostDeserialized,
|
|
208
|
+
TName,
|
|
209
|
+
TDefinition
|
|
210
|
+
> {
|
|
211
|
+
for (const field of this._fields) {
|
|
212
|
+
if (field[0] === name) {
|
|
213
|
+
throw new Error(`This struct already have a field with name '${name}'`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
this._fields.push([name, definition]);
|
|
218
|
+
|
|
219
|
+
const size = definition.getSize();
|
|
220
|
+
this._size += size;
|
|
221
|
+
|
|
222
|
+
// Force cast `this` to another type
|
|
223
|
+
return this as any;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Merges (flats) another `Struct`'s fields and extra fields into this one.
|
|
228
|
+
*/
|
|
229
|
+
public fields<TOther extends Struct<any, any, any, any>>(
|
|
230
|
+
other: TOther
|
|
231
|
+
): Struct<
|
|
232
|
+
TFields & TOther['TFields'],
|
|
233
|
+
TOmitInitKey | TOther['TOmitInitKey'],
|
|
234
|
+
TExtra & TOther['TExtra'],
|
|
235
|
+
TPostDeserialized
|
|
236
|
+
> {
|
|
237
|
+
for (const field of other._fields) {
|
|
238
|
+
this._fields.push(field);
|
|
239
|
+
}
|
|
240
|
+
this._size += other._size;
|
|
241
|
+
Object.assign(this._extra, other._extra);
|
|
242
|
+
return this as any;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
private number<
|
|
246
|
+
TName extends PropertyKey,
|
|
247
|
+
TType extends NumberFieldType = NumberFieldType,
|
|
248
|
+
TTypeScriptType = TType['TTypeScriptType']
|
|
249
|
+
>(
|
|
250
|
+
name: TName,
|
|
251
|
+
type: TType,
|
|
252
|
+
_typescriptType?: TTypeScriptType,
|
|
253
|
+
) {
|
|
254
|
+
return this.field(
|
|
255
|
+
name,
|
|
256
|
+
new NumberFieldDefinition(type, _typescriptType),
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Appends an `int8` field to the `Struct`
|
|
262
|
+
*/
|
|
263
|
+
public int8<
|
|
264
|
+
TName extends PropertyKey,
|
|
265
|
+
TTypeScriptType = (typeof NumberFieldType)['Uint8']['TTypeScriptType']
|
|
266
|
+
>(
|
|
267
|
+
name: TName,
|
|
268
|
+
_typescriptType?: TTypeScriptType,
|
|
269
|
+
) {
|
|
270
|
+
return this.number(
|
|
271
|
+
name,
|
|
272
|
+
NumberFieldType.Int8,
|
|
273
|
+
_typescriptType
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Appends an `uint8` field to the `Struct`
|
|
279
|
+
*/
|
|
280
|
+
public uint8<
|
|
281
|
+
TName extends PropertyKey,
|
|
282
|
+
TTypeScriptType = (typeof NumberFieldType)['Uint8']['TTypeScriptType']
|
|
283
|
+
>(
|
|
284
|
+
name: TName,
|
|
285
|
+
_typescriptType?: TTypeScriptType,
|
|
286
|
+
) {
|
|
287
|
+
return this.number(
|
|
288
|
+
name,
|
|
289
|
+
NumberFieldType.Uint8,
|
|
290
|
+
_typescriptType
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Appends an `int16` field to the `Struct`
|
|
296
|
+
*/
|
|
297
|
+
public int16<
|
|
298
|
+
TName extends PropertyKey,
|
|
299
|
+
TTypeScriptType = (typeof NumberFieldType)['Uint16']['TTypeScriptType']
|
|
300
|
+
>(
|
|
301
|
+
name: TName,
|
|
302
|
+
_typescriptType?: TTypeScriptType,
|
|
303
|
+
) {
|
|
304
|
+
return this.number(
|
|
305
|
+
name,
|
|
306
|
+
NumberFieldType.Int16,
|
|
307
|
+
_typescriptType
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Appends an `uint16` field to the `Struct`
|
|
313
|
+
*/
|
|
314
|
+
public uint16<
|
|
315
|
+
TName extends PropertyKey,
|
|
316
|
+
TTypeScriptType = (typeof NumberFieldType)['Uint16']['TTypeScriptType']
|
|
317
|
+
>(
|
|
318
|
+
name: TName,
|
|
319
|
+
_typescriptType?: TTypeScriptType,
|
|
320
|
+
) {
|
|
321
|
+
return this.number(
|
|
322
|
+
name,
|
|
323
|
+
NumberFieldType.Uint16,
|
|
324
|
+
_typescriptType
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Appends an `int32` field to the `Struct`
|
|
330
|
+
*/
|
|
331
|
+
public int32<
|
|
332
|
+
TName extends PropertyKey,
|
|
333
|
+
TTypeScriptType = (typeof NumberFieldType)['Int32']['TTypeScriptType']
|
|
334
|
+
>(
|
|
335
|
+
name: TName,
|
|
336
|
+
_typescriptType?: TTypeScriptType,
|
|
337
|
+
) {
|
|
338
|
+
return this.number(
|
|
339
|
+
name,
|
|
340
|
+
NumberFieldType.Int32,
|
|
341
|
+
_typescriptType
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Appends an `uint32` field to the `Struct`
|
|
347
|
+
*/
|
|
348
|
+
public uint32<
|
|
349
|
+
TName extends PropertyKey,
|
|
350
|
+
TTypeScriptType = (typeof NumberFieldType)['Uint32']['TTypeScriptType']
|
|
351
|
+
>(
|
|
352
|
+
name: TName,
|
|
353
|
+
typescriptType?: TTypeScriptType,
|
|
354
|
+
) {
|
|
355
|
+
return this.number(
|
|
356
|
+
name,
|
|
357
|
+
NumberFieldType.Uint32,
|
|
358
|
+
typescriptType
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Appends an `int64` field to the `Struct`
|
|
364
|
+
*
|
|
365
|
+
* Requires native `BigInt` support
|
|
366
|
+
*/
|
|
367
|
+
public int64<
|
|
368
|
+
TName extends PropertyKey,
|
|
369
|
+
TTypeScriptType = (typeof NumberFieldType)['Int64']['TTypeScriptType']
|
|
370
|
+
>(
|
|
371
|
+
name: TName,
|
|
372
|
+
_typescriptType?: TTypeScriptType,
|
|
373
|
+
) {
|
|
374
|
+
return this.number(
|
|
375
|
+
name,
|
|
376
|
+
NumberFieldType.Int64,
|
|
377
|
+
_typescriptType
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Appends an `uint64` field to the `Struct`
|
|
383
|
+
*
|
|
384
|
+
* Requires native `BigInt` support
|
|
385
|
+
*/
|
|
386
|
+
public uint64<
|
|
387
|
+
TName extends PropertyKey,
|
|
388
|
+
TTypeScriptType = (typeof NumberFieldType)['Uint64']['TTypeScriptType']
|
|
389
|
+
>(
|
|
390
|
+
name: TName,
|
|
391
|
+
_typescriptType?: TTypeScriptType,
|
|
392
|
+
) {
|
|
393
|
+
return this.number(
|
|
394
|
+
name,
|
|
395
|
+
NumberFieldType.Uint64,
|
|
396
|
+
_typescriptType
|
|
397
|
+
);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
private arrayBufferLike: ArrayBufferLikeFieldCreator<
|
|
401
|
+
TFields,
|
|
402
|
+
TOmitInitKey,
|
|
403
|
+
TExtra,
|
|
404
|
+
TPostDeserialized
|
|
405
|
+
> = (
|
|
406
|
+
name: PropertyKey,
|
|
407
|
+
type: ArrayBufferLikeFieldType,
|
|
408
|
+
options: FixedLengthArrayBufferLikeFieldOptions | VariableLengthArrayBufferLikeFieldOptions
|
|
409
|
+
): any => {
|
|
410
|
+
if ('length' in options) {
|
|
411
|
+
return this.field(
|
|
412
|
+
name,
|
|
413
|
+
new FixedLengthArrayBufferLikeFieldDefinition(type, options),
|
|
414
|
+
);
|
|
415
|
+
} else {
|
|
416
|
+
return this.field(
|
|
417
|
+
name,
|
|
418
|
+
new VariableLengthArrayBufferLikeFieldDefinition(type, options),
|
|
419
|
+
);
|
|
420
|
+
}
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
public arrayBuffer: BindedArrayBufferLikeFieldDefinitionCreator<
|
|
424
|
+
TFields,
|
|
425
|
+
TOmitInitKey,
|
|
426
|
+
TExtra,
|
|
427
|
+
TPostDeserialized,
|
|
428
|
+
ArrayBufferFieldType
|
|
429
|
+
> = (
|
|
430
|
+
name: PropertyKey,
|
|
431
|
+
options: any
|
|
432
|
+
): any => {
|
|
433
|
+
return this.arrayBufferLike(name, ArrayBufferFieldType.instance, options);
|
|
434
|
+
};
|
|
435
|
+
|
|
436
|
+
public uint8ClampedArray: BindedArrayBufferLikeFieldDefinitionCreator<
|
|
437
|
+
TFields,
|
|
438
|
+
TOmitInitKey,
|
|
439
|
+
TExtra,
|
|
440
|
+
TPostDeserialized,
|
|
441
|
+
Uint8ClampedArrayFieldType
|
|
442
|
+
> = (
|
|
443
|
+
name: PropertyKey,
|
|
444
|
+
options: any
|
|
445
|
+
): 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);
|
|
460
|
+
};
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* Adds some extra properties into every `Struct` value.
|
|
464
|
+
*
|
|
465
|
+
* Extra properties will not affect serialize or deserialize process.
|
|
466
|
+
*
|
|
467
|
+
* Multiple calls to `extra` will merge all properties together.
|
|
468
|
+
*
|
|
469
|
+
* @param value
|
|
470
|
+
* An object containing properties to be added to the result value. Accessors and methods are also allowed.
|
|
471
|
+
*/
|
|
472
|
+
public extra<T extends Record<
|
|
473
|
+
// This trick disallows any keys that are already in `TValue`
|
|
474
|
+
Exclude<
|
|
475
|
+
keyof T,
|
|
476
|
+
Exclude<keyof T, keyof TFields>
|
|
477
|
+
>,
|
|
478
|
+
never
|
|
479
|
+
>>(
|
|
480
|
+
value: T & ThisType<Overwrite<Overwrite<TExtra, T>, TFields>>
|
|
481
|
+
): Struct<
|
|
482
|
+
TFields,
|
|
483
|
+
TOmitInitKey,
|
|
484
|
+
Overwrite<TExtra, T>,
|
|
485
|
+
TPostDeserialized
|
|
486
|
+
> {
|
|
487
|
+
Object.assign(this._extra, Object.getOwnPropertyDescriptors(value));
|
|
488
|
+
return this as any;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
* Registers (or replaces) a custom callback to be run after deserialized.
|
|
493
|
+
*
|
|
494
|
+
* A callback returning `never` (always throw an error)
|
|
495
|
+
* will also change the return type of `deserialize` to `never`.
|
|
496
|
+
*/
|
|
497
|
+
public postDeserialize(
|
|
498
|
+
callback: StructPostDeserialized<TFields, never>
|
|
499
|
+
): Struct<TFields, TOmitInitKey, TExtra, never>;
|
|
500
|
+
/**
|
|
501
|
+
* Registers (or replaces) a custom callback to be run after deserialized.
|
|
502
|
+
*
|
|
503
|
+
* A callback returning `void` means it modify the result object in-place
|
|
504
|
+
* (or doesn't modify it at all), so `deserialize` will still return the result object.
|
|
505
|
+
*/
|
|
506
|
+
public postDeserialize(
|
|
507
|
+
callback?: StructPostDeserialized<TFields, void>
|
|
508
|
+
): Struct<TFields, TOmitInitKey, TExtra, undefined>;
|
|
509
|
+
/**
|
|
510
|
+
* Registers (or replaces) a custom callback to be run after deserialized.
|
|
511
|
+
*
|
|
512
|
+
* A callback returning anything other than `undefined`
|
|
513
|
+
* will `deserialize` to return that object instead.
|
|
514
|
+
*/
|
|
515
|
+
public postDeserialize<TPostSerialize>(
|
|
516
|
+
callback?: StructPostDeserialized<TFields, TPostSerialize>
|
|
517
|
+
): Struct<TFields, TOmitInitKey, TExtra, TPostSerialize>;
|
|
518
|
+
public postDeserialize(
|
|
519
|
+
callback?: StructPostDeserialized<TFields, any>
|
|
520
|
+
) {
|
|
521
|
+
this._postDeserialized = callback;
|
|
522
|
+
return this as any;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
public deserialize(
|
|
526
|
+
stream: StructDeserializeStream,
|
|
527
|
+
): StructDeserializedResult<TFields, TExtra, TPostDeserialized>;
|
|
528
|
+
public deserialize(
|
|
529
|
+
stream: StructAsyncDeserializeStream,
|
|
530
|
+
): Promise<StructDeserializedResult<TFields, TExtra, TPostDeserialized>>;
|
|
531
|
+
public deserialize(
|
|
532
|
+
stream: StructDeserializeStream | StructAsyncDeserializeStream,
|
|
533
|
+
): ValueOrPromise<StructDeserializedResult<TFields, TExtra, TPostDeserialized>> {
|
|
534
|
+
const value = new StructValue();
|
|
535
|
+
Object.defineProperties(value.value, this._extra);
|
|
536
|
+
|
|
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;
|
|
546
|
+
return Syncbird.resolve(
|
|
547
|
+
definition.deserialize(this.options, stream as any, value)
|
|
548
|
+
).then(fieldValue => {
|
|
549
|
+
value.set(name, fieldValue);
|
|
550
|
+
return iterate();
|
|
551
|
+
});
|
|
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;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
return value.value;
|
|
564
|
+
}).valueOrPromise();
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
public serialize(init: Evaluate<Omit<TFields, TOmitInitKey>>): ArrayBuffer {
|
|
568
|
+
const value = new StructValue();
|
|
569
|
+
|
|
570
|
+
for (const [name, definition] of this._fields) {
|
|
571
|
+
const fieldValue = definition.create(this.options, value, (init as any)[name]);
|
|
572
|
+
value.set(name, fieldValue);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
let structSize = 0;
|
|
576
|
+
const fieldsInfo: { fieldValue: StructFieldValue, size: number; }[] = [];
|
|
577
|
+
|
|
578
|
+
for (const [name] of this._fields) {
|
|
579
|
+
const fieldValue = value.get(name);
|
|
580
|
+
const size = fieldValue.getSize();
|
|
581
|
+
fieldsInfo.push({ fieldValue, size });
|
|
582
|
+
structSize += size;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
const buffer = new ArrayBuffer(structSize);
|
|
586
|
+
const dataView = new DataView(buffer);
|
|
587
|
+
let offset = 0;
|
|
588
|
+
for (const { fieldValue, size } of fieldsInfo) {
|
|
589
|
+
fieldValue.serialize(dataView, offset);
|
|
590
|
+
offset += size;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
return buffer;
|
|
594
|
+
}
|
|
595
|
+
}
|