@colyseus/schema 3.0.0-alpha.30 → 3.0.0-alpha.31

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 (73) hide show
  1. package/build/cjs/index.js +383 -341
  2. package/build/cjs/index.js.map +1 -1
  3. package/build/esm/index.mjs +383 -341
  4. package/build/esm/index.mjs.map +1 -1
  5. package/build/umd/index.js +383 -341
  6. package/lib/Metadata.d.ts +14 -5
  7. package/lib/Metadata.js +49 -20
  8. package/lib/Metadata.js.map +1 -1
  9. package/lib/Reflection.js +4 -13
  10. package/lib/Reflection.js.map +1 -1
  11. package/lib/Schema.js +26 -39
  12. package/lib/Schema.js.map +1 -1
  13. package/lib/annotations.d.ts +1 -2
  14. package/lib/annotations.js +58 -52
  15. package/lib/annotations.js.map +1 -1
  16. package/lib/bench_encode.js +33 -11
  17. package/lib/bench_encode.js.map +1 -1
  18. package/lib/decoder/DecodeOperation.js +4 -8
  19. package/lib/decoder/DecodeOperation.js.map +1 -1
  20. package/lib/decoder/ReferenceTracker.js +3 -2
  21. package/lib/decoder/ReferenceTracker.js.map +1 -1
  22. package/lib/decoder/strategy/StateCallbacks.js +4 -3
  23. package/lib/decoder/strategy/StateCallbacks.js.map +1 -1
  24. package/lib/encoder/ChangeTree.d.ts +8 -7
  25. package/lib/encoder/ChangeTree.js +128 -115
  26. package/lib/encoder/ChangeTree.js.map +1 -1
  27. package/lib/encoder/EncodeOperation.d.ts +1 -4
  28. package/lib/encoder/EncodeOperation.js +46 -46
  29. package/lib/encoder/EncodeOperation.js.map +1 -1
  30. package/lib/encoder/Encoder.js +11 -3
  31. package/lib/encoder/Encoder.js.map +1 -1
  32. package/lib/encoder/StateView.js +3 -3
  33. package/lib/encoder/StateView.js.map +1 -1
  34. package/lib/encoding/assert.d.ts +2 -1
  35. package/lib/encoding/assert.js +2 -2
  36. package/lib/encoding/assert.js.map +1 -1
  37. package/lib/index.d.ts +1 -2
  38. package/lib/index.js +11 -10
  39. package/lib/index.js.map +1 -1
  40. package/lib/types/TypeContext.js +7 -14
  41. package/lib/types/TypeContext.js.map +1 -1
  42. package/lib/types/custom/ArraySchema.js +6 -0
  43. package/lib/types/custom/ArraySchema.js.map +1 -1
  44. package/lib/types/custom/CollectionSchema.js +1 -0
  45. package/lib/types/custom/CollectionSchema.js.map +1 -1
  46. package/lib/types/custom/MapSchema.js +5 -0
  47. package/lib/types/custom/MapSchema.js.map +1 -1
  48. package/lib/types/custom/SetSchema.js +1 -0
  49. package/lib/types/custom/SetSchema.js.map +1 -1
  50. package/lib/types/symbols.d.ts +1 -0
  51. package/lib/types/symbols.js +2 -1
  52. package/lib/types/symbols.js.map +1 -1
  53. package/package.json +1 -1
  54. package/src/Metadata.ts +60 -29
  55. package/src/Reflection.ts +5 -15
  56. package/src/Schema.ts +33 -45
  57. package/src/annotations.ts +75 -67
  58. package/src/bench_encode.ts +37 -13
  59. package/src/decoder/DecodeOperation.ts +4 -10
  60. package/src/decoder/ReferenceTracker.ts +3 -2
  61. package/src/decoder/strategy/StateCallbacks.ts +4 -3
  62. package/src/encoder/ChangeTree.ts +146 -135
  63. package/src/encoder/EncodeOperation.ts +64 -58
  64. package/src/encoder/Encoder.ts +16 -4
  65. package/src/encoder/StateView.ts +4 -4
  66. package/src/encoding/assert.ts +4 -3
  67. package/src/index.ts +1 -4
  68. package/src/types/TypeContext.ts +10 -15
  69. package/src/types/custom/ArraySchema.ts +8 -0
  70. package/src/types/custom/CollectionSchema.ts +1 -0
  71. package/src/types/custom/MapSchema.ts +6 -0
  72. package/src/types/custom/SetSchema.ts +1 -0
  73. package/src/types/symbols.ts +2 -0
