@colyseus/schema 3.0.28 → 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.
- package/build/cjs/index.js +73 -21
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +73 -21
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +73 -21
- package/lib/Metadata.d.ts +1 -0
- package/lib/Metadata.js +3 -0
- package/lib/Metadata.js.map +1 -1
- package/lib/decoder/DecodeOperation.js +8 -4
- package/lib/decoder/DecodeOperation.js.map +1 -1
- package/lib/encoder/ChangeTree.js +1 -1
- package/lib/encoder/ChangeTree.js.map +1 -1
- package/lib/encoder/EncodeOperation.js +1 -1
- package/lib/encoder/EncodeOperation.js.map +1 -1
- package/lib/types/custom/ArraySchema.d.ts +18 -0
- package/lib/types/custom/ArraySchema.js +60 -15
- package/lib/types/custom/ArraySchema.js.map +1 -1
- package/package.json +1 -1
- package/src/Metadata.ts +4 -0
- package/src/decoder/DecodeOperation.ts +9 -4
- package/src/encoder/ChangeTree.ts +1 -1
- package/src/encoder/EncodeOperation.ts +1 -1
- package/src/types/custom/ArraySchema.ts +68 -17
package/build/esm/index.mjs
CHANGED
|
@@ -957,6 +957,9 @@ const Metadata = {
|
|
|
957
957
|
fields[metadata[i].name] = metadata[i].type;
|
|
958
958
|
}
|
|
959
959
|
return fields;
|
|
960
|
+
},
|
|
961
|
+
hasViewTagAtIndex(metadata, index) {
|
|
962
|
+
return metadata?.[$viewFieldIndexes]?.includes(index);
|
|
960
963
|
}
|
|
961
964
|
};
|
|
962
965
|
|
|
@@ -1377,7 +1380,7 @@ class ChangeTree {
|
|
|
1377
1380
|
key += `-${this.root.types.schemas.get(parentConstructor)}`;
|
|
1378
1381
|
}
|
|
1379
1382
|
key += `-${parentIndex}`;
|
|
1380
|
-
const fieldHasViewTag = parentConstructor?.[Symbol.metadata]
|
|
1383
|
+
const fieldHasViewTag = Metadata.hasViewTagAtIndex(parentConstructor?.[Symbol.metadata], parentIndex);
|
|
1381
1384
|
this.isFiltered = parent[$changes].isFiltered // in case parent is already filtered
|
|
1382
1385
|
|| this.root.types.parentFiltered[key]
|
|
1383
1386
|
|| fieldHasViewTag;
|
|
@@ -1520,7 +1523,7 @@ const encodeArray = function (encoder, bytes, changeTree, field, operation, it,
|
|
|
1520
1523
|
// encode index
|
|
1521
1524
|
encode.number(bytes, refOrIndex, it);
|
|
1522
1525
|
// Do not encode value for DELETE operations
|
|
1523
|
-
if (operation === OPERATION.DELETE) {
|
|
1526
|
+
if (operation === OPERATION.DELETE || operation === OPERATION.DELETE_BY_REFID) {
|
|
1524
1527
|
return;
|
|
1525
1528
|
}
|
|
1526
1529
|
const type = changeTree.getType(field);
|
|
@@ -1741,10 +1744,14 @@ const decodeArray = function (decoder, bytes, it, ref, allChanges) {
|
|
|
1741
1744
|
else if (operation === OPERATION.ADD_BY_REFID) {
|
|
1742
1745
|
const refId = decode.number(bytes, it);
|
|
1743
1746
|
const itemByRefId = decoder.root.refs.get(refId);
|
|
1744
|
-
//
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1747
|
+
// if item already exists, use existing index
|
|
1748
|
+
if (itemByRefId) {
|
|
1749
|
+
index = ref.findIndex((value) => value === itemByRefId);
|
|
1750
|
+
}
|
|
1751
|
+
// fallback to use last index
|
|
1752
|
+
if (index === -1 || index === undefined) {
|
|
1753
|
+
index = ref.length;
|
|
1754
|
+
}
|
|
1748
1755
|
}
|
|
1749
1756
|
else {
|
|
1750
1757
|
index = decode.number(bytes, it);
|
|
@@ -1863,6 +1870,7 @@ class ArraySchema {
|
|
|
1863
1870
|
this.items = [];
|
|
1864
1871
|
this.tmpItems = [];
|
|
1865
1872
|
this.deletedIndexes = {};
|
|
1873
|
+
this.isMovingItems = false;
|
|
1866
1874
|
Object.defineProperty(this, $childType, {
|
|
1867
1875
|
value: undefined,
|
|
1868
1876
|
enumerable: false,
|
|
@@ -1890,31 +1898,38 @@ class ArraySchema {
|
|
|
1890
1898
|
if (setValue[$changes]) {
|
|
1891
1899
|
assertInstanceType(setValue, obj[$childType], obj, key);
|
|
1892
1900
|
const previousValue = obj.items[key];
|
|
1893
|
-
if (
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
if (
|
|
1899
|
-
|
|
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);
|
|
1900
1908
|
}
|
|
1901
1909
|
else {
|
|
1902
|
-
|
|
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
|
+
}
|
|
1903
1916
|
}
|
|
1904
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) {
|
|
1905
1924
|
// remove root reference from previous value
|
|
1906
1925
|
previousValue[$changes].root?.remove(previousValue[$changes]);
|
|
1907
1926
|
}
|
|
1908
|
-
else if (setValue[$changes].isNew) {
|
|
1909
|
-
this[$changes].indexedOperation(Number(key), OPERATION.ADD);
|
|
1910
|
-
}
|
|
1911
|
-
setValue[$changes].setParent(this, obj[$changes].root, key);
|
|
1912
1927
|
}
|
|
1913
1928
|
else {
|
|
1914
1929
|
obj.$changeAt(Number(key), setValue);
|
|
1915
1930
|
}
|
|
1916
|
-
|
|
1917
|
-
|
|
1931
|
+
obj.items[key] = setValue;
|
|
1932
|
+
obj.tmpItems[key] = setValue;
|
|
1918
1933
|
}
|
|
1919
1934
|
return true;
|
|
1920
1935
|
}
|
|
@@ -2022,8 +2037,12 @@ class ArraySchema {
|
|
|
2022
2037
|
if (this.items[index] === value) {
|
|
2023
2038
|
return;
|
|
2024
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;
|
|
2025
2045
|
const changeTree = this[$changes];
|
|
2026
|
-
const operation = changeTree.indexes?.[index]?.op ?? OPERATION.ADD;
|
|
2027
2046
|
changeTree.change(index, operation);
|
|
2028
2047
|
//
|
|
2029
2048
|
// set value's parent after the value is set
|
|
@@ -2140,11 +2159,13 @@ class ArraySchema {
|
|
|
2140
2159
|
* ```
|
|
2141
2160
|
*/
|
|
2142
2161
|
sort(compareFn = DEFAULT_SORT) {
|
|
2162
|
+
this.isMovingItems = true;
|
|
2143
2163
|
const changeTree = this[$changes];
|
|
2144
2164
|
const sortedItems = this.items.sort(compareFn);
|
|
2145
2165
|
// wouldn't OPERATION.MOVE make more sense here?
|
|
2146
2166
|
sortedItems.forEach((_, i) => changeTree.change(i, OPERATION.REPLACE));
|
|
2147
2167
|
this.tmpItems.sort(compareFn);
|
|
2168
|
+
this.isMovingItems = false;
|
|
2148
2169
|
return this;
|
|
2149
2170
|
}
|
|
2150
2171
|
/**
|
|
@@ -2457,6 +2478,37 @@ class ArraySchema {
|
|
|
2457
2478
|
// @ts-ignore
|
|
2458
2479
|
return this.items.toSpliced.apply(copy, arguments);
|
|
2459
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
|
+
}
|
|
2460
2512
|
[($getByIndex)](index, isEncodeAll = false) {
|
|
2461
2513
|
//
|
|
2462
2514
|
// TODO: avoid unecessary `this.tmpItems` check during decoding.
|