@colyseus/schema 3.0.0-alpha.34 → 3.0.0-alpha.36

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 (71) hide show
  1. package/bin/schema-debug +4 -3
  2. package/build/cjs/index.js +612 -408
  3. package/build/cjs/index.js.map +1 -1
  4. package/build/esm/index.mjs +612 -408
  5. package/build/esm/index.mjs.map +1 -1
  6. package/build/umd/index.js +612 -408
  7. package/lib/Metadata.d.ts +6 -6
  8. package/lib/Metadata.js +48 -21
  9. package/lib/Metadata.js.map +1 -1
  10. package/lib/Reflection.d.ts +17 -2
  11. package/lib/Reflection.js +19 -6
  12. package/lib/Reflection.js.map +1 -1
  13. package/lib/Schema.js +24 -17
  14. package/lib/Schema.js.map +1 -1
  15. package/lib/annotations.d.ts +1 -1
  16. package/lib/annotations.js +13 -16
  17. package/lib/annotations.js.map +1 -1
  18. package/lib/bench_encode.js +12 -5
  19. package/lib/bench_encode.js.map +1 -1
  20. package/lib/debug.js +1 -2
  21. package/lib/debug.js.map +1 -1
  22. package/lib/decoder/Decoder.js +1 -1
  23. package/lib/decoder/Decoder.js.map +1 -1
  24. package/lib/encoder/ChangeTree.d.ts +23 -7
  25. package/lib/encoder/ChangeTree.js +183 -106
  26. package/lib/encoder/ChangeTree.js.map +1 -1
  27. package/lib/encoder/EncodeOperation.d.ts +2 -1
  28. package/lib/encoder/EncodeOperation.js +2 -2
  29. package/lib/encoder/EncodeOperation.js.map +1 -1
  30. package/lib/encoder/Encoder.d.ts +3 -5
  31. package/lib/encoder/Encoder.js +97 -61
  32. package/lib/encoder/Encoder.js.map +1 -1
  33. package/lib/encoder/Root.d.ts +12 -7
  34. package/lib/encoder/Root.js +41 -20
  35. package/lib/encoder/Root.js.map +1 -1
  36. package/lib/encoder/StateView.d.ts +5 -5
  37. package/lib/encoder/StateView.js +29 -23
  38. package/lib/encoder/StateView.js.map +1 -1
  39. package/lib/encoding/encode.js +12 -9
  40. package/lib/encoding/encode.js.map +1 -1
  41. package/lib/types/TypeContext.js +2 -1
  42. package/lib/types/TypeContext.js.map +1 -1
  43. package/lib/types/custom/ArraySchema.js +27 -13
  44. package/lib/types/custom/ArraySchema.js.map +1 -1
  45. package/lib/types/custom/MapSchema.d.ts +3 -1
  46. package/lib/types/custom/MapSchema.js +7 -4
  47. package/lib/types/custom/MapSchema.js.map +1 -1
  48. package/lib/types/symbols.d.ts +8 -6
  49. package/lib/types/symbols.js +9 -7
  50. package/lib/types/symbols.js.map +1 -1
  51. package/lib/utils.js +6 -3
  52. package/lib/utils.js.map +1 -1
  53. package/package.json +1 -1
  54. package/src/Metadata.ts +51 -27
  55. package/src/Reflection.ts +21 -8
  56. package/src/Schema.ts +33 -25
  57. package/src/annotations.ts +14 -18
  58. package/src/bench_encode.ts +15 -6
  59. package/src/debug.ts +1 -2
  60. package/src/decoder/Decoder.ts +1 -1
  61. package/src/encoder/ChangeTree.ts +220 -115
  62. package/src/encoder/EncodeOperation.ts +5 -4
  63. package/src/encoder/Encoder.ts +115 -68
  64. package/src/encoder/Root.ts +41 -21
  65. package/src/encoder/StateView.ts +32 -28
  66. package/src/encoding/encode.ts +12 -9
  67. package/src/types/TypeContext.ts +2 -1
  68. package/src/types/custom/ArraySchema.ts +39 -17
  69. package/src/types/custom/MapSchema.ts +12 -5
  70. package/src/types/symbols.ts +10 -9
  71. package/src/utils.ts +7 -3
@@ -1,31 +1,62 @@
1
1
  "use strict";
2
- var _a;
3
2
  Object.defineProperty(exports, "__esModule", { value: true });
4
3
  exports.ChangeTree = void 0;
4
+ exports.setOperationAtIndex = setOperationAtIndex;
5
+ exports.deleteOperationAtIndex = deleteOperationAtIndex;
5
6
  const spec_1 = require("../encoding/spec");
6
7
  const symbols_1 = require("../types/symbols");
7
8
  const Metadata_1 = require("../Metadata");
