@colyseus/schema 3.0.0-alpha.3 → 3.0.0-alpha.31
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 +131 -61
- package/build/cjs/index.js +966 -563
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +965 -562
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +966 -563
- package/lib/Metadata.d.ts +15 -4
- package/lib/Metadata.js +86 -18
- package/lib/Metadata.js.map +1 -1
- package/lib/Reflection.d.ts +2 -3
- package/lib/Reflection.js +24 -28
- package/lib/Reflection.js.map +1 -1
- package/lib/Schema.d.ts +2 -2
- package/lib/Schema.js +28 -41
- package/lib/Schema.js.map +1 -1
- package/lib/annotations.d.ts +1 -21
- package/lib/annotations.js +73 -153
- package/lib/annotations.js.map +1 -1
- package/lib/bench_encode.d.ts +1 -0
- package/lib/bench_encode.js +142 -0
- package/lib/bench_encode.js.map +1 -0
- 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 +1 -2
- package/lib/codegen/languages/csharp.js.map +1 -1
- package/lib/codegen/languages/haxe.js +1 -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 +1 -2
- 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 +2 -3
- package/lib/codegen/parser.js.map +1 -1
- package/lib/codegen/types.js +3 -3
- package/lib/codegen/types.js.map +1 -1
- package/lib/debug.d.ts +1 -0
- package/lib/debug.js +52 -0
- package/lib/debug.js.map +1 -0
- package/lib/decoder/DecodeOperation.d.ts +0 -1
- package/lib/decoder/DecodeOperation.js +23 -11
- package/lib/decoder/DecodeOperation.js.map +1 -1
- package/lib/decoder/Decoder.d.ts +6 -7
- package/lib/decoder/Decoder.js +8 -8
- package/lib/decoder/Decoder.js.map +1 -1
- package/lib/decoder/ReferenceTracker.js +3 -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 +75 -65
- package/lib/decoder/strategy/StateCallbacks.js.map +1 -1
- package/lib/encoder/ChangeTree.d.ts +9 -19
- package/lib/encoder/ChangeTree.js +129 -145
- package/lib/encoder/ChangeTree.js.map +1 -1
- package/lib/encoder/EncodeOperation.d.ts +1 -5
- package/lib/encoder/EncodeOperation.js +74 -58
- package/lib/encoder/EncodeOperation.js.map +1 -1
- package/lib/encoder/Encoder.d.ts +10 -8
- package/lib/encoder/Encoder.js +89 -56
- package/lib/encoder/Encoder.js.map +1 -1
- package/lib/encoder/Root.d.ts +17 -0
- package/lib/encoder/Root.js +44 -0
- package/lib/encoder/Root.js.map +1 -0
- package/lib/encoder/StateView.d.ts +2 -2
- package/lib/encoder/StateView.js +49 -59
- package/lib/encoder/StateView.js.map +1 -1
- package/lib/encoding/assert.d.ts +2 -1
- package/lib/encoding/assert.js +5 -5
- package/lib/encoding/assert.js.map +1 -1
- package/lib/encoding/decode.js +21 -22
- package/lib/encoding/decode.js.map +1 -1
- package/lib/encoding/encode.d.ts +2 -2
- package/lib/encoding/encode.js +40 -39
- package/lib/encoding/encode.js.map +1 -1
- package/lib/encoding/spec.d.ts +2 -1
- package/lib/encoding/spec.js +1 -0
- package/lib/encoding/spec.js.map +1 -1
- package/lib/index.d.ts +6 -3
- package/lib/index.js +18 -13
- package/lib/index.js.map +1 -1
- package/lib/types/TypeContext.d.ts +23 -0
- package/lib/types/TypeContext.js +102 -0
- package/lib/types/TypeContext.js.map +1 -0
- package/lib/types/custom/ArraySchema.d.ts +2 -2
- package/lib/types/custom/ArraySchema.js +6 -9
- package/lib/types/custom/ArraySchema.js.map +1 -1
- package/lib/types/custom/CollectionSchema.js +1 -0
- package/lib/types/custom/CollectionSchema.js.map +1 -1
- package/lib/types/custom/MapSchema.js +5 -0
- package/lib/types/custom/MapSchema.js.map +1 -1
- package/lib/types/custom/SetSchema.js +1 -0
- package/lib/types/custom/SetSchema.js.map +1 -1
- package/lib/types/registry.js +3 -4
- package/lib/types/registry.js.map +1 -1
- package/lib/types/symbols.d.ts +1 -0
- package/lib/types/symbols.js +2 -1
- 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 +3 -4
- package/lib/utils.js.map +1 -1
- package/package.json +5 -5
- package/src/Metadata.ts +104 -26
- package/src/Reflection.ts +26 -28
- package/src/Schema.ts +35 -47
- package/src/annotations.ts +82 -176
- package/src/bench_encode.ts +121 -0
- package/src/debug.ts +56 -0
- package/src/decoder/DecodeOperation.ts +28 -11
- package/src/decoder/Decoder.ts +13 -11
- package/src/decoder/ReferenceTracker.ts +3 -2
- package/src/decoder/strategy/StateCallbacks.ts +152 -81
- package/src/encoder/ChangeTree.ts +147 -166
- package/src/encoder/EncodeOperation.ts +93 -70
- package/src/encoder/Encoder.ts +111 -65
- package/src/encoder/Root.ts +51 -0
- package/src/encoder/StateView.ts +53 -69
- package/src/encoding/assert.ts +4 -3
- package/src/encoding/decode.ts +1 -2
- package/src/encoding/encode.ts +25 -22
- package/src/encoding/spec.ts +1 -0
- package/src/index.ts +8 -14
- package/src/types/TypeContext.ts +122 -0
- package/src/types/custom/ArraySchema.ts +10 -2
- package/src/types/custom/CollectionSchema.ts +1 -0
- package/src/types/custom/MapSchema.ts +6 -0
- package/src/types/custom/SetSchema.ts +1 -0
- package/src/types/symbols.ts +2 -0
|
@@ -1,95 +1,65 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var _a;
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.ChangeTree =
|
|
4
|
+
exports.ChangeTree = void 0;
|
|
5
5
|
const spec_1 = require("../encoding/spec");
|
|
6
6
|
const symbols_1 = require("../types/symbols");
|
|
7
7
|
const Metadata_1 = require("../Metadata");
|
|
8
|
-
class Root {
|
|
9
|
-
constructor() {
|
|
10
|
-
this.nextUniqueId = 0;
|
|
11
|
-
this.refCount = new WeakMap();
|
|
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();
|
|
18
|
-
}
|
|
19
|
-
getNextUniqueId() {
|
|
20
|
-
return this.nextUniqueId++;
|
|
21
|
-
}
|
|
22
|
-
add(changeTree) {
|
|
23
|
-
const refCount = this.refCount.get(changeTree) || 0;
|
|
24
|
-
this.refCount.set(changeTree, refCount + 1);
|
|
25
|
-
}
|
|
26
|
-
remove(changeTree) {
|
|
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));
|
|
41
|
-
}
|
|
42
|
-
clear() {
|
|
43
|
-
this.changes.clear();
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
exports.Root = Root;
|
|
47
8
|
class ChangeTree {
|
|
48
9
|
static { _a = symbols_1.$isNew; }
|
|
49
|
-
;
|
|
50
10
|
constructor(ref) {
|
|
51
|
-
this.
|
|
11
|
+
this.isFiltered = false;
|
|
12
|
+
this.isPartiallyFiltered = false;
|
|
52
13
|
this.currentOperationIndex = 0;
|
|
53
|
-
this.allChanges = new Map();
|
|
54
|
-
this.allFilteredChanges = new Map();
|
|
55
14
|
this.changes = new Map();
|
|
56
|
-
this.
|
|
15
|
+
this.allChanges = new Map();
|
|
57
16
|
this[_a] = true;
|
|
58
17
|
this.ref = ref;
|
|
18
|
+
//
|
|
19
|
+
// Does this structure have "filters" declared?
|
|
20
|
+
//
|
|
21
|
+
if (ref.constructor[Symbol.metadata]?.[-2]) {
|
|
22
|
+
this.allFilteredChanges = new Map();
|
|
23
|
+
this.filteredChanges = new Map();
|
|
24
|
+
}
|
|
59
25
|
}
|
|
60
26
|
setRoot(root) {
|
|
61
27
|
this.root = root;
|
|
62
28
|
this.root.add(this);
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
29
|
+
const metadata = this.ref.constructor[Symbol.metadata];
|
|
30
|
+
if (this.root.types.hasFilters) {
|
|
31
|
+
//
|
|
32
|
+
// At Schema initialization, the "root" structure might not be available
|
|
33
|
+
// yet, as it only does once the "Encoder" has been set up.
|
|
34
|
+
//
|
|
35
|
+
// So the "parent" may be already set without a "root".
|
|
36
|
+
//
|
|
37
|
+
this.checkIsFiltered(metadata, this.parent, this.parentIndex);
|
|
38
|
+
if (this.isFiltered || this.isPartiallyFiltered) {
|
|
39
|
+
this.root.allFilteredChanges.set(this, this.allFilteredChanges);
|
|
40
|
+
this.root.filteredChanges.set(this, this.filteredChanges);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
72
43
|
if (!this.isFiltered) {
|
|
73
44
|
this.root.changes.set(this, this.changes);
|
|
45
|
+
this.root.allChanges.set(this, this.allChanges);
|
|
74
46
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
47
|
+
this.ensureRefId();
|
|
48
|
+
if (metadata) {
|
|
49
|
+
metadata[-4]?.forEach((index) => {
|
|
50
|
+
const field = metadata[index];
|
|
51
|
+
const value = this.ref[field.name];
|
|
52
|
+
if (value) {
|
|
53
|
+
value[symbols_1.$changes].setRoot(root);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
80
56
|
}
|
|
81
|
-
if (
|
|
82
|
-
|
|
57
|
+
else if (this.ref[symbols_1.$childType] && typeof (this.ref[symbols_1.$childType]) !== "string") {
|
|
58
|
+
// MapSchema / ArraySchema, etc.
|
|
59
|
+
this.ref.forEach((value, key) => {
|
|
60
|
+
value[symbols_1.$changes].setRoot(root);
|
|
61
|
+
});
|
|
83
62
|
}
|
|
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
63
|
}
|
|
94
64
|
setParent(parent, root, parentIndex) {
|
|
95
65
|
this.parent = parent;
|
|
@@ -99,50 +69,60 @@ class ChangeTree {
|
|
|
99
69
|
return;
|
|
100
70
|
}
|
|
101
71
|
root.add(this);
|
|
72
|
+
const metadata = this.ref.constructor[Symbol.metadata];
|
|
102
73
|
// skip if parent is already set
|
|
103
|
-
if (root
|
|
104
|
-
this.
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
74
|
+
if (root !== this.root) {
|
|
75
|
+
this.root = root;
|
|
76
|
+
if (root.types.hasFilters) {
|
|
77
|
+
this.checkIsFiltered(metadata, parent, parentIndex);
|
|
78
|
+
if (this.isFiltered || this.isPartiallyFiltered) {
|
|
79
|
+
this.root.filteredChanges.set(this, this.filteredChanges);
|
|
80
|
+
this.root.allFilteredChanges.set(this, this.filteredChanges);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (!this.isFiltered) {
|
|
84
|
+
this.root.changes.set(this, this.changes);
|
|
85
|
+
this.root.allChanges.set(this, this.allChanges);
|
|
86
|
+
}
|
|
87
|
+
this.ensureRefId();
|
|
113
88
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
89
|
+
// assign same parent on child structures
|
|
90
|
+
if (metadata) {
|
|
91
|
+
metadata[-4]?.forEach((index) => {
|
|
92
|
+
const field = metadata[index];
|
|
93
|
+
const value = this.ref[field.name];
|
|
94
|
+
value?.[symbols_1.$changes].setParent(this.ref, root, index);
|
|
95
|
+
// console.log(this.ref.constructor.name, field.name, value);
|
|
96
|
+
// try { throw new Error(); } catch (e) {
|
|
97
|
+
// console.log(e.stack);
|
|
98
|
+
// }
|
|
99
|
+
});
|
|
117
100
|
}
|
|
118
|
-
else {
|
|
119
|
-
|
|
101
|
+
else if (this.ref[symbols_1.$childType] && typeof (this.ref[symbols_1.$childType]) !== "string") {
|
|
102
|
+
// MapSchema / ArraySchema, etc.
|
|
103
|
+
this.ref.forEach((value, key) => {
|
|
104
|
+
value[symbols_1.$changes].setParent(this.ref, root, this.indexes[key] ?? key);
|
|
105
|
+
});
|
|
120
106
|
}
|
|
121
|
-
this.ensureRefId();
|
|
122
|
-
this.forEachChild((changeTree, atIndex) => {
|
|
123
|
-
changeTree.setParent(this.ref, root, atIndex);
|
|
124
|
-
});
|
|
125
107
|
}
|
|
126
108
|
forEachChild(callback) {
|
|
127
109
|
//
|
|
128
110
|
// assign same parent on child structures
|
|
129
111
|
//
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
const value = this.ref[field];
|
|
135
|
-
if (value
|
|
136
|
-
callback(value[symbols_1.$changes],
|
|
112
|
+
const metadata = this.ref.constructor[Symbol.metadata];
|
|
113
|
+
if (metadata) {
|
|
114
|
+
metadata[-4]?.forEach((index) => {
|
|
115
|
+
const field = metadata[index];
|
|
116
|
+
const value = this.ref[field.name];
|
|
117
|
+
if (value) {
|
|
118
|
+
callback(value[symbols_1.$changes], index);
|
|
137
119
|
}
|
|
138
|
-
}
|
|
120
|
+
});
|
|
139
121
|
}
|
|
140
|
-
else if (typeof (this.ref)
|
|
122
|
+
else if (this.ref[symbols_1.$childType] && typeof (this.ref[symbols_1.$childType]) !== "string") {
|
|
141
123
|
// MapSchema / ArraySchema, etc.
|
|
142
124
|
this.ref.forEach((value, key) => {
|
|
143
|
-
|
|
144
|
-
callback(value[symbols_1.$changes], this.ref[symbols_1.$changes].indexes[key]);
|
|
145
|
-
}
|
|
125
|
+
callback(value[symbols_1.$changes], this.indexes[key] ?? key);
|
|
146
126
|
});
|
|
147
127
|
}
|
|
148
128
|
}
|
|
@@ -151,8 +131,8 @@ class ChangeTree {
|
|
|
151
131
|
this.root?.changes.set(this, this.changes);
|
|
152
132
|
}
|
|
153
133
|
change(index, operation = spec_1.OPERATION.ADD) {
|
|
154
|
-
const metadata = this.ref
|
|
155
|
-
const isFiltered = this.isFiltered || (metadata
|
|
134
|
+
const metadata = this.ref.constructor[Symbol.metadata];
|
|
135
|
+
const isFiltered = this.isFiltered || (metadata?.[index]?.tag !== undefined);
|
|
156
136
|
const changeSet = (isFiltered)
|
|
157
137
|
? this.filteredChanges
|
|
158
138
|
: this.changes;
|
|
@@ -163,14 +143,15 @@ class ChangeTree {
|
|
|
163
143
|
: (previousOperation === spec_1.OPERATION.DELETE)
|
|
164
144
|
? spec_1.OPERATION.DELETE_AND_ADD
|
|
165
145
|
: operation;
|
|
146
|
+
//
|
|
147
|
+
// TODO: are DELETE operations being encoded as ADD here ??
|
|
148
|
+
//
|
|
166
149
|
changeSet.set(index, op);
|
|
167
150
|
}
|
|
168
|
-
//
|
|
169
|
-
// TODO: are DELETE operations being encoded as ADD here ??
|
|
170
|
-
//
|
|
171
151
|
if (isFiltered) {
|
|
172
152
|
this.allFilteredChanges.set(index, spec_1.OPERATION.ADD);
|
|
173
153
|
this.root?.filteredChanges.set(this, this.filteredChanges);
|
|
154
|
+
this.root?.allFilteredChanges.set(this, this.allFilteredChanges);
|
|
174
155
|
}
|
|
175
156
|
else {
|
|
176
157
|
this.allChanges.set(index, spec_1.OPERATION.ADD);
|
|
@@ -209,7 +190,6 @@ class ChangeTree {
|
|
|
209
190
|
}
|
|
210
191
|
_shiftAllChangeIndexes(shiftIndex, startIndex = 0, allChangeSet) {
|
|
211
192
|
Array.from(allChangeSet.entries()).forEach(([index, op]) => {
|
|
212
|
-
// console.log('shiftAllChangeIndexes', index >= startIndex, { index, op, shiftIndex, startIndex })
|
|
213
193
|
if (index >= startIndex) {
|
|
214
194
|
allChangeSet.delete(index);
|
|
215
195
|
allChangeSet.set(index + shiftIndex, op);
|
|
@@ -217,9 +197,7 @@ class ChangeTree {
|
|
|
217
197
|
});
|
|
218
198
|
}
|
|
219
199
|
indexedOperation(index, operation, allChangesIndex = index) {
|
|
220
|
-
|
|
221
|
-
const isFiltered = this.isFiltered || (metadata && metadata[metadata[index]].tag !== undefined);
|
|
222
|
-
if (isFiltered) {
|
|
200
|
+
if (this.filteredChanges !== undefined) {
|
|
223
201
|
this.allFilteredChanges.set(allChangesIndex, spec_1.OPERATION.ADD);
|
|
224
202
|
this.filteredChanges.set(index, operation);
|
|
225
203
|
this.root?.filteredChanges.set(this, this.filteredChanges);
|
|
@@ -232,8 +210,8 @@ class ChangeTree {
|
|
|
232
210
|
}
|
|
233
211
|
getType(index) {
|
|
234
212
|
if (Metadata_1.Metadata.isValidInstance(this.ref)) {
|
|
235
|
-
const metadata = this.ref
|
|
236
|
-
return metadata[
|
|
213
|
+
const metadata = this.ref.constructor[Symbol.metadata];
|
|
214
|
+
return metadata[index].type;
|
|
237
215
|
}
|
|
238
216
|
else {
|
|
239
217
|
//
|
|
@@ -247,7 +225,7 @@ class ChangeTree {
|
|
|
247
225
|
}
|
|
248
226
|
getChange(index) {
|
|
249
227
|
// TODO: optimize this. avoid checking against multiple instances
|
|
250
|
-
return this.changes.get(index) ?? this.filteredChanges
|
|
228
|
+
return this.changes.get(index) ?? this.filteredChanges?.get(index);
|
|
251
229
|
}
|
|
252
230
|
//
|
|
253
231
|
// used during `.encode()`
|
|
@@ -268,9 +246,7 @@ class ChangeTree {
|
|
|
268
246
|
}
|
|
269
247
|
return;
|
|
270
248
|
}
|
|
271
|
-
const
|
|
272
|
-
const isFiltered = this.isFiltered || (metadata && metadata[metadata[index]].tag !== undefined);
|
|
273
|
-
const changeSet = (isFiltered)
|
|
249
|
+
const changeSet = (this.filteredChanges)
|
|
274
250
|
? this.filteredChanges
|
|
275
251
|
: this.changes;
|
|
276
252
|
const previousValue = this.getValue(index);
|
|
@@ -293,7 +269,7 @@ class ChangeTree {
|
|
|
293
269
|
//
|
|
294
270
|
// FIXME: this is looking a bit ugly (and repeated from `.change()`)
|
|
295
271
|
//
|
|
296
|
-
if (
|
|
272
|
+
if (this.filteredChanges) {
|
|
297
273
|
this.root?.filteredChanges.set(this, this.filteredChanges);
|
|
298
274
|
this.allFilteredChanges.delete(allChangesIndex);
|
|
299
275
|
}
|
|
@@ -304,6 +280,7 @@ class ChangeTree {
|
|
|
304
280
|
}
|
|
305
281
|
endEncode() {
|
|
306
282
|
this.changes.clear();
|
|
283
|
+
// ArraySchema and MapSchema have a custom "encode end" method
|
|
307
284
|
this.ref[symbols_1.$onEncodeEnd]?.();
|
|
308
285
|
// Not a new instance anymore
|
|
309
286
|
delete this[symbols_1.$isNew];
|
|
@@ -316,12 +293,12 @@ class ChangeTree {
|
|
|
316
293
|
//
|
|
317
294
|
this.ref[symbols_1.$onEncodeEnd]?.();
|
|
318
295
|
this.changes.clear();
|
|
319
|
-
this.filteredChanges
|
|
296
|
+
this.filteredChanges?.clear();
|
|
320
297
|
// reset operation index
|
|
321
298
|
this.currentOperationIndex = 0;
|
|
322
299
|
if (discardAll) {
|
|
323
300
|
this.allChanges.clear();
|
|
324
|
-
this.allFilteredChanges
|
|
301
|
+
this.allFilteredChanges?.clear();
|
|
325
302
|
// remove children references
|
|
326
303
|
this.forEachChild((changeTree, _) => this.root?.remove(changeTree));
|
|
327
304
|
}
|
|
@@ -348,34 +325,41 @@ class ChangeTree {
|
|
|
348
325
|
get changed() {
|
|
349
326
|
return this.changes.size > 0;
|
|
350
327
|
}
|
|
351
|
-
checkIsFiltered(parent, parentIndex) {
|
|
328
|
+
checkIsFiltered(metadata, parent, parentIndex) {
|
|
352
329
|
// Detect if current structure has "filters" declared
|
|
353
|
-
this.isPartiallyFiltered =
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
const metadata = parent['constructor'][Symbol.metadata];
|
|
358
|
-
const fieldName = metadata?.[parentIndex];
|
|
359
|
-
const isParentOwned = metadata?.[fieldName]?.tag !== undefined;
|
|
360
|
-
this.isFiltered = isParentOwned || parent[symbols_1.$changes].isFiltered; // metadata?.[-2]
|
|
361
|
-
parent = parent[symbols_1.$changes].parent;
|
|
330
|
+
this.isPartiallyFiltered = metadata?.[-2] !== undefined;
|
|
331
|
+
if (this.isPartiallyFiltered) {
|
|
332
|
+
this.filteredChanges = this.filteredChanges || new Map();
|
|
333
|
+
this.allFilteredChanges = this.allFilteredChanges || new Map();
|
|
362
334
|
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
//
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
//
|
|
376
|
-
|
|
377
|
-
this.
|
|
378
|
-
|
|
335
|
+
if (parent) {
|
|
336
|
+
if (!Metadata_1.Metadata.isValidInstance(parent)) {
|
|
337
|
+
const parentChangeTree = parent[symbols_1.$changes];
|
|
338
|
+
parent = parentChangeTree.parent;
|
|
339
|
+
parentIndex = parentChangeTree.parentIndex;
|
|
340
|
+
}
|
|
341
|
+
const parentMetadata = parent?.constructor?.[Symbol.metadata];
|
|
342
|
+
this.isFiltered = (parent && parentMetadata?.[-2]?.includes(parentIndex));
|
|
343
|
+
//
|
|
344
|
+
// TODO: refactor this!
|
|
345
|
+
//
|
|
346
|
+
// swapping `changes` and `filteredChanges` is required here
|
|
347
|
+
// because "isFiltered" may not be imedialely available on `change()`
|
|
348
|
+
//
|
|
349
|
+
if (this.isFiltered) {
|
|
350
|
+
this.filteredChanges = new Map();
|
|
351
|
+
this.allFilteredChanges = new Map();
|
|
352
|
+
if (this.changes.size > 0) {
|
|
353
|
+
// swap changes reference
|
|
354
|
+
const changes = this.changes;
|
|
355
|
+
this.changes = this.filteredChanges;
|
|
356
|
+
this.filteredChanges = changes;
|
|
357
|
+
// swap "all changes" reference
|
|
358
|
+
const allFilteredChanges = this.allFilteredChanges;
|
|
359
|
+
this.allFilteredChanges = this.allChanges;
|
|
360
|
+
this.allChanges = allFilteredChanges;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
379
363
|
}
|
|
380
364
|
}
|
|
381
365
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChangeTree.js","sourceRoot":"","sources":["../../src/encoder/ChangeTree.ts"],"names":[],"mappings":"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","sourcesContent":["import { OPERATION } from \"../encoding/spec\";\nimport { Schema } from \"../Schema\";\nimport { $changes, $childType, $decoder, $onEncodeEnd, $encoder, $getByIndex, $isNew } from \"../types/symbols\";\n\nimport type { MapSchema } from \"../types/custom/MapSchema\";\nimport type { ArraySchema } from \"../types/custom/ArraySchema\";\nimport type { CollectionSchema } from \"../types/custom/CollectionSchema\";\nimport type { SetSchema } from \"../types/custom/SetSchema\";\n\nimport { Metadata } from \"../Metadata\";\nimport type { EncodeOperation } from \"./EncodeOperation\";\nimport type { DecodeOperation } from \"../decoder/DecodeOperation\";\nimport type { StateView } from \"./StateView\";\n\ndeclare global {\n interface Object {\n // FIXME: not a good practice to extend globals here\n [$changes]?: ChangeTree;\n [$encoder]?: EncodeOperation,\n [$decoder]?: DecodeOperation,\n }\n}\n\nexport type Ref = Schema\n | ArraySchema\n | MapSchema\n | CollectionSchema\n | SetSchema;\n\nexport class Root {\n protected nextUniqueId: number = 0;\n refCount = new WeakMap<ChangeTree, number>();\n\n // all changes\n allChanges = new Map<ChangeTree, Map<number, OPERATION>>();\n allFilteredChanges = new Map<ChangeTree, Map<number, OPERATION>>();\n\n // pending changes to be encoded\n changes = new Map<ChangeTree, Map<number, OPERATION>>();\n filteredChanges = new Map<ChangeTree, Map<number, OPERATION>>();\n\n getNextUniqueId() {\n return this.nextUniqueId++;\n }\n\n add (changeTree: ChangeTree) {\n const refCount = this.refCount.get(changeTree) || 0;\n this.refCount.set(changeTree, refCount + 1);\n }\n\n remove(changeTree: ChangeTree) {\n const refCount = this.refCount.get(changeTree);\n if (refCount <= 1) {\n this.allChanges.delete(changeTree);\n this.changes.delete(changeTree);\n\n if (changeTree.isFiltered || changeTree.isPartiallyFiltered) {\n this.allFilteredChanges.delete(changeTree);\n this.filteredChanges.delete(changeTree);\n }\n\n this.refCount.delete(changeTree);\n\n } else {\n this.refCount.set(changeTree, refCount - 1);\n }\n\n changeTree.forEachChild((child, _) =>\n this.remove(child));\n }\n\n clear() {\n this.changes.clear();\n }\n}\n\nexport class ChangeTree<T extends Ref=any> {\n ref: T;\n refId: number;\n\n root?: Root;\n\n isFiltered?: boolean;\n isPartiallyFiltered?: boolean;\n\n parent?: Ref;\n parentIndex?: number;\n\n indexes: {[index: string]: any} = {}; // TODO: remove this, only used by MapSchema/SetSchema/CollectionSchema (`encodeKeyValueOperation`)\n currentOperationIndex: number = 0;\n\n allChanges = new Map<number, OPERATION>();\n allFilteredChanges = new Map<number, OPERATION>();\n\n changes = new Map<number, OPERATION>();\n filteredChanges = new Map<number, OPERATION>();;\n\n [$isNew] = true;\n\n constructor(ref: T) {\n this.ref = ref;\n }\n\n setRoot(root: Root) {\n this.root = root;\n this.root.add(this);\n\n //\n // At Schema initialization, the \"root\" structure might not be available\n // yet, as it only does once the \"Encoder\" has been set up.\n //\n // So the \"parent\" may be already set without a \"root\".\n //\n this.checkIsFiltered(this.parent, this.parentIndex);\n\n // unique refId for the ChangeTree.\n this.ensureRefId();\n\n if (!this.isFiltered) {\n this.root.changes.set(this, this.changes);\n }\n\n if (this.isFiltered || this.isPartiallyFiltered) {\n this.root.allFilteredChanges.set(this, this.allFilteredChanges);\n this.root.filteredChanges.set(this, this.filteredChanges);\n\n // } else {\n // this.root.allChanges.set(this, this.allChanges);\n }\n\n if (!this.isFiltered) {\n this.root.allChanges.set(this, this.allChanges);\n }\n\n this.forEachChild((changeTree, _) => {\n changeTree.setRoot(root);\n });\n\n // this.allChanges.forEach((_, index) => {\n // const childRef = this.ref[$getByIndex](index);\n // if (childRef && childRef[$changes]) {\n // childRef[$changes].setRoot(root);\n // }\n // });\n }\n\n setParent(\n parent: Ref,\n root?: Root,\n parentIndex?: number,\n ) {\n this.parent = parent;\n this.parentIndex = parentIndex;\n\n // avoid setting parents with empty `root`\n if (!root) { return; }\n\n root.add(this);\n\n // skip if parent is already set\n if (root === this.root) {\n this.forEachChild((changeTree, atIndex) => {\n changeTree.setParent(this.ref, root, atIndex);\n });\n return;\n }\n\n this.root = root;\n this.checkIsFiltered(parent, parentIndex);\n\n if (!this.isFiltered) {\n this.root.changes.set(this, this.changes);\n }\n\n if (this.isFiltered || this.isPartiallyFiltered) {\n this.root.filteredChanges.set(this, this.filteredChanges);\n this.root.allFilteredChanges.set(this, this.filteredChanges);\n } else {\n this.root.allChanges.set(this, this.allChanges);\n }\n\n this.ensureRefId();\n\n this.forEachChild((changeTree, atIndex) => {\n changeTree.setParent(this.ref, root, atIndex);\n });\n }\n\n forEachChild(callback: (change: ChangeTree, atIndex: number) => void) {\n //\n // assign same parent on child structures\n //\n if (Metadata.isValidInstance(this.ref)) {\n const metadata: Metadata = this.ref['constructor'][Symbol.metadata];\n\n // FIXME: need to iterate over parent metadata instead.\n for (const field in metadata) {\n const value = this.ref[field];\n\n if (value && value[$changes]) {\n callback(value[$changes], metadata[field].index);\n }\n }\n\n } else if (typeof (this.ref) === \"object\") {\n // MapSchema / ArraySchema, etc.\n (this.ref as MapSchema).forEach((value, key) => {\n if (Metadata.isValidInstance(value)) {\n callback(value[$changes], this.ref[$changes].indexes[key]);\n }\n });\n }\n }\n\n operation(op: OPERATION) {\n this.changes.set(--this.currentOperationIndex, op);\n this.root?.changes.set(this, this.changes);\n }\n\n change(index: number, operation: OPERATION = OPERATION.ADD) {\n const metadata = this.ref['constructor'][Symbol.metadata] as Metadata;\n\n const isFiltered = this.isFiltered || (metadata && metadata[metadata[index]].tag !== undefined);\n const changeSet = (isFiltered)\n ? this.filteredChanges\n : this.changes;\n\n const previousOperation = changeSet.get(index);\n if (!previousOperation || previousOperation === OPERATION.DELETE) {\n const op = (!previousOperation)\n ? operation\n : (previousOperation === OPERATION.DELETE)\n ? OPERATION.DELETE_AND_ADD\n : operation\n changeSet.set(index, op);\n }\n\n //\n // TODO: are DELETE operations being encoded as ADD here ??\n //\n\n if (isFiltered) {\n this.allFilteredChanges.set(index, OPERATION.ADD);\n this.root?.filteredChanges.set(this, this.filteredChanges);\n\n } else {\n this.allChanges.set(index, OPERATION.ADD);\n this.root?.changes.set(this, this.changes);\n }\n }\n\n shiftChangeIndexes(shiftIndex: number) {\n //\n // Used only during:\n //\n // - ArraySchema#unshift()\n //\n const changeSet = (this.isFiltered)\n ? this.filteredChanges\n : this.changes;\n\n const changeSetEntries = Array.from(changeSet.entries());\n changeSet.clear();\n\n // Re-insert each entry with the shifted index\n for (const [index, op] of changeSetEntries) {\n changeSet.set(index + shiftIndex, op);\n }\n }\n\n shiftAllChangeIndexes(shiftIndex: number, startIndex: number = 0) {\n //\n // Used only during:\n //\n // - ArraySchema#splice()\n //\n if (this.isFiltered || this.isPartiallyFiltered) {\n this._shiftAllChangeIndexes(shiftIndex, startIndex, this.allFilteredChanges);\n this._shiftAllChangeIndexes(shiftIndex, startIndex, this.allChanges);\n\n } else {\n this._shiftAllChangeIndexes(shiftIndex, startIndex, this.allChanges);\n }\n }\n\n private _shiftAllChangeIndexes(shiftIndex: number, startIndex: number = 0, allChangeSet: Map<number, OPERATION>) {\n Array.from(allChangeSet.entries()).forEach(([index, op]) => {\n // console.log('shiftAllChangeIndexes', index >= startIndex, { index, op, shiftIndex, startIndex })\n if (index >= startIndex) {\n allChangeSet.delete(index);\n allChangeSet.set(index + shiftIndex, op);\n }\n });\n }\n\n indexedOperation(index: number, operation: OPERATION, allChangesIndex = index) {\n const metadata = this.ref['constructor'][Symbol.metadata] as Metadata;\n const isFiltered = this.isFiltered || (metadata && metadata[metadata[index]].tag !== undefined);\n\n if (isFiltered) {\n this.allFilteredChanges.set(allChangesIndex, OPERATION.ADD);\n this.filteredChanges.set(index, operation);\n this.root?.filteredChanges.set(this, this.filteredChanges);\n\n } else {\n this.allChanges.set(allChangesIndex, OPERATION.ADD);\n this.changes.set(index, operation);\n this.root?.changes.set(this, this.changes);\n }\n }\n\n getType(index?: number) {\n if (Metadata.isValidInstance(this.ref)) {\n const metadata = this.ref['constructor'][Symbol.metadata] as Metadata;\n return metadata[metadata[index]].type;\n\n } else {\n //\n // Get the child type from parent structure.\n // - [\"string\"] => \"string\"\n // - { map: \"string\" } => \"string\"\n // - { set: \"string\" } => \"string\"\n //\n return this.ref[$childType];\n }\n }\n\n getChange(index: number) {\n // TODO: optimize this. avoid checking against multiple instances\n return this.changes.get(index) ?? this.filteredChanges.get(index);\n }\n\n //\n // used during `.encode()`\n //\n getValue(index: number, isEncodeAll: boolean = false) {\n //\n // `isEncodeAll` param is only used by ArraySchema\n //\n return this.ref[$getByIndex](index, isEncodeAll);\n }\n\n delete(index: number, operation?: OPERATION, allChangesIndex = index) {\n if (index === undefined) {\n try {\n throw new Error(`@colyseus/schema ${this.ref.constructor.name}: trying to delete non-existing index '${index}'`);\n } catch (e) {\n console.warn(e);\n }\n return;\n }\n\n const metadata = this.ref['constructor'][Symbol.metadata] as Metadata;\n const isFiltered = this.isFiltered || (metadata && metadata[metadata[index]].tag !== undefined);\n const changeSet = (isFiltered)\n ? this.filteredChanges\n : this.changes;\n\n const previousValue = this.getValue(index);\n\n changeSet.set(index, operation ?? OPERATION.DELETE);\n\n // remove `root` reference\n if (previousValue && previousValue[$changes]) {\n previousValue[$changes].root = undefined;\n\n //\n // FIXME: this.root is \"undefined\"\n //\n // This method is being called at decoding time when a DELETE operation is found.\n //\n // - This is due to using the concrete Schema class at decoding time.\n // - \"Reflected\" structures do not have this problem.\n //\n // (the property descriptors should NOT be used at decoding time. only at encoding time.)\n //\n this.root?.remove(previousValue[$changes]);\n }\n\n //\n // FIXME: this is looking a bit ugly (and repeated from `.change()`)\n //\n if (isFiltered) {\n this.root?.filteredChanges.set(this, this.filteredChanges);\n this.allFilteredChanges.delete(allChangesIndex);\n\n } else {\n this.root?.changes.set(this, this.changes);\n this.allChanges.delete(allChangesIndex);\n }\n }\n\n endEncode() {\n this.changes.clear();\n this.ref[$onEncodeEnd]?.();\n\n // Not a new instance anymore\n delete this[$isNew];\n }\n\n discard(discardAll: boolean = false) {\n //\n // > MapSchema:\n // Remove cached key to ensure ADD operations is unsed instead of\n // REPLACE in case same key is used on next patches.\n //\n this.ref[$onEncodeEnd]?.();\n\n this.changes.clear();\n this.filteredChanges.clear();\n\n // reset operation index\n this.currentOperationIndex = 0;\n\n if (discardAll) {\n this.allChanges.clear();\n this.allFilteredChanges.clear();\n\n // remove children references\n this.forEachChild((changeTree, _) =>\n this.root?.remove(changeTree));\n }\n }\n\n /**\n * Recursively discard all changes from this, and child structures.\n */\n discardAll() {\n this.changes.forEach((_, fieldIndex) => {\n const value = this.getValue(fieldIndex);\n\n if (value && value[$changes]) {\n value[$changes].discardAll();\n }\n });\n\n this.discard();\n }\n\n ensureRefId() {\n // skip if refId is already set.\n if (this.refId !== undefined) {\n return;\n }\n\n this.refId = this.root.getNextUniqueId();\n }\n\n get changed() {\n return this.changes.size > 0;\n }\n\n protected checkIsFiltered(parent: Ref, parentIndex: number) {\n // Detect if current structure has \"filters\" declared\n this.isPartiallyFiltered = this.ref['constructor']?.[Symbol.metadata]?.[-2];\n\n // TODO: support \"partially filtered\", where the instance is visible, but only a field is not.\n\n // Detect if parent has \"filters\" declared\n while (parent && !this.isFiltered) {\n const metadata: Metadata = parent['constructor'][Symbol.metadata];\n\n const fieldName = metadata?.[parentIndex];\n const isParentOwned = metadata?.[fieldName]?.tag !== undefined;\n\n this.isFiltered = isParentOwned || parent[$changes].isFiltered; // metadata?.[-2]\n\n parent = parent[$changes].parent;\n };\n\n //\n // TODO: refactor this!\n //\n // swapping `changes` and `filteredChanges` is required here\n // because \"isFiltered\" may not be imedialely available on `change()`\n //\n if (this.isFiltered && this.changes.size > 0) {\n // swap changes reference\n const changes = this.changes;\n this.changes = this.filteredChanges;\n this.filteredChanges = changes;\n\n // swap \"all changes\" reference\n const allFilteredChanges = this.allFilteredChanges;\n this.allFilteredChanges = this.allChanges;\n this.allChanges = allFilteredChanges;\n }\n }\n\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ChangeTree.js","sourceRoot":"","sources":["../../src/encoder/ChangeTree.ts"],"names":[],"mappings":"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","sourcesContent":["import { OPERATION } from \"../encoding/spec\";\nimport { Schema } from \"../Schema\";\nimport { $changes, $childType, $decoder, $onEncodeEnd, $encoder, $getByIndex, $isNew } from \"../types/symbols\";\n\nimport type { MapSchema } from \"../types/custom/MapSchema\";\nimport type { ArraySchema } from \"../types/custom/ArraySchema\";\nimport type { CollectionSchema } from \"../types/custom/CollectionSchema\";\nimport type { SetSchema } from \"../types/custom/SetSchema\";\n\nimport { Root } from \"./Root\";\nimport { Metadata } from \"../Metadata\";\nimport type { EncodeOperation } from \"./EncodeOperation\";\nimport type { DecodeOperation } from \"../decoder/DecodeOperation\";\n\ndeclare global {\n interface Object {\n // FIXME: not a good practice to extend globals here\n [$changes]?: ChangeTree;\n [$encoder]?: EncodeOperation,\n [$decoder]?: DecodeOperation,\n }\n}\n\nexport type Ref = Schema\n | ArraySchema\n | MapSchema\n | CollectionSchema\n | SetSchema;\n\nexport class ChangeTree<T extends Ref=any> {\n ref: T;\n refId: number;\n\n root?: Root;\n parent?: Ref;\n parentIndex?: number;\n\n isFiltered: boolean = false;\n isPartiallyFiltered: boolean = false;\n\n currentOperationIndex: number = 0;\n\n changes = new Map<number, OPERATION>();\n allChanges = new Map<number, OPERATION>();\n\n allFilteredChanges: Map<number, OPERATION>;\n filteredChanges: Map<number, OPERATION>;\n\n indexes: {[index: string]: any}; // TODO: remove this, only used by MapSchema/SetSchema/CollectionSchema (`encodeKeyValueOperation`)\n\n [$isNew] = true;\n\n constructor(ref: T) {\n this.ref = ref;\n\n //\n // Does this structure have \"filters\" declared?\n //\n if (ref.constructor[Symbol.metadata]?.[-2]) {\n this.allFilteredChanges = new Map<number, OPERATION>();\n this.filteredChanges = new Map<number, OPERATION>();\n }\n }\n\n setRoot(root: Root) {\n this.root = root;\n this.root.add(this);\n\n const metadata: Metadata = this.ref.constructor[Symbol.metadata];\n\n if (this.root.types.hasFilters) {\n //\n // At Schema initialization, the \"root\" structure might not be available\n // yet, as it only does once the \"Encoder\" has been set up.\n //\n // So the \"parent\" may be already set without a \"root\".\n //\n this.checkIsFiltered(metadata, this.parent, this.parentIndex);\n\n if (this.isFiltered || this.isPartiallyFiltered) {\n this.root.allFilteredChanges.set(this, this.allFilteredChanges);\n this.root.filteredChanges.set(this, this.filteredChanges);\n }\n }\n\n if (!this.isFiltered) {\n this.root.changes.set(this, this.changes);\n this.root.allChanges.set(this, this.allChanges);\n }\n\n this.ensureRefId();\n\n if (metadata) {\n metadata[-4]?.forEach((index) => {\n const field = metadata[index as any as number];\n const value = this.ref[field.name];\n if (value) {\n value[$changes].setRoot(root);\n }\n });\n\n } else if (this.ref[$childType] && typeof(this.ref[$childType]) !== \"string\") {\n // MapSchema / ArraySchema, etc.\n (this.ref as MapSchema).forEach((value, key) => {\n value[$changes].setRoot(root);\n });\n }\n\n }\n\n setParent(\n parent: Ref,\n root?: Root,\n parentIndex?: number,\n ) {\n this.parent = parent;\n this.parentIndex = parentIndex;\n\n // avoid setting parents with empty `root`\n if (!root) { return; }\n\n root.add(this);\n\n const metadata: Metadata = this.ref.constructor[Symbol.metadata];\n\n // skip if parent is already set\n if (root !== this.root) {\n this.root = root;\n\n if (root.types.hasFilters) {\n this.checkIsFiltered(metadata, parent, parentIndex);\n\n if (this.isFiltered || this.isPartiallyFiltered) {\n this.root.filteredChanges.set(this, this.filteredChanges);\n this.root.allFilteredChanges.set(this, this.filteredChanges);\n }\n }\n\n if (!this.isFiltered) {\n this.root.changes.set(this, this.changes);\n this.root.allChanges.set(this, this.allChanges);\n }\n\n this.ensureRefId();\n }\n\n // assign same parent on child structures\n if (metadata) {\n metadata[-4]?.forEach((index) => {\n const field = metadata[index as any as number];\n const value = this.ref[field.name];\n value?.[$changes].setParent(this.ref, root, index);\n\n // console.log(this.ref.constructor.name, field.name, value);\n\n // try { throw new Error(); } catch (e) {\n // console.log(e.stack);\n // }\n\n });\n\n } else if (this.ref[$childType] && typeof(this.ref[$childType]) !== \"string\") {\n // MapSchema / ArraySchema, etc.\n (this.ref as MapSchema).forEach((value, key) => {\n value[$changes].setParent(this.ref, root, this.indexes[key] ?? key);\n });\n }\n\n }\n\n forEachChild(callback: (change: ChangeTree, atIndex: number) => void) {\n //\n // assign same parent on child structures\n //\n const metadata: Metadata = this.ref.constructor[Symbol.metadata];\n if (metadata) {\n metadata[-4]?.forEach((index) => {\n const field = metadata[index as any as number];\n const value = this.ref[field.name];\n if (value) {\n callback(value[$changes], index);\n }\n });\n\n } else if (this.ref[$childType] && typeof(this.ref[$childType]) !== \"string\") {\n // MapSchema / ArraySchema, etc.\n (this.ref as MapSchema).forEach((value, key) => {\n callback(value[$changes], this.indexes[key] ?? key);\n });\n }\n }\n\n operation(op: OPERATION) {\n this.changes.set(--this.currentOperationIndex, op);\n this.root?.changes.set(this, this.changes);\n }\n\n change(index: number, operation: OPERATION = OPERATION.ADD) {\n const metadata = this.ref.constructor[Symbol.metadata] as Metadata;\n\n const isFiltered = this.isFiltered || (metadata?.[index]?.tag !== undefined);\n const changeSet = (isFiltered)\n ? this.filteredChanges\n : this.changes;\n\n const previousOperation = changeSet.get(index);\n if (!previousOperation || previousOperation === OPERATION.DELETE) {\n const op = (!previousOperation)\n ? operation\n : (previousOperation === OPERATION.DELETE)\n ? OPERATION.DELETE_AND_ADD\n : operation\n //\n // TODO: are DELETE operations being encoded as ADD here ??\n //\n changeSet.set(index, op);\n }\n\n if (isFiltered) {\n this.allFilteredChanges.set(index, OPERATION.ADD);\n this.root?.filteredChanges.set(this, this.filteredChanges);\n this.root?.allFilteredChanges.set(this, this.allFilteredChanges);\n\n } else {\n this.allChanges.set(index, OPERATION.ADD);\n this.root?.changes.set(this, this.changes);\n }\n }\n\n shiftChangeIndexes(shiftIndex: number) {\n //\n // Used only during:\n //\n // - ArraySchema#unshift()\n //\n const changeSet = (this.isFiltered)\n ? this.filteredChanges\n : this.changes;\n\n const changeSetEntries = Array.from(changeSet.entries());\n changeSet.clear();\n\n // Re-insert each entry with the shifted index\n for (const [index, op] of changeSetEntries) {\n changeSet.set(index + shiftIndex, op);\n }\n }\n\n shiftAllChangeIndexes(shiftIndex: number, startIndex: number = 0) {\n //\n // Used only during:\n //\n // - ArraySchema#splice()\n //\n if (this.isFiltered || this.isPartiallyFiltered) {\n this._shiftAllChangeIndexes(shiftIndex, startIndex, this.allFilteredChanges);\n this._shiftAllChangeIndexes(shiftIndex, startIndex, this.allChanges);\n\n } else {\n this._shiftAllChangeIndexes(shiftIndex, startIndex, this.allChanges);\n }\n }\n\n private _shiftAllChangeIndexes(shiftIndex: number, startIndex: number = 0, allChangeSet: Map<number, OPERATION>) {\n Array.from(allChangeSet.entries()).forEach(([index, op]) => {\n if (index >= startIndex) {\n allChangeSet.delete(index);\n allChangeSet.set(index + shiftIndex, op);\n }\n });\n }\n\n indexedOperation(index: number, operation: OPERATION, allChangesIndex = index) {\n if (this.filteredChanges !== undefined) {\n this.allFilteredChanges.set(allChangesIndex, OPERATION.ADD);\n this.filteredChanges.set(index, operation);\n this.root?.filteredChanges.set(this, this.filteredChanges);\n\n } else {\n this.allChanges.set(allChangesIndex, OPERATION.ADD);\n this.changes.set(index, operation);\n this.root?.changes.set(this, this.changes);\n }\n }\n\n getType(index?: number) {\n if (Metadata.isValidInstance(this.ref)) {\n const metadata = this.ref.constructor[Symbol.metadata] as Metadata;\n return metadata[index].type;\n\n } else {\n //\n // Get the child type from parent structure.\n // - [\"string\"] => \"string\"\n // - { map: \"string\" } => \"string\"\n // - { set: \"string\" } => \"string\"\n //\n return this.ref[$childType];\n }\n }\n\n getChange(index: number) {\n // TODO: optimize this. avoid checking against multiple instances\n return this.changes.get(index) ?? this.filteredChanges?.get(index);\n }\n\n //\n // used during `.encode()`\n //\n getValue(index: number, isEncodeAll: boolean = false) {\n //\n // `isEncodeAll` param is only used by ArraySchema\n //\n return this.ref[$getByIndex](index, isEncodeAll);\n }\n\n delete(index: number, operation?: OPERATION, allChangesIndex = index) {\n if (index === undefined) {\n try {\n throw new Error(`@colyseus/schema ${this.ref.constructor.name}: trying to delete non-existing index '${index}'`);\n } catch (e) {\n console.warn(e);\n }\n return;\n }\n\n const changeSet = (this.filteredChanges)\n ? this.filteredChanges\n : this.changes;\n\n const previousValue = this.getValue(index);\n\n changeSet.set(index, operation ?? OPERATION.DELETE);\n\n // remove `root` reference\n if (previousValue && previousValue[$changes]) {\n previousValue[$changes].root = undefined;\n\n //\n // FIXME: this.root is \"undefined\"\n //\n // This method is being called at decoding time when a DELETE operation is found.\n //\n // - This is due to using the concrete Schema class at decoding time.\n // - \"Reflected\" structures do not have this problem.\n //\n // (the property descriptors should NOT be used at decoding time. only at encoding time.)\n //\n this.root?.remove(previousValue[$changes]);\n }\n\n //\n // FIXME: this is looking a bit ugly (and repeated from `.change()`)\n //\n if (this.filteredChanges) {\n this.root?.filteredChanges.set(this, this.filteredChanges);\n this.allFilteredChanges.delete(allChangesIndex);\n\n } else {\n this.root?.changes.set(this, this.changes);\n this.allChanges.delete(allChangesIndex);\n }\n }\n\n endEncode() {\n this.changes.clear();\n\n // ArraySchema and MapSchema have a custom \"encode end\" method\n this.ref[$onEncodeEnd]?.();\n\n // Not a new instance anymore\n delete this[$isNew];\n }\n\n discard(discardAll: boolean = false) {\n //\n // > MapSchema:\n // Remove cached key to ensure ADD operations is unsed instead of\n // REPLACE in case same key is used on next patches.\n //\n this.ref[$onEncodeEnd]?.();\n\n this.changes.clear();\n this.filteredChanges?.clear();\n\n // reset operation index\n this.currentOperationIndex = 0;\n\n if (discardAll) {\n this.allChanges.clear();\n this.allFilteredChanges?.clear();\n\n // remove children references\n this.forEachChild((changeTree, _) =>\n this.root?.remove(changeTree));\n }\n }\n\n /**\n * Recursively discard all changes from this, and child structures.\n */\n discardAll() {\n this.changes.forEach((_, fieldIndex) => {\n const value = this.getValue(fieldIndex);\n\n if (value && value[$changes]) {\n value[$changes].discardAll();\n }\n });\n\n this.discard();\n }\n\n ensureRefId() {\n // skip if refId is already set.\n if (this.refId !== undefined) {\n return;\n }\n\n this.refId = this.root.getNextUniqueId();\n }\n\n get changed() {\n return this.changes.size > 0;\n }\n\n protected checkIsFiltered(metadata: Metadata, parent: Ref, parentIndex: number) {\n // Detect if current structure has \"filters\" declared\n this.isPartiallyFiltered = metadata?.[-2] !== undefined;\n\n if (this.isPartiallyFiltered) {\n this.filteredChanges = this.filteredChanges || new Map<number, OPERATION>();\n this.allFilteredChanges = this.allFilteredChanges || new Map<number, OPERATION>();\n }\n\n if (parent) {\n if (!Metadata.isValidInstance(parent)) {\n const parentChangeTree = parent[$changes];\n parent = parentChangeTree.parent;\n parentIndex = parentChangeTree.parentIndex;\n }\n\n const parentMetadata = parent?.constructor?.[Symbol.metadata];\n this.isFiltered = (parent && parentMetadata?.[-2]?.includes(parentIndex));\n\n //\n // TODO: refactor this!\n //\n // swapping `changes` and `filteredChanges` is required here\n // because \"isFiltered\" may not be imedialely available on `change()`\n //\n if (this.isFiltered) {\n this.filteredChanges = new Map<number, OPERATION>();\n this.allFilteredChanges = new Map<number, OPERATION>();\n\n if (this.changes.size > 0) {\n // swap changes reference\n const changes = this.changes;\n this.changes = this.filteredChanges;\n this.filteredChanges = changes;\n\n // swap \"all changes\" reference\n const allFilteredChanges = this.allFilteredChanges;\n this.allFilteredChanges = this.allChanges;\n this.allChanges = allFilteredChanges;\n }\n }\n }\n }\n\n}\n"]}
|
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
1
|
import { OPERATION } from "../encoding/spec";
|
|
3
2
|
import type { ChangeTree, Ref } from "./ChangeTree";
|
|
4
3
|
import type { Encoder } from "./Encoder";
|
|
5
|
-
import type { Schema } from "../Schema";
|
|
6
|
-
import type { PrimitiveType } from "../annotations";
|
|
7
4
|
import type { Iterator } from "../encoding/decode";
|
|
8
5
|
export type EncodeOperation<T extends Ref = any> = (encoder: Encoder, bytes: Buffer, changeTree: ChangeTree<T>, index: number, operation: OPERATION, it: Iterator, isEncodeAll: boolean, hasView: boolean) => void;
|
|
9
|
-
export declare function
|
|
10
|
-
export declare function encodeValue(encoder: Encoder, bytes: Buffer, ref: Ref, type: any, value: any, field: string | number, operation: OPERATION, it: Iterator): void;
|
|
6
|
+
export declare function encodeValue(encoder: Encoder, bytes: Buffer, type: any, value: any, operation: OPERATION, it: Iterator): void;
|
|
11
7
|
/**
|
|
12
8
|
* Used for Schema instances.
|
|
13
9
|
* @private
|