@colyseus/schema 3.0.0-alpha.24 → 3.0.0-alpha.26
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 +84 -90
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +84 -90
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +84 -90
- package/lib/Metadata.js +1 -1
- package/lib/Metadata.js.map +1 -1
- package/lib/Reflection.js +1 -3
- package/lib/Reflection.js.map +1 -1
- package/lib/Schema.d.ts +1 -1
- package/lib/Schema.js +2 -2
- package/lib/Schema.js.map +1 -1
- package/lib/annotations.js +19 -5
- package/lib/annotations.js.map +1 -1
- package/lib/decoder/DecodeOperation.js +1 -0
- package/lib/decoder/DecodeOperation.js.map +1 -1
- package/lib/decoder/Decoder.d.ts +1 -1
- package/lib/decoder/Decoder.js +2 -2
- package/lib/decoder/Decoder.js.map +1 -1
- package/lib/encoder/ChangeTree.js +3 -2
- package/lib/encoder/ChangeTree.js.map +1 -1
- package/lib/encoder/Encoder.d.ts +3 -3
- package/lib/encoder/Encoder.js +10 -16
- package/lib/encoder/Encoder.js.map +1 -1
- package/lib/encoder/StateView.d.ts +2 -2
- package/lib/encoder/StateView.js +45 -60
- package/lib/encoder/StateView.js.map +1 -1
- package/package.json +1 -1
- package/src/Metadata.ts +1 -1
- package/src/Reflection.ts +1 -3
- package/src/Schema.ts +2 -2
- package/src/annotations.ts +24 -5
- package/src/decoder/DecodeOperation.ts +4 -1
- package/src/decoder/Decoder.ts +3 -2
- package/src/encoder/ChangeTree.ts +4 -2
- package/src/encoder/Encoder.ts +11 -19
- package/src/encoder/StateView.ts +50 -69
package/src/encoder/Encoder.ts
CHANGED
|
@@ -20,14 +20,16 @@ export class Encoder<T extends Schema = any> {
|
|
|
20
20
|
|
|
21
21
|
root: Root;
|
|
22
22
|
|
|
23
|
-
constructor(
|
|
24
|
-
this.
|
|
23
|
+
constructor(state: T) {
|
|
24
|
+
this.root = new Root();
|
|
25
25
|
|
|
26
26
|
//
|
|
27
27
|
// TODO: cache and restore "Context" based on root schema
|
|
28
28
|
// (to avoid creating a new context for every new room)
|
|
29
29
|
//
|
|
30
|
-
this.context = new TypeContext(
|
|
30
|
+
this.context = new TypeContext(state.constructor as typeof Schema);
|
|
31
|
+
|
|
32
|
+
this.setState(state);
|
|
31
33
|
|
|
32
34
|
// console.log(">>>>>>>>>>>>>>>> Encoder types");
|
|
33
35
|
// this.context.schemas.forEach((id, schema) => {
|
|
@@ -35,16 +37,9 @@ export class Encoder<T extends Schema = any> {
|
|
|
35
37
|
// });
|
|
36
38
|
}
|
|
37
39
|
|
|
38
|
-
protected
|
|
39
|
-
this.root = new Root();
|
|
40
|
+
protected setState(state: T) {
|
|
40
41
|
this.state = state;
|
|
41
|
-
|
|
42
|
-
// Workaround to allow using an empty Schema.
|
|
43
|
-
if (state.constructor[Symbol.metadata] === undefined) {
|
|
44
|
-
Metadata.init(state);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
state[$changes].setRoot(this.root);
|
|
42
|
+
this.state[$changes].setRoot(this.root);
|
|
48
43
|
}
|
|
49
44
|
|
|
50
45
|
encode(
|
|
@@ -53,9 +48,8 @@ export class Encoder<T extends Schema = any> {
|
|
|
53
48
|
buffer = this.sharedBuffer,
|
|
54
49
|
changeTrees = this.root.changes,
|
|
55
50
|
isEncodeAll = this.root.allChanges === changeTrees,
|
|
51
|
+
initialOffset = it.offset // cache current offset in case we need to resize the buffer
|
|
56
52
|
): Buffer {
|
|
57
|
-
const initialOffset = it.offset; // cache current offset in case we need to resize the buffer
|
|
58
|
-
|
|
59
53
|
const hasView = (view !== undefined);
|
|
60
54
|
const rootChangeTree = this.state[$changes];
|
|
61
55
|
|
|
@@ -102,8 +96,6 @@ export class Encoder<T extends Schema = any> {
|
|
|
102
96
|
// TODO: avoid checking if no view tags were defined
|
|
103
97
|
//
|
|
104
98
|
if (filter && !filter(ref, fieldIndex, view)) {
|
|
105
|
-
// console.log("SKIP FIELD:", { ref: changeTree.ref.constructor.name, fieldIndex, })
|
|
106
|
-
|
|
107
99
|
// console.log("ADD AS INVISIBLE:", fieldIndex, changeTree.ref.constructor.name)
|
|
108
100
|
// view?.invisible.add(changeTree);
|
|
109
101
|
continue;
|
|
@@ -200,9 +192,6 @@ export class Encoder<T extends Schema = any> {
|
|
|
200
192
|
encodeView(view: StateView, sharedOffset: number, it: Iterator, bytes = this.sharedBuffer) {
|
|
201
193
|
const viewOffset = it.offset;
|
|
202
194
|
|
|
203
|
-
// try to encode "filtered" changes
|
|
204
|
-
this.encode(it, view, bytes, this.root.filteredChanges);
|
|
205
|
-
|
|
206
195
|
// encode visibility changes (add/remove for this view)
|
|
207
196
|
const viewChangesIterator = view.changes.entries();
|
|
208
197
|
for (const [changeTree, changes] of viewChangesIterator) {
|
|
@@ -236,6 +225,9 @@ export class Encoder<T extends Schema = any> {
|
|
|
236
225
|
// clear "view" changes after encoding
|
|
237
226
|
view.changes.clear();
|
|
238
227
|
|
|
228
|
+
// try to encode "filtered" changes
|
|
229
|
+
this.encode(it, view, bytes, this.root.filteredChanges, false, viewOffset);
|
|
230
|
+
|
|
239
231
|
return Buffer.concat([
|
|
240
232
|
bytes.subarray(0, sharedOffset),
|
|
241
233
|
bytes.subarray(viewOffset, it.offset)
|
package/src/encoder/StateView.ts
CHANGED
|
@@ -28,7 +28,7 @@ export class StateView {
|
|
|
28
28
|
changes = new Map<ChangeTree, Map<number, OPERATION>>();
|
|
29
29
|
|
|
30
30
|
// TODO: allow to set multiple tags at once
|
|
31
|
-
add(obj: Ref, tag: number = DEFAULT_VIEW_TAG) {
|
|
31
|
+
add(obj: Ref, tag: number = DEFAULT_VIEW_TAG, checkIncludeParent: boolean = true) {
|
|
32
32
|
if (!obj[$changes]) {
|
|
33
33
|
console.warn("StateView#add(), invalid object:", obj);
|
|
34
34
|
return this;
|
|
@@ -36,22 +36,15 @@ export class StateView {
|
|
|
36
36
|
|
|
37
37
|
// FIXME: ArraySchema/MapSchema does not have metadata
|
|
38
38
|
const metadata: Metadata = obj.constructor[Symbol.metadata];
|
|
39
|
-
|
|
40
|
-
let changeTree: ChangeTree = obj[$changes];
|
|
39
|
+
const changeTree: ChangeTree = obj[$changes];
|
|
41
40
|
this.items.add(changeTree);
|
|
42
41
|
|
|
43
|
-
//
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
this.add(change.ref, tag);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
// add parent ChangeTree's, if they are invisible to this view
|
|
53
|
-
// TODO: REFACTOR addParent()
|
|
54
|
-
this.addParent(changeTree, tag);
|
|
42
|
+
// add parent ChangeTree's
|
|
43
|
+
// - if it was invisible to this view
|
|
44
|
+
// - if it were previously filtered out
|
|
45
|
+
if (checkIncludeParent && changeTree.parent) {
|
|
46
|
+
this.addParent(changeTree.parent[$changes], changeTree.parentIndex, tag);
|
|
47
|
+
}
|
|
55
48
|
|
|
56
49
|
//
|
|
57
50
|
// TODO: when adding an item of a MapSchema, the changes may not
|
|
@@ -85,89 +78,77 @@ export class StateView {
|
|
|
85
78
|
});
|
|
86
79
|
|
|
87
80
|
} else {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
// // add default tag properties
|
|
92
|
-
// metadata?.[-3]?.[DEFAULT_VIEW_TAG]?.forEach((index) => {
|
|
93
|
-
// if (changeTree.getChange(index) !== OPERATION.DELETE) {
|
|
94
|
-
// changes.set(index, OPERATION.ADD);
|
|
95
|
-
// }
|
|
96
|
-
// });
|
|
97
|
-
|
|
98
|
-
const allChangesSet = (changeTree.isFiltered || changeTree.isPartiallyFiltered)
|
|
81
|
+
const isInvisible = this.invisible.has(changeTree);
|
|
82
|
+
const changeSet = (changeTree.isFiltered || changeTree.isPartiallyFiltered)
|
|
99
83
|
? changeTree.allFilteredChanges
|
|
100
84
|
: changeTree.allChanges;
|
|
101
|
-
const it = allChangesSet.keys();
|
|
102
|
-
const isInvisible = this.invisible.has(changeTree);
|
|
103
85
|
|
|
104
|
-
|
|
86
|
+
changeSet.forEach((op, index) => {
|
|
87
|
+
const tagAtIndex = metadata?.[metadata?.[index]].tag;
|
|
105
88
|
if (
|
|
106
|
-
(
|
|
107
|
-
|
|
89
|
+
(
|
|
90
|
+
isInvisible || // if "invisible", include all
|
|
91
|
+
tagAtIndex === undefined || // "all change" with no tag
|
|
92
|
+
tagAtIndex === tag // tagged property
|
|
93
|
+
) &&
|
|
94
|
+
op !== OPERATION.DELETE
|
|
108
95
|
) {
|
|
109
|
-
changes.set(index,
|
|
96
|
+
changes.set(index, op);
|
|
110
97
|
}
|
|
111
|
-
}
|
|
98
|
+
});
|
|
112
99
|
}
|
|
113
100
|
|
|
114
|
-
//
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
(
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
this.
|
|
121
|
-
}
|
|
101
|
+
// Add children of this ChangeTree to this view
|
|
102
|
+
changeTree.forEachChild((change, index) => {
|
|
103
|
+
// Do not ADD children that don't have the same tag
|
|
104
|
+
if (metadata && metadata[metadata[index]].tag !== tag) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
this.add(change.ref, tag, false);
|
|
108
|
+
});
|
|
122
109
|
|
|
123
110
|
return this;
|
|
124
111
|
}
|
|
125
112
|
|
|
126
|
-
protected addParent(changeTree: ChangeTree, tag: number) {
|
|
127
|
-
|
|
128
|
-
|
|
113
|
+
protected addParent(changeTree: ChangeTree, parentIndex: number, tag: number) {
|
|
114
|
+
// view must have all "changeTree" parent tree
|
|
115
|
+
this.items.add(changeTree);
|
|
129
116
|
|
|
130
|
-
|
|
131
|
-
const
|
|
117
|
+
// add parent's parent
|
|
118
|
+
const parentChangeTree = changeTree.parent?.[$changes];
|
|
119
|
+
if (parentChangeTree && (parentChangeTree.isFiltered || parentChangeTree.isPartiallyFiltered)) {
|
|
120
|
+
this.addParent(parentChangeTree, changeTree.parentIndex, tag);
|
|
121
|
+
}
|
|
132
122
|
|
|
133
|
-
|
|
134
|
-
|
|
123
|
+
// parent is already available, no need to add it!
|
|
124
|
+
if (!this.invisible.has(changeTree)) {
|
|
135
125
|
return;
|
|
136
126
|
}
|
|
137
127
|
|
|
138
|
-
this.addParent(parentChangeTree, tag);
|
|
139
|
-
|
|
140
128
|
// add parent's tag properties
|
|
141
|
-
if (
|
|
129
|
+
if (changeTree.getChange(parentIndex) !== OPERATION.DELETE) {
|
|
142
130
|
|
|
143
|
-
let
|
|
144
|
-
if (
|
|
145
|
-
|
|
146
|
-
this.changes.set(
|
|
131
|
+
let changes = this.changes.get(changeTree);
|
|
132
|
+
if (changes === undefined) {
|
|
133
|
+
changes = new Map<number, OPERATION>();
|
|
134
|
+
this.changes.set(changeTree, changes);
|
|
147
135
|
}
|
|
148
136
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
// parentChange: (
|
|
153
|
-
// parentChangeTree.getChange(parentIndex) &&
|
|
154
|
-
// OPERATION[parentChangeTree.getChange(parentIndex)]
|
|
155
|
-
// ),
|
|
156
|
-
// })
|
|
137
|
+
if (!this.tags) {
|
|
138
|
+
this.tags = new WeakMap<ChangeTree, Set<number>>();
|
|
139
|
+
}
|
|
157
140
|
|
|
158
|
-
if (!this.tags) { this.tags = new WeakMap<ChangeTree, Set<number>>(); }
|
|
159
141
|
let tags: Set<number>;
|
|
160
|
-
if (!this.tags.has(
|
|
142
|
+
if (!this.tags.has(changeTree)) {
|
|
161
143
|
tags = new Set<number>();
|
|
162
|
-
this.tags.set(
|
|
144
|
+
this.tags.set(changeTree, tags);
|
|
163
145
|
} else {
|
|
164
|
-
tags = this.tags.get(
|
|
146
|
+
tags = this.tags.get(changeTree);
|
|
165
147
|
}
|
|
166
148
|
tags.add(tag);
|
|
167
149
|
|
|
168
|
-
|
|
150
|
+
changes.set(parentIndex, OPERATION.ADD);
|
|
169
151
|
}
|
|
170
|
-
|
|
171
152
|
}
|
|
172
153
|
|
|
173
154
|
remove(obj: Ref, tag: number = DEFAULT_VIEW_TAG) {
|