@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.
@@ -1870,6 +1870,7 @@ class ArraySchema {
1870
1870
  this.items = [];
1871
1871
  this.tmpItems = [];
1872
1872
  this.deletedIndexes = {};
1873
+ this.isMovingItems = false;
1873
1874
  Object.defineProperty(this, $childType, {
1874
1875
  value: undefined,
1875
1876
  enumerable: false,
@@ -1897,31 +1898,38 @@ class ArraySchema {
1897
1898
  if (setValue[$changes]) {
1898
1899
  assertInstanceType(setValue, obj[$childType], obj, key);
1899
1900
  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);
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), OPERATION.MOVE_AND_ADD);
1907
1908
  }
1908
1909
  else {
1909
- this[$changes].indexedOperation(Number(key), OPERATION.MOVE);
1910
+ if ((obj[$changes].getChange(Number(key)) & OPERATION.DELETE) === OPERATION.DELETE) {
1911
+ obj[$changes].indexedOperation(Number(key), OPERATION.DELETE_AND_MOVE);
1912
+ }
1913
+ else {
1914
+ obj[$changes].indexedOperation(Number(key), OPERATION.MOVE);
1915
+ }
1910
1916
  }
1911
1917
  }
1918
+ else if (setValue[$changes].isNew) {
1919
+ obj[$changes].indexedOperation(Number(key), OPERATION.ADD);
1920
+ }
1921
+ setValue[$changes].setParent(this, obj[$changes].root, key);
1922
+ }
1923
+ if (previousValue !== undefined) {
1912
1924
  // remove root reference from previous value
1913
1925
  previousValue[$changes].root?.remove(previousValue[$changes]);
1914
1926
  }
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
1927
  }
1920
1928
  else {
1921
1929
  obj.$changeAt(Number(key), setValue);
1922
1930
  }
1923
- this.items[key] = setValue;
1924
- this.tmpItems[key] = setValue;
1931
+ obj.items[key] = setValue;
1932
+ obj.tmpItems[key] = setValue;
1925
1933
  }
1926
1934
  return true;
1927
1935
  }
@@ -2029,8 +2037,12 @@ class ArraySchema {
2029
2037
  if (this.items[index] === value) {
2030
2038
  return;
2031
2039
  }
2040
+ const operation = (this.items[index] !== undefined)
2041
+ ? typeof (value) === "object"
2042
+ ? OPERATION.DELETE_AND_ADD // schema child
2043
+ : OPERATION.REPLACE // primitive
2044
+ : OPERATION.ADD;
2032
2045
  const changeTree = this[$changes];
2033
- const operation = changeTree.indexes?.[index]?.op ?? OPERATION.ADD;
2034
2046
  changeTree.change(index, operation);
2035
2047
  //
2036
2048
  // set value's parent after the value is set
@@ -2147,11 +2159,13 @@ class ArraySchema {
2147
2159
  * ```
2148
2160
  */
2149
2161
  sort(compareFn = DEFAULT_SORT) {
2162
+ this.isMovingItems = true;
2150
2163
  const changeTree = this[$changes];
2151
2164
  const sortedItems = this.items.sort(compareFn);
2152
2165
  // wouldn't OPERATION.MOVE make more sense here?
2153
2166
  sortedItems.forEach((_, i) => changeTree.change(i, OPERATION.REPLACE));
2154
2167
  this.tmpItems.sort(compareFn);
2168
+ this.isMovingItems = false;
2155
2169
  return this;
2156
2170
  }
2157
2171
  /**
@@ -2464,6 +2478,37 @@ class ArraySchema {
2464
2478
  // @ts-ignore
2465
2479
  return this.items.toSpliced.apply(copy, arguments);
2466
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
+ }
2467
2512
  [($getByIndex)](index, isEncodeAll = false) {
2468
2513
  //
2469
2514
  // TODO: avoid unecessary `this.tmpItems` check during decoding.