@colyseus/schema 3.0.36 → 3.0.37

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.
@@ -160,22 +160,36 @@ export class ChangeTree<T extends Ref=any> {
160
160
  this.root = root;
161
161
  this.checkIsFiltered(this.parent, this.parentIndex);
162
162
 
163
+ //
164
+ // TODO: refactor and possibly unify .setRoot() and .setParent()
165
+ //
166
+
163
167
  // Recursively set root on child structures
164
168
  const metadata: Metadata = this.ref.constructor[Symbol.metadata];
165
169
  if (metadata) {
166
170
  metadata[$refTypeFieldIndexes]?.forEach((index) => {
167
171
  const field = metadata[index as any as number];
168
- const value = this.ref[field.name];
169
- value?.[$changes].setRoot(root);
172
+ const changeTree: ChangeTree = this.ref[field.name]?.[$changes];
173
+ if (changeTree) {
174
+ if (changeTree.root !== root) {
175
+ changeTree.setRoot(root);
176
+ } else {
177
+ root.add(changeTree); // increment refCount
178
+ }
179
+ }
170
180
  });
171
181
 
172
182
  } else if (this.ref[$childType] && typeof(this.ref[$childType]) !== "string") {
173
183
  // MapSchema / ArraySchema, etc.
174
184
  (this.ref as MapSchema).forEach((value, key) => {
175
- value[$changes].setRoot(root);
185
+ const changeTree: ChangeTree = value[$changes];
186
+ if (changeTree.root !== root) {
187
+ changeTree.setRoot(root);
188
+ } else {
189
+ root.add(changeTree); // increment refCount
190
+ }
176
191
  });
177
192
  }
178
-
179
193
  }
180
194
 
181
195
  setParent(
@@ -203,14 +217,19 @@ export class ChangeTree<T extends Ref=any> {
203
217
  if (metadata) {
204
218
  metadata[$refTypeFieldIndexes]?.forEach((index) => {
205
219
  const field = metadata[index as any as number];
206
- const value = this.ref[field.name];
207
- value?.[$changes].setParent(this.ref, root, index);
220
+ const changeTree: ChangeTree = this.ref[field.name]?.[$changes];
221
+ if (changeTree && changeTree.root !== root) {
222
+ changeTree.setParent(this.ref, root, index);
223
+ }
208
224
  });
209
225
 
210
226
  } else if (this.ref[$childType] && typeof(this.ref[$childType]) !== "string") {
211
227
  // MapSchema / ArraySchema, etc.
212
228
  (this.ref as MapSchema).forEach((value, key) => {
213
- value[$changes].setParent(this.ref, root, this.indexes[key] ?? key);
229
+ const changeTree: ChangeTree = value[$changes];
230
+ if (changeTree.root !== root) {
231
+ changeTree.setParent(this.ref, root, this.indexes[key] ?? key);
232
+ }
214
233
  });
215
234
  }
216
235
 
@@ -478,15 +497,12 @@ export class ChangeTree<T extends Ref=any> {
478
497
  this.allFilteredChanges.indexes = {};
479
498
  this.allFilteredChanges.operations.length = 0;
480
499
  }
481
-
482
- // remove children references
483
- this.forEachChild((changeTree, _) =>
484
- this.root?.remove(changeTree));
485
500
  }
486
501
  }
487
502
 
488
503
  /**
489
504
  * Recursively discard all changes from this, and child structures.
505
+ * (Used in tests only)
490
506
  */
491
507
  discardAll() {
492
508
  const keys = Object.keys(this.indexedOperations);
@@ -69,6 +69,8 @@ export class Root {
69
69
 
70
70
  this.refCount[changeTree.refId] = 0;
71
71
 
72
+ changeTree.forEachChild((child, _) => this.remove(child));
73
+
72
74
  } else {
73
75
  this.refCount[changeTree.refId] = refCount;
74
76
 
@@ -90,8 +92,6 @@ export class Root {
90
92
  }
91
93
  }
92
94
 
93
- changeTree.forEachChild((child, _) => this.remove(child));
94
-
95
95
  return refCount;
96
96
  }
97
97
 
@@ -185,9 +185,7 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
185
185
 
186
186
  const changeTree = this[$changes];
187
187
 
188
- // values.forEach((value, i) => {
189
-
190
- for (let i = 0, l = values.length; i < values.length; i++, length++) {
188
+ for (let i = 0, l = values.length; i < l; i++, length++) {
191
189
  const value = values[i];
192
190
 
193
191
  if (value === undefined || value === null) {
@@ -211,9 +209,6 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
211
209
  value[$changes]?.setParent(this, changeTree.root, length);
212
210
  }
213
211
 
214
- // length++;
215
- // });
216
-
217
212
  return length;
218
213
  }
219
214
 
@@ -310,22 +305,9 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
310
305
  // discard previous operations.
311
306
  const changeTree = this[$changes];
312
307
 
313
- // discard children
314
- changeTree.forEachChild((changeTree, _) => {
315
- changeTree.discard(true);
316
-
317
- //
318
- // TODO: add tests with instance sharing + .clear()
319
- // FIXME: this.root? is required because it is being called at decoding time.
320
- //
321
- // TODO: do not use [$changes] at decoding time.
322
- //
323
- const root = changeTree.root;
324
- if (root !== undefined) {
325
- root.removeChangeFromChangeSet("changes", changeTree);
326
- root.removeChangeFromChangeSet("allChanges", changeTree);
327
- root.removeChangeFromChangeSet("allFilteredChanges", changeTree);
328
- }
308
+ // remove children references
309
+ changeTree.forEachChild((childChangeTree, _) => {
310
+ changeTree.root?.remove(childChangeTree);
329
311
  });
330
312
 
331
313
  changeTree.discard(true);
@@ -116,6 +116,11 @@ export class CollectionSchema<V=any> implements Collection<K, V>{
116
116
  changeTree.discard(true);
117
117
  changeTree.indexes = {};
118
118
 
119
+ // remove children references
120
+ changeTree.forEachChild((childChangeTree, _) => {
121
+ changeTree.root?.remove(childChangeTree);
122
+ });
123
+
119
124
  // clear previous indexes
120
125
  this.$indexes.clear();
121
126
 
@@ -155,6 +155,11 @@ export class MapSchema<V=any, K extends string = string> implements Map<K, V>, C
155
155
  changeTree.discard(true);
156
156
  changeTree.indexes = {};
157
157
 
158
+ // remove children references
159
+ changeTree.forEachChild((childChangeTree, _) => {
160
+ changeTree.root?.remove(childChangeTree);
161
+ });
162
+
158
163
  // clear previous indexes
159
164
  this.$indexes.clear();
160
165