@colyseus/schema 3.0.0-alpha.9 → 3.0.1
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/README.md +148 -62
- package/bin/schema-debug +94 -0
- package/build/cjs/index.js +2222 -1513
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +2223 -1516
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +2225 -1516
- package/lib/Metadata.d.ts +21 -9
- package/lib/Metadata.js +169 -32
- package/lib/Metadata.js.map +1 -1
- package/lib/Reflection.d.ts +19 -4
- package/lib/Reflection.js +66 -31
- package/lib/Reflection.js.map +1 -1
- package/lib/Schema.d.ts +12 -5
- package/lib/Schema.js +57 -56
- package/lib/Schema.js.map +1 -1
- package/lib/annotations.d.ts +31 -34
- package/lib/annotations.js +110 -160
- package/lib/annotations.js.map +1 -1
- package/lib/codegen/api.js +1 -2
- package/lib/codegen/api.js.map +1 -1
- package/lib/codegen/languages/cpp.js +1 -2
- package/lib/codegen/languages/cpp.js.map +1 -1
- package/lib/codegen/languages/csharp.js +9 -46
- package/lib/codegen/languages/csharp.js.map +1 -1
- package/lib/codegen/languages/haxe.js +4 -2
- package/lib/codegen/languages/haxe.js.map +1 -1
- package/lib/codegen/languages/java.js +1 -2
- package/lib/codegen/languages/java.js.map +1 -1
- package/lib/codegen/languages/js.js +1 -2
- package/lib/codegen/languages/js.js.map +1 -1
- package/lib/codegen/languages/lua.js +23 -25
- package/lib/codegen/languages/lua.js.map +1 -1
- package/lib/codegen/languages/ts.js +1 -2
- package/lib/codegen/languages/ts.js.map +1 -1
- package/lib/codegen/parser.js +85 -3
- package/lib/codegen/parser.js.map +1 -1
- package/lib/codegen/types.js +6 -3
- package/lib/codegen/types.js.map +1 -1
- package/lib/decoder/DecodeOperation.d.ts +3 -4
- package/lib/decoder/DecodeOperation.js +35 -17
- package/lib/decoder/DecodeOperation.js.map +1 -1
- package/lib/decoder/Decoder.d.ts +5 -6
- package/lib/decoder/Decoder.js +10 -10
- package/lib/decoder/Decoder.js.map +1 -1
- package/lib/decoder/ReferenceTracker.js +4 -2
- package/lib/decoder/ReferenceTracker.js.map +1 -1
- package/lib/decoder/strategy/RawChanges.js +1 -2
- package/lib/decoder/strategy/RawChanges.js.map +1 -1
- package/lib/decoder/strategy/StateCallbacks.d.ts +44 -11
- package/lib/decoder/strategy/StateCallbacks.js +74 -64
- package/lib/decoder/strategy/StateCallbacks.js.map +1 -1
- package/lib/encoder/ChangeTree.d.ts +28 -20
- package/lib/encoder/ChangeTree.js +242 -188
- package/lib/encoder/ChangeTree.js.map +1 -1
- package/lib/encoder/EncodeOperation.d.ts +3 -6
- package/lib/encoder/EncodeOperation.js +51 -65
- package/lib/encoder/EncodeOperation.js.map +1 -1
- package/lib/encoder/Encoder.d.ts +8 -7
- package/lib/encoder/Encoder.js +128 -79
- package/lib/encoder/Encoder.js.map +1 -1
- package/lib/encoder/Root.d.ts +22 -0
- package/lib/encoder/Root.js +81 -0
- package/lib/encoder/Root.js.map +1 -0
- package/lib/encoder/StateView.d.ts +7 -7
- package/lib/encoder/StateView.js +72 -74
- package/lib/encoder/StateView.js.map +1 -1
- package/lib/encoding/assert.d.ts +7 -6
- package/lib/encoding/assert.js +13 -5
- package/lib/encoding/assert.js.map +1 -1
- package/lib/encoding/decode.d.ts +36 -19
- package/lib/encoding/decode.js +54 -84
- package/lib/encoding/decode.js.map +1 -1
- package/lib/encoding/encode.d.ts +36 -18
- package/lib/encoding/encode.js +61 -48
- package/lib/encoding/encode.js.map +1 -1
- package/lib/encoding/spec.d.ts +4 -5
- package/lib/encoding/spec.js +1 -2
- package/lib/encoding/spec.js.map +1 -1
- package/lib/index.d.ts +10 -9
- package/lib/index.js +24 -17
- package/lib/index.js.map +1 -1
- package/lib/types/HelperTypes.d.ts +34 -2
- package/lib/types/HelperTypes.js.map +1 -1
- package/lib/types/TypeContext.d.ts +29 -0
- package/lib/types/TypeContext.js +151 -0
- package/lib/types/TypeContext.js.map +1 -0
- package/lib/types/custom/ArraySchema.d.ts +2 -2
- package/lib/types/custom/ArraySchema.js +33 -22
- package/lib/types/custom/ArraySchema.js.map +1 -1
- package/lib/types/custom/CollectionSchema.d.ts +2 -2
- package/lib/types/custom/CollectionSchema.js +1 -0
- package/lib/types/custom/CollectionSchema.js.map +1 -1
- package/lib/types/custom/MapSchema.d.ts +18 -16
- package/lib/types/custom/MapSchema.js +12 -4
- package/lib/types/custom/MapSchema.js.map +1 -1
- package/lib/types/custom/SetSchema.d.ts +2 -2
- package/lib/types/custom/SetSchema.js +1 -0
- package/lib/types/custom/SetSchema.js.map +1 -1
- package/lib/types/registry.d.ts +8 -1
- package/lib/types/registry.js +23 -6
- package/lib/types/registry.js.map +1 -1
- package/lib/types/symbols.d.ts +8 -5
- package/lib/types/symbols.js +9 -6
- package/lib/types/symbols.js.map +1 -1
- package/lib/types/utils.js +1 -2
- package/lib/types/utils.js.map +1 -1
- package/lib/utils.js +9 -7
- package/lib/utils.js.map +1 -1
- package/package.json +19 -18
- package/src/Metadata.ts +190 -42
- package/src/Reflection.ts +76 -38
- package/src/Schema.ts +72 -70
- package/src/annotations.ts +156 -202
- package/src/codegen/languages/csharp.ts +8 -47
- package/src/codegen/languages/haxe.ts +4 -0
- package/src/codegen/languages/lua.ts +19 -27
- package/src/codegen/parser.ts +107 -0
- package/src/codegen/types.ts +1 -0
- package/src/decoder/DecodeOperation.ts +43 -15
- package/src/decoder/Decoder.ts +12 -10
- package/src/decoder/ReferenceTracker.ts +5 -3
- package/src/decoder/strategy/StateCallbacks.ts +152 -81
- package/src/encoder/ChangeTree.ts +282 -209
- package/src/encoder/EncodeOperation.ts +78 -78
- package/src/encoder/Encoder.ts +152 -88
- package/src/encoder/Root.ts +93 -0
- package/src/encoder/StateView.ts +80 -88
- package/src/encoding/assert.ts +17 -8
- package/src/encoding/decode.ts +73 -93
- package/src/encoding/encode.ts +76 -45
- package/src/encoding/spec.ts +3 -5
- package/src/index.ts +12 -20
- package/src/types/HelperTypes.ts +54 -2
- package/src/types/TypeContext.ts +175 -0
- package/src/types/custom/ArraySchema.ts +49 -19
- package/src/types/custom/CollectionSchema.ts +1 -0
- package/src/types/custom/MapSchema.ts +30 -17
- package/src/types/custom/SetSchema.ts +1 -0
- package/src/types/registry.ts +22 -3
- package/src/types/symbols.ts +10 -7
- package/src/utils.ts +7 -3
- package/lib/Decoder.d.ts +0 -16
- package/lib/Decoder.js +0 -182
- package/lib/Decoder.js.map +0 -1
- package/lib/Encoder.d.ts +0 -13
- package/lib/Encoder.js +0 -79
- package/lib/Encoder.js.map +0 -1
- package/lib/changes/ChangeSet.d.ts +0 -12
- package/lib/changes/ChangeSet.js +0 -35
- package/lib/changes/ChangeSet.js.map +0 -1
- package/lib/changes/ChangeTree.d.ts +0 -53
- package/lib/changes/ChangeTree.js +0 -202
- package/lib/changes/ChangeTree.js.map +0 -1
- package/lib/changes/DecodeOperation.d.ts +0 -15
- package/lib/changes/DecodeOperation.js +0 -186
- package/lib/changes/DecodeOperation.js.map +0 -1
- package/lib/changes/EncodeOperation.d.ts +0 -18
- package/lib/changes/EncodeOperation.js +0 -130
- package/lib/changes/EncodeOperation.js.map +0 -1
- package/lib/changes/ReferenceTracker.d.ts +0 -14
- package/lib/changes/ReferenceTracker.js +0 -83
- package/lib/changes/ReferenceTracker.js.map +0 -1
- package/lib/changes/consts.d.ts +0 -14
- package/lib/changes/consts.js +0 -18
- package/lib/changes/consts.js.map +0 -1
- package/lib/decoding/decode.d.ts +0 -48
- package/lib/decoding/decode.js +0 -267
- package/lib/decoding/decode.js.map +0 -1
- package/lib/ecs.d.ts +0 -11
- package/lib/ecs.js +0 -160
- package/lib/ecs.js.map +0 -1
- package/lib/filters/index.d.ts +0 -8
- package/lib/filters/index.js +0 -24
- package/lib/filters/index.js.map +0 -1
- package/lib/spec.d.ts +0 -13
- package/lib/spec.js +0 -42
- package/lib/spec.js.map +0 -1
- package/lib/types/ArraySchema.d.ts +0 -238
- package/lib/types/ArraySchema.js +0 -555
- package/lib/types/ArraySchema.js.map +0 -1
- package/lib/types/CollectionSchema.d.ts +0 -35
- package/lib/types/CollectionSchema.js +0 -150
- package/lib/types/CollectionSchema.js.map +0 -1
- package/lib/types/MapSchema.d.ts +0 -38
- package/lib/types/MapSchema.js +0 -215
- package/lib/types/MapSchema.js.map +0 -1
- package/lib/types/SetSchema.d.ts +0 -32
- package/lib/types/SetSchema.js +0 -162
- package/lib/types/SetSchema.js.map +0 -1
- package/lib/types/typeRegistry.d.ts +0 -5
- package/lib/types/typeRegistry.js +0 -13
- package/lib/types/typeRegistry.js.map +0 -1
- package/lib/usage.d.ts +0 -1
- package/lib/usage.js +0 -22
- package/lib/usage.js.map +0 -1
- package/lib/v3.d.ts +0 -1
- package/lib/v3.js +0 -427
- package/lib/v3.js.map +0 -1
- package/lib/v3_experiment.d.ts +0 -1
- package/lib/v3_experiment.js +0 -407
- package/lib/v3_experiment.js.map +0 -1
|
@@ -1,95 +1,80 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var _a;
|
|
3
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.ChangeTree =
|
|
3
|
+
exports.ChangeTree = void 0;
|
|
4
|
+
exports.setOperationAtIndex = setOperationAtIndex;
|
|
5
|
+
exports.deleteOperationAtIndex = deleteOperationAtIndex;
|
|
5
6
|
const spec_1 = require("../encoding/spec");
|
|
6
7
|
const symbols_1 = require("../types/symbols");
|
|
7
8
|
const Metadata_1 = require("../Metadata");
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
// all changes
|
|
13
|
-
this.allChanges = new Map();
|
|
14
|
-
this.allFilteredChanges = new Map();
|
|
15
|
-
// pending changes to be encoded
|
|
16
|
-
this.changes = new Map();
|
|
17
|
-
this.filteredChanges = new Map();
|
|
9
|
+
function setOperationAtIndex(changeSet, index) {
|
|
10
|
+
const operationsIndex = changeSet.indexes[index];
|
|
11
|
+
if (operationsIndex === undefined) {
|
|
12
|
+
changeSet.indexes[index] = changeSet.operations.push(index) - 1;
|
|
18
13
|
}
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
else {
|
|
15
|
+
changeSet.operations[operationsIndex] = index;
|
|
21
16
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const refCount = this.refCount.get(changeTree);
|
|
28
|
-
if (refCount <= 1) {
|
|
29
|
-
this.allChanges.delete(changeTree);
|
|
30
|
-
this.changes.delete(changeTree);
|
|
31
|
-
if (changeTree.isFiltered || changeTree.isPartiallyFiltered) {
|
|
32
|
-
this.allFilteredChanges.delete(changeTree);
|
|
33
|
-
this.filteredChanges.delete(changeTree);
|
|
34
|
-
}
|
|
35
|
-
this.refCount.delete(changeTree);
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
this.refCount.set(changeTree, refCount - 1);
|
|
39
|
-
}
|
|
40
|
-
changeTree.forEachChild((child, _) => this.remove(child));
|
|
17
|
+
}
|
|
18
|
+
function deleteOperationAtIndex(changeSet, index) {
|
|
19
|
+
const operationsIndex = changeSet.indexes[index];
|
|
20
|
+
if (operationsIndex !== undefined) {
|
|
21
|
+
changeSet.operations[operationsIndex] = undefined;
|
|
41
22
|
}
|
|
42
|
-
|
|
43
|
-
|
|
23
|
+
delete changeSet.indexes[index];
|
|
24
|
+
}
|
|
25
|
+
function enqueueChangeTree(root, changeTree, changeSet, queueRootIndex = changeTree[changeSet].queueRootIndex) {
|
|
26
|
+
if (root && root[changeSet][queueRootIndex] !== changeTree) {
|
|
27
|
+
changeTree[changeSet].queueRootIndex = root[changeSet].push(changeTree) - 1;
|
|
44
28
|
}
|
|
45
29
|
}
|
|
46
|
-
exports.Root = Root;
|
|
47
30
|
class ChangeTree {
|
|
48
|
-
static { _a = symbols_1.$isNew; }
|
|
49
|
-
;
|
|
50
31
|
constructor(ref) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
this.
|
|
55
|
-
this.
|
|
56
|
-
|
|
57
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Whether this structure is parent of a filtered structure.
|
|
34
|
+
*/
|
|
35
|
+
this.isFiltered = false;
|
|
36
|
+
this.indexedOperations = {};
|
|
37
|
+
//
|
|
38
|
+
// TODO:
|
|
39
|
+
// try storing the index + operation per item.
|
|
40
|
+
// example: 1024 & 1025 => ADD, 1026 => DELETE
|
|
41
|
+
//
|
|
42
|
+
// => https://chatgpt.com/share/67107d0c-bc20-8004-8583-83b17dd7c196
|
|
43
|
+
//
|
|
44
|
+
this.changes = { indexes: {}, operations: [] };
|
|
45
|
+
this.allChanges = { indexes: {}, operations: [] };
|
|
46
|
+
/**
|
|
47
|
+
* Is this a new instance? Used on ArraySchema to determine OPERATION.MOVE_AND_ADD operation.
|
|
48
|
+
*/
|
|
49
|
+
this.isNew = true;
|
|
58
50
|
this.ref = ref;
|
|
51
|
+
//
|
|
52
|
+
// Does this structure have "filters" declared?
|
|
53
|
+
//
|
|
54
|
+
const metadata = ref.constructor[Symbol.metadata];
|
|
55
|
+
if (metadata?.[symbols_1.$viewFieldIndexes]) {
|
|
56
|
+
this.allFilteredChanges = { indexes: {}, operations: [] };
|
|
57
|
+
this.filteredChanges = { indexes: {}, operations: [] };
|
|
58
|
+
}
|
|
59
59
|
}
|
|
60
60
|
setRoot(root) {
|
|
61
61
|
this.root = root;
|
|
62
|
-
this.root.add(this);
|
|
63
|
-
//
|
|
64
|
-
// At Schema initialization, the "root" structure might not be available
|
|
65
|
-
// yet, as it only does once the "Encoder" has been set up.
|
|
66
|
-
//
|
|
67
|
-
// So the "parent" may be already set without a "root".
|
|
68
|
-
//
|
|
69
62
|
this.checkIsFiltered(this.parent, this.parentIndex);
|
|
70
|
-
//
|
|
71
|
-
this.
|
|
72
|
-
if (
|
|
73
|
-
|
|
63
|
+
// Recursively set root on child structures
|
|
64
|
+
const metadata = this.ref.constructor[Symbol.metadata];
|
|
65
|
+
if (metadata) {
|
|
66
|
+
metadata[symbols_1.$refTypeFieldIndexes]?.forEach((index) => {
|
|
67
|
+
const field = metadata[index];
|
|
68
|
+
const value = this.ref[field.name];
|
|
69
|
+
value?.[symbols_1.$changes].setRoot(root);
|
|
70
|
+
});
|
|
74
71
|
}
|
|
75
|
-
if (this.
|
|
76
|
-
|
|
77
|
-
this.
|
|
78
|
-
|
|
79
|
-
|
|
72
|
+
else if (this.ref[symbols_1.$childType] && typeof (this.ref[symbols_1.$childType]) !== "string") {
|
|
73
|
+
// MapSchema / ArraySchema, etc.
|
|
74
|
+
this.ref.forEach((value, key) => {
|
|
75
|
+
value[symbols_1.$changes].setRoot(root);
|
|
76
|
+
});
|
|
80
77
|
}
|
|
81
|
-
if (!this.isFiltered) {
|
|
82
|
-
this.root.allChanges.set(this, this.allChanges);
|
|
83
|
-
}
|
|
84
|
-
this.forEachChild((changeTree, _) => {
|
|
85
|
-
changeTree.setRoot(root);
|
|
86
|
-
});
|
|
87
|
-
// this.allChanges.forEach((_, index) => {
|
|
88
|
-
// const childRef = this.ref[$getByIndex](index);
|
|
89
|
-
// if (childRef && childRef[$changes]) {
|
|
90
|
-
// childRef[$changes].setRoot(root);
|
|
91
|
-
// }
|
|
92
|
-
// });
|
|
93
78
|
}
|
|
94
79
|
setParent(parent, root, parentIndex) {
|
|
95
80
|
this.parent = parent;
|
|
@@ -98,83 +83,86 @@ class ChangeTree {
|
|
|
98
83
|
if (!root) {
|
|
99
84
|
return;
|
|
100
85
|
}
|
|
101
|
-
root.add(this);
|
|
102
86
|
// skip if parent is already set
|
|
103
|
-
if (root
|
|
104
|
-
this.
|
|
105
|
-
|
|
106
|
-
});
|
|
107
|
-
return;
|
|
87
|
+
if (root !== this.root) {
|
|
88
|
+
this.root = root;
|
|
89
|
+
this.checkIsFiltered(parent, parentIndex);
|
|
108
90
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
if (!this.isFiltered) {
|
|
112
|
-
this.root.changes.set(this, this.changes);
|
|
91
|
+
else {
|
|
92
|
+
root.add(this);
|
|
113
93
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
94
|
+
// assign same parent on child structures
|
|
95
|
+
const metadata = this.ref.constructor[Symbol.metadata];
|
|
96
|
+
if (metadata) {
|
|
97
|
+
metadata[symbols_1.$refTypeFieldIndexes]?.forEach((index) => {
|
|
98
|
+
const field = metadata[index];
|
|
99
|
+
const value = this.ref[field.name];
|
|
100
|
+
value?.[symbols_1.$changes].setParent(this.ref, root, index);
|
|
101
|
+
});
|
|
117
102
|
}
|
|
118
|
-
else {
|
|
119
|
-
|
|
103
|
+
else if (this.ref[symbols_1.$childType] && typeof (this.ref[symbols_1.$childType]) !== "string") {
|
|
104
|
+
// MapSchema / ArraySchema, etc.
|
|
105
|
+
this.ref.forEach((value, key) => {
|
|
106
|
+
value[symbols_1.$changes].setParent(this.ref, root, this.indexes[key] ?? key);
|
|
107
|
+
});
|
|
120
108
|
}
|
|
121
|
-
this.ensureRefId();
|
|
122
|
-
this.forEachChild((changeTree, atIndex) => {
|
|
123
|
-
changeTree.setParent(this.ref, root, atIndex);
|
|
124
|
-
});
|
|
125
109
|
}
|
|
126
110
|
forEachChild(callback) {
|
|
127
111
|
//
|
|
128
112
|
// assign same parent on child structures
|
|
129
113
|
//
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
const value = this.ref[field];
|
|
135
|
-
if (value
|
|
136
|
-
callback(value[symbols_1.$changes],
|
|
114
|
+
const metadata = this.ref.constructor[Symbol.metadata];
|
|
115
|
+
if (metadata) {
|
|
116
|
+
metadata[symbols_1.$refTypeFieldIndexes]?.forEach((index) => {
|
|
117
|
+
const field = metadata[index];
|
|
118
|
+
const value = this.ref[field.name];
|
|
119
|
+
if (value) {
|
|
120
|
+
callback(value[symbols_1.$changes], index);
|
|
137
121
|
}
|
|
138
|
-
}
|
|
122
|
+
});
|
|
139
123
|
}
|
|
140
|
-
else if (typeof (this.ref)
|
|
124
|
+
else if (this.ref[symbols_1.$childType] && typeof (this.ref[symbols_1.$childType]) !== "string") {
|
|
141
125
|
// MapSchema / ArraySchema, etc.
|
|
142
126
|
this.ref.forEach((value, key) => {
|
|
143
|
-
|
|
144
|
-
callback(value[symbols_1.$changes], this.ref[symbols_1.$changes].indexes[key]);
|
|
145
|
-
}
|
|
127
|
+
callback(value[symbols_1.$changes], this.indexes[key] ?? key);
|
|
146
128
|
});
|
|
147
129
|
}
|
|
148
130
|
}
|
|
149
131
|
operation(op) {
|
|
150
|
-
|
|
151
|
-
this.
|
|
132
|
+
// operations without index use negative values to represent them
|
|
133
|
+
// this is checked during .encode() time.
|
|
134
|
+
this.changes.operations.push(-op);
|
|
135
|
+
enqueueChangeTree(this.root, this, 'changes');
|
|
152
136
|
}
|
|
153
137
|
change(index, operation = spec_1.OPERATION.ADD) {
|
|
154
|
-
const metadata = this.ref
|
|
155
|
-
const isFiltered = this.isFiltered || (metadata
|
|
138
|
+
const metadata = this.ref.constructor[Symbol.metadata];
|
|
139
|
+
const isFiltered = this.isFiltered || (metadata?.[index]?.tag !== undefined);
|
|
156
140
|
const changeSet = (isFiltered)
|
|
157
141
|
? this.filteredChanges
|
|
158
142
|
: this.changes;
|
|
159
|
-
const previousOperation =
|
|
143
|
+
const previousOperation = this.indexedOperations[index];
|
|
160
144
|
if (!previousOperation || previousOperation === spec_1.OPERATION.DELETE) {
|
|
161
145
|
const op = (!previousOperation)
|
|
162
146
|
? operation
|
|
163
147
|
: (previousOperation === spec_1.OPERATION.DELETE)
|
|
164
148
|
? spec_1.OPERATION.DELETE_AND_ADD
|
|
165
149
|
: operation;
|
|
166
|
-
|
|
150
|
+
//
|
|
151
|
+
// TODO: are DELETE operations being encoded as ADD here ??
|
|
152
|
+
//
|
|
153
|
+
this.indexedOperations[index] = op;
|
|
167
154
|
}
|
|
168
|
-
|
|
169
|
-
// TODO: are DELETE operations being encoded as ADD here ??
|
|
170
|
-
//
|
|
155
|
+
setOperationAtIndex(changeSet, index);
|
|
171
156
|
if (isFiltered) {
|
|
172
|
-
this.allFilteredChanges
|
|
173
|
-
this.root
|
|
157
|
+
setOperationAtIndex(this.allFilteredChanges, index);
|
|
158
|
+
if (this.root) {
|
|
159
|
+
enqueueChangeTree(this.root, this, 'filteredChanges');
|
|
160
|
+
enqueueChangeTree(this.root, this, 'allFilteredChanges');
|
|
161
|
+
}
|
|
174
162
|
}
|
|
175
163
|
else {
|
|
176
|
-
this.allChanges
|
|
177
|
-
this.root
|
|
164
|
+
setOperationAtIndex(this.allChanges, index);
|
|
165
|
+
enqueueChangeTree(this.root, this, 'changes');
|
|
178
166
|
}
|
|
179
167
|
}
|
|
180
168
|
shiftChangeIndexes(shiftIndex) {
|
|
@@ -186,12 +174,15 @@ class ChangeTree {
|
|
|
186
174
|
const changeSet = (this.isFiltered)
|
|
187
175
|
? this.filteredChanges
|
|
188
176
|
: this.changes;
|
|
189
|
-
const
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
177
|
+
const newIndexedOperations = {};
|
|
178
|
+
const newIndexes = {};
|
|
179
|
+
for (const index in this.indexedOperations) {
|
|
180
|
+
newIndexedOperations[Number(index) + shiftIndex] = this.indexedOperations[index];
|
|
181
|
+
newIndexes[Number(index) + shiftIndex] = changeSet[index];
|
|
194
182
|
}
|
|
183
|
+
this.indexedOperations = newIndexedOperations;
|
|
184
|
+
changeSet.indexes = newIndexes;
|
|
185
|
+
changeSet.operations = changeSet.operations.map((index) => index + shiftIndex);
|
|
195
186
|
}
|
|
196
187
|
shiftAllChangeIndexes(shiftIndex, startIndex = 0) {
|
|
197
188
|
//
|
|
@@ -199,7 +190,7 @@ class ChangeTree {
|
|
|
199
190
|
//
|
|
200
191
|
// - ArraySchema#splice()
|
|
201
192
|
//
|
|
202
|
-
if (this.
|
|
193
|
+
if (this.filteredChanges !== undefined) {
|
|
203
194
|
this._shiftAllChangeIndexes(shiftIndex, startIndex, this.allFilteredChanges);
|
|
204
195
|
this._shiftAllChangeIndexes(shiftIndex, startIndex, this.allChanges);
|
|
205
196
|
}
|
|
@@ -207,33 +198,42 @@ class ChangeTree {
|
|
|
207
198
|
this._shiftAllChangeIndexes(shiftIndex, startIndex, this.allChanges);
|
|
208
199
|
}
|
|
209
200
|
}
|
|
210
|
-
_shiftAllChangeIndexes(shiftIndex, startIndex = 0,
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
201
|
+
_shiftAllChangeIndexes(shiftIndex, startIndex = 0, changeSet) {
|
|
202
|
+
const newIndexes = {};
|
|
203
|
+
for (const key in changeSet.indexes) {
|
|
204
|
+
const index = changeSet.indexes[key];
|
|
205
|
+
if (index > startIndex) {
|
|
206
|
+
newIndexes[Number(key) + shiftIndex] = index;
|
|
216
207
|
}
|
|
217
|
-
|
|
208
|
+
else {
|
|
209
|
+
newIndexes[key] = index;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
changeSet.indexes = newIndexes;
|
|
213
|
+
for (let i = 0; i < changeSet.operations.length; i++) {
|
|
214
|
+
const index = changeSet.operations[i];
|
|
215
|
+
if (index > startIndex) {
|
|
216
|
+
changeSet.operations[i] = index + shiftIndex;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
218
219
|
}
|
|
219
220
|
indexedOperation(index, operation, allChangesIndex = index) {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
this.
|
|
224
|
-
this.
|
|
225
|
-
this.root?.filteredChanges.set(this, this.filteredChanges);
|
|
221
|
+
this.indexedOperations[index] = operation;
|
|
222
|
+
if (this.filteredChanges !== undefined) {
|
|
223
|
+
setOperationAtIndex(this.allFilteredChanges, allChangesIndex);
|
|
224
|
+
setOperationAtIndex(this.filteredChanges, index);
|
|
225
|
+
enqueueChangeTree(this.root, this, 'filteredChanges');
|
|
226
226
|
}
|
|
227
227
|
else {
|
|
228
|
-
this.allChanges
|
|
229
|
-
this.changes
|
|
230
|
-
this.root
|
|
228
|
+
setOperationAtIndex(this.allChanges, allChangesIndex);
|
|
229
|
+
setOperationAtIndex(this.changes, index);
|
|
230
|
+
enqueueChangeTree(this.root, this, 'changes');
|
|
231
231
|
}
|
|
232
232
|
}
|
|
233
233
|
getType(index) {
|
|
234
234
|
if (Metadata_1.Metadata.isValidInstance(this.ref)) {
|
|
235
|
-
const metadata = this.ref
|
|
236
|
-
return metadata[
|
|
235
|
+
const metadata = this.ref.constructor[Symbol.metadata];
|
|
236
|
+
return metadata[index].type;
|
|
237
237
|
}
|
|
238
238
|
else {
|
|
239
239
|
//
|
|
@@ -246,8 +246,7 @@ class ChangeTree {
|
|
|
246
246
|
}
|
|
247
247
|
}
|
|
248
248
|
getChange(index) {
|
|
249
|
-
|
|
250
|
-
return this.changes.get(index) ?? this.filteredChanges.get(index);
|
|
249
|
+
return this.indexedOperations[index];
|
|
251
250
|
}
|
|
252
251
|
//
|
|
253
252
|
// used during `.encode()`
|
|
@@ -268,16 +267,14 @@ class ChangeTree {
|
|
|
268
267
|
}
|
|
269
268
|
return;
|
|
270
269
|
}
|
|
271
|
-
const
|
|
272
|
-
const isFiltered = this.isFiltered || (metadata && metadata[metadata[index]].tag !== undefined);
|
|
273
|
-
const changeSet = (isFiltered)
|
|
270
|
+
const changeSet = (this.filteredChanges !== undefined)
|
|
274
271
|
? this.filteredChanges
|
|
275
272
|
: this.changes;
|
|
273
|
+
this.indexedOperations[index] = operation ?? spec_1.OPERATION.DELETE;
|
|
274
|
+
setOperationAtIndex(changeSet, index);
|
|
276
275
|
const previousValue = this.getValue(index);
|
|
277
|
-
changeSet.set(index, operation ?? spec_1.OPERATION.DELETE);
|
|
278
276
|
// remove `root` reference
|
|
279
277
|
if (previousValue && previousValue[symbols_1.$changes]) {
|
|
280
|
-
previousValue[symbols_1.$changes].root = undefined;
|
|
281
278
|
//
|
|
282
279
|
// FIXME: this.root is "undefined"
|
|
283
280
|
//
|
|
@@ -286,27 +283,31 @@ class ChangeTree {
|
|
|
286
283
|
// - This is due to using the concrete Schema class at decoding time.
|
|
287
284
|
// - "Reflected" structures do not have this problem.
|
|
288
285
|
//
|
|
289
|
-
// (
|
|
286
|
+
// (The property descriptors should NOT be used at decoding time. only at encoding time.)
|
|
290
287
|
//
|
|
291
288
|
this.root?.remove(previousValue[symbols_1.$changes]);
|
|
292
289
|
}
|
|
293
290
|
//
|
|
294
|
-
// FIXME: this is looking a
|
|
291
|
+
// FIXME: this is looking a ugly and repeated
|
|
295
292
|
//
|
|
296
|
-
if (
|
|
297
|
-
this.
|
|
298
|
-
this.
|
|
293
|
+
if (this.filteredChanges !== undefined) {
|
|
294
|
+
deleteOperationAtIndex(this.allFilteredChanges, allChangesIndex);
|
|
295
|
+
enqueueChangeTree(this.root, this, 'filteredChanges');
|
|
299
296
|
}
|
|
300
297
|
else {
|
|
301
|
-
this.
|
|
302
|
-
this.
|
|
298
|
+
deleteOperationAtIndex(this.allChanges, allChangesIndex);
|
|
299
|
+
enqueueChangeTree(this.root, this, 'changes');
|
|
303
300
|
}
|
|
304
301
|
}
|
|
305
302
|
endEncode() {
|
|
306
|
-
this.
|
|
303
|
+
this.indexedOperations = {};
|
|
304
|
+
// // clear changes
|
|
305
|
+
// this.changes.indexes = {};
|
|
306
|
+
// this.changes.operations.length = 0;
|
|
307
|
+
// ArraySchema and MapSchema have a custom "encode end" method
|
|
307
308
|
this.ref[symbols_1.$onEncodeEnd]?.();
|
|
308
309
|
// Not a new instance anymore
|
|
309
|
-
|
|
310
|
+
this.isNew = false;
|
|
310
311
|
}
|
|
311
312
|
discard(discardAll = false) {
|
|
312
313
|
//
|
|
@@ -315,13 +316,22 @@ class ChangeTree {
|
|
|
315
316
|
// REPLACE in case same key is used on next patches.
|
|
316
317
|
//
|
|
317
318
|
this.ref[symbols_1.$onEncodeEnd]?.();
|
|
318
|
-
this.
|
|
319
|
-
this.
|
|
320
|
-
|
|
321
|
-
this.
|
|
319
|
+
this.indexedOperations = {};
|
|
320
|
+
this.changes.indexes = {};
|
|
321
|
+
this.changes.operations.length = 0;
|
|
322
|
+
this.changes.queueRootIndex = undefined;
|
|
323
|
+
if (this.filteredChanges !== undefined) {
|
|
324
|
+
this.filteredChanges.indexes = {};
|
|
325
|
+
this.filteredChanges.operations.length = 0;
|
|
326
|
+
this.filteredChanges.queueRootIndex = undefined;
|
|
327
|
+
}
|
|
322
328
|
if (discardAll) {
|
|
323
|
-
this.allChanges.
|
|
324
|
-
this.
|
|
329
|
+
this.allChanges.indexes = {};
|
|
330
|
+
this.allChanges.operations.length = 0;
|
|
331
|
+
if (this.allFilteredChanges !== undefined) {
|
|
332
|
+
this.allFilteredChanges.indexes = {};
|
|
333
|
+
this.allFilteredChanges.operations.length = 0;
|
|
334
|
+
}
|
|
325
335
|
// remove children references
|
|
326
336
|
this.forEachChild((changeTree, _) => this.root?.remove(changeTree));
|
|
327
337
|
}
|
|
@@ -330,12 +340,13 @@ class ChangeTree {
|
|
|
330
340
|
* Recursively discard all changes from this, and child structures.
|
|
331
341
|
*/
|
|
332
342
|
discardAll() {
|
|
333
|
-
this.
|
|
334
|
-
|
|
343
|
+
const keys = Object.keys(this.indexedOperations);
|
|
344
|
+
for (let i = 0, len = keys.length; i < len; i++) {
|
|
345
|
+
const value = this.getValue(Number(keys[i]));
|
|
335
346
|
if (value && value[symbols_1.$changes]) {
|
|
336
347
|
value[symbols_1.$changes].discardAll();
|
|
337
348
|
}
|
|
338
|
-
}
|
|
349
|
+
}
|
|
339
350
|
this.discard();
|
|
340
351
|
}
|
|
341
352
|
ensureRefId() {
|
|
@@ -346,36 +357,79 @@ class ChangeTree {
|
|
|
346
357
|
this.refId = this.root.getNextUniqueId();
|
|
347
358
|
}
|
|
348
359
|
get changed() {
|
|
349
|
-
return this.
|
|
360
|
+
return (Object.entries(this.indexedOperations).length > 0);
|
|
350
361
|
}
|
|
351
362
|
checkIsFiltered(parent, parentIndex) {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
this.
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
363
|
+
const isNewChangeTree = this.root.add(this);
|
|
364
|
+
if (this.root.types.hasFilters) {
|
|
365
|
+
//
|
|
366
|
+
// At Schema initialization, the "root" structure might not be available
|
|
367
|
+
// yet, as it only does once the "Encoder" has been set up.
|
|
368
|
+
//
|
|
369
|
+
// So the "parent" may be already set without a "root".
|
|
370
|
+
//
|
|
371
|
+
this._checkFilteredByParent(parent, parentIndex);
|
|
372
|
+
if (this.filteredChanges !== undefined) {
|
|
373
|
+
enqueueChangeTree(this.root, this, 'filteredChanges');
|
|
374
|
+
if (isNewChangeTree) {
|
|
375
|
+
this.root.allFilteredChanges.push(this);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
if (!this.isFiltered) {
|
|
380
|
+
enqueueChangeTree(this.root, this, 'changes');
|
|
381
|
+
if (isNewChangeTree) {
|
|
382
|
+
this.root.allChanges.push(this);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
_checkFilteredByParent(parent, parentIndex) {
|
|
387
|
+
// skip if parent is not set
|
|
388
|
+
if (!parent) {
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
//
|
|
392
|
+
// ArraySchema | MapSchema - get the child type
|
|
393
|
+
// (if refType is typeof string, the parentFiltered[key] below will always be invalid)
|
|
394
|
+
//
|
|
395
|
+
const refType = Metadata_1.Metadata.isValidInstance(this.ref)
|
|
396
|
+
? this.ref.constructor
|
|
397
|
+
: this.ref[symbols_1.$childType];
|
|
398
|
+
if (!Metadata_1.Metadata.isValidInstance(parent)) {
|
|
399
|
+
const parentChangeTree = parent[symbols_1.$changes];
|
|
400
|
+
parent = parentChangeTree.parent;
|
|
401
|
+
parentIndex = parentChangeTree.parentIndex;
|
|
402
|
+
}
|
|
403
|
+
const parentConstructor = parent.constructor;
|
|
404
|
+
let key = `${this.root.types.getTypeId(refType)}`;
|
|
405
|
+
if (parentConstructor) {
|
|
406
|
+
key += `-${this.root.types.schemas.get(parentConstructor)}`;
|
|
407
|
+
}
|
|
408
|
+
key += `-${parentIndex}`;
|
|
409
|
+
this.isFiltered = parent[symbols_1.$changes].isFiltered // in case parent is already filtered
|
|
410
|
+
|| this.root.types.parentFiltered[key];
|
|
411
|
+
// const parentMetadata = parentConstructor?.[Symbol.metadata];
|
|
412
|
+
// this.isFiltered = parentMetadata?.[$viewFieldIndexes]?.includes(parentIndex) || this.root.types.parentFiltered[key];
|
|
364
413
|
//
|
|
365
414
|
// TODO: refactor this!
|
|
366
415
|
//
|
|
367
416
|
// swapping `changes` and `filteredChanges` is required here
|
|
368
417
|
// because "isFiltered" may not be imedialely available on `change()`
|
|
418
|
+
// (this happens when instance is detached from root or parent)
|
|
369
419
|
//
|
|
370
|
-
if (this.isFiltered
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
this.changes
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
420
|
+
if (this.isFiltered) {
|
|
421
|
+
this.filteredChanges = { indexes: {}, operations: [] };
|
|
422
|
+
this.allFilteredChanges = { indexes: {}, operations: [] };
|
|
423
|
+
if (this.changes.operations.length > 0) {
|
|
424
|
+
// swap changes reference
|
|
425
|
+
const changes = this.changes;
|
|
426
|
+
this.changes = this.filteredChanges;
|
|
427
|
+
this.filteredChanges = changes;
|
|
428
|
+
// swap "all changes" reference
|
|
429
|
+
const allFilteredChanges = this.allFilteredChanges;
|
|
430
|
+
this.allFilteredChanges = this.allChanges;
|
|
431
|
+
this.allChanges = allFilteredChanges;
|
|
432
|
+
}
|
|
379
433
|
}
|
|
380
434
|
}
|
|
381
435
|
}
|