@colyseus/schema 3.0.0-alpha.31 → 3.0.0-alpha.32
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 +44 -51
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +44 -51
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +44 -51
- package/lib/bench_encode.js +21 -40
- package/lib/bench_encode.js.map +1 -1
- package/lib/decoder/DecodeOperation.js +3 -1
- package/lib/decoder/DecodeOperation.js.map +1 -1
- package/lib/encoder/ChangeTree.js +7 -2
- package/lib/encoder/ChangeTree.js.map +1 -1
- package/lib/encoder/EncodeOperation.js +8 -38
- package/lib/encoder/EncodeOperation.js.map +1 -1
- package/lib/encoder/Encoder.js +8 -4
- package/lib/encoder/Encoder.js.map +1 -1
- package/lib/encoder/Root.d.ts +2 -2
- package/lib/encoder/Root.js +18 -6
- package/lib/encoder/Root.js.map +1 -1
- package/package.json +1 -1
- package/src/bench_encode.ts +21 -43
- package/src/decoder/DecodeOperation.ts +8 -1
- package/src/encoder/ChangeTree.ts +8 -3
- package/src/encoder/EncodeOperation.ts +5 -31
- package/src/encoder/Encoder.ts +10 -5
- package/src/encoder/Root.ts +23 -6
package/build/esm/index.mjs
CHANGED
|
@@ -471,7 +471,6 @@ class ChangeTree {
|
|
|
471
471
|
changeSet.set(index, operation ?? OPERATION.DELETE);
|
|
472
472
|
// remove `root` reference
|
|
473
473
|
if (previousValue && previousValue[$changes]) {
|
|
474
|
-
previousValue[$changes].root = undefined;
|
|
475
474
|
//
|
|
476
475
|
// FIXME: this.root is "undefined"
|
|
477
476
|
//
|
|
@@ -482,7 +481,13 @@ class ChangeTree {
|
|
|
482
481
|
//
|
|
483
482
|
// (the property descriptors should NOT be used at decoding time. only at encoding time.)
|
|
484
483
|
//
|
|
485
|
-
this.root?.remove(previousValue[$changes]);
|
|
484
|
+
const refCount = this.root?.remove(previousValue[$changes]);
|
|
485
|
+
//
|
|
486
|
+
// Only remove "root" reference if it's the last reference
|
|
487
|
+
//
|
|
488
|
+
if (refCount <= 0) {
|
|
489
|
+
previousValue[$changes].root = undefined;
|
|
490
|
+
}
|
|
486
491
|
}
|
|
487
492
|
//
|
|
488
493
|
// FIXME: this is looking a bit ugly (and repeated from `.change()`)
|
|
@@ -861,21 +866,11 @@ var encode = /*#__PURE__*/Object.freeze({
|
|
|
861
866
|
writeFloat64: writeFloat64
|
|
862
867
|
});
|
|
863
868
|
|
|
864
|
-
function encodeValue(encoder, bytes,
|
|
865
|
-
// ref: Ref,
|
|
866
|
-
type, value,
|
|
867
|
-
// field: string | number,
|
|
868
|
-
operation, it) {
|
|
869
|
+
function encodeValue(encoder, bytes, type, value, operation, it) {
|
|
869
870
|
if (typeof (type) === "string") {
|
|
870
|
-
//
|
|
871
|
-
// Primitive values
|
|
872
|
-
//
|
|
873
|
-
// assertType(value, type as string, ref as Schema, field);
|
|
874
871
|
encode[type]?.(bytes, value, it);
|
|
875
872
|
}
|
|
876
873
|
else if (type[Symbol.metadata] !== undefined) {
|
|
877
|
-
// // TODO: move this to the `@type()` annotation
|
|
878
|
-
// assertInstanceType(value, type as typeof Schema, ref as Schema, field);
|
|
879
874
|
//
|
|
880
875
|
// Encode refId for this instance.
|
|
881
876
|
// The actual instance is going to be encoded on next `changeTree` iteration.
|
|
@@ -887,14 +882,6 @@ operation, it) {
|
|
|
887
882
|
}
|
|
888
883
|
}
|
|
889
884
|
else {
|
|
890
|
-
// //
|
|
891
|
-
// // Custom type (MapSchema, ArraySchema, etc)
|
|
892
|
-
// //
|
|
893
|
-
// const definition = getType(Object.keys(type)[0]);
|
|
894
|
-
// //
|
|
895
|
-
// // ensure a ArraySchema has been provided
|
|
896
|
-
// //
|
|
897
|
-
// assertInstanceType(ref[field], definition.constructor, ref as Schema, field);
|
|
898
885
|
//
|
|
899
886
|
// Encode refId for this instance.
|
|
900
887
|
// The actual instance is going to be encoded on next `changeTree` iteration.
|
|
@@ -914,14 +901,10 @@ const encodeSchemaOperation = function (encoder, bytes, changeTree, index, opera
|
|
|
914
901
|
return;
|
|
915
902
|
}
|
|
916
903
|
const ref = changeTree.ref;
|
|
917
|
-
const metadata = ref
|
|
904
|
+
const metadata = ref.constructor[Symbol.metadata];
|
|
918
905
|
const field = metadata[index];
|
|
919
906
|
// TODO: inline this function call small performance gain
|
|
920
|
-
encodeValue(encoder, bytes,
|
|
921
|
-
// ref,
|
|
922
|
-
metadata[index].type, ref[field.name],
|
|
923
|
-
// index,
|
|
924
|
-
operation, it);
|
|
907
|
+
encodeValue(encoder, bytes, metadata[index].type, ref[field.name], operation, it);
|
|
925
908
|
};
|
|
926
909
|
/**
|
|
927
910
|
* Used for collections (MapSchema, CollectionSchema, SetSchema)
|
|
@@ -944,7 +927,7 @@ const encodeKeyValueOperation = function (encoder, bytes, changeTree, index, ope
|
|
|
944
927
|
//
|
|
945
928
|
// encode "alias" for dynamic fields (maps)
|
|
946
929
|
//
|
|
947
|
-
if ((operation & OPERATION.ADD)
|
|
930
|
+
if ((operation & OPERATION.ADD) === OPERATION.ADD) { // ADD or DELETE_AND_ADD
|
|
948
931
|
if (typeof (ref['set']) === "function") {
|
|
949
932
|
//
|
|
950
933
|
// MapSchema dynamic key
|
|
@@ -953,8 +936,8 @@ const encodeKeyValueOperation = function (encoder, bytes, changeTree, index, ope
|
|
|
953
936
|
string$1(bytes, dynamicIndex, it);
|
|
954
937
|
}
|
|
955
938
|
}
|
|
956
|
-
const type =
|
|
957
|
-
const value =
|
|
939
|
+
const type = ref[$childType];
|
|
940
|
+
const value = ref[$getByIndex](index);
|
|
958
941
|
// try { throw new Error(); } catch (e) {
|
|
959
942
|
// // only print if not coming from Reflection.ts
|
|
960
943
|
// if (!e.stack.includes("src/Reflection.ts")) {
|
|
@@ -968,11 +951,7 @@ const encodeKeyValueOperation = function (encoder, bytes, changeTree, index, ope
|
|
|
968
951
|
// }
|
|
969
952
|
// }
|
|
970
953
|
// TODO: inline this function call small performance gain
|
|
971
|
-
encodeValue(encoder, bytes,
|
|
972
|
-
// ref,
|
|
973
|
-
type, value,
|
|
974
|
-
// index,
|
|
975
|
-
operation, it);
|
|
954
|
+
encodeValue(encoder, bytes, type, value, operation, it);
|
|
976
955
|
};
|
|
977
956
|
/**
|
|
978
957
|
* Used for collections (MapSchema, ArraySchema, etc.)
|
|
@@ -1016,11 +995,7 @@ const encodeArray = function (encoder, bytes, changeTree, field, operation, it,
|
|
|
1016
995
|
// items: ref.toJSON(),
|
|
1017
996
|
// });
|
|
1018
997
|
// TODO: inline this function call small performance gain
|
|
1019
|
-
encodeValue(encoder, bytes,
|
|
1020
|
-
// ref,
|
|
1021
|
-
type, value,
|
|
1022
|
-
// field,
|
|
1023
|
-
operation, it);
|
|
998
|
+
encodeValue(encoder, bytes, type, value, operation, it);
|
|
1024
999
|
};
|
|
1025
1000
|
|
|
1026
1001
|
/**
|
|
@@ -1326,7 +1301,9 @@ function decodeValue(decoder, operation, ref, index, type, bytes, it, allChanges
|
|
|
1326
1301
|
if (!value) {
|
|
1327
1302
|
value = decoder.createInstanceOfType(childType);
|
|
1328
1303
|
}
|
|
1329
|
-
$root.addRef(refId, value, (value !== previousValue
|
|
1304
|
+
$root.addRef(refId, value, (value !== previousValue || // increment ref count if value has changed
|
|
1305
|
+
(operation === OPERATION.DELETE_AND_ADD && value === previousValue) // increment ref count if the same instance is being added again
|
|
1306
|
+
));
|
|
1330
1307
|
}
|
|
1331
1308
|
}
|
|
1332
1309
|
else if (typeof (type) === "string") {
|
|
@@ -3473,24 +3450,36 @@ class Root {
|
|
|
3473
3450
|
return this.nextUniqueId++;
|
|
3474
3451
|
}
|
|
3475
3452
|
add(changeTree) {
|
|
3476
|
-
const
|
|
3477
|
-
|
|
3453
|
+
const previousRefCount = this.refCount.get(changeTree);
|
|
3454
|
+
if (previousRefCount === 0) {
|
|
3455
|
+
//
|
|
3456
|
+
// When a ChangeTree is re-added, it means that it was previously removed.
|
|
3457
|
+
// We need to re-add all changes to the `changes` map.
|
|
3458
|
+
//
|
|
3459
|
+
changeTree.allChanges.forEach((operation, index) => {
|
|
3460
|
+
changeTree.changes.set(index, operation);
|
|
3461
|
+
});
|
|
3462
|
+
}
|
|
3463
|
+
const refCount = (previousRefCount || 0) + 1;
|
|
3464
|
+
this.refCount.set(changeTree, refCount);
|
|
3465
|
+
return refCount;
|
|
3478
3466
|
}
|
|
3479
3467
|
remove(changeTree) {
|
|
3480
|
-
const refCount = this.refCount.get(changeTree);
|
|
3481
|
-
if (refCount <=
|
|
3468
|
+
const refCount = (this.refCount.get(changeTree)) - 1;
|
|
3469
|
+
if (refCount <= 0) {
|
|
3482
3470
|
this.allChanges.delete(changeTree);
|
|
3483
3471
|
this.changes.delete(changeTree);
|
|
3484
3472
|
if (changeTree.isFiltered || changeTree.isPartiallyFiltered) {
|
|
3485
3473
|
this.allFilteredChanges.delete(changeTree);
|
|
3486
3474
|
this.filteredChanges.delete(changeTree);
|
|
3487
3475
|
}
|
|
3488
|
-
this.refCount.
|
|
3476
|
+
this.refCount.set(changeTree, 0);
|
|
3489
3477
|
}
|
|
3490
3478
|
else {
|
|
3491
|
-
this.refCount.set(changeTree, refCount
|
|
3479
|
+
this.refCount.set(changeTree, refCount);
|
|
3492
3480
|
}
|
|
3493
3481
|
changeTree.forEachChild((child, _) => this.remove(child));
|
|
3482
|
+
return refCount;
|
|
3494
3483
|
}
|
|
3495
3484
|
clear() {
|
|
3496
3485
|
this.changes.clear();
|
|
@@ -3524,7 +3513,7 @@ class Encoder {
|
|
|
3524
3513
|
const shouldClearChanges = !isEncodeAll && !hasView;
|
|
3525
3514
|
for (const [changeTree, changes] of changeTrees.entries()) {
|
|
3526
3515
|
const ref = changeTree.ref;
|
|
3527
|
-
const ctor = ref
|
|
3516
|
+
const ctor = ref.constructor;
|
|
3528
3517
|
const encoder = ctor[$encoder];
|
|
3529
3518
|
const filter = ctor[$filter];
|
|
3530
3519
|
// try { throw new Error(); } catch (e) {
|
|
@@ -3548,8 +3537,7 @@ class Encoder {
|
|
|
3548
3537
|
buffer[it.offset++] = SWITCH_TO_STRUCTURE & 255;
|
|
3549
3538
|
number$1(buffer, changeTree.refId, it);
|
|
3550
3539
|
}
|
|
3551
|
-
const
|
|
3552
|
-
for (const [fieldIndex, operation] of changesIterator) {
|
|
3540
|
+
for (const [fieldIndex, operation] of changes.entries()) {
|
|
3553
3541
|
//
|
|
3554
3542
|
// first pass (encodeAll), identify "filtered" operations without encoding them
|
|
3555
3543
|
// they will be encoded per client, based on their view.
|
|
@@ -3575,7 +3563,12 @@ class Encoder {
|
|
|
3575
3563
|
encoder(this, buffer, changeTree, fieldIndex, operation, it, isEncodeAll, hasView);
|
|
3576
3564
|
}
|
|
3577
3565
|
// if (shouldClearChanges) {
|
|
3578
|
-
// changeTree.endEncode();
|
|
3566
|
+
// // changeTree.endEncode();
|
|
3567
|
+
// changeTree.changes.clear();
|
|
3568
|
+
// // ArraySchema and MapSchema have a custom "encode end" method
|
|
3569
|
+
// changeTree.ref[$onEncodeEnd]?.();
|
|
3570
|
+
// // Not a new instance anymore
|
|
3571
|
+
// delete changeTree[$isNew];
|
|
3579
3572
|
// }
|
|
3580
3573
|
}
|
|
3581
3574
|
if (it.offset > buffer.byteLength) {
|