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