@colyseus/schema 3.0.0-alpha.42 → 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 +112 -79
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +112 -79
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +112 -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/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/types/TypeContext.ts +55 -13
package/build/esm/index.mjs
CHANGED
|
@@ -615,6 +615,11 @@ class TypeContext {
|
|
|
615
615
|
this.hasFilters = false;
|
|
616
616
|
this.parentFiltered = {};
|
|
617
617
|
if (rootClass) {
|
|
618
|
+
//
|
|
619
|
+
// TODO:
|
|
620
|
+
// cache "discoverTypes" results for each rootClass
|
|
621
|
+
// to avoid re-discovering types for each new context/room
|
|
622
|
+
//
|
|
618
623
|
this.discoverTypes(rootClass);
|
|
619
624
|
}
|
|
620
625
|
}
|
|
@@ -642,13 +647,17 @@ class TypeContext {
|
|
|
642
647
|
getTypeId(klass) {
|
|
643
648
|
return this.schemas.get(klass);
|
|
644
649
|
}
|
|
645
|
-
discoverTypes(klass, parentIndex,
|
|
650
|
+
discoverTypes(klass, parentType, parentIndex, parentHasViewTag) {
|
|
651
|
+
if (parentHasViewTag) {
|
|
652
|
+
this.registerFilteredByParent(klass, parentType, parentIndex);
|
|
653
|
+
}
|
|
654
|
+
// skip if already registered
|
|
646
655
|
if (!this.add(klass)) {
|
|
647
656
|
return;
|
|
648
657
|
}
|
|
649
658
|
// add classes inherited from this base class
|
|
650
659
|
TypeContext.inheritedTypes.get(klass)?.forEach((child) => {
|
|
651
|
-
this.discoverTypes(child, parentIndex,
|
|
660
|
+
this.discoverTypes(child, klass, parentIndex, parentHasViewTag);
|
|
652
661
|
});
|
|
653
662
|
// add parent classes
|
|
654
663
|
let parent = klass;
|
|
@@ -663,13 +672,10 @@ class TypeContext {
|
|
|
663
672
|
if (metadata[$viewFieldIndexes]) {
|
|
664
673
|
this.hasFilters = true;
|
|
665
674
|
}
|
|
666
|
-
if (parentFieldViewTag !== undefined) {
|
|
667
|
-
this.parentFiltered[`${this.schemas.get(klass)}-${parentIndex}`] = true;
|
|
668
|
-
}
|
|
669
675
|
for (const fieldIndex in metadata) {
|
|
670
676
|
const index = fieldIndex;
|
|
671
677
|
const fieldType = metadata[index].type;
|
|
672
|
-
const
|
|
678
|
+
const fieldHasViewTag = (metadata[index].tag !== undefined);
|
|
673
679
|
if (typeof (fieldType) === "string") {
|
|
674
680
|
continue;
|
|
675
681
|
}
|
|
@@ -679,10 +685,10 @@ class TypeContext {
|
|
|
679
685
|
if (type === "string") {
|
|
680
686
|
continue;
|
|
681
687
|
}
|
|
682
|
-
this.discoverTypes(type, index,
|
|
688
|
+
this.discoverTypes(type, klass, index, parentHasViewTag || fieldHasViewTag);
|
|
683
689
|
}
|
|
684
690
|
else if (typeof (fieldType) === "function") {
|
|
685
|
-
this.discoverTypes(fieldType,
|
|
691
|
+
this.discoverTypes(fieldType, klass, index, parentHasViewTag || fieldHasViewTag);
|
|
686
692
|
}
|
|
687
693
|
else {
|
|
688
694
|
const type = Object.values(fieldType)[0];
|
|
@@ -690,10 +696,44 @@ class TypeContext {
|
|
|
690
696
|
if (typeof (type) === "string") {
|
|
691
697
|
continue;
|
|
692
698
|
}
|
|
693
|
-
this.discoverTypes(type, index,
|
|
699
|
+
this.discoverTypes(type, klass, index, parentHasViewTag || fieldHasViewTag);
|
|
694
700
|
}
|
|
695
701
|
}
|
|
696
702
|
}
|
|
703
|
+
/**
|
|
704
|
+
* Keep track of which classes have filters applied.
|
|
705
|
+
* Format: `${typeid}-${parentTypeid}-${parentIndex}`
|
|
706
|
+
*/
|
|
707
|
+
registerFilteredByParent(schema, parentType, parentIndex) {
|
|
708
|
+
const typeid = this.schemas.get(schema) ?? this.schemas.size;
|
|
709
|
+
let key = `${typeid}`;
|
|
710
|
+
if (parentType) {
|
|
711
|
+
key += `-${this.schemas.get(parentType)}`;
|
|
712
|
+
}
|
|
713
|
+
key += `-${parentIndex}`;
|
|
714
|
+
this.parentFiltered[key] = true;
|
|
715
|
+
}
|
|
716
|
+
debug() {
|
|
717
|
+
let parentFiltered = "";
|
|
718
|
+
for (const key in this.parentFiltered) {
|
|
719
|
+
const keys = key.split("-").map(Number);
|
|
720
|
+
const fieldIndex = keys.pop();
|
|
721
|
+
parentFiltered += `\n\t\t`;
|
|
722
|
+
parentFiltered += `${key}: ${keys.reverse().map((id, i) => {
|
|
723
|
+
const klass = this.types[id];
|
|
724
|
+
const metadata = klass[Symbol.metadata];
|
|
725
|
+
let txt = klass.name;
|
|
726
|
+
if (i === 0) {
|
|
727
|
+
txt += `[${metadata[fieldIndex].name}]`;
|
|
728
|
+
}
|
|
729
|
+
return `${txt}`;
|
|
730
|
+
}).join(" -> ")}`;
|
|
731
|
+
}
|
|
732
|
+
return `TypeContext ->\n` +
|
|
733
|
+
`\tSchema types: ${this.schemas.size}\n` +
|
|
734
|
+
`\thasFilters: ${this.hasFilters}\n` +
|
|
735
|
+
`\tparentFiltered:${parentFiltered}`;
|
|
736
|
+
}
|
|
697
737
|
}
|
|
698
738
|
|
|
699
739
|
function getNormalizedType(type) {
|
|
@@ -938,8 +978,10 @@ function enqueueChangeTree(root, changeTree, changeSet, queueRootIndex = changeT
|
|
|
938
978
|
}
|
|
939
979
|
class ChangeTree {
|
|
940
980
|
constructor(ref) {
|
|
981
|
+
/**
|
|
982
|
+
* Whether this structure is parent of a filtered structure.
|
|
983
|
+
*/
|
|
941
984
|
this.isFiltered = false;
|
|
942
|
-
this.isPartiallyFiltered = false;
|
|
943
985
|
this.indexedOperations = {};
|
|
944
986
|
//
|
|
945
987
|
// TODO:
|
|
@@ -958,37 +1000,17 @@ class ChangeTree {
|
|
|
958
1000
|
//
|
|
959
1001
|
// Does this structure have "filters" declared?
|
|
960
1002
|
//
|
|
961
|
-
|
|
1003
|
+
const metadata = ref.constructor[Symbol.metadata];
|
|
1004
|
+
if (metadata?.[$viewFieldIndexes]) {
|
|
962
1005
|
this.allFilteredChanges = { indexes: {}, operations: [] };
|
|
963
1006
|
this.filteredChanges = { indexes: {}, operations: [] };
|
|
964
1007
|
}
|
|
965
1008
|
}
|
|
966
1009
|
setRoot(root) {
|
|
967
1010
|
this.root = root;
|
|
968
|
-
|
|
969
|
-
const metadata = this.ref.constructor[Symbol.metadata];
|
|
970
|
-
if (this.root.types.hasFilters) {
|
|
971
|
-
//
|
|
972
|
-
// At Schema initialization, the "root" structure might not be available
|
|
973
|
-
// yet, as it only does once the "Encoder" has been set up.
|
|
974
|
-
//
|
|
975
|
-
// So the "parent" may be already set without a "root".
|
|
976
|
-
//
|
|
977
|
-
this.checkIsFiltered(metadata, this.parent, this.parentIndex);
|
|
978
|
-
if (this.isFiltered || this.isPartiallyFiltered) {
|
|
979
|
-
enqueueChangeTree(root, this, 'filteredChanges');
|
|
980
|
-
if (isNewChangeTree) {
|
|
981
|
-
this.root.allFilteredChanges.push(this);
|
|
982
|
-
}
|
|
983
|
-
}
|
|
984
|
-
}
|
|
985
|
-
if (!this.isFiltered) {
|
|
986
|
-
enqueueChangeTree(root, this, 'changes');
|
|
987
|
-
if (isNewChangeTree) {
|
|
988
|
-
this.root.allChanges.push(this);
|
|
989
|
-
}
|
|
990
|
-
}
|
|
1011
|
+
this.checkIsFiltered(this.parent, this.parentIndex);
|
|
991
1012
|
// Recursively set root on child structures
|
|
1013
|
+
const metadata = this.ref.constructor[Symbol.metadata];
|
|
992
1014
|
if (metadata) {
|
|
993
1015
|
metadata[$refTypeFieldIndexes]?.forEach((index) => {
|
|
994
1016
|
const field = metadata[index];
|
|
@@ -1010,39 +1032,21 @@ class ChangeTree {
|
|
|
1010
1032
|
if (!root) {
|
|
1011
1033
|
return;
|
|
1012
1034
|
}
|
|
1013
|
-
const metadata = this.ref.constructor[Symbol.metadata];
|
|
1014
1035
|
// skip if parent is already set
|
|
1015
1036
|
if (root !== this.root) {
|
|
1016
1037
|
this.root = root;
|
|
1017
|
-
|
|
1018
|
-
if (root.types.hasFilters) {
|
|
1019
|
-
this.checkIsFiltered(metadata, parent, parentIndex);
|
|
1020
|
-
if (this.isFiltered || this.isPartiallyFiltered) {
|
|
1021
|
-
enqueueChangeTree(root, this, 'filteredChanges');
|
|
1022
|
-
if (isNewChangeTree) {
|
|
1023
|
-
this.root.allFilteredChanges.push(this);
|
|
1024
|
-
}
|
|
1025
|
-
}
|
|
1026
|
-
}
|
|
1027
|
-
if (!this.isFiltered) {
|
|
1028
|
-
enqueueChangeTree(root, this, 'changes');
|
|
1029
|
-
if (isNewChangeTree) {
|
|
1030
|
-
this.root.allChanges.push(this);
|
|
1031
|
-
}
|
|
1032
|
-
}
|
|
1038
|
+
this.checkIsFiltered(parent, parentIndex);
|
|
1033
1039
|
}
|
|
1034
1040
|
else {
|
|
1035
1041
|
root.add(this);
|
|
1036
1042
|
}
|
|
1037
1043
|
// assign same parent on child structures
|
|
1044
|
+
const metadata = this.ref.constructor[Symbol.metadata];
|
|
1038
1045
|
if (metadata) {
|
|
1039
1046
|
metadata[$refTypeFieldIndexes]?.forEach((index) => {
|
|
1040
1047
|
const field = metadata[index];
|
|
1041
1048
|
const value = this.ref[field.name];
|
|
1042
1049
|
value?.[$changes].setParent(this.ref, root, index);
|
|
1043
|
-
// try { throw new Error(); } catch (e) {
|
|
1044
|
-
// console.log(e.stack);
|
|
1045
|
-
// }
|
|
1046
1050
|
});
|
|
1047
1051
|
}
|
|
1048
1052
|
else if (this.ref[$childType] && typeof (this.ref[$childType]) !== "string") {
|
|
@@ -1135,7 +1139,7 @@ class ChangeTree {
|
|
|
1135
1139
|
//
|
|
1136
1140
|
// - ArraySchema#splice()
|
|
1137
1141
|
//
|
|
1138
|
-
if (this.
|
|
1142
|
+
if (this.filteredChanges !== undefined) {
|
|
1139
1143
|
this._shiftAllChangeIndexes(shiftIndex, startIndex, this.allFilteredChanges);
|
|
1140
1144
|
this._shiftAllChangeIndexes(shiftIndex, startIndex, this.allChanges);
|
|
1141
1145
|
}
|
|
@@ -1164,7 +1168,7 @@ class ChangeTree {
|
|
|
1164
1168
|
}
|
|
1165
1169
|
indexedOperation(index, operation, allChangesIndex = index) {
|
|
1166
1170
|
this.indexedOperations[index] = operation;
|
|
1167
|
-
if (this.filteredChanges) {
|
|
1171
|
+
if (this.filteredChanges !== undefined) {
|
|
1168
1172
|
setOperationAtIndex(this.allFilteredChanges, allChangesIndex);
|
|
1169
1173
|
setOperationAtIndex(this.filteredChanges, index);
|
|
1170
1174
|
enqueueChangeTree(this.root, this, 'filteredChanges');
|
|
@@ -1212,7 +1216,7 @@ class ChangeTree {
|
|
|
1212
1216
|
}
|
|
1213
1217
|
return;
|
|
1214
1218
|
}
|
|
1215
|
-
const changeSet = (this.filteredChanges)
|
|
1219
|
+
const changeSet = (this.filteredChanges !== undefined)
|
|
1216
1220
|
? this.filteredChanges
|
|
1217
1221
|
: this.changes;
|
|
1218
1222
|
this.indexedOperations[index] = operation ?? OPERATION.DELETE;
|
|
@@ -1228,14 +1232,14 @@ class ChangeTree {
|
|
|
1228
1232
|
// - This is due to using the concrete Schema class at decoding time.
|
|
1229
1233
|
// - "Reflected" structures do not have this problem.
|
|
1230
1234
|
//
|
|
1231
|
-
// (
|
|
1235
|
+
// (The property descriptors should NOT be used at decoding time. only at encoding time.)
|
|
1232
1236
|
//
|
|
1233
1237
|
this.root?.remove(previousValue[$changes]);
|
|
1234
1238
|
}
|
|
1235
1239
|
//
|
|
1236
1240
|
// FIXME: this is looking a ugly and repeated
|
|
1237
1241
|
//
|
|
1238
|
-
if (this.filteredChanges) {
|
|
1242
|
+
if (this.filteredChanges !== undefined) {
|
|
1239
1243
|
deleteOperationAtIndex(this.allFilteredChanges, allChangesIndex);
|
|
1240
1244
|
enqueueChangeTree(this.root, this, 'filteredChanges');
|
|
1241
1245
|
}
|
|
@@ -1304,29 +1308,59 @@ class ChangeTree {
|
|
|
1304
1308
|
get changed() {
|
|
1305
1309
|
return (Object.entries(this.indexedOperations).length > 0);
|
|
1306
1310
|
}
|
|
1307
|
-
checkIsFiltered(
|
|
1308
|
-
|
|
1309
|
-
this.
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1311
|
+
checkIsFiltered(parent, parentIndex) {
|
|
1312
|
+
const isNewChangeTree = this.root.add(this);
|
|
1313
|
+
if (this.root.types.hasFilters) {
|
|
1314
|
+
//
|
|
1315
|
+
// At Schema initialization, the "root" structure might not be available
|
|
1316
|
+
// yet, as it only does once the "Encoder" has been set up.
|
|
1317
|
+
//
|
|
1318
|
+
// So the "parent" may be already set without a "root".
|
|
1319
|
+
//
|
|
1320
|
+
this._checkFilteredByParent(parent, parentIndex);
|
|
1321
|
+
if (this.filteredChanges !== undefined) {
|
|
1322
|
+
enqueueChangeTree(this.root, this, 'filteredChanges');
|
|
1323
|
+
if (isNewChangeTree) {
|
|
1324
|
+
this.root.allFilteredChanges.push(this);
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1313
1327
|
}
|
|
1328
|
+
if (!this.isFiltered) {
|
|
1329
|
+
enqueueChangeTree(this.root, this, 'changes');
|
|
1330
|
+
if (isNewChangeTree) {
|
|
1331
|
+
this.root.allChanges.push(this);
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
_checkFilteredByParent(parent, parentIndex) {
|
|
1314
1336
|
// skip if parent is not set
|
|
1315
1337
|
if (!parent) {
|
|
1316
1338
|
return;
|
|
1317
1339
|
}
|
|
1340
|
+
// ArraySchema | MapSchema - get the child type
|
|
1341
|
+
const ref = Metadata.isValidInstance(this.ref)
|
|
1342
|
+
? this.ref
|
|
1343
|
+
: new this.ref[$childType];
|
|
1318
1344
|
if (!Metadata.isValidInstance(parent)) {
|
|
1319
1345
|
const parentChangeTree = parent[$changes];
|
|
1320
1346
|
parent = parentChangeTree.parent;
|
|
1321
1347
|
parentIndex = parentChangeTree.parentIndex;
|
|
1322
1348
|
}
|
|
1323
|
-
const
|
|
1324
|
-
|
|
1349
|
+
const parentConstructor = parent.constructor;
|
|
1350
|
+
let key = `${this.root.types.getTypeId(ref.constructor)}`;
|
|
1351
|
+
if (parentConstructor) {
|
|
1352
|
+
key += `-${this.root.types.schemas.get(parentConstructor)}`;
|
|
1353
|
+
}
|
|
1354
|
+
key += `-${parentIndex}`;
|
|
1355
|
+
this.isFiltered = this.root.types.parentFiltered[key];
|
|
1356
|
+
// const parentMetadata = parentConstructor?.[Symbol.metadata];
|
|
1357
|
+
// this.isFiltered = parentMetadata?.[$viewFieldIndexes]?.includes(parentIndex) || this.root.types.parentFiltered[key];
|
|
1325
1358
|
//
|
|
1326
1359
|
// TODO: refactor this!
|
|
1327
1360
|
//
|
|
1328
1361
|
// swapping `changes` and `filteredChanges` is required here
|
|
1329
1362
|
// because "isFiltered" may not be imedialely available on `change()`
|
|
1363
|
+
// (this happens when instance is detached from root or parent)
|
|
1330
1364
|
//
|
|
1331
1365
|
if (this.isFiltered) {
|
|
1332
1366
|
this.filteredChanges = { indexes: {}, operations: [] };
|
|
@@ -1340,10 +1374,6 @@ class ChangeTree {
|
|
|
1340
1374
|
const allFilteredChanges = this.allFilteredChanges;
|
|
1341
1375
|
this.allFilteredChanges = this.allChanges;
|
|
1342
1376
|
this.allChanges = allFilteredChanges;
|
|
1343
|
-
// console.log("SWAP =>", {
|
|
1344
|
-
// "this.allFilteredChanges": this.allFilteredChanges,
|
|
1345
|
-
// "this.allChanges": this.allChanges
|
|
1346
|
-
// })
|
|
1347
1377
|
}
|
|
1348
1378
|
}
|
|
1349
1379
|
}
|
|
@@ -3231,7 +3261,7 @@ class Schema {
|
|
|
3231
3261
|
const rootChangeTree = ref[$changes];
|
|
3232
3262
|
const root = rootChangeTree.root;
|
|
3233
3263
|
const changeTrees = new Map();
|
|
3234
|
-
|
|
3264
|
+
const instanceRefIds = [];
|
|
3235
3265
|
let totalOperations = 0;
|
|
3236
3266
|
for (const [refId, changes] of Object.entries(root[changeSetName])) {
|
|
3237
3267
|
const changeTree = root.changeTrees[refId];
|
|
@@ -3252,14 +3282,14 @@ class Schema {
|
|
|
3252
3282
|
}
|
|
3253
3283
|
}
|
|
3254
3284
|
if (includeChangeTree) {
|
|
3255
|
-
|
|
3285
|
+
instanceRefIds.push(changeTree.refId);
|
|
3256
3286
|
totalOperations += Object.keys(changes).length;
|
|
3257
3287
|
changeTrees.set(changeTree, parentChangeTrees.reverse());
|
|
3258
3288
|
}
|
|
3259
3289
|
}
|
|
3260
3290
|
output += "---\n";
|
|
3261
3291
|
output += `root refId: ${rootChangeTree.refId}\n`;
|
|
3262
|
-
output += `Total instances: ${
|
|
3292
|
+
output += `Total instances: ${instanceRefIds.length} (refIds: ${instanceRefIds.join(", ")})\n`;
|
|
3263
3293
|
output += `Total changes: ${totalOperations}\n`;
|
|
3264
3294
|
output += "---\n";
|
|
3265
3295
|
// based on root.changes, display a tree of changes that has the "ref" instance as parent
|
|
@@ -3700,7 +3730,7 @@ class Root {
|
|
|
3700
3730
|
delete this.changeTrees[changeTree.refId];
|
|
3701
3731
|
this.removeChangeFromChangeSet("allChanges", changeTree);
|
|
3702
3732
|
this.removeChangeFromChangeSet("changes", changeTree);
|
|
3703
|
-
if (changeTree.
|
|
3733
|
+
if (changeTree.filteredChanges) {
|
|
3704
3734
|
this.removeChangeFromChangeSet("allFilteredChanges", changeTree);
|
|
3705
3735
|
this.removeChangeFromChangeSet("filteredChanges", changeTree);
|
|
3706
3736
|
}
|
|
@@ -4046,6 +4076,7 @@ class ReferenceTracker {
|
|
|
4046
4076
|
clearRefs() {
|
|
4047
4077
|
this.refs.clear();
|
|
4048
4078
|
this.deletedRefs.clear();
|
|
4079
|
+
this.callbacks = {};
|
|
4049
4080
|
this.refCounts = {};
|
|
4050
4081
|
}
|
|
4051
4082
|
// for decoding
|
|
@@ -4710,7 +4741,7 @@ class StateView {
|
|
|
4710
4741
|
}
|
|
4711
4742
|
else {
|
|
4712
4743
|
const isInvisible = this.invisible.has(changeTree);
|
|
4713
|
-
const changeSet = (changeTree.
|
|
4744
|
+
const changeSet = (changeTree.filteredChanges !== undefined)
|
|
4714
4745
|
? changeTree.allFilteredChanges
|
|
4715
4746
|
: changeTree.allChanges;
|
|
4716
4747
|
for (let i = 0, len = changeSet.operations.length; i < len; i++) {
|
|
@@ -4718,7 +4749,7 @@ class StateView {
|
|
|
4718
4749
|
if (index === undefined) {
|
|
4719
4750
|
continue;
|
|
4720
4751
|
} // skip "undefined" indexes
|
|
4721
|
-
const op = changeTree.indexedOperations[index];
|
|
4752
|
+
const op = changeTree.indexedOperations[index] ?? OPERATION.ADD;
|
|
4722
4753
|
const tagAtIndex = metadata?.[index].tag;
|
|
4723
4754
|
if ((isInvisible || // if "invisible", include all
|
|
4724
4755
|
tagAtIndex === undefined || // "all change" with no tag
|
|
@@ -4732,7 +4763,9 @@ class StateView {
|
|
|
4732
4763
|
// Add children of this ChangeTree to this view
|
|
4733
4764
|
changeTree.forEachChild((change, index) => {
|
|
4734
4765
|
// Do not ADD children that don't have the same tag
|
|
4735
|
-
if (metadata &&
|
|
4766
|
+
if (metadata &&
|
|
4767
|
+
metadata[index].tag !== undefined &&
|
|
4768
|
+
metadata[index].tag !== tag) {
|
|
4736
4769
|
return;
|
|
4737
4770
|
}
|
|
4738
4771
|
this.add(change.ref, tag, false);
|
|
@@ -4744,7 +4777,7 @@ class StateView {
|
|
|
4744
4777
|
this.items.add(changeTree);
|
|
4745
4778
|
// add parent's parent
|
|
4746
4779
|
const parentChangeTree = changeTree.parent?.[$changes];
|
|
4747
|
-
if (parentChangeTree && (parentChangeTree.
|
|
4780
|
+
if (parentChangeTree && (parentChangeTree.filteredChanges !== undefined)) {
|
|
4748
4781
|
this.addParent(parentChangeTree, changeTree.parentIndex, tag);
|
|
4749
4782
|
}
|
|
4750
4783
|
// parent is already available, no need to add it!
|