@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.
@@ -10,7 +10,7 @@ import { Root } from "./Root";
10
10
 
11
11
  import type { StateView } from "./StateView";
12
12
  import type { Metadata } from "../Metadata";
13
- import type { ChangeTree } from "./ChangeTree";
13
+ import type { ChangeSetName, ChangeTree } from "./ChangeTree";
14
14
 
15
15
  export class Encoder<T extends Schema = any> {
16
16
  static BUFFER_SIZE = (typeof(Buffer) !== "undefined") && Buffer.poolSize || 8 * 1024; // 8KB
@@ -48,7 +48,7 @@ export class Encoder<T extends Schema = any> {
48
48
  it: Iterator = { offset: 0 },
49
49
  view?: StateView,
50
50
  buffer = this.sharedBuffer,
51
- changeSetName: "changes" | "allChanges" | "filteredChanges" | "allFilteredChanges" = "changes",
51
+ changeSetName: ChangeSetName = "changes",
52
52
  isEncodeAll = changeSetName === "allChanges",
53
53
  initialOffset = it.offset // cache current offset in case we need to resize the buffer
54
54
  ): Buffer {
@@ -70,11 +70,11 @@ export class Encoder<T extends Schema = any> {
70
70
  }
71
71
  }
72
72
 
73
- const operations = changeTree[changeSetName];
73
+ const changeSet = changeTree[changeSetName];
74
74
  const ref = changeTree.ref;
75
75
 
76
76
  // TODO: avoid iterating over change tree if no changes were made
77
- const numChanges = operations.operations.length;
77
+ const numChanges = changeSet.operations.length;
78
78
  if (numChanges === 0) { continue; }
79
79
 
80
80
  const ctor = ref.constructor;
@@ -90,7 +90,7 @@ export class Encoder<T extends Schema = any> {
90
90
  }
91
91
 
92
92
  for (let j = 0; j < numChanges; j++) {
93
- const fieldIndex = operations.operations[j];
93
+ const fieldIndex = changeSet.operations[j];
94
94
 
95
95
  const operation = (fieldIndex < 0)
96
96
  ? Math.abs(fieldIndex) // "pure" operation without fieldIndex (e.g. CLEAR, REVERSE, etc.)
package/src/index.ts CHANGED
@@ -50,7 +50,7 @@ export { getRawChangesCallback } from "./decoder/strategy/RawChanges";
50
50
 
51
51
  export { Encoder } from "./encoder/Encoder";
52
52
  export { encodeSchemaOperation, encodeArray, encodeKeyValueOperation } from "./encoder/EncodeOperation";
53
- export { ChangeTree, Ref } from "./encoder/ChangeTree";
53
+ export { ChangeTree, Ref, type ChangeSetName, type ChangeSet} from "./encoder/ChangeTree";
54
54
  export { StateView } from "./encoder/StateView";
55
55
 
56
56
  export { Decoder } from "./decoder/Decoder";
@@ -1,6 +1,6 @@
1
1
  import { $changes, $childType, $decoder, $deleteByIndex, $onEncodeEnd, $encoder, $filter, $getByIndex, $onDecodeEnd } from "../symbols";
2
2
  import type { Schema } from "../../Schema";
3
- import { ChangeTree, setOperationAtIndex } from "../../encoder/ChangeTree";
3
+ import { ChangeTree, debugChangeSet, deleteOperationAtIndex, enqueueChangeTree, setOperationAtIndex } from "../../encoder/ChangeTree";
4
4
  import { OPERATION } from "../../encoding/spec";
5
5
  import { registerType } from "../registry";
6
6
  import { Collection } from "../HelperTypes";
@@ -229,9 +229,6 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
229
229
 
230
230
  this[$changes].delete(index, undefined, this.items.length - 1);
231
231
 
232
- // this.tmpItems[index] = undefined;
233
- // this.tmpItems.pop();
234
-
235
232
  this.deletedIndexes[index] = true;
236
233
 
237
234
  return this.items.pop();
@@ -412,38 +409,63 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
412
409
  */
413
410
  splice(
414
411
  start: number,
415
- deleteCount: number = this.items.length - start,
412
+ deleteCount?: number,
416
413
  ...insertItems: V[]
417
414
  ): V[] {
418
415
  const changeTree = this[$changes];
419
416
 
417
+ const itemsLength = this.items.length;
420
418
  const tmpItemsLength = this.tmpItems.length;
421
419
  const insertCount = insertItems.length;
422
420
 
423
421
  // build up-to-date list of indexes, excluding removed values.
424
422
  const indexes: number[] = [];
425
423
  for (let i = 0; i < tmpItemsLength; i++) {
426
- // if (this.tmpItems[i] !== undefined) {
427
424
  if (this.deletedIndexes[i] !== true) {
428
425
  indexes.push(i);
429
426
  }
430
427
  }
431
428
 
432
- // delete operations at correct index
433
- for (let i = start; i < start + deleteCount; i++) {
434
- const index = indexes[i];
435
- changeTree.delete(index);
436
- // this.tmpItems[index] = undefined;
437
- this.deletedIndexes[index] = true;
429
+ if (itemsLength > start) {
430
+ // if deleteCount is not provided, delete all items from start to end
431
+ if (deleteCount === undefined) {
432
+ deleteCount = itemsLength - start;
433
+ }
434
+
435
+ //
436
+ // delete operations at correct index
437
+ //
438
+ for (let i = start; i < start + deleteCount; i++) {
439
+ const index = indexes[i];
440
+ changeTree.delete(index, OPERATION.DELETE);
441
+ this.deletedIndexes[index] = true;
442
+ }
443
+
444
+ } else {
445
+ // not enough items to delete
446
+ deleteCount = 0;
438
447
  }
439
448
 
440
- // force insert operations
441
- for (let i = 0; i < insertCount; i++) {
442
- const addIndex = indexes[start] + i;
443
- changeTree.indexedOperation(addIndex, OPERATION.ADD);
449
+ // insert operations
450
+ if (insertCount > 0) {
451
+ if (insertCount > deleteCount) {
452
+ console.error("Inserting more elements than deleting during ArraySchema#splice()");
453
+ throw new Error("ArraySchema#splice(): insertCount must be equal or lower than deleteCount.");
454
+ }
455
+
456
+ for (let i = 0; i < insertCount; i++) {
457
+ const addIndex = (indexes[start] ?? itemsLength) + i;
458
+
459
+ changeTree.indexedOperation(
460
+ addIndex,
461
+ (this.deletedIndexes[addIndex])
462
+ ? OPERATION.DELETE_AND_ADD
463
+ : OPERATION.ADD
464
+ );
444
465
 
445
- // set value's parent/root
446
- insertItems[i][$changes]?.setParent(this, changeTree.root, addIndex);
466
+ // set value's parent/root
467
+ insertItems[i][$changes]?.setParent(this, changeTree.root, addIndex);
468
+ }
447
469
  }
448
470
 
449
471
  //
@@ -452,6 +474,17 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
452
474
  //
453
475
  if (deleteCount > insertCount) {
454
476
  changeTree.shiftAllChangeIndexes(-(deleteCount - insertCount), indexes[start + insertCount]);
477
+ // debugChangeSet("AFTER SHIFT indexes", changeTree.allChanges);
478
+ }
479
+
480
+ //
481
+ // FIXME: this code block is duplicated on ChangeTree
482
+ //
483
+ if (changeTree.filteredChanges !== undefined) {
484
+ enqueueChangeTree(changeTree.root, changeTree, 'filteredChanges');
485
+
486
+ } else {
487
+ enqueueChangeTree(changeTree.root, changeTree, 'changes');
455
488
  }
456
489
 
457
490
  return this.items.splice(start, deleteCount, ...insertItems);
@@ -767,10 +800,6 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
767
800
  : this.deletedIndexes[index]
768
801
  ? this.items[index]
769
802
  : this.tmpItems[index] || this.items[index];
770
-
771
- // return (isEncodeAll)
772
- // ? this.items[index]
773
- // : this.tmpItems[index] ?? this.items[index];
774
803
  }
775
804
 
776
805
  protected [$deleteByIndex](index: number) {