@colyseus/schema 3.0.0-alpha.41 → 3.0.0-alpha.44
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 +125 -79
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +125 -79
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +125 -79
- package/lib/Metadata.js.map +1 -1
- package/lib/Schema.js +3 -3
- package/lib/Schema.js.map +1 -1
- package/lib/codegen/languages/haxe.js +2 -1
- package/lib/codegen/languages/haxe.js.map +1 -1
- package/lib/codegen/languages/lua.js +21 -22
- package/lib/codegen/languages/lua.js.map +1 -1
- package/lib/decoder/ReferenceTracker.js +1 -0
- package/lib/decoder/ReferenceTracker.js.map +1 -1
- package/lib/encoder/ChangeTree.d.ts +5 -3
- package/lib/encoder/ChangeTree.js +52 -62
- package/lib/encoder/ChangeTree.js.map +1 -1
- package/lib/encoder/Root.js +1 -1
- package/lib/encoder/Root.js.map +1 -1
- package/lib/encoder/StateView.js +6 -4
- package/lib/encoder/StateView.js.map +1 -1
- package/lib/encoding/decode.d.ts +2 -0
- package/lib/encoding/decode.js +14 -0
- package/lib/encoding/decode.js.map +1 -1
- package/lib/types/TypeContext.d.ts +6 -0
- package/lib/types/TypeContext.js +49 -9
- package/lib/types/TypeContext.js.map +1 -1
- package/package.json +1 -1
- package/src/Metadata.ts +1 -1
- package/src/Schema.ts +3 -3
- package/src/codegen/languages/haxe.ts +2 -1
- package/src/codegen/languages/lua.ts +18 -26
- package/src/decoder/ReferenceTracker.ts +2 -1
- package/src/encoder/ChangeTree.ts +59 -76
- package/src/encoder/Root.ts +1 -1
- package/src/encoder/StateView.ts +9 -5
- package/src/encoding/decode.ts +16 -1
- package/src/types/TypeContext.ts +55 -13
package/build/cjs/index.js
CHANGED
|
@@ -538,6 +538,18 @@ function number(bytes, it) {
|
|
|
538
538
|
return (0xff - prefix + 1) * -1;
|
|
539
539
|
}
|
|
540
540
|
}
|
|
541
|
+
function stringCheck(bytes, it) {
|
|
542
|
+
const prefix = bytes[it.offset];
|
|
543
|
+
return (
|
|
544
|
+
// fixstr
|
|
545
|
+
(prefix < 0xc0 && prefix > 0xa0) ||
|
|
546
|
+
// str 8
|
|
547
|
+
prefix === 0xd9 ||
|
|
548
|
+
// str 16
|
|
549
|
+
prefix === 0xda ||
|
|
550
|
+
// str 32
|
|
551
|
+
prefix === 0xdb);
|
|
552
|
+
}
|
|
541
553
|
const decode = {
|
|
542
554
|
utf8Read,
|
|
543
555
|
int8,
|
|
@@ -555,6 +567,7 @@ const decode = {
|
|
|
555
567
|
boolean,
|
|
556
568
|
string,
|
|
557
569
|
number,
|
|
570
|
+
stringCheck,
|
|
558
571
|
};
|
|
559
572
|
|
|
560
573
|
const registeredTypes = {};
|
|
@@ -604,6 +617,11 @@ class TypeContext {
|
|
|
604
617
|
this.hasFilters = false;
|
|
605
618
|
this.parentFiltered = {};
|
|
606
619
|
if (rootClass) {
|
|
620
|
+
//
|
|
621
|
+
// TODO:
|
|
622
|
+
// cache "discoverTypes" results for each rootClass
|
|
623
|
+
// to avoid re-discovering types for each new context/room
|
|
624
|
+
//
|
|
607
625
|
this.discoverTypes(rootClass);
|
|
608
626
|
}
|
|
609
627
|
}
|
|
@@ -631,13 +649,17 @@ class TypeContext {
|
|
|
631
649
|
getTypeId(klass) {
|
|
632
650
|
return this.schemas.get(klass);
|
|
633
651
|
}
|
|
634
|
-
discoverTypes(klass, parentIndex,
|
|
652
|
+
discoverTypes(klass, parentType, parentIndex, parentHasViewTag) {
|
|
653
|
+
if (parentHasViewTag) {
|
|
654
|
+
this.registerFilteredByParent(klass, parentType, parentIndex);
|
|
655
|
+
}
|
|
656
|
+
// skip if already registered
|
|
635
657
|
if (!this.add(klass)) {
|
|
636
658
|
return;
|
|
637
659
|
}
|
|
638
660
|
// add classes inherited from this base class
|
|
639
661
|
TypeContext.inheritedTypes.get(klass)?.forEach((child) => {
|
|
640
|
-
this.discoverTypes(child, parentIndex,
|
|
662
|
+
this.discoverTypes(child, klass, parentIndex, parentHasViewTag);
|
|
641
663
|
});
|
|
642
664
|
// add parent classes
|
|
643
665
|
let parent = klass;
|
|
@@ -652,13 +674,10 @@ class TypeContext {
|
|
|
652
674
|
if (metadata[$viewFieldIndexes]) {
|
|
653
675
|
this.hasFilters = true;
|
|
654
676
|
}
|
|
655
|
-
if (parentFieldViewTag !== undefined) {
|
|
656
|
-
this.parentFiltered[`${this.schemas.get(klass)}-${parentIndex}`] = true;
|
|
657
|
-
}
|
|
658
677
|
for (const fieldIndex in metadata) {
|
|
659
678
|
const index = fieldIndex;
|
|
660
679
|
const fieldType = metadata[index].type;
|
|
661
|
-
const
|
|
680
|
+
const fieldHasViewTag = (metadata[index].tag !== undefined);
|
|
662
681
|
if (typeof (fieldType) === "string") {
|
|
663
682
|
continue;
|
|
664
683
|
}
|
|
@@ -668,10 +687,10 @@ class TypeContext {
|
|
|
668
687
|
if (type === "string") {
|
|
669
688
|
continue;
|
|
670
689
|
}
|
|
671
|
-
this.discoverTypes(type, index,
|
|
690
|
+
this.discoverTypes(type, klass, index, parentHasViewTag || fieldHasViewTag);
|
|
672
691
|
}
|
|
673
692
|
else if (typeof (fieldType) === "function") {
|
|
674
|
-
this.discoverTypes(fieldType,
|
|
693
|
+
this.discoverTypes(fieldType, klass, index, parentHasViewTag || fieldHasViewTag);
|
|
675
694
|
}
|
|
676
695
|
else {
|
|
677
696
|
const type = Object.values(fieldType)[0];
|
|
@@ -679,10 +698,44 @@ class TypeContext {
|
|
|
679
698
|
if (typeof (type) === "string") {
|
|
680
699
|
continue;
|
|
681
700
|
}
|
|
682
|
-
this.discoverTypes(type, index,
|
|
701
|
+
this.discoverTypes(type, klass, index, parentHasViewTag || fieldHasViewTag);
|
|
683
702
|
}
|
|
684
703
|
}
|
|
685
704
|
}
|
|
705
|
+
/**
|
|
706
|
+
* Keep track of which classes have filters applied.
|
|
707
|
+
* Format: `${typeid}-${parentTypeid}-${parentIndex}`
|
|
708
|
+
*/
|
|
709
|
+
registerFilteredByParent(schema, parentType, parentIndex) {
|
|
710
|
+
const typeid = this.schemas.get(schema) ?? this.schemas.size;
|
|
711
|
+
let key = `${typeid}`;
|
|
712
|
+
if (parentType) {
|
|
713
|
+
key += `-${this.schemas.get(parentType)}`;
|
|
714
|
+
}
|
|
715
|
+
key += `-${parentIndex}`;
|
|
716
|
+
this.parentFiltered[key] = true;
|
|
717
|
+
}
|
|
718
|
+
debug() {
|
|
719
|
+
let parentFiltered = "";
|
|
720
|
+
for (const key in this.parentFiltered) {
|
|
721
|
+
const keys = key.split("-").map(Number);
|
|
722
|
+
const fieldIndex = keys.pop();
|
|
723
|
+
parentFiltered += `\n\t\t`;
|
|
724
|
+
parentFiltered += `${key}: ${keys.reverse().map((id, i) => {
|
|
725
|
+
const klass = this.types[id];
|
|
726
|
+
const metadata = klass[Symbol.metadata];
|
|
727
|
+
let txt = klass.name;
|
|
728
|
+
if (i === 0) {
|
|
729
|
+
txt += `[${metadata[fieldIndex].name}]`;
|
|
730
|
+
}
|
|
731
|
+
return `${txt}`;
|
|
732
|
+
}).join(" -> ")}`;
|
|
733
|
+
}
|
|
734
|
+
return `TypeContext ->\n` +
|
|
735
|
+
`\tSchema types: ${this.schemas.size}\n` +
|
|
736
|
+
`\thasFilters: ${this.hasFilters}\n` +
|
|
737
|
+
`\tparentFiltered:${parentFiltered}`;
|
|
738
|
+
}
|
|
686
739
|
}
|
|
687
740
|
|
|
688
741
|
function getNormalizedType(type) {
|
|
@@ -927,8 +980,10 @@ function enqueueChangeTree(root, changeTree, changeSet, queueRootIndex = changeT
|
|
|
927
980
|
}
|
|
928
981
|
class ChangeTree {
|
|
929
982
|
constructor(ref) {
|
|
983
|
+
/**
|
|
984
|
+
* Whether this structure is parent of a filtered structure.
|
|
985
|
+
*/
|
|
930
986
|
this.isFiltered = false;
|
|
931
|
-
this.isPartiallyFiltered = false;
|
|
932
987
|
this.indexedOperations = {};
|
|
933
988
|
//
|
|
934
989
|
// TODO:
|
|
@@ -947,37 +1002,17 @@ class ChangeTree {
|
|
|
947
1002
|
//
|
|
948
1003
|
// Does this structure have "filters" declared?
|
|
949
1004
|
//
|
|
950
|
-
|
|
1005
|
+
const metadata = ref.constructor[Symbol.metadata];
|
|
1006
|
+
if (metadata?.[$viewFieldIndexes]) {
|
|
951
1007
|
this.allFilteredChanges = { indexes: {}, operations: [] };
|
|
952
1008
|
this.filteredChanges = { indexes: {}, operations: [] };
|
|
953
1009
|
}
|
|
954
1010
|
}
|
|
955
1011
|
setRoot(root) {
|
|
956
1012
|
this.root = root;
|
|
957
|
-
|
|
958
|
-
const metadata = this.ref.constructor[Symbol.metadata];
|
|
959
|
-
if (this.root.types.hasFilters) {
|
|
960
|
-
//
|
|
961
|
-
// At Schema initialization, the "root" structure might not be available
|
|
962
|
-
// yet, as it only does once the "Encoder" has been set up.
|
|
963
|
-
//
|
|
964
|
-
// So the "parent" may be already set without a "root".
|
|
965
|
-
//
|
|
966
|
-
this.checkIsFiltered(metadata, this.parent, this.parentIndex);
|
|
967
|
-
if (this.isFiltered || this.isPartiallyFiltered) {
|
|
968
|
-
enqueueChangeTree(root, this, 'filteredChanges');
|
|
969
|
-
if (isNewChangeTree) {
|
|
970
|
-
this.root.allFilteredChanges.push(this);
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
|
-
}
|
|
974
|
-
if (!this.isFiltered) {
|
|
975
|
-
enqueueChangeTree(root, this, 'changes');
|
|
976
|
-
if (isNewChangeTree) {
|
|
977
|
-
this.root.allChanges.push(this);
|
|
978
|
-
}
|
|
979
|
-
}
|
|
1013
|
+
this.checkIsFiltered(this.parent, this.parentIndex);
|
|
980
1014
|
// Recursively set root on child structures
|
|
1015
|
+
const metadata = this.ref.constructor[Symbol.metadata];
|
|
981
1016
|
if (metadata) {
|
|
982
1017
|
metadata[$refTypeFieldIndexes]?.forEach((index) => {
|
|
983
1018
|
const field = metadata[index];
|
|
@@ -999,39 +1034,21 @@ class ChangeTree {
|
|
|
999
1034
|
if (!root) {
|
|
1000
1035
|
return;
|
|
1001
1036
|
}
|
|
1002
|
-
const metadata = this.ref.constructor[Symbol.metadata];
|
|
1003
1037
|
// skip if parent is already set
|
|
1004
1038
|
if (root !== this.root) {
|
|
1005
1039
|
this.root = root;
|
|
1006
|
-
|
|
1007
|
-
if (root.types.hasFilters) {
|
|
1008
|
-
this.checkIsFiltered(metadata, parent, parentIndex);
|
|
1009
|
-
if (this.isFiltered || this.isPartiallyFiltered) {
|
|
1010
|
-
enqueueChangeTree(root, this, 'filteredChanges');
|
|
1011
|
-
if (isNewChangeTree) {
|
|
1012
|
-
this.root.allFilteredChanges.push(this);
|
|
1013
|
-
}
|
|
1014
|
-
}
|
|
1015
|
-
}
|
|
1016
|
-
if (!this.isFiltered) {
|
|
1017
|
-
enqueueChangeTree(root, this, 'changes');
|
|
1018
|
-
if (isNewChangeTree) {
|
|
1019
|
-
this.root.allChanges.push(this);
|
|
1020
|
-
}
|
|
1021
|
-
}
|
|
1040
|
+
this.checkIsFiltered(parent, parentIndex);
|
|
1022
1041
|
}
|
|
1023
1042
|
else {
|
|
1024
1043
|
root.add(this);
|
|
1025
1044
|
}
|
|
1026
1045
|
// assign same parent on child structures
|
|
1046
|
+
const metadata = this.ref.constructor[Symbol.metadata];
|
|
1027
1047
|
if (metadata) {
|
|
1028
1048
|
metadata[$refTypeFieldIndexes]?.forEach((index) => {
|
|
1029
1049
|
const field = metadata[index];
|
|
1030
1050
|
const value = this.ref[field.name];
|
|
1031
1051
|
value?.[$changes].setParent(this.ref, root, index);
|
|
1032
|
-
// try { throw new Error(); } catch (e) {
|
|
1033
|
-
// console.log(e.stack);
|
|
1034
|
-
// }
|
|
1035
1052
|
});
|
|
1036
1053
|
}
|
|
1037
1054
|
else if (this.ref[$childType] && typeof (this.ref[$childType]) !== "string") {
|
|
@@ -1124,7 +1141,7 @@ class ChangeTree {
|
|
|
1124
1141
|
//
|
|
1125
1142
|
// - ArraySchema#splice()
|
|
1126
1143
|
//
|
|
1127
|
-
if (this.
|
|
1144
|
+
if (this.filteredChanges !== undefined) {
|
|
1128
1145
|
this._shiftAllChangeIndexes(shiftIndex, startIndex, this.allFilteredChanges);
|
|
1129
1146
|
this._shiftAllChangeIndexes(shiftIndex, startIndex, this.allChanges);
|
|
1130
1147
|
}
|
|
@@ -1153,7 +1170,7 @@ class ChangeTree {
|
|
|
1153
1170
|
}
|
|
1154
1171
|
indexedOperation(index, operation, allChangesIndex = index) {
|
|
1155
1172
|
this.indexedOperations[index] = operation;
|
|
1156
|
-
if (this.filteredChanges) {
|
|
1173
|
+
if (this.filteredChanges !== undefined) {
|
|
1157
1174
|
setOperationAtIndex(this.allFilteredChanges, allChangesIndex);
|
|
1158
1175
|
setOperationAtIndex(this.filteredChanges, index);
|
|
1159
1176
|
enqueueChangeTree(this.root, this, 'filteredChanges');
|
|
@@ -1201,7 +1218,7 @@ class ChangeTree {
|
|
|
1201
1218
|
}
|
|
1202
1219
|
return;
|
|
1203
1220
|
}
|
|
1204
|
-
const changeSet = (this.filteredChanges)
|
|
1221
|
+
const changeSet = (this.filteredChanges !== undefined)
|
|
1205
1222
|
? this.filteredChanges
|
|
1206
1223
|
: this.changes;
|
|
1207
1224
|
this.indexedOperations[index] = operation ?? exports.OPERATION.DELETE;
|
|
@@ -1217,14 +1234,14 @@ class ChangeTree {
|
|
|
1217
1234
|
// - This is due to using the concrete Schema class at decoding time.
|
|
1218
1235
|
// - "Reflected" structures do not have this problem.
|
|
1219
1236
|
//
|
|
1220
|
-
// (
|
|
1237
|
+
// (The property descriptors should NOT be used at decoding time. only at encoding time.)
|
|
1221
1238
|
//
|
|
1222
1239
|
this.root?.remove(previousValue[$changes]);
|
|
1223
1240
|
}
|
|
1224
1241
|
//
|
|
1225
1242
|
// FIXME: this is looking a ugly and repeated
|
|
1226
1243
|
//
|
|
1227
|
-
if (this.filteredChanges) {
|
|
1244
|
+
if (this.filteredChanges !== undefined) {
|
|
1228
1245
|
deleteOperationAtIndex(this.allFilteredChanges, allChangesIndex);
|
|
1229
1246
|
enqueueChangeTree(this.root, this, 'filteredChanges');
|
|
1230
1247
|
}
|
|
@@ -1293,29 +1310,59 @@ class ChangeTree {
|
|
|
1293
1310
|
get changed() {
|
|
1294
1311
|
return (Object.entries(this.indexedOperations).length > 0);
|
|
1295
1312
|
}
|
|
1296
|
-
checkIsFiltered(
|
|
1297
|
-
|
|
1298
|
-
this.
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1313
|
+
checkIsFiltered(parent, parentIndex) {
|
|
1314
|
+
const isNewChangeTree = this.root.add(this);
|
|
1315
|
+
if (this.root.types.hasFilters) {
|
|
1316
|
+
//
|
|
1317
|
+
// At Schema initialization, the "root" structure might not be available
|
|
1318
|
+
// yet, as it only does once the "Encoder" has been set up.
|
|
1319
|
+
//
|
|
1320
|
+
// So the "parent" may be already set without a "root".
|
|
1321
|
+
//
|
|
1322
|
+
this._checkFilteredByParent(parent, parentIndex);
|
|
1323
|
+
if (this.filteredChanges !== undefined) {
|
|
1324
|
+
enqueueChangeTree(this.root, this, 'filteredChanges');
|
|
1325
|
+
if (isNewChangeTree) {
|
|
1326
|
+
this.root.allFilteredChanges.push(this);
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1302
1329
|
}
|
|
1330
|
+
if (!this.isFiltered) {
|
|
1331
|
+
enqueueChangeTree(this.root, this, 'changes');
|
|
1332
|
+
if (isNewChangeTree) {
|
|
1333
|
+
this.root.allChanges.push(this);
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
_checkFilteredByParent(parent, parentIndex) {
|
|
1303
1338
|
// skip if parent is not set
|
|
1304
1339
|
if (!parent) {
|
|
1305
1340
|
return;
|
|
1306
1341
|
}
|
|
1342
|
+
// ArraySchema | MapSchema - get the child type
|
|
1343
|
+
const ref = Metadata.isValidInstance(this.ref)
|
|
1344
|
+
? this.ref
|
|
1345
|
+
: new this.ref[$childType];
|
|
1307
1346
|
if (!Metadata.isValidInstance(parent)) {
|
|
1308
1347
|
const parentChangeTree = parent[$changes];
|
|
1309
1348
|
parent = parentChangeTree.parent;
|
|
1310
1349
|
parentIndex = parentChangeTree.parentIndex;
|
|
1311
1350
|
}
|
|
1312
|
-
const
|
|
1313
|
-
|
|
1351
|
+
const parentConstructor = parent.constructor;
|
|
1352
|
+
let key = `${this.root.types.getTypeId(ref.constructor)}`;
|
|
1353
|
+
if (parentConstructor) {
|
|
1354
|
+
key += `-${this.root.types.schemas.get(parentConstructor)}`;
|
|
1355
|
+
}
|
|
1356
|
+
key += `-${parentIndex}`;
|
|
1357
|
+
this.isFiltered = this.root.types.parentFiltered[key];
|
|
1358
|
+
// const parentMetadata = parentConstructor?.[Symbol.metadata];
|
|
1359
|
+
// this.isFiltered = parentMetadata?.[$viewFieldIndexes]?.includes(parentIndex) || this.root.types.parentFiltered[key];
|
|
1314
1360
|
//
|
|
1315
1361
|
// TODO: refactor this!
|
|
1316
1362
|
//
|
|
1317
1363
|
// swapping `changes` and `filteredChanges` is required here
|
|
1318
1364
|
// because "isFiltered" may not be imedialely available on `change()`
|
|
1365
|
+
// (this happens when instance is detached from root or parent)
|
|
1319
1366
|
//
|
|
1320
1367
|
if (this.isFiltered) {
|
|
1321
1368
|
this.filteredChanges = { indexes: {}, operations: [] };
|
|
@@ -1329,10 +1376,6 @@ class ChangeTree {
|
|
|
1329
1376
|
const allFilteredChanges = this.allFilteredChanges;
|
|
1330
1377
|
this.allFilteredChanges = this.allChanges;
|
|
1331
1378
|
this.allChanges = allFilteredChanges;
|
|
1332
|
-
// console.log("SWAP =>", {
|
|
1333
|
-
// "this.allFilteredChanges": this.allFilteredChanges,
|
|
1334
|
-
// "this.allChanges": this.allChanges
|
|
1335
|
-
// })
|
|
1336
1379
|
}
|
|
1337
1380
|
}
|
|
1338
1381
|
}
|
|
@@ -3220,7 +3263,7 @@ class Schema {
|
|
|
3220
3263
|
const rootChangeTree = ref[$changes];
|
|
3221
3264
|
const root = rootChangeTree.root;
|
|
3222
3265
|
const changeTrees = new Map();
|
|
3223
|
-
|
|
3266
|
+
const instanceRefIds = [];
|
|
3224
3267
|
let totalOperations = 0;
|
|
3225
3268
|
for (const [refId, changes] of Object.entries(root[changeSetName])) {
|
|
3226
3269
|
const changeTree = root.changeTrees[refId];
|
|
@@ -3241,14 +3284,14 @@ class Schema {
|
|
|
3241
3284
|
}
|
|
3242
3285
|
}
|
|
3243
3286
|
if (includeChangeTree) {
|
|
3244
|
-
|
|
3287
|
+
instanceRefIds.push(changeTree.refId);
|
|
3245
3288
|
totalOperations += Object.keys(changes).length;
|
|
3246
3289
|
changeTrees.set(changeTree, parentChangeTrees.reverse());
|
|
3247
3290
|
}
|
|
3248
3291
|
}
|
|
3249
3292
|
output += "---\n";
|
|
3250
3293
|
output += `root refId: ${rootChangeTree.refId}\n`;
|
|
3251
|
-
output += `Total instances: ${
|
|
3294
|
+
output += `Total instances: ${instanceRefIds.length} (refIds: ${instanceRefIds.join(", ")})\n`;
|
|
3252
3295
|
output += `Total changes: ${totalOperations}\n`;
|
|
3253
3296
|
output += "---\n";
|
|
3254
3297
|
// based on root.changes, display a tree of changes that has the "ref" instance as parent
|
|
@@ -3689,7 +3732,7 @@ class Root {
|
|
|
3689
3732
|
delete this.changeTrees[changeTree.refId];
|
|
3690
3733
|
this.removeChangeFromChangeSet("allChanges", changeTree);
|
|
3691
3734
|
this.removeChangeFromChangeSet("changes", changeTree);
|
|
3692
|
-
if (changeTree.
|
|
3735
|
+
if (changeTree.filteredChanges) {
|
|
3693
3736
|
this.removeChangeFromChangeSet("allFilteredChanges", changeTree);
|
|
3694
3737
|
this.removeChangeFromChangeSet("filteredChanges", changeTree);
|
|
3695
3738
|
}
|
|
@@ -4035,6 +4078,7 @@ class ReferenceTracker {
|
|
|
4035
4078
|
clearRefs() {
|
|
4036
4079
|
this.refs.clear();
|
|
4037
4080
|
this.deletedRefs.clear();
|
|
4081
|
+
this.callbacks = {};
|
|
4038
4082
|
this.refCounts = {};
|
|
4039
4083
|
}
|
|
4040
4084
|
// for decoding
|
|
@@ -4699,7 +4743,7 @@ class StateView {
|
|
|
4699
4743
|
}
|
|
4700
4744
|
else {
|
|
4701
4745
|
const isInvisible = this.invisible.has(changeTree);
|
|
4702
|
-
const changeSet = (changeTree.
|
|
4746
|
+
const changeSet = (changeTree.filteredChanges !== undefined)
|
|
4703
4747
|
? changeTree.allFilteredChanges
|
|
4704
4748
|
: changeTree.allChanges;
|
|
4705
4749
|
for (let i = 0, len = changeSet.operations.length; i < len; i++) {
|
|
@@ -4707,7 +4751,7 @@ class StateView {
|
|
|
4707
4751
|
if (index === undefined) {
|
|
4708
4752
|
continue;
|
|
4709
4753
|
} // skip "undefined" indexes
|
|
4710
|
-
const op = changeTree.indexedOperations[index];
|
|
4754
|
+
const op = changeTree.indexedOperations[index] ?? exports.OPERATION.ADD;
|
|
4711
4755
|
const tagAtIndex = metadata?.[index].tag;
|
|
4712
4756
|
if ((isInvisible || // if "invisible", include all
|
|
4713
4757
|
tagAtIndex === undefined || // "all change" with no tag
|
|
@@ -4721,7 +4765,9 @@ class StateView {
|
|
|
4721
4765
|
// Add children of this ChangeTree to this view
|
|
4722
4766
|
changeTree.forEachChild((change, index) => {
|
|
4723
4767
|
// Do not ADD children that don't have the same tag
|
|
4724
|
-
if (metadata &&
|
|
4768
|
+
if (metadata &&
|
|
4769
|
+
metadata[index].tag !== undefined &&
|
|
4770
|
+
metadata[index].tag !== tag) {
|
|
4725
4771
|
return;
|
|
4726
4772
|
}
|
|
4727
4773
|
this.add(change.ref, tag, false);
|
|
@@ -4733,7 +4779,7 @@ class StateView {
|
|
|
4733
4779
|
this.items.add(changeTree);
|
|
4734
4780
|
// add parent's parent
|
|
4735
4781
|
const parentChangeTree = changeTree.parent?.[$changes];
|
|
4736
|
-
if (parentChangeTree && (parentChangeTree.
|
|
4782
|
+
if (parentChangeTree && (parentChangeTree.filteredChanges !== undefined)) {
|
|
4737
4783
|
this.addParent(parentChangeTree, changeTree.parentIndex, tag);
|
|
4738
4784
|
}
|
|
4739
4785
|
// parent is already available, no need to add it!
|