@@ -32,66 +32,80 @@ export class ChangeTree<T extends Ref=any> {
32
32
  refId: number;
33
33
 
34
34
  root?: Root;
35
-
36
- isFiltered?: boolean;
37
- isPartiallyFiltered?: boolean;
38
-
39
35
  parent?: Ref;
40
36
  parentIndex?: number;
41
37
 
42
- indexes: {[index: string]: any} = {}; // TODO: remove this, only used by MapSchema/SetSchema/CollectionSchema (`encodeKeyValueOperation`)
38
+ isFiltered: boolean = false;
39
+ isPartiallyFiltered: boolean = false;
40
+
43
41
  currentOperationIndex: number = 0;
44
42
 
43
+ changes = new Map<number, OPERATION>();
45
44
  allChanges = new Map<number, OPERATION>();
46
- allFilteredChanges = new Map<number, OPERATION>();
47
45
 
48
- changes = new Map<number, OPERATION>();
49
- filteredChanges = new Map<number, OPERATION>();;
46
+ allFilteredChanges: Map<number, OPERATION>;
47
+ filteredChanges: Map<number, OPERATION>;
48
+
49
+ indexes: {[index: string]: any}; // TODO: remove this, only used by MapSchema/SetSchema/CollectionSchema (`encodeKeyValueOperation`)
50
50
 
51
51
  [$isNew] = true;
52
52
 
53
53
  constructor(ref: T) {
54
54
  this.ref = ref;
55
+
56
+ //
57
+ // Does this structure have "filters" declared?
58
+ //
59
+ if (ref.constructor[Symbol.metadata]?.[-2]) {
60
+ this.allFilteredChanges = new Map<number, OPERATION>();
61
+ this.filteredChanges = new Map<number, OPERATION>();
62
+ }
55
63
  }
56
64
 
57
65
  setRoot(root: Root) {
58
66
  this.root = root;
59
67
  this.root.add(this);
60
68
 
61
- //
62
- // At Schema initialization, the "root" structure might not be available
63
- // yet, as it only does once the "Encoder" has been set up.
64
- //
65
- // So the "parent" may be already set without a "root".
66
- //
67
- this.checkIsFiltered(this.parent, this.parentIndex);
68
-
69
- // unique refId for the ChangeTree.
70
- this.ensureRefId();
69
+ const metadata: Metadata = this.ref.constructor[Symbol.metadata];
71
70
 
72
- if (!this.isFiltered) {
73
- this.root.changes.set(this, this.changes);
74
- }
71
+ if (this.root.types.hasFilters) {
72
+ //
73
+ // At Schema initialization, the "root" structure might not be available
74
+ // yet, as it only does once the "Encoder" has been set up.
75
+ //
76
+ // So the "parent" may be already set without a "root".
77
+ //
78
+ this.checkIsFiltered(metadata, this.parent, this.parentIndex);
75
79
 
76
- if (this.isFiltered || this.isPartiallyFiltered) {
77
- this.root.allFilteredChanges.set(this, this.allFilteredChanges);
78
- this.root.filteredChanges.set(this, this.filteredChanges);
80
+ if (this.isFiltered || this.isPartiallyFiltered) {
81
+ this.root.allFilteredChanges.set(this, this.allFilteredChanges);
82
+ this.root.filteredChanges.set(this, this.filteredChanges);
83
+ }
79
84
  }
80
85
 
81
86
  if (!this.isFiltered) {
87
+ this.root.changes.set(this, this.changes);
82
88
  this.root.allChanges.set(this, this.allChanges);
83
89
  }
84
90
 
85
- this.forEachChild((changeTree, _) => {
86
- changeTree.setRoot(root);
87
- });
91
+ this.ensureRefId();
92
+
93
+ if (metadata) {
94
+ metadata[-4]?.forEach((index) => {
95
+ const field = metadata[index as any as number];
96
+ const value = this.ref[field.name];
97
+ if (value) {
98
+ value[$changes].setRoot(root);
99
+ }
100
+ });
101
+
102
+ } else if (this.ref[$childType] && typeof(this.ref[$childType]) !== "string") {
103
+ // MapSchema / ArraySchema, etc.
104
+ (this.ref as MapSchema).forEach((value, key) => {
105
+ value[$changes].setRoot(root);
106
+ });
107
+ }
88
108
 
89
- // this.allChanges.forEach((_, index) => {
90
- // const childRef = this.ref[$getByIndex](index);
91
- // if (childRef && childRef[$changes]) {
92
- // childRef[$changes].setRoot(root);
93
- // }
94
- // });
95
109
  }
96
110
 
97
111
  setParent(
@@ -107,56 +121,71 @@ export class ChangeTree<T extends Ref=any> {
107
121
 
108
122
  root.add(this);
109
123
 
124
+ const metadata: Metadata = this.ref.constructor[Symbol.metadata];
125
+
110
126
  // skip if parent is already set
111
- if (root === this.root) {
112
- this.forEachChild((changeTree, atIndex) => {
113
- changeTree.setParent(this.ref, root, atIndex);
114
- });
115
- return;
116
- }
127
+ if (root !== this.root) {
128
+ this.root = root;
117
129
 
118
- this.root = root;
119
- this.checkIsFiltered(parent, parentIndex);
130
+ if (root.types.hasFilters) {
131
+ this.checkIsFiltered(metadata, parent, parentIndex);
120
132
 
121
- if (!this.isFiltered) {
122
- this.root.changes.set(this, this.changes);
123
- this.root.allChanges.set(this, this.allChanges);
124
- }
133
+ if (this.isFiltered || this.isPartiallyFiltered) {
134
+ this.root.filteredChanges.set(this, this.filteredChanges);
135
+ this.root.allFilteredChanges.set(this, this.filteredChanges);
136
+ }
137
+ }
125
138
 
126
- if (this.isFiltered || this.isPartiallyFiltered) {
127
- this.root.filteredChanges.set(this, this.filteredChanges);
128
- this.root.allFilteredChanges.set(this, this.filteredChanges);
139
+ if (!this.isFiltered) {
140
+ this.root.changes.set(this, this.changes);
141
+ this.root.allChanges.set(this, this.allChanges);
142
+ }
143
+
144
+ this.ensureRefId();
129
145
  }
130
146
 
131
- this.ensureRefId();
147
+ // assign same parent on child structures
148
+ if (metadata) {
149
+ metadata[-4]?.forEach((index) => {
150
+ const field = metadata[index as any as number];
151
+ const value = this.ref[field.name];
152
+ value?.[$changes].setParent(this.ref, root, index);
153
+
154
+ // console.log(this.ref.constructor.name, field.name, value);
155
+
156
+ // try { throw new Error(); } catch (e) {
157
+ // console.log(e.stack);
158
+ // }
159
+
160
+ });
161
+
162
+ } else if (this.ref[$childType] && typeof(this.ref[$childType]) !== "string") {
163
+ // MapSchema / ArraySchema, etc.
164
+ (this.ref as MapSchema).forEach((value, key) => {
165
+ value[$changes].setParent(this.ref, root, this.indexes[key] ?? key);
166
+ });
167
+ }
132
168
 
133
- this.forEachChild((changeTree, atIndex) => {
134
- changeTree.setParent(this.ref, root, atIndex);
135
- });
136
169
  }
137
170
 
138
171
  forEachChild(callback: (change: ChangeTree, atIndex: number) => void) {
139
172
  //
140
173
  // assign same parent on child structures
141
174
  //
142
- if (Metadata.isValidInstance(this.ref)) {
143
- const metadata: Metadata = this.ref['constructor'][Symbol.metadata];
144
-
145
- // FIXME: need to iterate over parent metadata instead.
146
- for (const field in metadata) {
147
- const value = this.ref[field];
148
-
149
- if (value && value[$changes]) {
150
- callback(value[$changes], metadata[field].index);
175
+ const metadata: Metadata = this.ref.constructor[Symbol.metadata];
176
+ if (metadata) {
177
+ metadata[-4]?.forEach((index) => {
178
+ const field = metadata[index as any as number];
179
+ const value = this.ref[field.name];
180
+ if (value) {
181
+ callback(value[$changes], index);
151
182
  }
152
- }
183
+ });
153
184
 
154
- } else if (typeof (this.ref) === "object") {
185
+ } else if (this.ref[$childType] && typeof(this.ref[$childType]) !== "string") {
155
186
  // MapSchema / ArraySchema, etc.
156
187
  (this.ref as MapSchema).forEach((value, key) => {
157
- if (Metadata.isValidInstance(value)) {
158
- callback(value[$changes], this.ref[$changes].indexes[key] ?? key);
159
- }
188
+ callback(value[$changes], this.indexes[key] ?? key);
160
189
  });
161
190
  }
162
191
  }
@@ -167,9 +196,9 @@ export class ChangeTree<T extends Ref=any> {
167
196
  }
168
197
 
169
198
  change(index: number, operation: OPERATION = OPERATION.ADD) {
170
- const metadata = this.ref['constructor'][Symbol.metadata] as Metadata;
199
+ const metadata = this.ref.constructor[Symbol.metadata] as Metadata;
171
200
 
172
- const isFiltered = this.isFiltered || (metadata && metadata[metadata[index]].tag !== undefined);
201
+ const isFiltered = this.isFiltered || (metadata?.[index]?.tag !== undefined);
173
202
  const changeSet = (isFiltered)
174
203
  ? this.filteredChanges
175
204
  : this.changes;
@@ -181,17 +210,15 @@ export class ChangeTree<T extends Ref=any> {
181
210
  : (previousOperation === OPERATION.DELETE)
182
211
  ? OPERATION.DELETE_AND_ADD
183
212
  : operation
213
+ //
214
+ // TODO: are DELETE operations being encoded as ADD here ??
215
+ //
184
216
  changeSet.set(index, op);
185
217
  }
186
218
 
187
- //
188
- // TODO: are DELETE operations being encoded as ADD here ??
189
- //
190
-
191
219
  if (isFiltered) {
192
- this.root?.filteredChanges.set(this, this.filteredChanges);
193
-
194
220
  this.allFilteredChanges.set(index, OPERATION.ADD);
221
+ this.root?.filteredChanges.set(this, this.filteredChanges);
195
222
  this.root?.allFilteredChanges.set(this, this.allFilteredChanges);
196
223
 
197
224
  } else {
@@ -244,10 +271,7 @@ export class ChangeTree<T extends Ref=any> {
244
271
  }
245
272
 
246
273
  indexedOperation(index: number, operation: OPERATION, allChangesIndex = index) {
247
- const metadata = this.ref['constructor'][Symbol.metadata] as Metadata;
248
- const isFiltered = this.isFiltered || (metadata && metadata[metadata[index]].tag !== undefined);
249
-
250
- if (isFiltered) {
274
+ if (this.filteredChanges !== undefined) {
251
275
  this.allFilteredChanges.set(allChangesIndex, OPERATION.ADD);
252
276
  this.filteredChanges.set(index, operation);
253
277
  this.root?.filteredChanges.set(this, this.filteredChanges);
@@ -261,8 +285,8 @@ export class ChangeTree<T extends Ref=any> {
261
285
 
262
286
  getType(index?: number) {
263
287
  if (Metadata.isValidInstance(this.ref)) {
264
- const metadata = this.ref['constructor'][Symbol.metadata] as Metadata;
265
- return metadata[metadata[index]].type;
288
+ const metadata = this.ref.constructor[Symbol.metadata] as Metadata;
289
+ return metadata[index].type;
266
290
 
267
291
  } else {
268
292
  //
@@ -277,7 +301,7 @@ export class ChangeTree<T extends Ref=any> {
277
301
 
278
302
  getChange(index: number) {
279
303
  // TODO: optimize this. avoid checking against multiple instances
280
- return this.changes.get(index) ?? this.filteredChanges.get(index);
304
+ return this.changes.get(index) ?? this.filteredChanges?.get(index);
281
305
  }
282
306
 
283
307
  //
@@ -300,9 +324,7 @@ export class ChangeTree<T extends Ref=any> {
300
324
  return;
301
325
  }
302
326
 
303
- const metadata = this.ref['constructor'][Symbol.metadata] as Metadata;
304
- const isFiltered = this.isFiltered || (metadata && metadata[metadata[index]].tag !== undefined);
305
- const changeSet = (isFiltered)
327
+ const changeSet = (this.filteredChanges)
306
328
  ? this.filteredChanges
307
329
  : this.changes;
308
330
 
@@ -330,7 +352,7 @@ export class ChangeTree<T extends Ref=any> {
330
352
  //
331
353
  // FIXME: this is looking a bit ugly (and repeated from `.change()`)
332
354
  //
333
- if (isFiltered) {
355
+ if (this.filteredChanges) {
334
356
  this.root?.filteredChanges.set(this, this.filteredChanges);
335
357
  this.allFilteredChanges.delete(allChangesIndex);
336
358
 
@@ -342,6 +364,8 @@ export class ChangeTree<T extends Ref=any> {
342
364
 
343
365
  endEncode() {
344
366
  this.changes.clear();
367
+
368
+ // ArraySchema and MapSchema have a custom "encode end" method
345
369
  this.ref[$onEncodeEnd]?.();
346
370
 
347
371
  // Not a new instance anymore
@@ -357,14 +381,14 @@ export class ChangeTree<T extends Ref=any> {
357
381
  this.ref[$onEncodeEnd]?.();
358
382
 
359
383
  this.changes.clear();
360
- this.filteredChanges.clear();
384
+ this.filteredChanges?.clear();
361
385
 
362
386
  // reset operation index
363
387
  this.currentOperationIndex = 0;
364
388
 
365
389
  if (discardAll) {
366
390
  this.allChanges.clear();
367
- this.allFilteredChanges.clear();
391
+ this.allFilteredChanges?.clear();
368
392
 
369
393
  // remove children references
370
394
  this.forEachChild((changeTree, _) =>
@@ -400,60 +424,47 @@ export class ChangeTree<T extends Ref=any> {
400
424
  return this.changes.size > 0;
401
425
  }
402
426
 
403
- protected checkIsFiltered(parent: Ref, parentIndex: number) {
427
+ protected checkIsFiltered(metadata: Metadata, parent: Ref, parentIndex: number) {
404
428
  // Detect if current structure has "filters" declared
405
- this.isPartiallyFiltered = (this.ref['constructor']?.[Symbol.metadata]?.[-2] !== undefined);
429
+ this.isPartiallyFiltered = metadata?.[-2] !== undefined;
406
430
 
407
- if (parent && !Metadata.isValidInstance(parent)) {
408
- const parentChangeTree = parent[$changes];
409
- parent = parentChangeTree.parent;
410
- parentIndex = parentChangeTree.parentIndex;
431
+ if (this.isPartiallyFiltered) {
432
+ this.filteredChanges = this.filteredChanges || new Map<number, OPERATION>();
433
+ this.allFilteredChanges = this.allFilteredChanges || new Map<number, OPERATION>();
411
434
  }
412
435
 
413
- const parentMetadata = parent?.['constructor']?.[Symbol.metadata];
414
-
415
- this.isFiltered = (
416
- parent &&
417
- parentMetadata?.[-2]?.includes(parentIndex)
418
- );
419
-
420
- // this.isFiltered = this.ref['constructor']?.[Symbol.metadata]?.[-4];
421
-
422
- // // Detect if parent has "filters" declared
423
- // while (parent && !this.isFiltered) {
424
- // const metadata: Metadata = parent['constructor'][Symbol.metadata];
425
- // // this.isFiltered = metadata?.[-4];
426
-
427
- // const fieldName = metadata?.[parentIndex];
428
- // const isParentOwned = metadata?.[fieldName]?.tag !== undefined;
429
- // this.isFiltered = isParentOwned || parent[$changes].isFiltered; // metadata?.[-2]
430
-
431
- // parent = parent[$changes].parent;
432
- // };
436
+ if (parent) {
437
+ if (!Metadata.isValidInstance(parent)) {
438
+ const parentChangeTree = parent[$changes];
439
+ parent = parentChangeTree.parent;
440
+ parentIndex = parentChangeTree.parentIndex;
441
+ }
433
442
 
434
- // console.log("ChangeTree.checkIsFiltered", {
435
- // parent: parent?.constructor.name,
436
- // ref: this.ref.constructor.name,
437
- // isFiltered: this.isFiltered,
438
- // isPartiallyFiltered: this.isPartiallyFiltered,
439
- // });
443
+ const parentMetadata = parent?.constructor?.[Symbol.metadata];
444
+ this.isFiltered = (parent && parentMetadata?.[-2]?.includes(parentIndex));
440
445
 
441
- //
442
- // TODO: refactor this!
443
- //
444
- // swapping `changes` and `filteredChanges` is required here
445
- // because "isFiltered" may not be imedialely available on `change()`
446
- //
447
- if (this.isFiltered && this.changes.size > 0) {
448
- // swap changes reference
449
- const changes = this.changes;
450
- this.changes = this.filteredChanges;
451
- this.filteredChanges = changes;
452
-
453
- // swap "all changes" reference
454
- const allFilteredChanges = this.allFilteredChanges;
455
- this.allFilteredChanges = this.allChanges;
456
- this.allChanges = allFilteredChanges;
446
+ //
447
+ // TODO: refactor this!
448
+ //
449
+ // swapping `changes` and `filteredChanges` is required here
450
+ // because "isFiltered" may not be imedialely available on `change()`
451
+ //
452
+ if (this.isFiltered) {
453
+ this.filteredChanges = new Map<number, OPERATION>();
454
+ this.allFilteredChanges = new Map<number, OPERATION>();
455
+
456
+ if (this.changes.size > 0) {
457
+ // swap changes reference
458
+ const changes = this.changes;
459
+ this.changes = this.filteredChanges;
460
+ this.filteredChanges = changes;
461
+
462
+ // swap "all changes" reference
463
+ const allFilteredChanges = this.allFilteredChanges;
464
+ this.allFilteredChanges = this.allChanges;
465
+ this.allChanges = allFilteredChanges;
466
+ }
467
+ }
457
468
  }
458
469
  }
459
470
 
@@ -3,7 +3,7 @@ import { $changes } from "../types/symbols";
3
3
  import { getType } from "../types/registry";
4
4
 
5
5
  import * as encode from "../encoding/encode";
6
- import { EncodeSchemaError, assertInstanceType, assertType } from "../encoding/assert";
6
+ // import { EncodeSchemaError, assertInstanceType, assertType } from "../encoding/assert";
7
7
 
8
8
  import type { ChangeTree, Ref } from "./ChangeTree";
9
9
  import type { Encoder } from "./Encoder";
@@ -12,6 +12,7 @@ import type { PrimitiveType } from "../annotations";
12
12
 
13
13
  import type { Iterator } from "../encoding/decode";
14
14
  import type { ArraySchema } from "../types/custom/ArraySchema";
15
+ import type { Metadata } from "../Metadata";
15
16
 
16
17
  export type EncodeOperation<T extends Ref = any> = (
17
18
  encoder: Encoder,
@@ -24,40 +25,27 @@ export type EncodeOperation<T extends Ref = any> = (
24
25
  hasView: boolean,
25
26
  ) => void;
26
27
 
27
- export function encodePrimitiveType(
28
- type: PrimitiveType,
29
- bytes: Buffer,
30
- value: any,
31
- klass: Schema,
32
- field: string | number,
33
- it: Iterator,
34
- ) {
35
- assertType(value, type as string, klass, field);
36
-
37
- const encodeFunc = encode[type as string];
38
-
39
- if (encodeFunc) {
40
- encodeFunc(bytes, value, it);
41
- // encodeFunc(bytes, value);
42
-
43
- } else {
44
- throw new EncodeSchemaError(`a '${type}' was expected, but ${value} was provided in ${klass.constructor.name}#${field}`);
45
- }
46
- };
47
-
48
28
  export function encodeValue(
49
29
  encoder: Encoder,
50
30
  bytes: Buffer,
51
- ref: Ref,
31
+ // ref: Ref,
52
32
  type: any,
53
33
  value: any,
54
- field: string | number,
34
+ // field: string | number,
55
35
  operation: OPERATION,
56
36
  it: Iterator,
57
37
  ) {
58
- if (type[Symbol.metadata] !== undefined) {
59
- // TODO: move this to the `@type()` annotation
60
- assertInstanceType(value, type as typeof Schema, ref as Schema, field);
38
+ if (typeof (type) === "string") {
39
+ //
40
+ // Primitive values
41
+ //
42
+ // assertType(value, type as string, ref as Schema, field);
43
+
44
+ encode[type]?.(bytes, value, it);
45
+
46
+ } else if (type[Symbol.metadata] !== undefined) {
47
+ // // TODO: move this to the `@type()` annotation
48
+ // assertInstanceType(value, type as typeof Schema, ref as Schema, field);
61
49
 
62
50
  //
63
51
  // Encode refId for this instance.
@@ -70,22 +58,16 @@ export function encodeValue(
70
58
  encoder.tryEncodeTypeId(bytes, type as typeof Schema, value.constructor as typeof Schema, it);
71
59
  }
72
60
 
73
- } else if (typeof (type) === "string") {
74
- //
75
- // Primitive values
76
- //
77
- encodePrimitiveType(type as PrimitiveType, bytes, value, ref as Schema, field, it);
78
-
79
61
  } else {
80
- //
81
- // Custom type (MapSchema, ArraySchema, etc)
82
- //
83
- const definition = getType(Object.keys(type)[0]);
62
+ // //
63
+ // // Custom type (MapSchema, ArraySchema, etc)
64
+ // //
65
+ // const definition = getType(Object.keys(type)[0]);
84
66
 
85
- //
86
- // ensure a ArraySchema has been provided
87
- //
88
- assertInstanceType(ref[field], definition.constructor, ref as Schema, field);
67
+ // //
68
+ // // ensure a ArraySchema has been provided
69
+ // //
70
+ // assertInstanceType(ref[field], definition.constructor, ref as Schema, field);
89
71
 
90
72
  //
91
73
  // Encode refId for this instance.
@@ -107,13 +89,6 @@ export const encodeSchemaOperation: EncodeOperation = function (
107
89
  operation: OPERATION,
108
90
  it: Iterator,
109
91
  ) {
110
- const ref = changeTree.ref;
111
- const metadata = ref['constructor'][Symbol.metadata];
112
-
113
- const field = metadata[index];
114
- const type = metadata[field].type;
115
- const value = ref[field];
116
-
117
92
  // "compress" field index + operation
118
93
  bytes[it.offset++] = (index | operation) & 255;
119
94
 
@@ -122,8 +97,21 @@ export const encodeSchemaOperation: EncodeOperation = function (
122
97
  return;
123
98
  }
124
99
 
100
+ const ref = changeTree.ref;
101
+ const metadata: Metadata = ref['constructor'][Symbol.metadata];
102
+ const field = metadata[index];
103
+
125
104
  // TODO: inline this function call small performance gain
126
- encodeValue(encoder, bytes, ref, type, value, field, operation, it);
105
+ encodeValue(
106
+ encoder,
107
+ bytes,
108
+ // ref,
109
+ metadata[index].type,
110
+ ref[field.name],
111
+ // index,
112
+ operation,
113
+ it
114
+ );
127
115
  }
128
116
 
129
117
  /**
@@ -134,12 +122,10 @@ export const encodeKeyValueOperation: EncodeOperation = function (
134
122
  encoder: Encoder,
135
123
  bytes: Buffer,
136
124
  changeTree: ChangeTree,
137
- field: number,
125
+ index: number,
138
126
  operation: OPERATION,
139
127
  it: Iterator,
140
128
  ) {
141
- const ref = changeTree.ref;
142
-
143
129
  // encode operation
144
130
  bytes[it.offset++] = operation & 255;
145
131
 
@@ -149,13 +135,15 @@ export const encodeKeyValueOperation: EncodeOperation = function (
149
135
  }
150
136
 
151
137
  // encode index
152
- encode.number(bytes, field, it);
138
+ encode.number(bytes, index, it);
153
139
 
154
140
  // Do not encode value for DELETE operations
155
141
  if (operation === OPERATION.DELETE) {
156
142
  return;
157
143
  }
158
144
 
145
+ const ref = changeTree.ref;
146
+
159
147
  //
160
148
  // encode "alias" for dynamic fields (maps)
161
149
  //
@@ -164,13 +152,13 @@ export const encodeKeyValueOperation: EncodeOperation = function (
164
152
  //
165
153
  // MapSchema dynamic key
166
154
  //
167
- const dynamicIndex = changeTree.ref['$indexes'].get(field);
155
+ const dynamicIndex = changeTree.ref['$indexes'].get(index);
168
156
  encode.string(bytes, dynamicIndex, it);
169
157
  }
170
158
  }
171
159
 
172
- const type = changeTree.getType(field);
173
- const value = changeTree.getValue(field);
160
+ const type = changeTree.getType(index);
161
+ const value = changeTree.getValue(index);
174
162
 
175
163
  // try { throw new Error(); } catch (e) {
176
164
  // // only print if not coming from Reflection.ts
@@ -186,7 +174,16 @@ export const encodeKeyValueOperation: EncodeOperation = function (
186
174
  // }
187
175
 
188
176
  // TODO: inline this function call small performance gain
189
- encodeValue(encoder, bytes, ref, type, value, field, operation, it);
177
+ encodeValue(
178
+ encoder,
179
+ bytes,
180
+ // ref,
181
+ type,
182
+ value,
183
+ // index,
184
+ operation,
185
+ it
186
+ );
190
187
  }
191
188
 
192
189
  /**
@@ -250,5 +247,14 @@ export const encodeArray: EncodeOperation = function (
250
247
  // });
251
248
 
252
249
  // TODO: inline this function call small performance gain
253
- encodeValue(encoder, bytes, ref, type, value, field, operation, it);
250
+ encodeValue(
251
+ encoder,
252
+ bytes,
253
+ // ref,
254
+ type,
255
+ value,
256
+ // field,
257
+ operation,
258
+ it
259
+ );
254
260
  }