@colyseus/schema 3.0.29 → 3.0.30

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