@colyseus/schema 3.0.0-alpha.34 → 3.0.0-alpha.35
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/bin/schema-debug +4 -3
- package/build/cjs/index.js +465 -303
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +465 -303
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +465 -303
- package/lib/Metadata.d.ts +5 -5
- package/lib/Metadata.js +17 -17
- package/lib/Metadata.js.map +1 -1
- package/lib/Schema.js +24 -17
- package/lib/Schema.js.map +1 -1
- package/lib/annotations.js +11 -11
- package/lib/annotations.js.map +1 -1
- package/lib/bench_encode.js +12 -5
- package/lib/bench_encode.js.map +1 -1
- package/lib/decoder/Decoder.js +1 -1
- package/lib/decoder/Decoder.js.map +1 -1
- package/lib/encoder/ChangeTree.d.ts +23 -7
- package/lib/encoder/ChangeTree.js +183 -106
- package/lib/encoder/ChangeTree.js.map +1 -1
- package/lib/encoder/EncodeOperation.d.ts +2 -1
- package/lib/encoder/EncodeOperation.js +2 -2
- package/lib/encoder/EncodeOperation.js.map +1 -1
- package/lib/encoder/Encoder.d.ts +3 -5
- package/lib/encoder/Encoder.js +93 -61
- package/lib/encoder/Encoder.js.map +1 -1
- package/lib/encoder/Root.d.ts +12 -7
- package/lib/encoder/Root.js +41 -20
- package/lib/encoder/Root.js.map +1 -1
- package/lib/encoder/StateView.d.ts +5 -5
- package/lib/encoder/StateView.js +29 -23
- package/lib/encoder/StateView.js.map +1 -1
- package/lib/encoding/encode.js +12 -9
- package/lib/encoding/encode.js.map +1 -1
- package/lib/types/TypeContext.js +2 -1
- package/lib/types/TypeContext.js.map +1 -1
- package/lib/types/custom/ArraySchema.js +27 -13
- package/lib/types/custom/ArraySchema.js.map +1 -1
- package/lib/types/custom/MapSchema.d.ts +3 -1
- package/lib/types/custom/MapSchema.js +7 -4
- package/lib/types/custom/MapSchema.js.map +1 -1
- package/lib/types/symbols.d.ts +8 -6
- package/lib/types/symbols.js +9 -7
- package/lib/types/symbols.js.map +1 -1
- package/lib/utils.js +6 -3
- package/lib/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/Metadata.ts +22 -22
- package/src/Schema.ts +33 -25
- package/src/annotations.ts +12 -12
- package/src/bench_encode.ts +15 -6
- package/src/decoder/Decoder.ts +1 -1
- package/src/encoder/ChangeTree.ts +220 -115
- package/src/encoder/EncodeOperation.ts +5 -1
- package/src/encoder/Encoder.ts +110 -68
- package/src/encoder/Root.ts +41 -21
- package/src/encoder/StateView.ts +32 -28
- package/src/encoding/encode.ts +12 -9
- package/src/types/TypeContext.ts +2 -1
- package/src/types/custom/ArraySchema.ts +39 -17
- package/src/types/custom/MapSchema.ts +12 -5
- package/src/types/symbols.ts +10 -9
- package/src/utils.ts +7 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { $changes, $childType, $decoder, $deleteByIndex, $onEncodeEnd, $encoder, $filter, $getByIndex, $onDecodeEnd
|
|
1
|
+
import { $changes, $childType, $decoder, $deleteByIndex, $onEncodeEnd, $encoder, $filter, $getByIndex, $onDecodeEnd } from "../symbols";
|
|
2
2
|
import type { Schema } from "../../Schema";
|
|
3
|
-
import { ChangeTree } from "../../encoder/ChangeTree";
|
|
3
|
+
import { ChangeTree, setOperationAtIndex } from "../../encoder/ChangeTree";
|
|
4
4
|
import { OPERATION } from "../../encoding/spec";
|
|
5
5
|
import { registerType } from "../registry";
|
|
6
6
|
import { Collection } from "../HelperTypes";
|
|
@@ -70,6 +70,7 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
|
|
|
70
70
|
get: (obj, prop) => {
|
|
71
71
|
if (
|
|
72
72
|
typeof (prop) !== "symbol" &&
|
|
73
|
+
// FIXME: d8 accuses this as low performance
|
|
73
74
|
!isNaN(prop as any) // https://stackoverflow.com/a/175787/892698
|
|
74
75
|
) {
|
|
75
76
|
return this.items[prop];
|
|
@@ -89,7 +90,7 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
|
|
|
89
90
|
assertInstanceType(setValue, obj[$childType] as typeof Schema, obj, key);
|
|
90
91
|
|
|
91
92
|
if (obj.items[key as unknown as number] !== undefined) {
|
|
92
|
-
if (setValue[$changes]
|
|
93
|
+
if (setValue[$changes].isNew) {
|
|
93
94
|
this[$changes].indexedOperation(Number(key), OPERATION.MOVE_AND_ADD);
|
|
94
95
|
|
|
95
96
|
} else {
|
|
@@ -99,7 +100,7 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
|
|
|
99
100
|
this[$changes].indexedOperation(Number(key), OPERATION.MOVE);
|
|
100
101
|
}
|
|
101
102
|
}
|
|
102
|
-
} else if (setValue[$changes]
|
|
103
|
+
} else if (setValue[$changes].isNew) {
|
|
103
104
|
this[$changes].indexedOperation(Number(key), OPERATION.ADD);
|
|
104
105
|
}
|
|
105
106
|
|
|
@@ -138,7 +139,10 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
|
|
|
138
139
|
|
|
139
140
|
this[$changes] = new ChangeTree(proxy);
|
|
140
141
|
this[$changes].indexes = {};
|
|
141
|
-
|
|
142
|
+
|
|
143
|
+
if (items.length > 0) {
|
|
144
|
+
this.push(...items);
|
|
145
|
+
}
|
|
142
146
|
|
|
143
147
|
return proxy;
|
|
144
148
|
}
|
|
@@ -160,16 +164,22 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
|
|
|
160
164
|
push(...values: V[]) {
|
|
161
165
|
let length = this.tmpItems.length;
|
|
162
166
|
|
|
163
|
-
|
|
164
|
-
|
|
167
|
+
const changeTree = this[$changes];
|
|
168
|
+
|
|
169
|
+
// values.forEach((value, i) => {
|
|
170
|
+
|
|
171
|
+
for (let i = 0, l = values.length; i < values.length; i++, length++) {
|
|
172
|
+
const value = values[i];
|
|
173
|
+
|
|
165
174
|
if (value === undefined || value === null) {
|
|
175
|
+
// skip null values
|
|
166
176
|
return;
|
|
167
177
|
|
|
168
178
|
} else if (typeof (value) === "object" && this[$childType]) {
|
|
169
179
|
assertInstanceType(value as any, this[$childType] as typeof Schema, this, i);
|
|
180
|
+
// TODO: move value[$changes]?.setParent() to this block.
|
|
170
181
|
}
|
|
171
182
|
|
|
172
|
-
const changeTree = this[$changes];
|
|
173
183
|
changeTree.indexedOperation(length, OPERATION.ADD, this.items.length);
|
|
174
184
|
|
|
175
185
|
this.items.push(value);
|
|
@@ -180,9 +190,10 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
|
|
|
180
190
|
// (to avoid encoding "refId" operations before parent's "ADD" operation)
|
|
181
191
|
//
|
|
182
192
|
value[$changes]?.setParent(this, changeTree.root, length);
|
|
193
|
+
}
|
|
183
194
|
|
|
184
|
-
|
|
185
|
-
});
|
|
195
|
+
// length++;
|
|
196
|
+
// });
|
|
186
197
|
|
|
187
198
|
return length;
|
|
188
199
|
}
|
|
@@ -209,6 +220,8 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
|
|
|
209
220
|
this[$changes].delete(index, undefined, this.items.length - 1);
|
|
210
221
|
|
|
211
222
|
// this.tmpItems[index] = undefined;
|
|
223
|
+
// this.tmpItems.pop();
|
|
224
|
+
|
|
212
225
|
this.deletedIndexes[index] = true;
|
|
213
226
|
|
|
214
227
|
return this.items.pop();
|
|
@@ -270,10 +283,12 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
|
|
|
270
283
|
|
|
271
284
|
clear() {
|
|
272
285
|
// skip if already clear
|
|
273
|
-
if (this.items.length === 0) {
|
|
286
|
+
if (this.items.length === 0) {
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
274
289
|
|
|
275
290
|
// discard previous operations.
|
|
276
|
-
const changeTree = this[$changes]
|
|
291
|
+
const changeTree = this[$changes];
|
|
277
292
|
|
|
278
293
|
// discard children
|
|
279
294
|
changeTree.forEachChild((changeTree, _) => {
|
|
@@ -285,9 +300,12 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
|
|
|
285
300
|
//
|
|
286
301
|
// TODO: do not use [$changes] at decoding time.
|
|
287
302
|
//
|
|
288
|
-
changeTree.root
|
|
289
|
-
|
|
290
|
-
|
|
303
|
+
const root = changeTree.root;
|
|
304
|
+
if (root !== undefined) {
|
|
305
|
+
root.removeChangeFromChangeSet("changes", changeTree);
|
|
306
|
+
root.removeChangeFromChangeSet("allChanges", changeTree);
|
|
307
|
+
root.removeChangeFromChangeSet("allFilteredChanges", changeTree);
|
|
308
|
+
}
|
|
291
309
|
});
|
|
292
310
|
|
|
293
311
|
changeTree.discard(true);
|
|
@@ -338,6 +356,8 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
|
|
|
338
356
|
changeTree.delete(index);
|
|
339
357
|
changeTree.shiftAllChangeIndexes(-1, index);
|
|
340
358
|
|
|
359
|
+
// this.deletedIndexes[index] = true;
|
|
360
|
+
|
|
341
361
|
return this.items.shift();
|
|
342
362
|
}
|
|
343
363
|
|
|
@@ -437,9 +457,11 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
|
|
|
437
457
|
|
|
438
458
|
// new index
|
|
439
459
|
if (changeTree.isFiltered) {
|
|
440
|
-
changeTree.filteredChanges
|
|
460
|
+
setOperationAtIndex(changeTree.filteredChanges, this.items.length);
|
|
461
|
+
// changeTree.filteredChanges[this.items.length] = OPERATION.ADD;
|
|
441
462
|
} else {
|
|
442
|
-
changeTree.allChanges
|
|
463
|
+
setOperationAtIndex(changeTree.allChanges, this.items.length);
|
|
464
|
+
// changeTree.allChanges[this.items.length] = OPERATION.ADD;
|
|
443
465
|
}
|
|
444
466
|
|
|
445
467
|
// FIXME: should we use OPERATION.MOVE here instead?
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $changes, $childType, $decoder, $deleteByIndex, $onEncodeEnd, $encoder, $filter, $getByIndex } from "../symbols";
|
|
1
|
+
import { $changes, $childType, $decoder, $deleteByIndex, $onEncodeEnd, $encoder, $filter, $getByIndex, $numFields } from "../symbols";
|
|
2
2
|
import { ChangeTree } from "../../encoder/ChangeTree";
|
|
3
3
|
import { OPERATION } from "../../encoding/spec";
|
|
4
4
|
import { registerType } from "../registry";
|
|
@@ -15,6 +15,8 @@ export class MapSchema<V=any, K extends string = string> implements Map<K, V>, C
|
|
|
15
15
|
protected $items: Map<K, V> = new Map<K, V>();
|
|
16
16
|
protected $indexes: Map<number, K> = new Map<number, K>();
|
|
17
17
|
|
|
18
|
+
protected [$changes]: ChangeTree;
|
|
19
|
+
|
|
18
20
|
static [$encoder] = encodeKeyValueOperation;
|
|
19
21
|
static [$decoder] = decodeKeyValueOperation;
|
|
20
22
|
|
|
@@ -90,7 +92,7 @@ export class MapSchema<V=any, K extends string = string> implements Map<K, V>, C
|
|
|
90
92
|
|
|
91
93
|
const index = (isReplace)
|
|
92
94
|
? changeTree.indexes[key]
|
|
93
|
-
: changeTree.indexes[
|
|
95
|
+
: changeTree.indexes[$numFields] ?? 0;
|
|
94
96
|
|
|
95
97
|
let operation: OPERATION = (isReplace)
|
|
96
98
|
? OPERATION.REPLACE
|
|
@@ -105,7 +107,7 @@ export class MapSchema<V=any, K extends string = string> implements Map<K, V>, C
|
|
|
105
107
|
if (!isReplace) {
|
|
106
108
|
this.$indexes.set(index, key);
|
|
107
109
|
changeTree.indexes[key] = index;
|
|
108
|
-
changeTree.indexes[
|
|
110
|
+
changeTree.indexes[$numFields] = index + 1;
|
|
109
111
|
|
|
110
112
|
} else if (
|
|
111
113
|
!isRef &&
|
|
@@ -208,8 +210,13 @@ export class MapSchema<V=any, K extends string = string> implements Map<K, V>, C
|
|
|
208
210
|
|
|
209
211
|
protected [$onEncodeEnd]() {
|
|
210
212
|
const changeTree = this[$changes];
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
+
const keys = Object.keys(changeTree.indexedOperations);
|
|
214
|
+
|
|
215
|
+
for (let i = 0, len = keys.length; i < len; i++) {
|
|
216
|
+
const key = keys[i];
|
|
217
|
+
const fieldIndex = Number(key);
|
|
218
|
+
const operation = changeTree.indexedOperations[key];
|
|
219
|
+
|
|
213
220
|
if (operation === OPERATION.DELETE) {
|
|
214
221
|
const index = this[$getByIndex](fieldIndex) as string;
|
|
215
222
|
delete changeTree.indexes[index];
|
package/src/types/symbols.ts
CHANGED
|
@@ -7,8 +7,6 @@ export const $filter = Symbol("$filter");
|
|
|
7
7
|
export const $getByIndex = Symbol("$getByIndex");
|
|
8
8
|
export const $deleteByIndex = Symbol("$deleteByIndex");
|
|
9
9
|
|
|
10
|
-
export const $descriptors = Symbol("$descriptors");
|
|
11
|
-
|
|
12
10
|
/**
|
|
13
11
|
* Used to hold ChangeTree instances whitin the structures
|
|
14
12
|
*/
|
|
@@ -20,12 +18,6 @@ export const $changes = Symbol('$changes');
|
|
|
20
18
|
*/
|
|
21
19
|
export const $childType = Symbol('$childType');
|
|
22
20
|
|
|
23
|
-
/**
|
|
24
|
-
* Special ChangeTree property to identify new instances
|
|
25
|
-
* (Once they're encoded, they're not new anymore)
|
|
26
|
-
*/
|
|
27
|
-
export const $isNew = Symbol("$isNew");
|
|
28
|
-
|
|
29
21
|
/**
|
|
30
22
|
* Optional "discard" method for custom types (ArraySchema)
|
|
31
23
|
* (Discards changes for next serialization)
|
|
@@ -35,4 +27,13 @@ export const $onEncodeEnd = Symbol('$onEncodeEnd');
|
|
|
35
27
|
/**
|
|
36
28
|
* When decoding, this method is called after the instance is fully decoded
|
|
37
29
|
*/
|
|
38
|
-
export const $onDecodeEnd = Symbol("$onDecodeEnd");
|
|
30
|
+
export const $onDecodeEnd = Symbol("$onDecodeEnd");
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Metadata
|
|
34
|
+
*/
|
|
35
|
+
export const $descriptors = Symbol("$descriptors");
|
|
36
|
+
export const $numFields = "$__numFields";
|
|
37
|
+
export const $refTypeFieldIndexes = "$__refTypeFieldIndexes";
|
|
38
|
+
export const $viewFieldIndexes = "$__viewFieldIndexes";
|
|
39
|
+
export const $fieldIndexesByViewTag = "$__fieldIndexesByViewTag";
|
package/src/utils.ts
CHANGED
|
@@ -27,13 +27,17 @@ export function dumpChanges(schema: Schema) {
|
|
|
27
27
|
refs: []
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
-
$root.changes
|
|
30
|
+
// for (const refId in $root.changes) {
|
|
31
|
+
$root.changes.forEach(changeTree => {
|
|
32
|
+
const changes = changeTree.indexedOperations;
|
|
33
|
+
|
|
31
34
|
dump.refs.push(`refId#${changeTree.refId}`);
|
|
32
|
-
|
|
35
|
+
for (const index in changes) {
|
|
36
|
+
const op = changes[index];
|
|
33
37
|
const opName = OPERATION[op];
|
|
34
38
|
if (!dump.ops[opName]) { dump.ops[opName] = 0; }
|
|
35
39
|
dump.ops[OPERATION[op]]++;
|
|
36
|
-
}
|
|
40
|
+
}
|
|
37
41
|
});
|
|
38
42
|
|
|
39
43
|
return dump;
|