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