@colyseus/schema 3.0.26 → 3.0.27

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.
@@ -1,3 +1,5 @@
1
+ import 'util';
2
+
1
3
  const SWITCH_TO_STRUCTURE = 255; // (decoding collides with DELETE_AND_ADD + fieldIndex = 63)
2
4
  const TYPE_ID = 213;
3
5
  /**
@@ -971,10 +973,18 @@ function setOperationAtIndex(changeSet, index) {
971
973
  }
972
974
  }
973
975
  function deleteOperationAtIndex(changeSet, index) {
974
- const operationsIndex = changeSet.indexes[index];
975
- if (operationsIndex !== undefined) {
976
- changeSet.operations[operationsIndex] = undefined;
976
+ let operationsIndex = changeSet.indexes[index];
977
+ if (operationsIndex === undefined) {
978
+ //
979
+ // if index is not found, we need to find the last operation
980
+ // FIXME: this is not very efficient
981
+ //
982
+ // > See "should allow consecutive splices (same place)" tests
983
+ //
984
+ operationsIndex = Object.values(changeSet.indexes).at(-1);
985
+ index = Object.entries(changeSet.indexes).find(([_, value]) => value === operationsIndex)?.[0];
977
986
  }
987
+ changeSet.operations[operationsIndex] = undefined;
978
988
  delete changeSet.indexes[index];
979
989
  }
980
990
  function enqueueChangeTree(root, changeTree, changeSet, queueRootIndex = changeTree[changeSet].queueRootIndex) {
@@ -1159,15 +1169,22 @@ class ChangeTree {
1159
1169
  }
1160
1170
  _shiftAllChangeIndexes(shiftIndex, startIndex = 0, changeSet) {
1161
1171
  const newIndexes = {};
1172
+ let newKey = 0;
1162
1173
  for (const key in changeSet.indexes) {
1163
- const index = changeSet.indexes[key];
1164
- if (index > startIndex) {
1165
- newIndexes[Number(key) + shiftIndex] = index;
1166
- }
1167
- else {
1168
- newIndexes[key] = index;
1169
- }
1170
- }
1174
+ newIndexes[newKey++] = changeSet.indexes[key];
1175
+ }
1176
+ // const newIndexes = {};
1177
+ // let newKey = 0;
1178
+ // for (const key in changeSet.indexes) {
1179
+ // const index = changeSet.indexes[key];
1180
+ // newIndexes[newKey++] = changeSet.indexes[key];
1181
+ // console.log("...shiftAllChangeIndexes", { index: key, targetIndex: index, startIndex, shiftIndex });
1182
+ // if (index > startIndex) {
1183
+ // newIndexes[Number(key) + shiftIndex] = index;
1184
+ // } else {
1185
+ // newIndexes[Number(key)] = index;
1186
+ // }
1187
+ // }
1171
1188
  changeSet.indexes = newIndexes;
1172
1189
  for (let i = 0; i < changeSet.operations.length; i++) {
1173
1190
  const index = changeSet.operations[i];
@@ -1510,6 +1527,7 @@ const encodeArray = function (encoder, bytes, changeTree, field, operation, it,
1510
1527
  }
1511
1528
  const type = changeTree.getType(field);
1512
1529
  const value = changeTree.getValue(field, isEncodeAll);
1530
+ // console.log({ type, field, value });
1513
1531
  // console.log("encodeArray -> ", {
1514
1532
  // ref: changeTree.ref.constructor.name,
1515
1533
  // field,
@@ -1988,8 +2006,6 @@ class ArraySchema {
1988
2006
  return undefined;
1989
2007
  }
1990
2008
  this[$changes].delete(index, undefined, this.items.length - 1);
1991
- // this.tmpItems[index] = undefined;
1992
- // this.tmpItems.pop();
1993
2009
  this.deletedIndexes[index] = true;
1994
2010
  return this.items.pop();
1995
2011
  }
@@ -2140,31 +2156,50 @@ class ArraySchema {
2140
2156
  * @param deleteCount The number of elements to remove.
2141
2157
  * @param insertItems Elements to insert into the array in place of the deleted elements.
2142
2158
  */
