@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.
- package/build/cjs/index.js +383 -341
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +383 -341
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +383 -341
- package/lib/Metadata.d.ts +14 -5
- package/lib/Metadata.js +49 -20
- package/lib/Metadata.js.map +1 -1
- package/lib/Reflection.js +4 -13
- package/lib/Reflection.js.map +1 -1
- package/lib/Schema.js +26 -39
- package/lib/Schema.js.map +1 -1
- package/lib/annotations.d.ts +1 -2
- package/lib/annotations.js +58 -52
- package/lib/annotations.js.map +1 -1
- package/lib/bench_encode.js +33 -11
- package/lib/bench_encode.js.map +1 -1
- package/lib/decoder/DecodeOperation.js +4 -8
- package/lib/decoder/DecodeOperation.js.map +1 -1
- package/lib/decoder/ReferenceTracker.js +3 -2
- package/lib/decoder/ReferenceTracker.js.map +1 -1
- package/lib/decoder/strategy/StateCallbacks.js +4 -3
- package/lib/decoder/strategy/StateCallbacks.js.map +1 -1
- package/lib/encoder/ChangeTree.d.ts +8 -7
- package/lib/encoder/ChangeTree.js +128 -115
- package/lib/encoder/ChangeTree.js.map +1 -1
- package/lib/encoder/EncodeOperation.d.ts +1 -4
- package/lib/encoder/EncodeOperation.js +46 -46
- package/lib/encoder/EncodeOperation.js.map +1 -1
- package/lib/encoder/Encoder.js +11 -3
- package/lib/encoder/Encoder.js.map +1 -1
- package/lib/encoder/StateView.js +3 -3
- package/lib/encoder/StateView.js.map +1 -1
- package/lib/encoding/assert.d.ts +2 -1
- package/lib/encoding/assert.js +2 -2
- package/lib/encoding/assert.js.map +1 -1
- package/lib/index.d.ts +1 -2
- package/lib/index.js +11 -10
- package/lib/index.js.map +1 -1
- package/lib/types/TypeContext.js +7 -14
- package/lib/types/TypeContext.js.map +1 -1
- package/lib/types/custom/ArraySchema.js +6 -0
- package/lib/types/custom/ArraySchema.js.map +1 -1
- package/lib/types/custom/CollectionSchema.js +1 -0
- package/lib/types/custom/CollectionSchema.js.map +1 -1
- package/lib/types/custom/MapSchema.js +5 -0
- package/lib/types/custom/MapSchema.js.map +1 -1
- package/lib/types/custom/SetSchema.js +1 -0
- package/lib/types/custom/SetSchema.js.map +1 -1
- package/lib/types/symbols.d.ts +1 -0
- package/lib/types/symbols.js +2 -1
- package/lib/types/symbols.js.map +1 -1
- package/package.json +1 -1
- package/src/Metadata.ts +60 -29
- package/src/Reflection.ts +5 -15
- package/src/Schema.ts +33 -45
- package/src/annotations.ts +75 -67
- package/src/bench_encode.ts +37 -13
- package/src/decoder/DecodeOperation.ts +4 -10
- package/src/decoder/ReferenceTracker.ts +3 -2
- package/src/decoder/strategy/StateCallbacks.ts +4 -3
- package/src/encoder/ChangeTree.ts +146 -135
- package/src/encoder/EncodeOperation.ts +64 -58
- package/src/encoder/Encoder.ts +16 -4
- package/src/encoder/StateView.ts +4 -4
- package/src/encoding/assert.ts +4 -3
- package/src/index.ts +1 -4
- package/src/types/TypeContext.ts +10 -15
- package/src/types/custom/ArraySchema.ts +8 -0
- package/src/types/custom/CollectionSchema.ts +1 -0
- package/src/types/custom/MapSchema.ts +6 -0
- package/src/types/custom/SetSchema.ts +1 -0
- 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
|
-
|
|
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
|
-
|
|
49
|
-
filteredChanges
|
|
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 (
|
|
73
|
-
|
|
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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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.
|
|
86
|
-
|
|
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
|
|
112
|
-
this.
|
|
113
|
-
changeTree.setParent(this.ref, root, atIndex);
|
|
114
|
-
});
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
127
|
+
if (root !== this.root) {
|
|
128
|
+
this.root = root;
|
|
117
129
|
|
|
118
|
-
|
|
119
|
-
|
|
130
|
+
if (root.types.hasFilters) {
|
|
131
|
+
this.checkIsFiltered(metadata, parent, parentIndex);
|
|
120
132
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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
|
-
|
|
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
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
199
|
+
const metadata = this.ref.constructor[Symbol.metadata] as Metadata;
|
|
171
200
|
|
|
172
|
-
const isFiltered = this.isFiltered || (metadata
|
|
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
|
-
|
|
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
|
|
265
|
-
return metadata[
|
|
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
|
|
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
|
|
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 (
|
|
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
|
|
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
|
|
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 =
|
|
429
|
+
this.isPartiallyFiltered = metadata?.[-2] !== undefined;
|
|
406
430
|
|
|
407
|
-
if (
|
|
408
|
-
|
|
409
|
-
|
|
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
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
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
|
-
|
|
435
|
-
|
|
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
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
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
|
|
59
|
-
//
|
|
60
|
-
|
|
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(
|
|
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
|
-
|
|
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,
|
|
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(
|
|
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(
|
|
173
|
-
const value = changeTree.getValue(
|
|
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(
|
|
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(
|
|
250
|
+
encodeValue(
|
|
251
|
+
encoder,
|
|
252
|
+
bytes,
|
|
253
|
+
// ref,
|
|
254
|
+
type,
|
|
255
|
+
value,
|
|
256
|
+
// field,
|
|
257
|
+
operation,
|
|
258
|
+
it
|
|
259
|
+
);
|
|
254
260
|
}
|