@colyseus/schema 3.0.29 → 3.0.31

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,3 @@
1
- import 'util';
2
-
3
1
  const SWITCH_TO_STRUCTURE = 255; // (decoding collides with DELETE_AND_ADD + fieldIndex = 63)
4
2
  const TYPE_ID = 213;
5
3
  /**
@@ -1870,6 +1868,7 @@ class ArraySchema {
1870
1868
  this.items = [];
1871
1869
  this.tmpItems = [];
1872
1870
  this.deletedIndexes = {};
1871
+ this.isMovingItems = false;
1873
1872
  Object.defineProperty(this, $childType, {
1874
1873
  value: undefined,
1875
1874
  enumerable: false,
@@ -1897,31 +1896,38 @@ class ArraySchema {
1897
1896
  if (setValue[$changes]) {
1898
1897
  assertInstanceType(setValue, obj[$childType], obj, key);
1899
1898
  const previousValue = obj.items[key];
1900
- if (previousValue !== undefined) {
1901
- if (setValue[$changes].isNew) {
1902
- this[$changes].indexedOperation(Number(key), OPERATION.MOVE_AND_ADD);
1903
- }
1904
- else {
1905
- if ((obj[$changes].getChange(Number(key)) & OPERATION.DELETE) === OPERATION.DELETE) {
1906
- this[$changes].indexedOperation(Number(key), OPERATION.DELETE_AND_MOVE);
1899
+ if (!obj.isMovingItems) {
1900
+ obj.$changeAt(Number(key), setValue);
1901
+ }
1902
+ else {
1903
+ if (previousValue !== undefined) {
1904
+ if (setValue[$changes].isNew) {
1905
+ obj[$changes].indexedOperation(Number(key), OPERATION.MOVE_AND_ADD);
1907
1906
  }
1908
1907
  else {
1909
- this[$changes].indexedOperation(Number(key), OPERATION.MOVE);
1908
+ if ((obj[$changes].getChange(Number(key)) & OPERATION.DELETE) === OPERATION.DELETE) {
1909
+ obj[$changes].indexedOperation(Number(key), OPERATION.DELETE_AND_MOVE);
1910
+ }
1911
+ else {
1912
+ obj[$changes].indexedOperation(Number(key), OPERATION.MOVE);
1913
+ }
1910
1914
  }
1911
1915
  }
1916
+ else if (setValue[$changes].isNew) {
1917
+ obj[$changes].indexedOperation(Number(key), OPERATION.ADD);
1918
+ }
1919
+ setValue[$changes].setParent(this, obj[$changes].root, key);
1920
+ }
1921
+ if (previousValue !== undefined) {
1912
1922
  // remove root reference from previous value
1913
1923
  previousValue[$changes].root?.remove(previousValue[$changes]);
1914
1924
  }
1915
- else if (setValue[$changes].isNew) {
1916
- this[$changes].indexedOperation(Number(key), OPERATION.ADD);
1917
- }
1918
- setValue[$changes].setParent(this, obj[$changes].root, key);
1919
1925
  }
1920
1926
  else {
1921
1927
  obj.$changeAt(Number(key), setValue);
1922
1928
  }
1923
- this.items[key] = setValue;
1924
- this.tmpItems[key] = setValue;
1929
+ obj.items[key] = setValue;
1930
+ obj.tmpItems[key] = setValue;
1925
1931
  }
1926
1932
  return true;
1927
1933
  }
@@ -2029,8 +2035,12 @@ class ArraySchema {
2029
2035
  if (this.items[index] === value) {
2030
2036
  return;
2031
2037
  }
2038
+ const operation = (this.items[index] !== undefined)
2039
+ ? typeof (value) === "object"
2040
+ ? OPERATION.DELETE_AND_ADD // schema child
2041
+ : OPERATION.REPLACE // primitive
2042
+ : OPERATION.ADD;
2032
2043
  const changeTree = this[$changes];
2033
- const operation = changeTree.indexes?.[index]?.op ?? OPERATION.ADD;
2034
2044
  changeTree.change(index, operation);
2035
2045
  //
2036
2046
  // set value's parent after the value is set
@@ -2147,11 +2157,13 @@ class ArraySchema {
2147
2157
  * ```
2148
2158
  */
2149
2159
  sort(compareFn = DEFAULT_SORT) {
2160
+ this.isMovingItems = true;
2150
2161
  const changeTree = this[$changes];
2151
2162
  const sortedItems = this.items.sort(compareFn);
2152
2163
  // wouldn't OPERATION.MOVE make more sense here?
2153
2164
  sortedItems.forEach((_, i) => changeTree.change(i, OPERATION.REPLACE));
2154
2165
  this.tmpItems.sort(compareFn);
2166
+ this.isMovingItems = false;
2155
2167
  return this;
2156
2168
  }
2157
2169
  /**
@@ -2464,6 +2476,37 @@ class ArraySchema {
2464
2476
  // @ts-ignore
2465
2477
  return this.items.toSpliced.apply(copy, arguments);
2466
2478
  }
2479
+ shuffle() {
2480
+ return this.move((_) => {
2481
+ let currentIndex = this.items.length;
2482
+ while (currentIndex != 0) {
2483
+ let randomIndex = Math.floor(Math.random() * currentIndex);
2484
+ currentIndex--;
2485
+ [this[currentIndex], this[randomIndex]] = [this[randomIndex], this[currentIndex]];
2486
+ }
2487
+ });
2488
+ }
2489
+ /**
2490
+ * Allows to move items around in the array.
2491
+ *
2492
+ * Example:
2493
+ * state.cards.move((cards) => {
2494
+ * [cards[4], cards[3]] = [cards[3], cards[4]];
2495
+ * [cards[3], cards[2]] = [cards[2], cards[3]];
2496
+ * [cards[2], cards[0]] = [cards[0], cards[2]];
2497
+ * [cards[1], cards[1]] = [cards[1], cards[1]];
2498
+ * [cards[0], cards[0]] = [cards[0], cards[0]];
2499
+ * })
2500
+ *
2501
+ * @param cb
2502
+ * @returns
2503
+ */
2504
+ move(cb) {
2505
+ this.isMovingItems = true;
2506
+ cb(this);
2507
+ this.isMovingItems = false;
2508
+ return this;
2509
+ }
2467
2510
  [($getByIndex)](index, isEncodeAll = false) {
2468
2511
  //
2469
2512
  // TODO: avoid unecessary `this.tmpItems` check during decoding.