@colyseus/schema 3.0.24 → 3.0.26

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.
@@ -958,6 +958,9 @@ const Metadata = {
958
958
  }
959
959
  };
960
960
 
961
+ function createChangeSet() {
962
+ return { indexes: {}, operations: [] };
963
+ }
961
964
  function setOperationAtIndex(changeSet, index) {
962
965
  const operationsIndex = changeSet.indexes[index];
963
966
  if (operationsIndex === undefined) {
@@ -975,7 +978,11 @@ function deleteOperationAtIndex(changeSet, index) {
975
978
  delete changeSet.indexes[index];
976
979
  }
977
980
  function enqueueChangeTree(root, changeTree, changeSet, queueRootIndex = changeTree[changeSet].queueRootIndex) {
978
- if (root && root[changeSet][queueRootIndex] !== changeTree) {
981
+ if (!root) {
982
+ // skip
983
+ return;
984
+ }
985
+ else if (root[changeSet][queueRootIndex] !== changeTree) {
979
986
  changeTree[changeSet].queueRootIndex = root[changeSet].push(changeTree) - 1;
980
987
  }
981
988
  }
@@ -1130,7 +1137,7 @@ class ChangeTree {
1130
1137
  const newIndexes = {};
1131
1138
  for (const index in this.indexedOperations) {
1132
1139
  newIndexedOperations[Number(index) + shiftIndex] = this.indexedOperations[index];
1133
- newIndexes[Number(index) + shiftIndex] = changeSet[index];
1140
+ newIndexes[Number(index) + shiftIndex] = changeSet.indexes[index];
1134
1141
  }
1135
1142
  this.indexedOperations = newIndexedOperations;
1136
1143
  changeSet.indexes = newIndexes;
@@ -1224,6 +1231,7 @@ class ChangeTree {
1224
1231
  : this.changes;
1225
1232
  this.indexedOperations[index] = operation ?? OPERATION.DELETE;
1226
1233
  setOperationAtIndex(changeSet, index);
1234
+ deleteOperationAtIndex(this.allChanges, allChangesIndex);
1227
1235
  const previousValue = this.getValue(index);
1228
1236
  // remove `root` reference
1229
1237
  if (previousValue && previousValue[$changes]) {
@@ -1239,7 +1247,6 @@ class ChangeTree {
1239
1247
  //
1240
1248
  this.root?.remove(previousValue[$changes]);
1241
1249
  }
1242
- deleteOperationAtIndex(this.allChanges, allChangesIndex);
1243
1250
  //
1244
1251
  // FIXME: this is looking a ugly and repeated
1245
1252
  //
@@ -1252,11 +1259,12 @@ class ChangeTree {
1252
1259
  }
1253
1260
  return previousValue;
1254
1261
  }
1255
- endEncode() {
1262
+ endEncode(changeSetName) {
1256
1263
  this.indexedOperations = {};
1257
- // // clear changes
1258
- // this.changes.indexes = {};
1259
- // this.changes.operations.length = 0;
1264
+ // clear changeset
1265
+ this[changeSetName].indexes = {};
1266
+ this[changeSetName].operations.length = 0;
1267
+ this[changeSetName].queueRootIndex = undefined;
1260
1268
  // ArraySchema and MapSchema have a custom "encode end" method
1261
1269
  this.ref[$onEncodeEnd]?.();
1262
1270
  // Not a new instance anymore
@@ -1363,24 +1371,19 @@ class ChangeTree {
1363
1371
  || this.root.types.parentFiltered[key]
1364
1372
  || parentConstructor?.[Symbol.metadata]?.[$viewFieldIndexes]?.includes(parentIndex);
1365
1373
  //
1366
- // TODO: refactor this!
1367
- //
1368
- // swapping `changes` and `filteredChanges` is required here
1369
- // because "isFiltered" may not be imedialely available on `change()`
1370
- // (this happens when instance is detached from root or parent)
1374
+ // "isFiltered" may not be imedialely available during `change()` due to the instance not being attached to the root yet.
1375
+ // when it's available, we need to enqueue the "changes" changeset into the "filteredChanges" changeset.
1371
1376
  //
1372
1377
  if (this.isFiltered) {
1373
- this.filteredChanges = { indexes: {}, operations: [] };
1374
- this.allFilteredChanges = { indexes: {}, operations: [] };
1378
+ if (!this.filteredChanges) {
1379
+ this.filteredChanges = createChangeSet();
1380
+ this.allFilteredChanges = createChangeSet();
1381
+ }
1375
1382
  if (this.changes.operations.length > 0) {
1376
- // swap changes reference
1377
- const changes = this.changes;
1378
- this.changes = this.filteredChanges;
1379
- this.filteredChanges = changes;
1380
- // swap "all changes" reference
1381
- const allFilteredChanges = this.allFilteredChanges;
1382
- this.allFilteredChanges = this.allChanges;
1383
- this.allChanges = allFilteredChanges;
1383
+ this.changes.operations.forEach((index) => setOperationAtIndex(this.filteredChanges, index));
1384
+ this.allChanges.operations.forEach((index) => setOperationAtIndex(this.allFilteredChanges, index));
1385
+ this.changes = createChangeSet();
1386
+ this.allChanges = createChangeSet();
1384
1387
  }
1385
1388
  }
1386
1389
  }
@@ -2096,10 +2099,11 @@ class ArraySchema {
2096
2099
  return undefined;
2097
2100
  }
2098
2101
  // const index = Number(Object.keys(changeTree.indexes)[0]);
2099
- const index = this.tmpItems.findIndex((item, i) => item === this.items[0]);
2100
2102
  const changeTree = this[$changes];
2101
- changeTree.delete(index);
2102
- changeTree.shiftAllChangeIndexes(-1, index);
2103
+ const index = this.tmpItems.findIndex(item => item === this.items[0]);
2104
+ const allChangesIndex = this.items.findIndex(item => item === this.items[0]);
2105
+ changeTree.delete(index, OPERATION.DELETE, allChangesIndex);
2106
+ changeTree.shiftAllChangeIndexes(-1, allChangesIndex);
2103
2107
  // this.deletedIndexes[index] = true;
2104
2108
  return this.items.shift();
2105
2109
  }
@@ -3660,19 +3664,6 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
3660
3664
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
3661
3665
  };
3662
3666
 
3663
- function spliceOne(arr, index) {
3664
- // manually splice an array
3665
- if (index === -1 || index >= arr.length) {
3666
- return false;
3667
- }
3668
- const len = arr.length - 1;
3669
- for (let i = index; i < len; i++) {
3670
- arr[i] = arr[i + 1];
3671
- }
3672
- arr.length = len;
3673
- return true;
3674
- }
3675
-
3676
3667
  class Root {
3677
3668
  constructor(types) {
3678
3669
  this.types = types;
@@ -3753,11 +3744,16 @@ class Root {
3753
3744
  }
3754
3745
  removeChangeFromChangeSet(changeSetName, changeTree) {
3755
3746
  const changeSet = this[changeSetName];
3756
- if (spliceOne(changeSet, changeSet.indexOf(changeTree))) {
3747
+ const changeSetIndex = changeSet.indexOf(changeTree);
3748
+ if (changeSetIndex !== -1) {
3757
3749
  changeTree[changeSetName].queueRootIndex = -1;
3758
- // changeSet[index] = undefined;
3750
+ changeSet[changeSetIndex] = undefined;
3759
3751
  return true;
3760
3752
  }
3753
+ // if (spliceOne(changeSet, changeSet.indexOf(changeTree))) {
3754
+ // changeTree[changeSetName].queueRootIndex = -1;
3755
+ // return true;
3756
+ // }
3761
3757
  }
3762
3758
  clear() {
3763
3759
  this.changes.length = 0;
@@ -3790,10 +3786,12 @@ class Encoder {
3790
3786
  ) {
3791
3787
  const hasView = (view !== undefined);
3792
3788
  const rootChangeTree = this.state[$changes];
3793
- const shouldDiscardChanges = !isEncodeAll && !hasView;
3794
3789
  const changeTrees = this.root[changeSetName];
3795
3790
  for (let i = 0, numChangeTrees = changeTrees.length; i < numChangeTrees; i++) {
3796
3791
  const changeTree = changeTrees[i];
3792
+ if (!changeTree) {
3793
+ continue;
3794
+ }
3797
3795
  if (hasView) {
3798
3796
  if (!view.visible.has(changeTree)) {
3799
3797
  view.invisible.add(changeTree);
@@ -3841,10 +3839,6 @@ class Encoder {
3841
3839
  }
3842
3840
  encoder(this, buffer, changeTree, fieldIndex, operation, it, isEncodeAll, hasView, metadata);
3843
3841
  }
3844
- // if (shouldDiscardChanges) {
3845
- // changeTree.discard();
3846
- // changeTree.isNew = false; // Not a new instance anymore
3847
- // }
3848
3842
  }
3849
3843
  if (it.offset > buffer.byteLength) {
3850
3844
  // we can assume that n + 1 poolSize will suffice given that we are likely done with encoding at this point
@@ -3868,19 +3862,6 @@ class Encoder {
3868
3862
  return this.encode({ offset: initialOffset }, view, buffer, changeSetName, isEncodeAll);
3869
3863
  }
3870
3864
  else {
3871
- //
3872
- // only clear changes after making sure buffer resize is not required.
3873
- //
3874
- if (shouldDiscardChanges) {
3875
- //
3876
- // TODO: avoid iterating over change trees twice.
3877
- //
3878
- for (let i = 0, numChangeTrees = changeTrees.length; i < numChangeTrees; i++) {
3879
- const changeTree = changeTrees[i];
3880
- changeTree.discard();
3881
- changeTree.isNew = false; // Not a new instance anymore
3882
- }
3883
- }
3884
3865
  return buffer.subarray(0, it.offset);
3885
3866
  }
3886
3867
  }
@@ -3965,7 +3946,7 @@ class Encoder {
3965
3946
  let length = this.root.changes.length;
3966
3947
  if (length > 0) {
3967
3948
  while (length--) {
3968
- this.root.changes[length]?.endEncode();
3949
+ this.root.changes[length]?.endEncode('changes');
3969
3950
  }
3970
3951
  this.root.changes.length = 0;
3971
3952
  }
@@ -3973,7 +3954,7 @@ class Encoder {
3973
3954
  length = this.root.filteredChanges.length;
3974
3955
  if (length > 0) {
3975
3956
  while (length--) {
3976
- this.root.filteredChanges[length]?.endEncode();
3957
+ this.root.filteredChanges[length]?.endEncode('filteredChanges');
3977
3958
  }
3978
3959
  this.root.filteredChanges.length = 0;
3979
3960
  }
@@ -3996,6 +3977,19 @@ class Encoder {
3996
3977
  }
3997
3978
  }
3998
3979
 
3980
+ function spliceOne(arr, index) {
3981
+ // manually splice an array
3982
+ if (index === -1 || index >= arr.length) {
3983
+ return false;
3984
+ }
3985
+ const len = arr.length - 1;
3986
+ for (let i = index; i < len; i++) {
3987
+ arr[i] = arr[i + 1];
3988
+ }
3989
+ arr.length = len;
3990
+ return true;
3991
+ }
3992
+
3999
3993
  class DecodingWarning extends Error {
4000
3994
  constructor(message) {
4001
3995
  super(message);