9
+ function setOperationAtIndex(changeSet, index) {
10
+ const operationsIndex = changeSet.indexes[index];
11
+ if (operationsIndex === undefined) {
12
+ changeSet.indexes[index] = changeSet.operations.push(index) - 1;
13
+ }
14
+ else {
15
+ changeSet.operations[operationsIndex] = index;
16
+ }
17
+ }
18
+ function deleteOperationAtIndex(changeSet, index) {
19
+ const operationsIndex = changeSet.indexes[index];
20
+ if (operationsIndex !== undefined) {
21
+ changeSet.operations[operationsIndex] = undefined;
22
+ }
23
+ delete changeSet.indexes[index];
24
+ }
25
+ function enqueueChangeTree(root, changeTree, changeSet, queueRootIndex = changeTree[changeSet].queueRootIndex) {
26
+ if (root && root[changeSet][queueRootIndex] !== changeTree) {
27
+ changeTree[changeSet].queueRootIndex = root[changeSet].push(changeTree) - 1;
28
+ }
29
+ }
8
30
  class ChangeTree {
9
- static { _a = symbols_1.$isNew; }
10
31
  constructor(ref) {
11
32
  this.isFiltered = false;
12
33
  this.isPartiallyFiltered = false;
13
- this.currentOperationIndex = 0;
14
- this.changes = new Map();
15
- this.allChanges = new Map();
16
- this[_a] = true;
34
+ this.indexedOperations = {};
35
+ //
36
+ // TODO:
37
+ // try storing the index + operation per item.
38
+ // example: 1024 & 1025 => ADD, 1026 => DELETE
39
+ //
40
+ // => https://chatgpt.com/share/67107d0c-bc20-8004-8583-83b17dd7c196
41
+ //
42
+ this.changes = { indexes: {}, operations: [] };
43
+ this.allChanges = { indexes: {}, operations: [] };
44
+ /**
45
+ * Is this a new instance? Used on ArraySchema to determine OPERATION.MOVE_AND_ADD operation.
46
+ */
47
+ this.isNew = true;
17
48
  this.ref = ref;
18
49
  //
19
50
  // Does this structure have "filters" declared?
20
51
  //
21
- if (ref.constructor[Symbol.metadata]?.[-2]) {
22
- this.allFilteredChanges = new Map();
23
- this.filteredChanges = new Map();
52
+ if (ref.constructor[Symbol.metadata]?.[symbols_1.$viewFieldIndexes]) {
53
+ this.allFilteredChanges = { indexes: {}, operations: [] };
54
+ this.filteredChanges = { indexes: {}, operations: [] };
24
55
  }
25
56
  }
26
57
  setRoot(root) {
27
58
  this.root = root;
28
- this.root.add(this);
59
+ const isNewChangeTree = this.root.add(this);
29
60
  const metadata = this.ref.constructor[Symbol.metadata];
30
61
  if (this.root.types.hasFilters) {
31
62
  //
@@ -36,22 +67,24 @@ class ChangeTree {
36
67
  //
37
68
  this.checkIsFiltered(metadata, this.parent, this.parentIndex);
38
69
  if (this.isFiltered || this.isPartiallyFiltered) {
39
- this.root.allFilteredChanges.set(this, this.allFilteredChanges);
40
- this.root.filteredChanges.set(this, this.filteredChanges);
70
+ enqueueChangeTree(root, this, 'filteredChanges');
71
+ if (isNewChangeTree) {
72
+ this.root.allFilteredChanges.push(this);
73
+ }
41
74
  }
42
75
  }
43
76
  if (!this.isFiltered) {
44
- this.root.changes.set(this, this.changes);
45
- this.root.allChanges.set(this, this.allChanges);
77
+ enqueueChangeTree(root, this, 'changes');
78
+ if (isNewChangeTree) {
79
+ this.root.allChanges.push(this);
80
+ }
46
81
  }
47
- this.ensureRefId();
82
+ // Recursively set root on child structures
48
83
  if (metadata) {
49
- metadata[-4]?.forEach((index) => {
84
+ metadata[symbols_1.$refTypeFieldIndexes]?.forEach((index) => {
50
85
  const field = metadata[index];
51
86
  const value = this.ref[field.name];
52
- if (value) {
53
- value[symbols_1.$changes].setRoot(root);
54
- }
87
+ value?.[symbols_1.$changes].setRoot(root);
55
88
  });
56
89
  }
57
90
  else if (this.ref[symbols_1.$childType] && typeof (this.ref[symbols_1.$childType]) !== "string") {
@@ -68,31 +101,36 @@ class ChangeTree {
68
101
  if (!root) {
69
102
  return;
70
103
  }
71
- root.add(this);
72
104
  const metadata = this.ref.constructor[Symbol.metadata];
73
105
  // skip if parent is already set
74
106
  if (root !== this.root) {
75
107
  this.root = root;
108
+ const isNewChangeTree = root.add(this);
76
109
  if (root.types.hasFilters) {
77
110
  this.checkIsFiltered(metadata, parent, parentIndex);
78
111
  if (this.isFiltered || this.isPartiallyFiltered) {
79
- this.root.filteredChanges.set(this, this.filteredChanges);
80
- this.root.allFilteredChanges.set(this, this.filteredChanges);
112
+ enqueueChangeTree(root, this, 'filteredChanges');
113
+ if (isNewChangeTree) {
114
+ this.root.allFilteredChanges.push(this);
115
+ }
81
116
  }
82
117
  }
83
118
  if (!this.isFiltered) {
84
- this.root.changes.set(this, this.changes);
85
- this.root.allChanges.set(this, this.allChanges);
119
+ enqueueChangeTree(root, this, 'changes');
120
+ if (isNewChangeTree) {
121
+ this.root.allChanges.push(this);
122
+ }
86
123
  }
87
- this.ensureRefId();
124
+ }
125
+ else {
126
+ root.add(this);
88
127
  }
89
128
  // assign same parent on child structures
90
129
  if (metadata) {
91
- metadata[-4]?.forEach((index) => {
130
+ metadata[symbols_1.$refTypeFieldIndexes]?.forEach((index) => {
92
131
  const field = metadata[index];
93
132
  const value = this.ref[field.name];
94
133
  value?.[symbols_1.$changes].setParent(this.ref, root, index);
95
- // console.log(this.ref.constructor.name, field.name, value);
96
134
  // try { throw new Error(); } catch (e) {
97
135
  // console.log(e.stack);
98
136
  // }
@@ -111,7 +149,7 @@ class ChangeTree {
111
149
  //
112
150
  const metadata = this.ref.constructor[Symbol.metadata];
113
151
  if (metadata) {
114
- metadata[-4]?.forEach((index) => {
152
+ metadata[symbols_1.$refTypeFieldIndexes]?.forEach((index) => {
115
153
  const field = metadata[index];
116
154
  const value = this.ref[field.name];
117
155
  if (value) {
@@ -127,8 +165,10 @@ class ChangeTree {
127
165
  }
128
166
  }
129
167
  operation(op) {
130
- this.changes.set(--this.currentOperationIndex, op);
131
- this.root?.changes.set(this, this.changes);
168
+ // operations without index use negative values to represent them
169
+ // this is checked during .encode() time.
170
+ this.changes.operations.push(-op);
171
+ enqueueChangeTree(this.root, this, 'changes');
132
172
  }
133
173
  change(index, operation = spec_1.OPERATION.ADD) {
134
174
  const metadata = this.ref.constructor[Symbol.metadata];
@@ -136,7 +176,7 @@ class ChangeTree {
136
176
  const changeSet = (isFiltered)
137
177
  ? this.filteredChanges
138
178
  : this.changes;
139
- const previousOperation = changeSet.get(index);
179
+ const previousOperation = this.indexedOperations[index];
140
180
  if (!previousOperation || previousOperation === spec_1.OPERATION.DELETE) {
141
181
  const op = (!previousOperation)
142
182
  ? operation
@@ -146,16 +186,19 @@ class ChangeTree {
146
186
  //
147
187
  // TODO: are DELETE operations being encoded as ADD here ??
148
188
  //
149
- changeSet.set(index, op);
189
+ this.indexedOperations[index] = op;
150
190
  }
191
+ setOperationAtIndex(changeSet, index);
151
192
  if (isFiltered) {
152
- this.allFilteredChanges.set(index, spec_1.OPERATION.ADD);
153
- this.root?.filteredChanges.set(this, this.filteredChanges);
154
- this.root?.allFilteredChanges.set(this, this.allFilteredChanges);
193
+ setOperationAtIndex(this.allFilteredChanges, index);
194
+ if (this.root) {
195
+ enqueueChangeTree(this.root, this, 'filteredChanges');
196
+ enqueueChangeTree(this.root, this, 'allFilteredChanges');
197
+ }
155
198
  }
156
199
  else {
157
- this.allChanges.set(index, spec_1.OPERATION.ADD);
158
- this.root?.changes.set(this, this.changes);
200
+ setOperationAtIndex(this.allChanges, index);
201
+ enqueueChangeTree(this.root, this, 'changes');
159
202
  }
160
203
  }
161
204
  shiftChangeIndexes(shiftIndex) {
@@ -167,12 +210,15 @@ class ChangeTree {
167
210
  const changeSet = (this.isFiltered)
168
211
  ? this.filteredChanges
169
212
  : this.changes;
170
- const changeSetEntries = Array.from(changeSet.entries());
171
- changeSet.clear();
172
- // Re-insert each entry with the shifted index
173
- for (const [index, op] of changeSetEntries) {
174
- changeSet.set(index + shiftIndex, op);
213
+ const newIndexedOperations = {};
214
+ const newIndexes = {};
215
+ for (const index in this.indexedOperations) {
216
+ newIndexedOperations[Number(index) + shiftIndex] = this.indexedOperations[index];
217
+ newIndexes[Number(index) + shiftIndex] = changeSet[index];
175
218
  }
219
+ this.indexedOperations = newIndexedOperations;
220
+ changeSet.indexes = newIndexes;
221
+ changeSet.operations = changeSet.operations.map((index) => index + shiftIndex);
176
222
  }
177
223
  shiftAllChangeIndexes(shiftIndex, startIndex = 0) {
178
224
  //
@@ -188,24 +234,36 @@ class ChangeTree {
188
234
  this._shiftAllChangeIndexes(shiftIndex, startIndex, this.allChanges);
189
235
  }
190
236
  }
191
- _shiftAllChangeIndexes(shiftIndex, startIndex = 0, allChangeSet) {
192
- Array.from(allChangeSet.entries()).forEach(([index, op]) => {
193
- if (index >= startIndex) {
194
- allChangeSet.delete(index);
195
- allChangeSet.set(index + shiftIndex, op);
237
+ _shiftAllChangeIndexes(shiftIndex, startIndex = 0, changeSet) {
238
+ const newIndexes = {};
239
+ for (const key in changeSet.indexes) {
240
+ const index = changeSet.indexes[key];
241
+ if (index > startIndex) {
242
+ newIndexes[Number(key) + shiftIndex] = index;
243
+ }
244
+ else {
245
+ newIndexes[key] = index;
246
+ }
247
+ }
248
+ changeSet.indexes = newIndexes;
249
+ for (let i = 0; i < changeSet.operations.length; i++) {
250
+ const index = changeSet.operations[i];
251
+ if (index > startIndex) {
252
+ changeSet.operations[i] = index + shiftIndex;
196
253
  }
197
- });
254
+ }
198
255
  }
199
256
  indexedOperation(index, operation, allChangesIndex = index) {
200
- if (this.filteredChanges !== undefined) {
201
- this.allFilteredChanges.set(allChangesIndex, spec_1.OPERATION.ADD);
202
- this.filteredChanges.set(index, operation);
203
- this.root?.filteredChanges.set(this, this.filteredChanges);
257
+ this.indexedOperations[index] = operation;
258
+ if (this.filteredChanges) {
259
+ setOperationAtIndex(this.allFilteredChanges, allChangesIndex);
260
+ setOperationAtIndex(this.filteredChanges, index);
261
+ enqueueChangeTree(this.root, this, 'filteredChanges');
204
262
  }
205
263
  else {
206
- this.allChanges.set(allChangesIndex, spec_1.OPERATION.ADD);
207
- this.changes.set(index, operation);
208
- this.root?.changes.set(this, this.changes);
264
+ setOperationAtIndex(this.allChanges, allChangesIndex);
265
+ setOperationAtIndex(this.changes, index);
266
+ enqueueChangeTree(this.root, this, 'changes');
209
267
  }
210
268
  }
211
269
  getType(index) {
@@ -224,8 +282,7 @@ class ChangeTree {
224
282
  }
225
283
  }
226
284
  getChange(index) {
227
- // TODO: optimize this. avoid checking against multiple instances
228
- return this.changes.get(index) ?? this.filteredChanges?.get(index);
285
+ return this.indexedOperations[index];
229
286
  }
230
287
  //
231
288
  // used during `.encode()`
@@ -249,8 +306,9 @@ class ChangeTree {
249
306
  const changeSet = (this.filteredChanges)
250
307
  ? this.filteredChanges
251
308
  : this.changes;
309
+ this.indexedOperations[index] = operation ?? spec_1.OPERATION.DELETE;
310
+ setOperationAtIndex(changeSet, index);
252
311
  const previousValue = this.getValue(index);
253
- changeSet.set(index, operation ?? spec_1.OPERATION.DELETE);
254
312
  // remove `root` reference
255
313
  if (previousValue && previousValue[symbols_1.$changes]) {
256
314
  //
@@ -266,23 +324,26 @@ class ChangeTree {
266
324
  this.root?.remove(previousValue[symbols_1.$changes]);
267
325
  }
268
326
  //
269
- // FIXME: this is looking a bit ugly (and repeated from `.change()`)
327
+ // FIXME: this is looking a ugly and repeated
270
328
  //
271
329
  if (this.filteredChanges) {
272
- this.root?.filteredChanges.set(this, this.filteredChanges);
273
- this.allFilteredChanges.delete(allChangesIndex);
330
+ deleteOperationAtIndex(this.allFilteredChanges, allChangesIndex);
331
+ enqueueChangeTree(this.root, this, 'filteredChanges');
274
332
  }
275
333
  else {
276
- this.root?.changes.set(this, this.changes);
277
- this.allChanges.delete(allChangesIndex);
334
+ deleteOperationAtIndex(this.allChanges, allChangesIndex);
335
+ enqueueChangeTree(this.root, this, 'changes');
278
336
  }
279
337
  }
280
338
  endEncode() {
281
- this.changes.clear();
339
+ this.indexedOperations = {};
340
+ // // clear changes
341
+ // this.changes.indexes = {};
342
+ // this.changes.operations.length = 0;
282
343
  // ArraySchema and MapSchema have a custom "encode end" method
283
344
  this.ref[symbols_1.$onEncodeEnd]?.();
284
345
  // Not a new instance anymore
285
- delete this[symbols_1.$isNew];
346
+ this.isNew = false;
286
347
  }
287
348
  discard(discardAll = false) {
288
349
  //
@@ -291,13 +352,22 @@ class ChangeTree {
291
352
  // REPLACE in case same key is used on next patches.
292
353
  //
293
354
  this.ref[symbols_1.$onEncodeEnd]?.();
294
- this.changes.clear();
295
- this.filteredChanges?.clear();
296
- // reset operation index
297
- this.currentOperationIndex = 0;
355
+ this.indexedOperations = {};
356
+ this.changes.indexes = {};
357
+ this.changes.operations.length = 0;
358
+ this.changes.queueRootIndex = undefined;
359
+ if (this.filteredChanges !== undefined) {
360
+ this.filteredChanges.indexes = {};
361
+ this.filteredChanges.operations.length = 0;
362
+ this.filteredChanges.queueRootIndex = undefined;
363
+ }
298
364
  if (discardAll) {
299
- this.allChanges.clear();
300
- this.allFilteredChanges?.clear();
365
+ this.allChanges.indexes = {};
366
+ this.allChanges.operations.length = 0;
367
+ if (this.allFilteredChanges !== undefined) {
368
+ this.allFilteredChanges.indexes = {};
369
+ this.allFilteredChanges.operations.length = 0;
370
+ }
301
371
  // remove children references
302
372
  this.forEachChild((changeTree, _) => this.root?.remove(changeTree));
303
373
  }
@@ -306,12 +376,13 @@ class ChangeTree {
306
376
  * Recursively discard all changes from this, and child structures.
307
377
  */
308
378
  discardAll() {
309
- this.changes.forEach((_, fieldIndex) => {
310
- const value = this.getValue(fieldIndex);
379
+ const keys = Object.keys(this.indexedOperations);
380
+ for (let i = 0, len = keys.length; i < len; i++) {
381
+ const value = this.getValue(Number(keys[i]));
311
382
  if (value && value[symbols_1.$changes]) {
312
383
  value[symbols_1.$changes].discardAll();
313
384
  }
314
- });
385
+ }
315
386
  this.discard();
316
387
  }
317
388
  ensureRefId() {
@@ -322,42 +393,48 @@ class ChangeTree {
322
393
  this.refId = this.root.getNextUniqueId();
323
394
  }
324
395
  get changed() {
325
- return this.changes.size > 0;
396
+ return (Object.entries(this.indexedOperations).length > 0);
326
397
  }
327
398
  checkIsFiltered(metadata, parent, parentIndex) {
328
399
  // Detect if current structure has "filters" declared
329
- this.isPartiallyFiltered = metadata?.[-2] !== undefined;
400
+ this.isPartiallyFiltered = metadata?.[symbols_1.$viewFieldIndexes] !== undefined;
330
401
  if (this.isPartiallyFiltered) {
331
- this.filteredChanges = this.filteredChanges || new Map();
332
- this.allFilteredChanges = this.allFilteredChanges || new Map();
333
- }
334
- if (parent) {
335
- if (!Metadata_1.Metadata.isValidInstance(parent)) {
336
- const parentChangeTree = parent[symbols_1.$changes];
337
- parent = parentChangeTree.parent;
338
- parentIndex = parentChangeTree.parentIndex;
339
- }
340
- const parentMetadata = parent?.constructor?.[Symbol.metadata];
341
- this.isFiltered = (parent && parentMetadata?.[-2]?.includes(parentIndex));
342
- //
343
- // TODO: refactor this!
344
- //
345
- // swapping `changes` and `filteredChanges` is required here
346
- // because "isFiltered" may not be imedialely available on `change()`
347
- //
348
- if (this.isFiltered) {
349
- this.filteredChanges = new Map();
350
- this.allFilteredChanges = new Map();
351
- if (this.changes.size > 0) {
352
- // swap changes reference
353
- const changes = this.changes;
354
- this.changes = this.filteredChanges;
355
- this.filteredChanges = changes;
356
- // swap "all changes" reference
357
- const allFilteredChanges = this.allFilteredChanges;
358
- this.allFilteredChanges = this.allChanges;
359
- this.allChanges = allFilteredChanges;
360
- }
402
+ this.filteredChanges = this.filteredChanges || { indexes: {}, operations: [] };
403
+ this.allFilteredChanges = this.allFilteredChanges || { indexes: {}, operations: [] };
404
+ }
405
+ // skip if parent is not set
406
+ if (!parent) {
407
+ return;
408
+ }
409
+ if (!Metadata_1.Metadata.isValidInstance(parent)) {
410
+ const parentChangeTree = parent[symbols_1.$changes];
411
+ parent = parentChangeTree.parent;
412
+ parentIndex = parentChangeTree.parentIndex;
413
+ }
414
+ const parentMetadata = parent.constructor?.[Symbol.metadata];
415
+ this.isFiltered = parentMetadata?.[symbols_1.$viewFieldIndexes]?.includes(parentIndex);
416
+ //
417
+ // TODO: refactor this!
418
+ //
419
+ // swapping `changes` and `filteredChanges` is required here
420
+ // because "isFiltered" may not be imedialely available on `change()`
421
+ //
422
+ if (this.isFiltered) {
423
+ this.filteredChanges = { indexes: {}, operations: [] };
424
+ this.allFilteredChanges = { indexes: {}, operations: [] };
425
+ if (this.changes.operations.length > 0) {
426
+ // swap changes reference
427
+ const changes = this.changes;
428
+ this.changes = this.filteredChanges;
429
+ this.filteredChanges = changes;
430
+ // swap "all changes" reference
431
+ const allFilteredChanges = this.allFilteredChanges;
432
+ this.allFilteredChanges = this.allChanges;
433
+ this.allChanges = allFilteredChanges;
434
+ // console.log("SWAP =>", {
435
+ // "this.allFilteredChanges": this.allFilteredChanges,
436
+ // "this.allChanges": this.allChanges
437
+ // })
361
438
  }
362
439
  }
363
440
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ChangeTree.js","sourceRoot":"","sources":["../../src/encoder/ChangeTree.ts"],"names":[],"mappings":"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","sourcesContent":["import { OPERATION } from \"../encoding/spec\";\nimport { Schema } from \"../Schema\";\nimport { $changes, $childType, $decoder, $onEncodeEnd, $encoder, $getByIndex, $isNew } from \"../types/symbols\";\n\nimport type { MapSchema } from \"../types/custom/MapSchema\";\nimport type { ArraySchema } from \"../types/custom/ArraySchema\";\nimport type { CollectionSchema } from \"../types/custom/CollectionSchema\";\nimport type { SetSchema } from \"../types/custom/SetSchema\";\n\nimport { Root } from \"./Root\";\nimport { Metadata } from \"../Metadata\";\nimport type { EncodeOperation } from \"./EncodeOperation\";\nimport type { DecodeOperation } from \"../decoder/DecodeOperation\";\n\ndeclare global {\n interface Object {\n // FIXME: not a good practice to extend globals here\n [$changes]?: ChangeTree;\n [$encoder]?: EncodeOperation,\n [$decoder]?: DecodeOperation,\n }\n}\n\nexport type Ref = Schema\n | ArraySchema\n | MapSchema\n | CollectionSchema\n | SetSchema;\n\nexport class ChangeTree<T extends Ref=any> {\n ref: T;\n refId: number;\n\n root?: Root;\n parent?: Ref;\n parentIndex?: number;\n\n isFiltered: boolean = false;\n isPartiallyFiltered: boolean = false;\n\n currentOperationIndex: number = 0;\n\n changes = new Map<number, OPERATION>();\n allChanges = new Map<number, OPERATION>();\n\n allFilteredChanges: Map<number, OPERATION>;\n filteredChanges: Map<number, OPERATION>;\n\n indexes: {[index: string]: any}; // TODO: remove this, only used by MapSchema/SetSchema/CollectionSchema (`encodeKeyValueOperation`)\n\n [$isNew] = true;\n\n constructor(ref: T) {\n this.ref = ref;\n\n //\n // Does this structure have \"filters\" declared?\n //\n if (ref.constructor[Symbol.metadata]?.[-2]) {\n this.allFilteredChanges = new Map<number, OPERATION>();\n this.filteredChanges = new Map<number, OPERATION>();\n }\n }\n\n setRoot(root: Root) {\n this.root = root;\n this.root.add(this);\n\n const metadata: Metadata = this.ref.constructor[Symbol.metadata];\n\n if (this.root.types.hasFilters) {\n //\n // At Schema initialization, the \"root\" structure might not be available\n // yet, as it only does once the \"Encoder\" has been set up.\n //\n // So the \"parent\" may be already set without a \"root\".\n //\n this.checkIsFiltered(metadata, this.parent, this.parentIndex);\n\n if (this.isFiltered || this.isPartiallyFiltered) {\n this.root.allFilteredChanges.set(this, this.allFilteredChanges);\n this.root.filteredChanges.set(this, this.filteredChanges);\n }\n }\n\n if (!this.isFiltered) {\n this.root.changes.set(this, this.changes);\n this.root.allChanges.set(this, this.allChanges);\n }\n\n this.ensureRefId();\n\n if (metadata) {\n metadata[-4]?.forEach((index) => {\n const field = metadata[index as any as number];\n const value = this.ref[field.name];\n if (value) {\n value[$changes].setRoot(root);\n }\n });\n\n } else if (this.ref[$childType] && typeof(this.ref[$childType]) !== \"string\") {\n // MapSchema / ArraySchema, etc.\n (this.ref as MapSchema).forEach((value, key) => {\n value[$changes].setRoot(root);\n });\n }\n\n }\n\n setParent(\n parent: Ref,\n root?: Root,\n parentIndex?: number,\n ) {\n this.parent = parent;\n this.parentIndex = parentIndex;\n\n // avoid setting parents with empty `root`\n if (!root) { return; }\n\n root.add(this);\n\n const metadata: Metadata = this.ref.constructor[Symbol.metadata];\n\n // skip if parent is already set\n if (root !== this.root) {\n this.root = root;\n\n if (root.types.hasFilters) {\n this.checkIsFiltered(metadata, parent, parentIndex);\n\n if (this.isFiltered || this.isPartiallyFiltered) {\n this.root.filteredChanges.set(this, this.filteredChanges);\n this.root.allFilteredChanges.set(this, this.filteredChanges);\n }\n }\n\n if (!this.isFiltered) {\n this.root.changes.set(this, this.changes);\n this.root.allChanges.set(this, this.allChanges);\n }\n\n this.ensureRefId();\n }\n\n // assign same parent on child structures\n if (metadata) {\n metadata[-4]?.forEach((index) => {\n const field = metadata[index as any as number];\n const value = this.ref[field.name];\n value?.[$changes].setParent(this.ref, root, index);\n\n // console.log(this.ref.constructor.name, field.name, value);\n\n // try { throw new Error(); } catch (e) {\n // console.log(e.stack);\n // }\n\n });\n\n } else if (this.ref[$childType] && typeof(this.ref[$childType]) !== \"string\") {\n // MapSchema / ArraySchema, etc.\n (this.ref as MapSchema).forEach((value, key) => {\n value[$changes].setParent(this.ref, root, this.indexes[key] ?? key);\n });\n }\n\n }\n\n forEachChild(callback: (change: ChangeTree, atIndex: number) => void) {\n //\n // assign same parent on child structures\n //\n const metadata: Metadata = this.ref.constructor[Symbol.metadata];\n if (metadata) {\n metadata[-4]?.forEach((index) => {\n const field = metadata[index as any as number];\n const value = this.ref[field.name];\n if (value) {\n callback(value[$changes], index);\n }\n });\n\n } else if (this.ref[$childType] && typeof(this.ref[$childType]) !== \"string\") {\n // MapSchema / ArraySchema, etc.\n (this.ref as MapSchema).forEach((value, key) => {\n callback(value[$changes], this.indexes[key] ?? key);\n });\n }\n }\n\n operation(op: OPERATION) {\n this.changes.set(--this.currentOperationIndex, op);\n this.root?.changes.set(this, this.changes);\n }\n\n change(index: number, operation: OPERATION = OPERATION.ADD) {\n const metadata = this.ref.constructor[Symbol.metadata] as Metadata;\n\n const isFiltered = this.isFiltered || (metadata?.[index]?.tag !== undefined);\n const changeSet = (isFiltered)\n ? this.filteredChanges\n : this.changes;\n\n const previousOperation = changeSet.get(index);\n if (!previousOperation || previousOperation === OPERATION.DELETE) {\n const op = (!previousOperation)\n ? operation\n : (previousOperation === OPERATION.DELETE)\n ? OPERATION.DELETE_AND_ADD\n : operation\n //\n // TODO: are DELETE operations being encoded as ADD here ??\n //\n changeSet.set(index, op);\n }\n\n if (isFiltered) {\n this.allFilteredChanges.set(index, OPERATION.ADD);\n this.root?.filteredChanges.set(this, this.filteredChanges);\n this.root?.allFilteredChanges.set(this, this.allFilteredChanges);\n\n } else {\n this.allChanges.set(index, OPERATION.ADD);\n this.root?.changes.set(this, this.changes);\n }\n }\n\n shiftChangeIndexes(shiftIndex: number) {\n //\n // Used only during:\n //\n // - ArraySchema#unshift()\n //\n const changeSet = (this.isFiltered)\n ? this.filteredChanges\n : this.changes;\n\n const changeSetEntries = Array.from(changeSet.entries());\n changeSet.clear();\n\n // Re-insert each entry with the shifted index\n for (const [index, op] of changeSetEntries) {\n changeSet.set(index + shiftIndex, op);\n }\n }\n\n shiftAllChangeIndexes(shiftIndex: number, startIndex: number = 0) {\n //\n // Used only during:\n //\n // - ArraySchema#splice()\n //\n if (this.isFiltered || this.isPartiallyFiltered) {\n this._shiftAllChangeIndexes(shiftIndex, startIndex, this.allFilteredChanges);\n this._shiftAllChangeIndexes(shiftIndex, startIndex, this.allChanges);\n\n } else {\n this._shiftAllChangeIndexes(shiftIndex, startIndex, this.allChanges);\n }\n }\n\n private _shiftAllChangeIndexes(shiftIndex: number, startIndex: number = 0, allChangeSet: Map<number, OPERATION>) {\n Array.from(allChangeSet.entries()).forEach(([index, op]) => {\n if (index >= startIndex) {\n allChangeSet.delete(index);\n allChangeSet.set(index + shiftIndex, op);\n }\n });\n }\n\n indexedOperation(index: number, operation: OPERATION, allChangesIndex = index) {\n if (this.filteredChanges !== undefined) {\n this.allFilteredChanges.set(allChangesIndex, OPERATION.ADD);\n this.filteredChanges.set(index, operation);\n this.root?.filteredChanges.set(this, this.filteredChanges);\n\n } else {\n this.allChanges.set(allChangesIndex, OPERATION.ADD);\n this.changes.set(index, operation);\n this.root?.changes.set(this, this.changes);\n }\n }\n\n getType(index?: number) {\n if (Metadata.isValidInstance(this.ref)) {\n const metadata = this.ref.constructor[Symbol.metadata] as Metadata;\n return metadata[index].type;\n\n } else {\n //\n // Get the child type from parent structure.\n // - [\"string\"] => \"string\"\n // - { map: \"string\" } => \"string\"\n // - { set: \"string\" } => \"string\"\n //\n return this.ref[$childType];\n }\n }\n\n getChange(index: number) {\n // TODO: optimize this. avoid checking against multiple instances\n return this.changes.get(index) ?? this.filteredChanges?.get(index);\n }\n\n //\n // used during `.encode()`\n //\n getValue(index: number, isEncodeAll: boolean = false) {\n //\n // `isEncodeAll` param is only used by ArraySchema\n //\n return this.ref[$getByIndex](index, isEncodeAll);\n }\n\n delete(index: number, operation?: OPERATION, allChangesIndex = index) {\n if (index === undefined) {\n try {\n throw new Error(`@colyseus/schema ${this.ref.constructor.name}: trying to delete non-existing index '${index}'`);\n } catch (e) {\n console.warn(e);\n }\n return;\n }\n\n const changeSet = (this.filteredChanges)\n ? this.filteredChanges\n : this.changes;\n\n const previousValue = this.getValue(index);\n\n changeSet.set(index, operation ?? OPERATION.DELETE);\n\n // remove `root` reference\n if (previousValue && previousValue[$changes]) {\n //\n // FIXME: this.root is \"undefined\"\n //\n // This method is being called at decoding time when a DELETE operation is found.\n //\n // - This is due to using the concrete Schema class at decoding time.\n // - \"Reflected\" structures do not have this problem.\n //\n // (the property descriptors should NOT be used at decoding time. only at encoding time.)\n //\n this.root?.remove(previousValue[$changes]);\n }\n\n //\n // FIXME: this is looking a bit ugly (and repeated from `.change()`)\n //\n if (this.filteredChanges) {\n this.root?.filteredChanges.set(this, this.filteredChanges);\n this.allFilteredChanges.delete(allChangesIndex);\n\n } else {\n this.root?.changes.set(this, this.changes);\n this.allChanges.delete(allChangesIndex);\n }\n }\n\n endEncode() {\n this.changes.clear();\n\n // ArraySchema and MapSchema have a custom \"encode end\" method\n this.ref[$onEncodeEnd]?.();\n\n // Not a new instance anymore\n delete this[$isNew];\n }\n\n discard(discardAll: boolean = false) {\n //\n // > MapSchema:\n // Remove cached key to ensure ADD operations is unsed instead of\n // REPLACE in case same key is used on next patches.\n //\n this.ref[$onEncodeEnd]?.();\n\n this.changes.clear();\n this.filteredChanges?.clear();\n\n // reset operation index\n this.currentOperationIndex = 0;\n\n if (discardAll) {\n this.allChanges.clear();\n this.allFilteredChanges?.clear();\n\n // remove children references\n this.forEachChild((changeTree, _) =>\n this.root?.remove(changeTree));\n }\n }\n\n /**\n * Recursively discard all changes from this, and child structures.\n */\n discardAll() {\n this.changes.forEach((_, fieldIndex) => {\n const value = this.getValue(fieldIndex);\n\n if (value && value[$changes]) {\n value[$changes].discardAll();\n }\n });\n\n this.discard();\n }\n\n ensureRefId() {\n // skip if refId is already set.\n if (this.refId !== undefined) {\n return;\n }\n\n this.refId = this.root.getNextUniqueId();\n }\n\n get changed() {\n return this.changes.size > 0;\n }\n\n protected checkIsFiltered(metadata: Metadata, parent: Ref, parentIndex: number) {\n // Detect if current structure has \"filters\" declared\n this.isPartiallyFiltered = metadata?.[-2] !== undefined;\n\n if (this.isPartiallyFiltered) {\n this.filteredChanges = this.filteredChanges || new Map<number, OPERATION>();\n this.allFilteredChanges = this.allFilteredChanges || new Map<number, OPERATION>();\n }\n\n if (parent) {\n if (!Metadata.isValidInstance(parent)) {\n const parentChangeTree = parent[$changes];\n parent = parentChangeTree.parent;\n parentIndex = parentChangeTree.parentIndex;\n }\n\n const parentMetadata = parent?.constructor?.[Symbol.metadata];\n this.isFiltered = (parent && parentMetadata?.[-2]?.includes(parentIndex));\n\n //\n // TODO: refactor this!\n //\n // swapping `changes` and `filteredChanges` is required here\n // because \"isFiltered\" may not be imedialely available on `change()`\n //\n if (this.isFiltered) {\n this.filteredChanges = new Map<number, OPERATION>();\n this.allFilteredChanges = new Map<number, OPERATION>();\n\n if (this.changes.size > 0) {\n // swap changes reference\n const changes = this.changes;\n this.changes = this.filteredChanges;\n this.filteredChanges = changes;\n\n // swap \"all changes\" reference\n const allFilteredChanges = this.allFilteredChanges;\n this.allFilteredChanges = this.allChanges;\n this.allChanges = allFilteredChanges;\n }\n }\n }\n }\n\n}\n"]}
1
+ {"version":3,"file":"ChangeTree.js","sourceRoot":"","sources":["../../src/encoder/ChangeTree.ts"],"names":[],"mappings":"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","sourcesContent":["import { OPERATION } from \"../encoding/spec\";\nimport { Schema } from \"../Schema\";\nimport { $changes, $childType, $decoder, $onEncodeEnd, $encoder, $getByIndex, $refTypeFieldIndexes, $viewFieldIndexes } from \"../types/symbols\";\n\nimport type { MapSchema } from \"../types/custom/MapSchema\";\nimport type { ArraySchema } from \"../types/custom/ArraySchema\";\nimport type { CollectionSchema } from \"../types/custom/CollectionSchema\";\nimport type { SetSchema } from \"../types/custom/SetSchema\";\n\nimport { Root } from \"./Root\";\nimport { Metadata } from \"../Metadata\";\nimport type { EncodeOperation } from \"./EncodeOperation\";\nimport type { DecodeOperation } from \"../decoder/DecodeOperation\";\n\ndeclare global {\n interface Object {\n // FIXME: not a good practice to extend globals here\n [$changes]?: ChangeTree;\n [$encoder]?: EncodeOperation,\n [$decoder]?: DecodeOperation,\n }\n}\n\nexport type Ref = Schema\n | ArraySchema\n | MapSchema\n | CollectionSchema\n | SetSchema;\n\nexport type ChangeSetName = \"changes\"\n | \"allChanges\"\n | \"filteredChanges\"\n | \"allFilteredChanges\";\n\nexport interface IndexedOperations {\n [index: number]: OPERATION;\n}\n\nexport interface ChangeSet {\n // field index -> operation index\n indexes: { [index: number]: number };\n operations: OPERATION[]\n queueRootIndex?: number; // index of ChangeTree structure in `root.changes` or `root.filteredChanges`\n}\n\nexport function setOperationAtIndex(changeSet: ChangeSet, index: number) {\n const operationsIndex = changeSet.indexes[index];\n if (operationsIndex === undefined) {\n changeSet.indexes[index] = changeSet.operations.push(index) - 1;\n } else {\n changeSet.operations[operationsIndex] = index;\n }\n}\n\nexport function deleteOperationAtIndex(changeSet: ChangeSet, index: number) {\n const operationsIndex = changeSet.indexes[index];\n if (operationsIndex !== undefined) {\n changeSet.operations[operationsIndex] = undefined;\n }\n delete changeSet.indexes[index];\n}\n\nfunction enqueueChangeTree(\n root: Root,\n changeTree: ChangeTree,\n changeSet: 'changes' | 'filteredChanges' | 'allFilteredChanges',\n queueRootIndex = changeTree[changeSet].queueRootIndex\n) {\n if (root && root[changeSet][queueRootIndex] !== changeTree) {\n changeTree[changeSet].queueRootIndex = root[changeSet].push(changeTree) - 1;\n }\n}\n\nexport class ChangeTree<T extends Ref=any> {\n ref: T;\n refId: number;\n\n root?: Root;\n parent?: Ref;\n parentIndex?: number;\n\n isFiltered: boolean = false;\n isPartiallyFiltered: boolean = false;\n\n indexedOperations: IndexedOperations = {};\n\n //\n // TODO:\n // try storing the index + operation per item.\n // example: 1024 & 1025 => ADD, 1026 => DELETE\n //\n // => https://chatgpt.com/share/67107d0c-bc20-8004-8583-83b17dd7c196\n //\n changes: ChangeSet = { indexes: {}, operations: [] };\n allChanges: ChangeSet = { indexes: {}, operations: [] };\n filteredChanges: ChangeSet;\n allFilteredChanges: ChangeSet;\n\n indexes: {[index: string]: any}; // TODO: remove this, only used by MapSchema/SetSchema/CollectionSchema (`encodeKeyValueOperation`)\n\n /**\n * Is this a new instance? Used on ArraySchema to determine OPERATION.MOVE_AND_ADD operation.\n */\n isNew = true;\n\n constructor(ref: T) {\n this.ref = ref;\n\n //\n // Does this structure have \"filters\" declared?\n //\n if (ref.constructor[Symbol.metadata]?.[$viewFieldIndexes]) {\n this.allFilteredChanges = { indexes: {}, operations: [] };\n this.filteredChanges = { indexes: {}, operations: [] };\n }\n }\n\n setRoot(root: Root) {\n this.root = root;\n const isNewChangeTree = this.root.add(this);\n\n const metadata: Metadata = this.ref.constructor[Symbol.metadata];\n\n if (this.root.types.hasFilters) {\n //\n // At Schema initialization, the \"root\" structure might not be available\n // yet, as it only does once the \"Encoder\" has been set up.\n //\n // So the \"parent\" may be already set without a \"root\".\n //\n this.checkIsFiltered(metadata, this.parent, this.parentIndex);\n\n if (this.isFiltered || this.isPartiallyFiltered) {\n enqueueChangeTree(root, this, 'filteredChanges');\n if (isNewChangeTree) {\n this.root.allFilteredChanges.push(this);\n }\n }\n }\n\n if (!this.isFiltered) {\n enqueueChangeTree(root, this, 'changes');\n if (isNewChangeTree) {\n this.root.allChanges.push(this);\n }\n }\n\n // Recursively set root on child structures\n if (metadata) {\n metadata[$refTypeFieldIndexes]?.forEach((index) => {\n const field = metadata[index as any as number];\n const value = this.ref[field.name];\n value?.[$changes].setRoot(root);\n });\n\n } else if (this.ref[$childType] && typeof(this.ref[$childType]) !== \"string\") {\n // MapSchema / ArraySchema, etc.\n (this.ref as MapSchema).forEach((value, key) => {\n value[$changes].setRoot(root);\n });\n }\n\n }\n\n setParent(\n parent: Ref,\n root?: Root,\n parentIndex?: number,\n ) {\n this.parent = parent;\n this.parentIndex = parentIndex;\n\n // avoid setting parents with empty `root`\n if (!root) { return; }\n\n const metadata: Metadata = this.ref.constructor[Symbol.metadata];\n\n // skip if parent is already set\n if (root !== this.root) {\n this.root = root;\n const isNewChangeTree = root.add(this);\n\n if (root.types.hasFilters) {\n this.checkIsFiltered(metadata, parent, parentIndex);\n\n if (this.isFiltered || this.isPartiallyFiltered) {\n enqueueChangeTree(root, this, 'filteredChanges');\n if (isNewChangeTree) {\n this.root.allFilteredChanges.push(this);\n }\n }\n }\n\n if (!this.isFiltered) {\n enqueueChangeTree(root, this, 'changes');\n if (isNewChangeTree) {\n this.root.allChanges.push(this);\n }\n }\n\n } else {\n root.add(this);\n }\n\n // assign same parent on child structures\n if (metadata) {\n metadata[$refTypeFieldIndexes]?.forEach((index) => {\n const field = metadata[index as any as number];\n const value = this.ref[field.name];\n value?.[$changes].setParent(this.ref, root, index);\n\n // try { throw new Error(); } catch (e) {\n // console.log(e.stack);\n // }\n\n });\n\n } else if (this.ref[$childType] && typeof(this.ref[$childType]) !== \"string\") {\n // MapSchema / ArraySchema, etc.\n (this.ref as MapSchema).forEach((value, key) => {\n value[$changes].setParent(this.ref, root, this.indexes[key] ?? key);\n });\n }\n\n }\n\n forEachChild(callback: (change: ChangeTree, atIndex: number) => void) {\n //\n // assign same parent on child structures\n //\n const metadata: Metadata = this.ref.constructor[Symbol.metadata];\n if (metadata) {\n metadata[$refTypeFieldIndexes]?.forEach((index) => {\n const field = metadata[index as any as number];\n const value = this.ref[field.name];\n if (value) {\n callback(value[$changes], index);\n }\n });\n\n } else if (this.ref[$childType] && typeof(this.ref[$childType]) !== \"string\") {\n // MapSchema / ArraySchema, etc.\n (this.ref as MapSchema).forEach((value, key) => {\n callback(value[$changes], this.indexes[key] ?? key);\n });\n }\n }\n\n operation(op: OPERATION) {\n // operations without index use negative values to represent them\n // this is checked during .encode() time.\n this.changes.operations.push(-op);\n\n enqueueChangeTree(this.root, this, 'changes');\n }\n\n change(index: number, operation: OPERATION = OPERATION.ADD) {\n const metadata = this.ref.constructor[Symbol.metadata] as Metadata;\n\n const isFiltered = this.isFiltered || (metadata?.[index]?.tag !== undefined);\n const changeSet = (isFiltered)\n ? this.filteredChanges\n : this.changes;\n\n const previousOperation = this.indexedOperations[index];\n if (!previousOperation || previousOperation === OPERATION.DELETE) {\n const op = (!previousOperation)\n ? operation\n : (previousOperation === OPERATION.DELETE)\n ? OPERATION.DELETE_AND_ADD\n : operation\n //\n // TODO: are DELETE operations being encoded as ADD here ??\n //\n this.indexedOperations[index] = op;\n }\n\n setOperationAtIndex(changeSet, index);\n\n if (isFiltered) {\n setOperationAtIndex(this.allFilteredChanges, index);\n\n if (this.root) {\n enqueueChangeTree(this.root, this, 'filteredChanges');\n enqueueChangeTree(this.root, this, 'allFilteredChanges');\n }\n\n } else {\n setOperationAtIndex(this.allChanges, index);\n enqueueChangeTree(this.root, this, 'changes');\n }\n }\n\n shiftChangeIndexes(shiftIndex: number) {\n //\n // Used only during:\n //\n // - ArraySchema#unshift()\n //\n const changeSet = (this.isFiltered)\n ? this.filteredChanges\n : this.changes;\n\n const newIndexedOperations = {};\n const newIndexes = {};\n for (const index in this.indexedOperations) {\n newIndexedOperations[Number(index) + shiftIndex] = this.indexedOperations[index];\n newIndexes[Number(index) + shiftIndex] = changeSet[index];\n }\n this.indexedOperations = newIndexedOperations;\n changeSet.indexes = newIndexes;\n\n changeSet.operations = changeSet.operations.map((index) => index + shiftIndex);\n }\n\n shiftAllChangeIndexes(shiftIndex: number, startIndex: number = 0) {\n //\n // Used only during:\n //\n // - ArraySchema#splice()\n //\n if (this.isFiltered || this.isPartiallyFiltered) {\n this._shiftAllChangeIndexes(shiftIndex, startIndex, this.allFilteredChanges);\n this._shiftAllChangeIndexes(shiftIndex, startIndex, this.allChanges);\n\n } else {\n this._shiftAllChangeIndexes(shiftIndex, startIndex, this.allChanges);\n }\n }\n\n private _shiftAllChangeIndexes(shiftIndex: number, startIndex: number = 0, changeSet: ChangeSet) {\n const newIndexes = {};\n\n for (const key in changeSet.indexes) {\n const index = changeSet.indexes[key];\n if (index > startIndex) {\n newIndexes[Number(key) + shiftIndex] = index;\n } else {\n newIndexes[key] = index;\n }\n }\n changeSet.indexes = newIndexes;\n\n for (let i = 0; i < changeSet.operations.length; i++) {\n const index = changeSet.operations[i];\n if (index > startIndex) {\n changeSet.operations[i] = index + shiftIndex;\n }\n }\n }\n\n indexedOperation(index: number, operation: OPERATION, allChangesIndex: number = index) {\n this.indexedOperations[index] = operation;\n\n if (this.filteredChanges) {\n setOperationAtIndex(this.allFilteredChanges, allChangesIndex);\n setOperationAtIndex(this.filteredChanges, index);\n enqueueChangeTree(this.root, this, 'filteredChanges');\n\n } else {\n setOperationAtIndex(this.allChanges, allChangesIndex);\n setOperationAtIndex(this.changes, index);\n enqueueChangeTree(this.root, this, 'changes');\n }\n }\n\n getType(index?: number) {\n if (Metadata.isValidInstance(this.ref)) {\n const metadata = this.ref.constructor[Symbol.metadata] as Metadata;\n return metadata[index].type;\n\n } else {\n //\n // Get the child type from parent structure.\n // - [\"string\"] => \"string\"\n // - { map: \"string\" } => \"string\"\n // - { set: \"string\" } => \"string\"\n //\n return this.ref[$childType];\n }\n }\n\n getChange(index: number) {\n return this.indexedOperations[index];\n }\n\n //\n // used during `.encode()`\n //\n getValue(index: number, isEncodeAll: boolean = false) {\n //\n // `isEncodeAll` param is only used by ArraySchema\n //\n return this.ref[$getByIndex](index, isEncodeAll);\n }\n\n delete(index: number, operation?: OPERATION, allChangesIndex = index) {\n if (index === undefined) {\n try {\n throw new Error(`@colyseus/schema ${this.ref.constructor.name}: trying to delete non-existing index '${index}'`);\n } catch (e) {\n console.warn(e);\n }\n return;\n }\n\n const changeSet = (this.filteredChanges)\n ? this.filteredChanges\n : this.changes;\n\n this.indexedOperations[index] = operation ?? OPERATION.DELETE;\n setOperationAtIndex(changeSet, index);\n\n const previousValue = this.getValue(index);\n\n // remove `root` reference\n if (previousValue && previousValue[$changes]) {\n //\n // FIXME: this.root is \"undefined\"\n //\n // This method is being called at decoding time when a DELETE operation is found.\n //\n // - This is due to using the concrete Schema class at decoding time.\n // - \"Reflected\" structures do not have this problem.\n //\n // (the property descriptors should NOT be used at decoding time. only at encoding time.)\n //\n this.root?.remove(previousValue[$changes]);\n }\n\n //\n // FIXME: this is looking a ugly and repeated\n //\n if (this.filteredChanges) {\n deleteOperationAtIndex(this.allFilteredChanges, allChangesIndex);\n enqueueChangeTree(this.root, this, 'filteredChanges');\n\n } else {\n deleteOperationAtIndex(this.allChanges, allChangesIndex);\n enqueueChangeTree(this.root, this, 'changes');\n }\n }\n\n endEncode() {\n this.indexedOperations = {};\n\n // // clear changes\n // this.changes.indexes = {};\n // this.changes.operations.length = 0;\n\n // ArraySchema and MapSchema have a custom \"encode end\" method\n this.ref[$onEncodeEnd]?.();\n\n // Not a new instance anymore\n this.isNew = false;\n }\n\n discard(discardAll: boolean = false) {\n //\n // > MapSchema:\n // Remove cached key to ensure ADD operations is unsed instead of\n // REPLACE in case same key is used on next patches.\n //\n this.ref[$onEncodeEnd]?.();\n\n this.indexedOperations = {};\n\n this.changes.indexes = {};\n this.changes.operations.length = 0;\n this.changes.queueRootIndex = undefined;\n\n if (this.filteredChanges !== undefined) {\n this.filteredChanges.indexes = {};\n this.filteredChanges.operations.length = 0;\n this.filteredChanges.queueRootIndex = undefined;\n }\n\n if (discardAll) {\n this.allChanges.indexes = {};\n this.allChanges.operations.length = 0;\n\n if (this.allFilteredChanges !== undefined) {\n this.allFilteredChanges.indexes = {};\n this.allFilteredChanges.operations.length = 0;\n }\n\n // remove children references\n this.forEachChild((changeTree, _) =>\n this.root?.remove(changeTree));\n }\n }\n\n /**\n * Recursively discard all changes from this, and child structures.\n */\n discardAll() {\n const keys = Object.keys(this.indexedOperations);\n for (let i = 0, len = keys.length; i < len; i++) {\n const value = this.getValue(Number(keys[i]));\n\n if (value && value[$changes]) {\n value[$changes].discardAll();\n }\n }\n\n this.discard();\n }\n\n ensureRefId() {\n // skip if refId is already set.\n if (this.refId !== undefined) {\n return;\n }\n\n this.refId = this.root.getNextUniqueId();\n }\n\n get changed() {\n return (Object.entries(this.indexedOperations).length > 0);\n }\n\n protected checkIsFiltered(metadata: Metadata, parent: Ref, parentIndex: number) {\n // Detect if current structure has \"filters\" declared\n this.isPartiallyFiltered = metadata?.[$viewFieldIndexes] !== undefined;\n\n if (this.isPartiallyFiltered) {\n this.filteredChanges = this.filteredChanges || { indexes: {}, operations: [] };\n this.allFilteredChanges = this.allFilteredChanges || { indexes: {}, operations: [] };\n }\n\n // skip if parent is not set\n if (!parent) {\n return;\n }\n\n if (!Metadata.isValidInstance(parent)) {\n const parentChangeTree = parent[$changes];\n parent = parentChangeTree.parent;\n parentIndex = parentChangeTree.parentIndex;\n }\n\n const parentMetadata = parent.constructor?.[Symbol.metadata];\n this.isFiltered = parentMetadata?.[$viewFieldIndexes]?.includes(parentIndex);\n\n //\n // TODO: refactor this!\n //\n // swapping `changes` and `filteredChanges` is required here\n // because \"isFiltered\" may not be imedialely available on `change()`\n //\n if (this.isFiltered) {\n this.filteredChanges = { indexes: {}, operations: [] };\n this.allFilteredChanges = { indexes: {}, operations: [] };\n\n if (this.changes.operations.length > 0) {\n // swap changes reference\n const changes = this.changes;\n this.changes = this.filteredChanges;\n this.filteredChanges = changes;\n\n // swap \"all changes\" reference\n const allFilteredChanges = this.allFilteredChanges;\n this.allFilteredChanges = this.allChanges;\n this.allChanges = allFilteredChanges;\n\n // console.log(\"SWAP =>\", {\n // \"this.allFilteredChanges\": this.allFilteredChanges,\n // \"this.allChanges\": this.allChanges\n // })\n }\n }\n }\n\n}\n"]}
@@ -2,7 +2,8 @@ import { OPERATION } from "../encoding/spec";
2
2
  import type { ChangeTree, Ref } from "./ChangeTree";
3
3
  import type { Encoder } from "./Encoder";
4
4
  import type { Iterator } from "../encoding/decode";
5
- export type EncodeOperation<T extends Ref = any> = (encoder: Encoder, bytes: Buffer, changeTree: ChangeTree<T>, index: number, operation: OPERATION, it: Iterator, isEncodeAll: boolean, hasView: boolean) => void;
5
+ import type { Metadata } from "../Metadata";
6
+ export type EncodeOperation<T extends Ref = any> = (encoder: Encoder, bytes: Buffer, changeTree: ChangeTree<T>, index: number, operation: OPERATION, it: Iterator, isEncodeAll: boolean, hasView: boolean, metadata?: Metadata) => void;
6
7
  export declare function encodeValue(encoder: Encoder, bytes: Buffer, type: any, value: any, operation: OPERATION, it: Iterator): void;
7
8
  /**
8
9
  * Used for Schema instances.
@@ -32,7 +32,7 @@ function encodeValue(encoder, bytes, type, value, operation, it) {
32
32
  * Used for Schema instances.
33
33
  * @private
34
34
  */
35
- const encodeSchemaOperation = function (encoder, bytes, changeTree, index, operation, it) {
35
+ const encodeSchemaOperation = function (encoder, bytes, changeTree, index, operation, it, _, __, metadata) {
36
36
  // "compress" field index + operation
37
37
  bytes[it.offset++] = (index | operation) & 255;
38
38
  // Do not encode value for DELETE operations
@@ -40,7 +40,7 @@ const encodeSchemaOperation = function (encoder, bytes, changeTree, index, opera
40
40
  return;
41
41
  }
42
42
  const ref = changeTree.ref;
43
- const metadata = ref.constructor[Symbol.metadata];
43
+ // const metadata: Metadata = ref.constructor[Symbol.metadata];
44
44
  const field = metadata[index];
45
45
  // TODO: inline this function call small performance gain
46
46
  encodeValue(encoder, bytes, metadata[index].type, ref[field.name], operation, it);