@colyseus/schema 3.0.76 → 4.0.0
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 +781 -434
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +779 -435
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +781 -434
- package/lib/Metadata.js +1 -5
- package/lib/Metadata.js.map +1 -1
- package/lib/Reflection.d.ts +50 -17
- package/lib/Reflection.js +151 -202
- package/lib/Reflection.js.map +1 -1
- package/lib/Schema.d.ts +13 -1
- package/lib/Schema.js +73 -9
- package/lib/Schema.js.map +1 -1
- package/lib/annotations.d.ts +6 -1
- package/lib/annotations.js +8 -34
- package/lib/annotations.js.map +1 -1
- package/lib/bench_encode.js +34 -1
- package/lib/bench_encode.js.map +1 -1
- package/lib/codegen/api.js +35 -2
- package/lib/codegen/api.js.map +1 -1
- package/lib/codegen/cli.js +4 -1
- package/lib/codegen/cli.js.map +1 -1
- package/lib/codegen/parser.js +35 -2
- package/lib/codegen/parser.js.map +1 -1
- package/lib/codegen/types.js +34 -1
- package/lib/codegen/types.js.map +1 -1
- package/lib/decoder/DecodeOperation.d.ts +2 -2
- package/lib/decoder/DecodeOperation.js +3 -3
- package/lib/decoder/DecodeOperation.js.map +1 -1
- package/lib/decoder/Decoder.d.ts +3 -3
- package/lib/decoder/Decoder.js +2 -2
- package/lib/decoder/Decoder.js.map +1 -1
- package/lib/decoder/ReferenceTracker.d.ts +0 -1
- package/lib/decoder/ReferenceTracker.js +9 -7
- package/lib/decoder/ReferenceTracker.js.map +1 -1
- package/lib/decoder/strategy/Callbacks.d.ts +154 -0
- package/lib/decoder/strategy/Callbacks.js +340 -0
- package/lib/decoder/strategy/Callbacks.js.map +1 -0
- package/lib/decoder/strategy/{StateCallbacks.d.ts → getDecoderStateCallbacks.d.ts} +6 -0
- package/lib/decoder/strategy/{StateCallbacks.js → getDecoderStateCallbacks.js} +17 -10
- package/lib/decoder/strategy/getDecoderStateCallbacks.js.map +1 -0
- package/lib/encoder/ChangeTree.d.ts +2 -2
- package/lib/encoder/ChangeTree.js.map +1 -1
- package/lib/encoder/EncodeOperation.d.ts +2 -2
- package/lib/encoder/EncodeOperation.js +3 -3
- package/lib/encoder/EncodeOperation.js.map +1 -1
- package/lib/encoder/Encoder.d.ts +6 -6
- package/lib/encoder/Encoder.js +19 -18
- package/lib/encoder/Encoder.js.map +1 -1
- package/lib/encoder/Root.js +17 -14
- package/lib/encoder/Root.js.map +1 -1
- package/lib/encoder/StateView.js +13 -12
- package/lib/encoder/StateView.js.map +1 -1
- package/lib/encoding/decode.d.ts +2 -2
- package/lib/encoding/encode.d.ts +3 -1
- package/lib/encoding/encode.js.map +1 -1
- package/lib/index.d.ts +3 -2
- package/lib/index.js +7 -3
- package/lib/index.js.map +1 -1
- package/lib/types/HelperTypes.d.ts +7 -14
- package/lib/types/HelperTypes.js.map +1 -1
- package/lib/types/custom/ArraySchema.d.ts +2 -1
- package/lib/types/custom/ArraySchema.js.map +1 -1
- package/lib/types/custom/CollectionSchema.d.ts +2 -1
- package/lib/types/custom/CollectionSchema.js.map +1 -1
- package/lib/types/custom/MapSchema.d.ts +3 -2
- package/lib/types/custom/MapSchema.js.map +1 -1
- package/lib/types/custom/SetSchema.d.ts +2 -1
- package/lib/types/custom/SetSchema.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/utils.js +1 -1
- package/lib/utils.js.map +1 -1
- package/package.json +12 -16
- package/src/Metadata.ts +1 -5
- package/src/Reflection.ts +185 -174
- package/src/Schema.ts +81 -13
- package/src/annotations.ts +14 -40
- package/src/codegen/parser.ts +1 -1
- package/src/decoder/DecodeOperation.ts +9 -9
- package/src/decoder/Decoder.ts +6 -6
- package/src/decoder/ReferenceTracker.ts +10 -8
- package/src/decoder/strategy/Callbacks.ts +547 -0
- package/src/decoder/strategy/{StateCallbacks.ts → getDecoderStateCallbacks.ts} +17 -11
- package/src/encoder/ChangeTree.ts +4 -7
- package/src/encoder/EncodeOperation.ts +9 -9
- package/src/encoder/Encoder.ts +26 -18
- package/src/encoder/Root.ts +20 -15
- package/src/encoder/StateView.ts +15 -13
- package/src/encoding/encode.ts +1 -1
- package/src/index.ts +3 -2
- package/src/types/HelperTypes.ts +13 -11
- package/src/types/custom/ArraySchema.ts +2 -1
- package/src/types/custom/CollectionSchema.ts +4 -2
- package/src/types/custom/MapSchema.ts +4 -2
- package/src/types/custom/SetSchema.ts +3 -1
- package/src/types/symbols.ts +1 -0
- package/src/utils.ts +2 -2
- 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/decoder/strategy/StateCallbacks.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
package/src/Schema.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { DEFAULT_VIEW_TAG, type DefinitionType } from "./annotations";
|
|
|
4
4
|
import { AssignableProps, NonFunctionPropNames, ToJSON } from './types/HelperTypes';
|
|
5
5
|
|
|
6
6
|
import { ChangeSet, ChangeSetName, ChangeTree, IRef, Ref } from './encoder/ChangeTree';
|
|
7
|
-
import { $changes, $decoder, $deleteByIndex, $descriptors, $encoder, $filter, $getByIndex, $track } from './types/symbols';
|
|
7
|
+
import { $changes, $decoder, $deleteByIndex, $descriptors, $encoder, $filter, $getByIndex, $refId, $track } from './types/symbols';
|
|
8
8
|
import { StateView } from './encoder/StateView';
|
|
9
9
|
|
|
10
10
|
import { encodeSchemaOperation } from './encoder/EncodeOperation';
|
|
@@ -22,6 +22,8 @@ export class Schema<C = any> implements IRef {
|
|
|
22
22
|
static [$encoder] = encodeSchemaOperation;
|
|
23
23
|
static [$decoder] = decodeSchemaOperation;
|
|
24
24
|
|
|
25
|
+
[$refId]?: number;
|
|
26
|
+
|
|
25
27
|
/**
|
|
26
28
|
* Assign the property descriptors required to track changes on this instance.
|
|
27
29
|
* @param instance
|
|
@@ -95,13 +97,79 @@ export class Schema<C = any> implements IRef {
|
|
|
95
97
|
}
|
|
96
98
|
}
|
|
97
99
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
100
|
+
/**
|
|
101
|
+
* Assign properties to the instance.
|
|
102
|
+
* @param props Properties to assign to the instance
|
|
103
|
+
* @returns
|
|
104
|
+
*/
|
|
105
|
+
public assign<T extends Partial<this>>(props: AssignableProps<T>,): this {
|
|
101
106
|
Object.assign(this, props);
|
|
102
107
|
return this;
|
|
103
108
|
}
|
|
104
109
|
|
|
110
|
+
/**
|
|
111
|
+
* Restore the instance from JSON data.
|
|
112
|
+
* @param jsonData JSON data to restore the instance from
|
|
113
|
+
* @returns
|
|
114
|
+
*/
|
|
115
|
+
public restore(jsonData: ToJSON<this>): this {
|
|
116
|
+
const metadata: Metadata = (this.constructor as typeof Schema)[Symbol.metadata];
|
|
117
|
+
|
|
118
|
+
for (const fieldIndex in metadata) {
|
|
119
|
+
const field = metadata[fieldIndex as any as number];
|
|
120
|
+
const fieldName = field.name as keyof this;
|
|
121
|
+
const fieldType = field.type;
|
|
122
|
+
const value = (jsonData as any)[fieldName];
|
|
123
|
+
|
|
124
|
+
if (value === undefined || value === null) {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (typeof fieldType === "string") {
|
|
129
|
+
// Primitive type: assign directly
|
|
130
|
+
this[fieldName] = value;
|
|
131
|
+
|
|
132
|
+
} else if (Schema.is(fieldType)) {
|
|
133
|
+
// Schema type: create instance and restore
|
|
134
|
+
const instance = new (fieldType as typeof Schema)();
|
|
135
|
+
instance.restore(value);
|
|
136
|
+
this[fieldName] = instance as any;
|
|
137
|
+
|
|
138
|
+
} else if (typeof fieldType === "object") {
|
|
139
|
+
// Collection types: { map: ... }, { array: ... }, etc.
|
|
140
|
+
const collectionType = Object.keys(fieldType)[0] as string;
|
|
141
|
+
const childType = (fieldType as any)[collectionType];
|
|
142
|
+
|
|
143
|
+
if (collectionType === "map") {
|
|
144
|
+
const mapSchema = this[fieldName] as any;
|
|
145
|
+
for (const key in value) {
|
|
146
|
+
if (Schema.is(childType)) {
|
|
147
|
+
const childInstance = new (childType as typeof Schema)();
|
|
148
|
+
childInstance.restore(value[key]);
|
|
149
|
+
mapSchema.set(key, childInstance);
|
|
150
|
+
} else {
|
|
151
|
+
mapSchema.set(key, value[key]);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
} else if (collectionType === "array") {
|
|
156
|
+
const arraySchema = this[fieldName] as any;
|
|
157
|
+
for (let i = 0; i < value.length; i++) {
|
|
158
|
+
if (Schema.is(childType)) {
|
|
159
|
+
const childInstance = new (childType as typeof Schema)();
|
|
160
|
+
childInstance.restore(value[i]);
|
|
161
|
+
arraySchema.push(childInstance);
|
|
162
|
+
} else {
|
|
163
|
+
arraySchema.push(value[i]);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return this;
|
|
171
|
+
}
|
|
172
|
+
|
|
105
173
|
/**
|
|
106
174
|
* (Server-side): Flag a property to be encoded for the next patch.
|
|
107
175
|
* @param instance Schema instance
|
|
@@ -190,7 +258,7 @@ export class Schema<C = any> implements IRef {
|
|
|
190
258
|
const contents = (showContents) ? ` - ${JSON.stringify(ref.toJSON())}` : "";
|
|
191
259
|
const changeTree: ChangeTree = ref[$changes];
|
|
192
260
|
|
|
193
|
-
const refId = (
|
|
261
|
+
const refId = (ref as IRef)[$refId];
|
|
194
262
|
const root = (decoder) ? decoder.root : changeTree.root;
|
|
195
263
|
|
|
196
264
|
// log reference count if > 1
|
|
@@ -218,7 +286,7 @@ export class Schema<C = any> implements IRef {
|
|
|
218
286
|
let current = ref[$changes].root[changeSet].next;
|
|
219
287
|
while (current) {
|
|
220
288
|
if (current.changeTree) {
|
|
221
|
-
encodeOrder.push(current.changeTree.refId);
|
|
289
|
+
encodeOrder.push(current.changeTree.ref[$refId]);
|
|
222
290
|
}
|
|
223
291
|
current = current.next;
|
|
224
292
|
}
|
|
@@ -243,7 +311,7 @@ export class Schema<C = any> implements IRef {
|
|
|
243
311
|
const changeSet = (isEncodeAll) ? changeTree.allChanges : changeTree.changes;
|
|
244
312
|
const changeSetName = (isEncodeAll) ? "allChanges" : "changes";
|
|
245
313
|
|
|
246
|
-
let output = `${instance.constructor.name} (${
|
|
314
|
+
let output = `${instance.constructor.name} (${instance[$refId]}) -> .${changeSetName}:\n`;
|
|
247
315
|
|
|
248
316
|
function dumpChangeSet(changeSet: ChangeSet) {
|
|
249
317
|
changeSet.operations
|
|
@@ -262,7 +330,7 @@ export class Schema<C = any> implements IRef {
|
|
|
262
330
|
changeTree.filteredChanges &&
|
|
263
331
|
(changeTree.filteredChanges.operations).filter(op => op).length > 0
|
|
264
332
|
) {
|
|
265
|
-
output += `${instance.constructor.name} (${
|
|
333
|
+
output += `${instance.constructor.name} (${instance[$refId]}) -> .filteredChanges:\n`;
|
|
266
334
|
dumpChangeSet(changeTree.filteredChanges);
|
|
267
335
|
}
|
|
268
336
|
|
|
@@ -272,7 +340,7 @@ export class Schema<C = any> implements IRef {
|
|
|
272
340
|
changeTree.allFilteredChanges &&
|
|
273
341
|
(changeTree.allFilteredChanges.operations).filter(op => op).length > 0
|
|
274
342
|
) {
|
|
275
|
-
output += `${instance.constructor.name} (${
|
|
343
|
+
output += `${instance.constructor.name} (${instance[$refId]}) -> .allFilteredChanges:\n`;
|
|
276
344
|
dumpChangeSet(changeTree.allFilteredChanges);
|
|
277
345
|
}
|
|
278
346
|
|
|
@@ -313,14 +381,14 @@ export class Schema<C = any> implements IRef {
|
|
|
313
381
|
}
|
|
314
382
|
|
|
315
383
|
if (includeChangeTree) {
|
|
316
|
-
instanceRefIds.push(changeTree.refId);
|
|
384
|
+
instanceRefIds.push(changeTree.ref[$refId]);
|
|
317
385
|
totalOperations += Object.keys(changes).length;
|
|
318
386
|
changeTrees.set(changeTree, parentChangeTrees.reverse());
|
|
319
387
|
}
|
|
320
388
|
}
|
|
321
389
|
|
|
322
390
|
output += "---\n"
|
|
323
|
-
output += `root refId: ${rootChangeTree.refId}\n`;
|
|
391
|
+
output += `root refId: ${rootChangeTree.ref[$refId]}\n`;
|
|
324
392
|
output += `Total instances: ${instanceRefIds.length} (refIds: ${instanceRefIds.join(", ")})\n`;
|
|
325
393
|
output += `Total changes: ${totalOperations}\n`;
|
|
326
394
|
output += "---\n"
|
|
@@ -330,7 +398,7 @@ export class Schema<C = any> implements IRef {
|
|
|
330
398
|
for (const [changeTree, parentChangeTrees] of changeTrees.entries()) {
|
|
331
399
|
parentChangeTrees.forEach((parentChangeTree, level) => {
|
|
332
400
|
if (!visitedParents.has(parentChangeTree)) {
|
|
333
|
-
output += `${getIndent(level)}${parentChangeTree.ref.constructor.name} (refId: ${parentChangeTree.refId})\n`;
|
|
401
|
+
output += `${getIndent(level)}${parentChangeTree.ref.constructor.name} (refId: ${parentChangeTree.ref[$refId]})\n`;
|
|
334
402
|
visitedParents.add(parentChangeTree);
|
|
335
403
|
}
|
|
336
404
|
});
|
|
@@ -340,7 +408,7 @@ export class Schema<C = any> implements IRef {
|
|
|
340
408
|
const indent = getIndent(level);
|
|
341
409
|
|
|
342
410
|
const parentIndex = (level > 0) ? `(${changeTree.parentIndex}) ` : "";
|
|
343
|
-
output += `${indent}${parentIndex}${changeTree.ref.constructor.name} (refId: ${changeTree.refId}) - changes: ${Object.keys(changes).length}\n`;
|
|
411
|
+
output += `${indent}${parentIndex}${changeTree.ref.constructor.name} (refId: ${changeTree.ref[$refId]}) - changes: ${Object.keys(changes).length}\n`;
|
|
344
412
|
|
|
345
413
|
for (const index in changes) {
|
|
346
414
|
const operation = changes[index];
|
package/src/annotations.ts
CHANGED
|
@@ -33,11 +33,11 @@ export type PrimitiveType = RawPrimitiveType | typeof Schema | object;
|
|
|
33
33
|
// TODO: infer "default" value type correctly.
|
|
34
34
|
export type DefinitionType<T extends PrimitiveType = PrimitiveType> = T
|
|
35
35
|
| T[]
|
|
36
|
-
| { type: T, default?: InferValueType<T>, view?: boolean | number }
|
|
37
|
-
| { array: T, default?: ArraySchema<InferValueType<T>>, view?: boolean | number }
|
|
38
|
-
| { map: T, default?: MapSchema<InferValueType<T>>, view?: boolean | number }
|
|
39
|
-
| { collection: T, default?: CollectionSchema<InferValueType<T>>, view?: boolean | number }
|
|
40
|
-
| { set: T, default?: SetSchema<InferValueType<T>>, view?: boolean | number };
|
|
36
|
+
| { type: T, default?: InferValueType<T>, view?: boolean | number, sync?: boolean }
|
|
37
|
+
| { array: T, default?: ArraySchema<InferValueType<T>>, view?: boolean | number, sync?: boolean }
|
|
38
|
+
| { map: T, default?: MapSchema<InferValueType<T>>, view?: boolean | number, sync?: boolean }
|
|
39
|
+
| { collection: T, default?: CollectionSchema<InferValueType<T>>, view?: boolean | number, sync?: boolean }
|
|
40
|
+
| { set: T, default?: SetSchema<InferValueType<T>>, view?: boolean | number, sync?: boolean };
|
|
41
41
|
|
|
42
42
|
export type Definition = { [field: string]: DefinitionType };
|
|
43
43
|
|
|
@@ -574,7 +574,10 @@ export function schema<
|
|
|
574
574
|
: value['view'];
|
|
575
575
|
}
|
|
576
576
|
|
|
577
|
-
|
|
577
|
+
// allow to define a field as not synced
|
|
578
|
+
if (value['sync'] !== false) {
|
|
579
|
+
fields[fieldName] = getNormalizedType(value);
|
|
580
|
+
}
|
|
578
581
|
|
|
579
582
|
// If no explicit default provided, handle automatic instantiation for collection types
|
|
580
583
|
if (!Object.prototype.hasOwnProperty.call(value, 'default')) {
|
|
@@ -597,12 +600,7 @@ export function schema<
|
|
|
597
600
|
|
|
598
601
|
} else if (value['type'] !== undefined && Schema.is(value['type'])) {
|
|
599
602
|
// Direct Schema type: Type → new Type()
|
|
600
|
-
|
|
601
|
-
// only auto-initialize Schema instances if:
|
|
602
|
-
// - they don't have an initialize method
|
|
603
|
-
// - or initialize method doesn't accept any parameters
|
|
604
|
-
defaultValues[fieldName] = new value['type']();
|
|
605
|
-
}
|
|
603
|
+
defaultValues[fieldName] = new value['type']();
|
|
606
604
|
}
|
|
607
605
|
} else {
|
|
608
606
|
defaultValues[fieldName] = value['default'];
|
|
@@ -612,12 +610,7 @@ export function schema<
|
|
|
612
610
|
} else if (typeof (value) === "function") {
|
|
613
611
|
if (Schema.is(value)) {
|
|
614
612
|
// Direct Schema type: Type → new Type()
|
|
615
|
-
|
|
616
|
-
// only auto-initialize Schema instances if:
|
|
617
|
-
// - they don't have an initialize method
|
|
618
|
-
// - or initialize method doesn't accept any parameters
|
|
619
|
-
defaultValues[fieldName] = new value();
|
|
620
|
-
}
|
|
613
|
+
defaultValues[fieldName] = new value();
|
|
621
614
|
fields[fieldName] = getNormalizedType(value);
|
|
622
615
|
} else {
|
|
623
616
|
methods[fieldName] = value;
|
|
@@ -645,33 +638,14 @@ export function schema<
|
|
|
645
638
|
return defaults;
|
|
646
639
|
};
|
|
647
640
|
|
|
648
|
-
const getParentProps = (props: any) => {
|
|
649
|
-
const fieldNames = Object.keys(fields);
|
|
650
|
-
const parentProps: any = {};
|
|
651
|
-
for (const key in props) {
|
|
652
|
-
if (!fieldNames.includes(key)) {
|
|
653
|
-
parentProps[key] = props[key];
|
|
654
|
-
}
|
|
655
|
-
}
|
|
656
|
-
return parentProps;
|
|
657
|
-
}
|
|
658
|
-
|
|
659
641
|
/** @codegen-ignore */
|
|
660
642
|
const klass = Metadata.setFields<any>(class extends (inherits as any) {
|
|
661
643
|
constructor(...args: any[]) {
|
|
644
|
+
super(Object.assign({}, getDefaultValues(), args[0] || {}));
|
|
645
|
+
|
|
662
646
|
// call initialize method
|
|
663
647
|
if (methods.initialize && typeof methods.initialize === 'function') {
|
|
664
|
-
|
|
665
|
-
/**
|
|
666
|
-
* only call initialize() in the current class, not the parent ones.
|
|
667
|
-
* see "should not call initialize automatically when creating an instance of inherited Schema"
|
|
668
|
-
*/
|
|
669
|
-
if (new.target === klass) {
|
|
670
|
-
methods.initialize.apply(this, args);
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
} else {
|
|
674
|
-
super(Object.assign({}, getDefaultValues(), args[0] || {}));
|
|
648
|
+
methods.initialize.apply(this, args);
|
|
675
649
|
}
|
|
676
650
|
}
|
|
677
651
|
}, fields) as SchemaWithExtendsConstructor<T, ExtractInitProps<T>, P>;
|
package/src/codegen/parser.ts
CHANGED
|
@@ -326,7 +326,7 @@ function inspectNode(node: ts.Node, context: Context, decoratorName: string) {
|
|
|
326
326
|
break;
|
|
327
327
|
}
|
|
328
328
|
|
|
329
|
-
ts.forEachChild(node, (n) => inspectNode(n, context, decoratorName));
|
|
329
|
+
ts.forEachChild(node, (n: ts.Node) => inspectNode(n, context, decoratorName));
|
|
330
330
|
}
|
|
331
331
|
|
|
332
332
|
let parsedFiles: { [filename: string]: boolean };
|
|
@@ -4,7 +4,7 @@ import { Schema } from "../Schema";
|
|
|
4
4
|
import type { Ref } from "../encoder/ChangeTree";
|
|
5
5
|
import type { Decoder } from "./Decoder";
|
|
6
6
|
import { Iterator, decode } from "../encoding/decode";
|
|
7
|
-
import { $childType, $deleteByIndex, $getByIndex } from "../types/symbols";
|
|
7
|
+
import { $childType, $deleteByIndex, $getByIndex, $refId } from "../types/symbols";
|
|
8
8
|
|
|
9
9
|
import type { MapSchema } from "../types/custom/MapSchema";
|
|
10
10
|
import type { ArraySchema } from "../types/custom/ArraySchema";
|
|
@@ -27,7 +27,7 @@ export const DEFINITION_MISMATCH = -1;
|
|
|
27
27
|
|
|
28
28
|
export type DecodeOperation<T extends Schema = any> = (
|
|
29
29
|
decoder: Decoder<T>,
|
|
30
|
-
bytes:
|
|
30
|
+
bytes: Uint8Array,
|
|
31
31
|
it: Iterator,
|
|
32
32
|
ref: Ref,
|
|
33
33
|
allChanges: DataChange[],
|
|
@@ -39,7 +39,7 @@ export function decodeValue<T extends Ref>(
|
|
|
39
39
|
ref: T,
|
|
40
40
|
index: number,
|
|
41
41
|
type: any,
|
|
42
|
-
bytes:
|
|
42
|
+
bytes: Uint8Array,
|
|
43
43
|
it: Iterator,
|
|
44
44
|
allChanges: DataChange[],
|
|
45
45
|
) {
|
|
@@ -51,7 +51,7 @@ export function decodeValue<T extends Ref>(
|
|
|
51
51
|
if ((operation & OPERATION.DELETE) === OPERATION.DELETE)
|
|
52
52
|
{
|
|
53
53
|
// Flag `refId` for garbage collection.
|
|
54
|
-
const previousRefId = $
|
|
54
|
+
const previousRefId = previousValue?.[$refId];
|
|
55
55
|
if (previousRefId !== undefined) { $root.removeRef(previousRefId); }
|
|
56
56
|
|
|
57
57
|
//
|
|
@@ -107,7 +107,7 @@ export function decodeValue<T extends Ref>(
|
|
|
107
107
|
value[$childType] = Object.values(type)[0]; // cache childType for ArraySchema and MapSchema
|
|
108
108
|
|
|
109
109
|
if (previousValue) {
|
|
110
|
-
let previousRefId = $
|
|
110
|
+
let previousRefId = previousValue[$refId];
|
|
111
111
|
|
|
112
112
|
if (previousRefId !== undefined && refId !== previousRefId) {
|
|
113
113
|
//
|
|
@@ -120,7 +120,7 @@ export function decodeValue<T extends Ref>(
|
|
|
120
120
|
|
|
121
121
|
// if value is a schema, remove its reference
|
|
122
122
|
if (typeof(value) === "object") {
|
|
123
|
-
previousRefId = $
|
|
123
|
+
previousRefId = value[$refId];
|
|
124
124
|
$root.removeRef(previousRefId);
|
|
125
125
|
}
|
|
126
126
|
|
|
@@ -148,7 +148,7 @@ export function decodeValue<T extends Ref>(
|
|
|
148
148
|
|
|
149
149
|
export const decodeSchemaOperation: DecodeOperation = function <T extends Schema>(
|
|
150
150
|
decoder: Decoder<any>,
|
|
151
|
-
bytes:
|
|
151
|
+
bytes: Uint8Array,
|
|
152
152
|
it: Iterator,
|
|
153
153
|
ref: T,
|
|
154
154
|
allChanges: DataChange[],
|
|
@@ -197,7 +197,7 @@ export const decodeSchemaOperation: DecodeOperation = function <T extends Schema
|
|
|
197
197
|
|
|
198
198
|
export const decodeKeyValueOperation: DecodeOperation = function (
|
|
199
199
|
decoder: Decoder<any>,
|
|
200
|
-
bytes:
|
|
200
|
+
bytes: Uint8Array,
|
|
201
201
|
it: Iterator,
|
|
202
202
|
ref: Ref,
|
|
203
203
|
allChanges: DataChange[]
|
|
@@ -280,7 +280,7 @@ export const decodeKeyValueOperation: DecodeOperation = function (
|
|
|
280
280
|
|
|
281
281
|
export const decodeArray: DecodeOperation = function (
|
|
282
282
|
decoder: Decoder<any>,
|
|
283
|
-
bytes:
|
|
283
|
+
bytes: Uint8Array,
|
|
284
284
|
it: Iterator,
|
|
285
285
|
ref: ArraySchema,
|
|
286
286
|
allChanges: DataChange[]
|
package/src/decoder/Decoder.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { TypeContext } from "../types/TypeContext";
|
|
2
|
-
import { $changes, $childType, $decoder, $onDecodeEnd } from "../types/symbols";
|
|
2
|
+
import { $changes, $childType, $decoder, $onDecodeEnd, $refId } from "../types/symbols";
|
|
3
3
|
import { Schema } from "../Schema";
|
|
4
4
|
|
|
5
5
|
import { decode } from "../encoding/decode";
|
|
@@ -38,7 +38,7 @@ export class Decoder<T extends Schema = any> {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
decode(
|
|
41
|
-
bytes:
|
|
41
|
+
bytes: Uint8Array,
|
|
42
42
|
it: Iterator = { offset: 0 },
|
|
43
43
|
ref: Ref = this.state,
|
|
44
44
|
) {
|
|
@@ -102,7 +102,7 @@ export class Decoder<T extends Schema = any> {
|
|
|
102
102
|
return allChanges;
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
skipCurrentStructure(bytes:
|
|
105
|
+
skipCurrentStructure(bytes: Uint8Array, it: Iterator, totalBytes: number) {
|
|
106
106
|
//
|
|
107
107
|
// keep skipping next bytes until reaches a known structure
|
|
108
108
|
// by local decoder.
|
|
@@ -119,7 +119,7 @@ export class Decoder<T extends Schema = any> {
|
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
getInstanceType(bytes:
|
|
122
|
+
getInstanceType(bytes: Uint8Array, it: Iterator, defaultType: typeof Schema): typeof Schema {
|
|
123
123
|
let type: typeof Schema;
|
|
124
124
|
|
|
125
125
|
if (bytes[it.offset] === TYPE_ID) {
|
|
@@ -137,7 +137,7 @@ export class Decoder<T extends Schema = any> {
|
|
|
137
137
|
|
|
138
138
|
removeChildRefs(ref: Collection, allChanges: DataChange[]) {
|
|
139
139
|
const needRemoveRef = typeof ((ref as any)[$childType]) !== "string";
|
|
140
|
-
const refId =
|
|
140
|
+
const refId = (ref as Ref)[$refId];
|
|
141
141
|
|
|
142
142
|
ref.forEach((value: any, key: any) => {
|
|
143
143
|
allChanges.push({
|
|
@@ -150,7 +150,7 @@ export class Decoder<T extends Schema = any> {
|
|
|
150
150
|
});
|
|
151
151
|
|
|
152
152
|
if (needRemoveRef) {
|
|
153
|
-
this.root.removeRef(
|
|
153
|
+
this.root.removeRef(value[$refId]);
|
|
154
154
|
}
|
|
155
155
|
});
|
|
156
156
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Metadata } from "../Metadata";
|
|
2
|
-
import { $childType } from "../types/symbols";
|
|
2
|
+
import { $childType, $refId } from "../types/symbols";
|
|
3
3
|
import { Ref } from "../encoder/ChangeTree";
|
|
4
4
|
import { spliceOne } from "../types/utils";
|
|
5
5
|
import { OPERATION } from "../encoding/spec";
|
|
@@ -26,7 +26,6 @@ export class ReferenceTracker {
|
|
|
26
26
|
// For direct access of structures during decoding time.
|
|
27
27
|
//
|
|
28
28
|
public refs = new Map<number, Ref>();
|
|
29
|
-
public refIds = new WeakMap<Ref, number>();
|
|
30
29
|
|
|
31
30
|
public refCount: { [refId: number]: number; } = {};
|
|
32
31
|
public deletedRefs = new Set<number>();
|
|
@@ -41,7 +40,7 @@ export class ReferenceTracker {
|
|
|
41
40
|
// for decoding
|
|
42
41
|
addRef(refId: number, ref: Ref, incrementCount: boolean = true) {
|
|
43
42
|
this.refs.set(refId, ref);
|
|
44
|
-
|
|
43
|
+
ref[$refId] = refId;
|
|
45
44
|
|
|
46
45
|
if (incrementCount) {
|
|
47
46
|
this.refCount[refId] = (this.refCount[refId] || 0) + 1;
|
|
@@ -104,9 +103,12 @@ export class ReferenceTracker {
|
|
|
104
103
|
const metadata: Metadata = (ref.constructor as typeof Schema)[Symbol.metadata];
|
|
105
104
|
for (const index in metadata) {
|
|
106
105
|
const field = metadata[index as any as number].name;
|
|
107
|
-
const
|
|
108
|
-
if (
|
|
109
|
-
|
|
106
|
+
const child = ref[field as keyof Ref];
|
|
107
|
+
if (typeof(child) === "object" && child) {
|
|
108
|
+
const childRefId = (child as any)[$refId];
|
|
109
|
+
if (childRefId !== undefined && !this.deletedRefs.has(childRefId)) {
|
|
110
|
+
this.removeRef(childRefId);
|
|
111
|
+
}
|
|
110
112
|
}
|
|
111
113
|
}
|
|
112
114
|
|
|
@@ -114,8 +116,8 @@ export class ReferenceTracker {
|
|
|
114
116
|
if (typeof ((ref as any)[$childType]) === "function") {
|
|
115
117
|
Array.from((ref as MapSchema).values())
|
|
116
118
|
.forEach((child) => {
|
|
117
|
-
const childRefId =
|
|
118
|
-
if (!this.deletedRefs.has(childRefId)) {
|
|
119
|
+
const childRefId = child[$refId];
|
|
120
|
+
if (childRefId !== undefined && !this.deletedRefs.has(childRefId)) {
|
|
119
121
|
this.removeRef(childRefId);
|
|
120
122
|
}
|
|
121
123
|
});
|