2143
- splice(start, deleteCount = this.items.length - start, ...insertItems) {
2159
+ splice(start, deleteCount, ...insertItems) {
2144
2160
  const changeTree = this[$changes];
2161
+ const itemsLength = this.items.length;
2145
2162
  const tmpItemsLength = this.tmpItems.length;
2146
2163
  const insertCount = insertItems.length;
2147
2164
  // build up-to-date list of indexes, excluding removed values.
2148
2165
  const indexes = [];
2149
2166
  for (let i = 0; i < tmpItemsLength; i++) {
2150
- // if (this.tmpItems[i] !== undefined) {
2151
2167
  if (this.deletedIndexes[i] !== true) {
2152
2168
  indexes.push(i);
2153
2169
  }
2154
2170
  }
2155
- // delete operations at correct index
2156
- for (let i = start; i < start + deleteCount; i++) {
2157
- const index = indexes[i];
2158
- changeTree.delete(index);
2159
- // this.tmpItems[index] = undefined;
2160
- this.deletedIndexes[index] = true;
2171
+ if (itemsLength > start) {
2172
+ // if deleteCount is not provided, delete all items from start to end
2173
+ if (deleteCount === undefined) {
2174
+ deleteCount = itemsLength - start;
2175
+ }
2176
+ //
2177
+ // delete operations at correct index
2178
+ //
2179
+ for (let i = start; i < start + deleteCount; i++) {
2180
+ const index = indexes[i];
2181
+ changeTree.delete(index, OPERATION.DELETE);
2182
+ this.deletedIndexes[index] = true;
2183
+ }
2161
2184
  }
2162
- // force insert operations
2163
- for (let i = 0; i < insertCount; i++) {
2164
- const addIndex = indexes[start] + i;
2165
- changeTree.indexedOperation(addIndex, OPERATION.ADD);
2166
- // set value's parent/root
2167
- insertItems[i][$changes]?.setParent(this, changeTree.root, addIndex);
2185
+ else {
2186
+ // not enough items to delete
2187
+ deleteCount = 0;
2188
+ }
2189
+ // insert operations
2190
+ if (insertCount > 0) {
2191
+ if (insertCount > deleteCount) {
2192
+ console.error("Inserting more elements than deleting during ArraySchema#splice()");
2193
+ throw new Error("ArraySchema#splice(): insertCount must be equal or lower than deleteCount.");
2194
+ }
2195
+ for (let i = 0; i < insertCount; i++) {
2196
+ const addIndex = (indexes[start] ?? itemsLength) + i;
2197
+ changeTree.indexedOperation(addIndex, (this.deletedIndexes[addIndex])
2198
+ ? OPERATION.DELETE_AND_ADD
2199
+ : OPERATION.ADD);
2200
+ // set value's parent/root
2201
+ insertItems[i][$changes]?.setParent(this, changeTree.root, addIndex);
2202
+ }
2168
2203
  }
2169
2204
  //
2170
2205
  // delete exceeding indexes from "allChanges"
@@ -2172,6 +2207,16 @@ class ArraySchema {
2172
2207
  //
2173
2208
  if (deleteCount > insertCount) {
2174
2209
  changeTree.shiftAllChangeIndexes(-(deleteCount - insertCount), indexes[start + insertCount]);
2210
+ // debugChangeSet("AFTER SHIFT indexes", changeTree.allChanges);
2211
+ }
2212
+ //
2213
+ // FIXME: this code block is duplicated on ChangeTree
2214
+ //
2215
+ if (changeTree.filteredChanges !== undefined) {
2216
+ enqueueChangeTree(changeTree.root, changeTree, 'filteredChanges');
2217
+ }
2218
+ else {
2219
+ enqueueChangeTree(changeTree.root, changeTree, 'changes');
2175
2220
  }
2176
2221
  return this.items.splice(start, deleteCount, ...insertItems);
2177
2222
  }
@@ -2427,9 +2472,6 @@ class ArraySchema {
2427
2472
  : this.deletedIndexes[index]
2428
2473
  ? this.items[index]
2429
2474
  : this.tmpItems[index] || this.items[index];
2430
- // return (isEncodeAll)
2431
- // ? this.items[index]
2432
- // : this.tmpItems[index] ?? this.items[index];
2433
2475
  }
2434
2476
  [$deleteByIndex](index) {
2435
2477
  this.items[index] = undefined;
@@ -3801,10 +3843,10 @@ class Encoder {
3801
3843
  view.invisible.delete(changeTree); // remove from invisible list
3802
3844
  }
3803
3845
  }
3804
- const operations = changeTree[changeSetName];
3846
+ const changeSet = changeTree[changeSetName];
3805
3847
  const ref = changeTree.ref;
3806
3848
  // TODO: avoid iterating over change tree if no changes were made
3807
- const numChanges = operations.operations.length;
3849
+ const numChanges = changeSet.operations.length;
3808
3850
  if (numChanges === 0) {
3809
3851
  continue;
3810
3852
  }
@@ -3819,7 +3861,7 @@ class Encoder {
3819
3861
  encode.number(buffer, changeTree.refId, it);
3820
3862
  }
3821
3863
  for (let j = 0; j < numChanges; j++) {
3822
- const fieldIndex = operations.operations[j];
3864
+ const fieldIndex = changeSet.operations[j];
3823
3865
  const operation = (fieldIndex < 0)
3824
3866
  ? Math.abs(fieldIndex) // "pure" operation without fieldIndex (e.g. CLEAR, REVERSE, etc.)
3825
3867
  : (isEncodeAll)