@colyseus/schema 3.0.24 → 3.0.25

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.
@@ -960,6 +960,9 @@ const Metadata = {
960
960
  }
961
961
  };
962
962
 
963
+ function createChangeSet() {
964
+ return { indexes: {}, operations: [] };
965
+ }
963
966
  function setOperationAtIndex(changeSet, index) {
964
967
  const operationsIndex = changeSet.indexes[index];
965
968
  if (operationsIndex === undefined) {
@@ -977,7 +980,11 @@ function deleteOperationAtIndex(changeSet, index) {
977
980
  delete changeSet.indexes[index];
978
981
  }
979
982
  function enqueueChangeTree(root, changeTree, changeSet, queueRootIndex = changeTree[changeSet].queueRootIndex) {
980
- if (root && root[changeSet][queueRootIndex] !== changeTree) {
983
+ if (!root) {
984
+ // skip
985
+ return;
986
+ }
987
+ else if (root[changeSet][queueRootIndex] !== changeTree) {
981
988
  changeTree[changeSet].queueRootIndex = root[changeSet].push(changeTree) - 1;
982
989
  }
983
990
  }
@@ -1254,11 +1261,12 @@ class ChangeTree {
1254
1261
  }
1255
1262
  return previousValue;
1256
1263
  }
1257
- endEncode() {
1264
+ endEncode(changeSetName) {
1258
1265
  this.indexedOperations = {};
1259
- // // clear changes
1260
- // this.changes.indexes = {};
1261
- // this.changes.operations.length = 0;
1266
+ // clear changeset
1267
+ this[changeSetName].indexes = {};
1268
+ this[changeSetName].operations.length = 0;
1269
+ this[changeSetName].queueRootIndex = undefined;
1262
1270
  // ArraySchema and MapSchema have a custom "encode end" method
1263
1271
  this.ref[$onEncodeEnd]?.();
1264
1272
  // Not a new instance anymore
@@ -1365,24 +1373,19 @@ class ChangeTree {
1365
1373
  || this.root.types.parentFiltered[key]
1366
1374
  || parentConstructor?.[Symbol.metadata]?.[$viewFieldIndexes]?.includes(parentIndex);
1367
1375
  //
1368
- // TODO: refactor this!
1369
- //
1370
- // swapping `changes` and `filteredChanges` is required here
1371
- // because "isFiltered" may not be imedialely available on `change()`
1372
- // (this happens when instance is detached from root or parent)
1376
+ // "isFiltered" may not be imedialely available during `change()` due to the instance not being attached to the root yet.
1377
+ // when it's available, we need to enqueue the "changes" changeset into the "filteredChanges" changeset.
1373
1378
  //
1374
1379
  if (this.isFiltered) {
1375
- this.filteredChanges = { indexes: {}, operations: [] };
1376
- this.allFilteredChanges = { indexes: {}, operations: [] };
1380
+ if (!this.filteredChanges) {
1381
+ this.filteredChanges = createChangeSet();
1382
+ this.allFilteredChanges = createChangeSet();
1383
+ }
1377
1384
  if (this.changes.operations.length > 0) {
1378
- // swap changes reference
1379
- const changes = this.changes;
1380
- this.changes = this.filteredChanges;
1381
- this.filteredChanges = changes;
1382
- // swap "all changes" reference
1383
- const allFilteredChanges = this.allFilteredChanges;
1384
- this.allFilteredChanges = this.allChanges;
1385
- this.allChanges = allFilteredChanges;
1385
+ this.changes.operations.forEach((index) => setOperationAtIndex(this.filteredChanges, index));
1386
+ this.allChanges.operations.forEach((index) => setOperationAtIndex(this.allFilteredChanges, index));
1387
+ this.changes = createChangeSet();
1388
+ this.allChanges = createChangeSet();
1386
1389
  }
1387
1390
  }
1388
1391
  }
@@ -3662,19 +3665,6 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
3662
3665
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
3663
3666
  };
3664
3667
 
3665
- function spliceOne(arr, index) {
3666
- // manually splice an array
3667
- if (index === -1 || index >= arr.length) {
3668
- return false;
3669
- }
3670
- const len = arr.length - 1;
3671
- for (let i = index; i < len; i++) {
3672
- arr[i] = arr[i + 1];
3673
- }
3674
- arr.length = len;
3675
- return true;
3676
- }
3677
-
3678
3668
  class Root {
3679
3669
  constructor(types) {
3680
3670
  this.types = types;
@@ -3755,11 +3745,16 @@ class Root {
3755
3745
  }
3756
3746
  removeChangeFromChangeSet(changeSetName, changeTree) {
3757
3747
  const changeSet = this[changeSetName];
3758
- if (spliceOne(changeSet, changeSet.indexOf(changeTree))) {
3748
+ const changeSetIndex = changeSet.indexOf(changeTree);
3749
+ if (changeSetIndex !== -1) {
3759
3750
  changeTree[changeSetName].queueRootIndex = -1;
3760
- // changeSet[index] = undefined;
3751
+ changeSet[changeSetIndex] = undefined;
3761
3752
  return true;
3762
3753
  }
3754
+ // if (spliceOne(changeSet, changeSet.indexOf(changeTree))) {
3755
+ // changeTree[changeSetName].queueRootIndex = -1;
3756
+ // return true;
3757
+ // }
3763
3758
  }
3764
3759
  clear() {
3765
3760
  this.changes.length = 0;
@@ -3792,10 +3787,12 @@ class Encoder {
3792
3787
  ) {
3793
3788
  const hasView = (view !== undefined);
3794
3789
  const rootChangeTree = this.state[$changes];
3795
- const shouldDiscardChanges = !isEncodeAll && !hasView;
3796
3790
  const changeTrees = this.root[changeSetName];
3797
3791
  for (let i = 0, numChangeTrees = changeTrees.length; i < numChangeTrees; i++) {
3798
3792
  const changeTree = changeTrees[i];
3793
+ if (!changeTree) {
3794
+ continue;
3795
+ }
3799
3796
  if (hasView) {
3800
3797
  if (!view.visible.has(changeTree)) {
3801
3798
  view.invisible.add(changeTree);
@@ -3843,10 +3840,6 @@ class Encoder {
3843
3840
  }
3844
3841
  encoder(this, buffer, changeTree, fieldIndex, operation, it, isEncodeAll, hasView, metadata);
3845
3842
  }
3846
- // if (shouldDiscardChanges) {
3847
- // changeTree.discard();
3848
- // changeTree.isNew = false; // Not a new instance anymore
3849
- // }
3850
3843
  }
3851
3844
  if (it.offset > buffer.byteLength) {
3852
3845
  // we can assume that n + 1 poolSize will suffice given that we are likely done with encoding at this point
@@ -3870,19 +3863,6 @@ class Encoder {
3870
3863
  return this.encode({ offset: initialOffset }, view, buffer, changeSetName, isEncodeAll);
3871
3864
  }
3872
3865
  else {
3873
- //
3874
- // only clear changes after making sure buffer resize is not required.
3875
- //
3876
- if (shouldDiscardChanges) {
3877
- //
3878
- // TODO: avoid iterating over change trees twice.
3879
- //
3880
- for (let i = 0, numChangeTrees = changeTrees.length; i < numChangeTrees; i++) {
3881
- const changeTree = changeTrees[i];
3882
- changeTree.discard();
3883
- changeTree.isNew = false; // Not a new instance anymore
3884
- }
3885
- }
3886
3866
  return buffer.subarray(0, it.offset);
3887
3867
  }
3888
3868
  }
@@ -3967,7 +3947,7 @@ class Encoder {
3967
3947
  let length = this.root.changes.length;
3968
3948
  if (length > 0) {
3969
3949
  while (length--) {
3970
- this.root.changes[length]?.endEncode();
3950
+ this.root.changes[length]?.endEncode('changes');
3971
3951
  }
3972
3952
  this.root.changes.length = 0;
3973
3953
  }
@@ -3975,7 +3955,7 @@ class Encoder {
3975
3955
  length = this.root.filteredChanges.length;
3976
3956
  if (length > 0) {
3977
3957
  while (length--) {
3978
- this.root.filteredChanges[length]?.endEncode();
3958
+ this.root.filteredChanges[length]?.endEncode('filteredChanges');
3979
3959
  }
3980
3960
  this.root.filteredChanges.length = 0;
3981
3961
  }
@@ -3998,6 +3978,19 @@ class Encoder {
3998
3978
  }
3999
3979
  }
4000
3980
 
3981
+ function spliceOne(arr, index) {
3982
+ // manually splice an array
3983
+ if (index === -1 || index >= arr.length) {
3984
+ return false;
3985
+ }
3986
+ const len = arr.length - 1;
3987
+ for (let i = index; i < len; i++) {
3988
+ arr[i] = arr[i + 1];
3989
+ }
3990
+ arr.length = len;
3991
+ return true;
3992
+ }
3993
+
4001
3994
  class DecodingWarning extends Error {
4002
3995
  constructor(message) {
4003
3996
  super(message);