@colyseus/schema 3.0.0-alpha.4 → 3.0.0-alpha.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +148 -62
- package/bin/schema-debug +94 -0
- package/build/cjs/index.js +2201 -1507
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +2198 -1506
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +2208 -1514
- package/lib/Metadata.d.ts +21 -9
- package/lib/Metadata.js +169 -32
- package/lib/Metadata.js.map +1 -1
- package/lib/Reflection.d.ts +19 -4
- package/lib/Reflection.js +66 -32
- package/lib/Reflection.js.map +1 -1
- package/lib/Schema.d.ts +4 -4
- package/lib/Schema.js +44 -50
- package/lib/Schema.js.map +1 -1
- package/lib/annotations.d.ts +31 -34
- package/lib/annotations.js +110 -160
- package/lib/annotations.js.map +1 -1
- package/lib/bench_encode.d.ts +1 -0
- package/lib/bench_encode.js +130 -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 +2 -46
- 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 +85 -3
- package/lib/codegen/parser.js.map +1 -1
- package/lib/codegen/types.js +6 -3
- package/lib/codegen/types.js.map +1 -1
- package/lib/debug.d.ts +1 -0
- package/lib/debug.js +51 -0
- package/lib/debug.js.map +1 -0
- package/lib/decoder/DecodeOperation.d.ts +3 -4
- package/lib/decoder/DecodeOperation.js +37 -19
- package/lib/decoder/DecodeOperation.js.map +1 -1
- package/lib/decoder/Decoder.d.ts +6 -7
- package/lib/decoder/Decoder.js +14 -14
- 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 +27 -21
- package/lib/encoder/ChangeTree.js +246 -186
- package/lib/encoder/ChangeTree.js.map +1 -1
- package/lib/encoder/EncodeOperation.d.ts +3 -6
- package/lib/encoder/EncodeOperation.js +51 -65
- package/lib/encoder/EncodeOperation.js.map +1 -1
- package/lib/encoder/Encoder.d.ts +9 -8
- package/lib/encoder/Encoder.js +168 -91
- package/lib/encoder/Encoder.js.map +1 -1
- package/lib/encoder/Root.d.ts +22 -0
- package/lib/encoder/Root.js +81 -0
- package/lib/encoder/Root.js.map +1 -0
- package/lib/encoder/StateView.d.ts +7 -7
- package/lib/encoder/StateView.js +70 -74
- package/lib/encoder/StateView.js.map +1 -1
- package/lib/encoding/assert.d.ts +7 -6
- package/lib/encoding/assert.js +13 -5
- package/lib/encoding/assert.js.map +1 -1
- package/lib/encoding/decode.d.ts +35 -20
- package/lib/encoding/decode.js +43 -87
- package/lib/encoding/decode.js.map +1 -1
- package/lib/encoding/encode.d.ts +36 -17
- package/lib/encoding/encode.js +82 -68
- package/lib/encoding/encode.js.map +1 -1
- package/lib/encoding/spec.d.ts +4 -5
- package/lib/encoding/spec.js +1 -2
- package/lib/encoding/spec.js.map +1 -1
- package/lib/index.d.ts +10 -9
- package/lib/index.js +24 -17
- package/lib/index.js.map +1 -1
- package/lib/types/HelperTypes.d.ts +34 -2
- package/lib/types/HelperTypes.js.map +1 -1
- package/lib/types/TypeContext.d.ts +23 -0
- package/lib/types/TypeContext.js +111 -0
- package/lib/types/TypeContext.js.map +1 -0
- package/lib/types/custom/ArraySchema.d.ts +2 -2
- package/lib/types/custom/ArraySchema.js +33 -22
- package/lib/types/custom/ArraySchema.js.map +1 -1
- package/lib/types/custom/CollectionSchema.js +1 -0
- package/lib/types/custom/CollectionSchema.js.map +1 -1
- package/lib/types/custom/MapSchema.d.ts +3 -1
- package/lib/types/custom/MapSchema.js +12 -4
- 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.d.ts +8 -1
- package/lib/types/registry.js +23 -6
- package/lib/types/registry.js.map +1 -1
- package/lib/types/symbols.d.ts +8 -5
- package/lib/types/symbols.js +9 -6
- package/lib/types/symbols.js.map +1 -1
- package/lib/types/utils.js +1 -2
- package/lib/types/utils.js.map +1 -1
- package/lib/utils.js +9 -7
- package/lib/utils.js.map +1 -1
- package/package.json +7 -6
- package/src/Metadata.ts +190 -42
- package/src/Reflection.ts +77 -39
- package/src/Schema.ts +59 -64
- package/src/annotations.ts +156 -202
- package/src/bench_encode.ts +108 -0
- package/src/codegen/languages/csharp.ts +1 -47
- package/src/codegen/parser.ts +107 -0
- package/src/codegen/types.ts +1 -0
- package/src/debug.ts +55 -0
- package/src/decoder/DecodeOperation.ts +46 -18
- package/src/decoder/Decoder.ts +17 -15
- package/src/decoder/ReferenceTracker.ts +3 -2
- package/src/decoder/strategy/StateCallbacks.ts +153 -82
- package/src/encoder/ChangeTree.ts +286 -202
- package/src/encoder/EncodeOperation.ts +78 -78
- package/src/encoder/Encoder.ts +202 -97
- package/src/encoder/Root.ts +93 -0
- package/src/encoder/StateView.ts +76 -88
- package/src/encoding/assert.ts +17 -8
- package/src/encoding/decode.ts +62 -97
- package/src/encoding/encode.ts +99 -65
- package/src/encoding/spec.ts +3 -5
- package/src/index.ts +12 -20
- package/src/types/HelperTypes.ts +54 -2
- package/src/types/TypeContext.ts +133 -0
- package/src/types/custom/ArraySchema.ts +49 -19
- package/src/types/custom/CollectionSchema.ts +1 -0
- package/src/types/custom/MapSchema.ts +18 -5
- package/src/types/custom/SetSchema.ts +1 -0
- package/src/types/registry.ts +22 -3
- package/src/types/symbols.ts +10 -7
- package/src/utils.ts +7 -3
package/src/Reflection.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { type, PrimitiveType, DefinitionType
|
|
1
|
+
import { type, PrimitiveType, DefinitionType } from "./annotations";
|
|
2
|
+
import { TypeContext } from "./types/TypeContext";
|
|
2
3
|
import { Metadata } from "./Metadata";
|
|
3
4
|
import { ArraySchema } from "./types/custom/ArraySchema";
|
|
4
5
|
import { Iterator } from "./encoding/decode";
|
|
5
6
|
import { Encoder } from "./encoder/Encoder";
|
|
6
7
|
import { Decoder } from "./decoder/Decoder";
|
|
7
8
|
import { Schema } from "./Schema";
|
|
9
|
+
import { $numFields } from "./types/symbols";
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
* Reflection
|
|
@@ -22,18 +24,32 @@ export class ReflectionType extends Schema {
|
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
export class Reflection extends Schema {
|
|
25
|
-
@type([
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
@type([ReflectionType]) types: ArraySchema<ReflectionType> = new ArraySchema<ReflectionType>();
|
|
28
|
+
@type("number") rootType: number;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Encodes the TypeContext of an Encoder into a buffer.
|
|
32
|
+
*
|
|
33
|
+
* @param encoder Encoder instance
|
|
34
|
+
* @param it
|
|
35
|
+
* @returns
|
|
36
|
+
*/
|
|
37
|
+
static encode(encoder: Encoder, it: Iterator = { offset: 0 }) {
|
|
38
|
+
const context = encoder.context;
|
|
31
39
|
|
|
32
40
|
const reflection = new Reflection();
|
|
33
|
-
const
|
|
41
|
+
const reflectionEncoder = new Encoder(reflection);
|
|
42
|
+
|
|
43
|
+
// rootType is usually the first schema passed to the Encoder
|
|
44
|
+
// (unless it inherits from another schema)
|
|
45
|
+
const rootType = context.schemas.get(encoder.state.constructor);
|
|
46
|
+
if (rootType > 0) { reflection.rootType = rootType; }
|
|
34
47
|
|
|
35
48
|
const buildType = (currentType: ReflectionType, metadata: Metadata) => {
|
|
36
|
-
for (const
|
|
49
|
+
for (const fieldIndex in metadata) {
|
|
50
|
+
const index = Number(fieldIndex);
|
|
51
|
+
const fieldName = metadata[index].name;
|
|
52
|
+
|
|
37
53
|
// skip fields from parent classes
|
|
38
54
|
if (!Object.prototype.hasOwnProperty.call(metadata, fieldName)) {
|
|
39
55
|
continue;
|
|
@@ -44,7 +60,7 @@ export class Reflection extends Schema {
|
|
|
44
60
|
|
|
45
61
|
let fieldType: string;
|
|
46
62
|
|
|
47
|
-
const type = metadata[
|
|
63
|
+
const type = metadata[index].type;
|
|
48
64
|
|
|
49
65
|
if (typeof (type) === "string") {
|
|
50
66
|
fieldType = type;
|
|
@@ -96,73 +112,95 @@ export class Reflection extends Schema {
|
|
|
96
112
|
buildType(type, klass[Symbol.metadata]);
|
|
97
113
|
}
|
|
98
114
|
|
|
99
|
-
const
|
|
100
|
-
const buf = encoder.encodeAll(it);
|
|
115
|
+
const buf = reflectionEncoder.encodeAll(it);
|
|
101
116
|
return Buffer.from(buf, 0, it.offset);
|
|
102
117
|
}
|
|
103
118
|
|
|
104
|
-
|
|
119
|
+
/**
|
|
120
|
+
* Decodes the TypeContext from a buffer into a Decoder instance.
|
|
121
|
+
*
|
|
122
|
+
* @param bytes Reflection.encode() output
|
|
123
|
+
* @param it
|
|
124
|
+
* @returns Decoder instance
|
|
125
|
+
*/
|
|
126
|
+
static decode<T extends Schema = Schema>(bytes: Buffer, it?: Iterator): Decoder<T> {
|
|
105
127
|
const reflection = new Reflection();
|
|
106
128
|
|
|
107
129
|
const reflectionDecoder = new Decoder(reflection);
|
|
108
130
|
reflectionDecoder.decode(bytes, it);
|
|
109
131
|
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
const schemaTypes = reflection.types.reduce((types, reflectionType) => {
|
|
113
|
-
const parentKlass: typeof Schema = types[reflectionType.extendsId] || Schema;
|
|
114
|
-
const schema: typeof Schema = class _ extends parentKlass {};
|
|
132
|
+
const typeContext = new TypeContext();
|
|
115
133
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
134
|
+
// 1st pass, initialize metadata + inheritance
|
|
135
|
+
reflection.types.forEach((reflectionType) => {
|
|
136
|
+
const parentClass: typeof Schema = typeContext.get(reflectionType.extendsId) ?? Schema;
|
|
137
|
+
const schema: typeof Schema = class _ extends parentClass {};
|
|
119
138
|
|
|
120
139
|
// register for inheritance support
|
|
121
140
|
TypeContext.register(schema);
|
|
122
141
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
context.add(schema, typeid);
|
|
126
|
-
return types;
|
|
127
|
-
}, {});
|
|
142
|
+
// // for inheritance support
|
|
143
|
+
// Metadata.initialize(schema);
|
|
128
144
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const metadata = schemaType[Symbol.metadata];
|
|
132
|
-
|
|
133
|
-
const parentKlass = reflection.types[reflectionType.extendsId];
|
|
134
|
-
const parentFieldIndex = parentKlass && parentKlass.fields.length || 0;
|
|
145
|
+
typeContext.add(schema, reflectionType.id);
|
|
146
|
+
}, {});
|
|
135
147
|
|
|
148
|
+
// define fields
|
|
149
|
+
const addFields = (metadata: Metadata, reflectionType: ReflectionType, parentFieldIndex: number) => {
|
|
136
150
|
reflectionType.fields.forEach((field, i) => {
|
|
137
151
|
const fieldIndex = parentFieldIndex + i;
|
|
138
152
|
|
|
139
153
|
if (field.referencedType !== undefined) {
|
|
140
154
|
let fieldType = field.type;
|
|
141
|
-
let refType =
|
|
155
|
+
let refType: PrimitiveType = typeContext.get(field.referencedType);
|
|
142
156
|
|
|
143
157
|
// map or array of primitive type (-1)
|
|
144
158
|
if (!refType) {
|
|
145
159
|
const typeInfo = field.type.split(":");
|
|
146
160
|
fieldType = typeInfo[0];
|
|
147
|
-
refType = typeInfo[1];
|
|
161
|
+
refType = typeInfo[1] as PrimitiveType; // string
|
|
148
162
|
}
|
|
149
163
|
|
|
150
164
|
if (fieldType === "ref") {
|
|
151
|
-
// type(refType)(schemaType.prototype, field.name);
|
|
152
165
|
Metadata.addField(metadata, fieldIndex, field.name, refType);
|
|
153
166
|
|
|
154
167
|
} else {
|
|
155
|
-
|
|
156
|
-
Metadata.addField(metadata, fieldIndex, field.name, { [fieldType]: refType } as DefinitionType);
|
|
168
|
+
Metadata.addField(metadata, fieldIndex, field.name, { [fieldType]: refType });
|
|
157
169
|
}
|
|
158
170
|
|
|
159
171
|
} else {
|
|
160
|
-
// type(field.type as PrimitiveType)(schemaType.prototype, field.name);
|
|
161
172
|
Metadata.addField(metadata, fieldIndex, field.name, field.type as PrimitiveType);
|
|
162
173
|
}
|
|
163
174
|
});
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
// 2nd pass, set fields
|
|
178
|
+
reflection.types.forEach((reflectionType) => {
|
|
179
|
+
const schema = typeContext.get(reflectionType.id);
|
|
180
|
+
|
|
181
|
+
// for inheritance support
|
|
182
|
+
const metadata = Metadata.initialize(schema);
|
|
183
|
+
|
|
184
|
+
const inheritedTypes: ReflectionType[] = [];
|
|
185
|
+
|
|
186
|
+
let parentType: ReflectionType = reflectionType;
|
|
187
|
+
do {
|
|
188
|
+
inheritedTypes.push(parentType);
|
|
189
|
+
parentType = reflection.types.find((t) => t.id === parentType.extendsId);
|
|
190
|
+
} while (parentType);
|
|
191
|
+
|
|
192
|
+
let parentFieldIndex = 0;
|
|
193
|
+
|
|
194
|
+
inheritedTypes.reverse().forEach((reflectionType) => {
|
|
195
|
+
// add fields from all inherited classes
|
|
196
|
+
// TODO: refactor this to avoid adding fields from parent classes
|
|
197
|
+
addFields(metadata, reflectionType, parentFieldIndex);
|
|
198
|
+
parentFieldIndex += reflectionType.fields.length;
|
|
199
|
+
});
|
|
164
200
|
});
|
|
165
201
|
|
|
166
|
-
|
|
202
|
+
const state: T = new (typeContext.get(reflection.rootType || 0) as unknown as any)();
|
|
203
|
+
|
|
204
|
+
return new Decoder<T>(state, typeContext);
|
|
167
205
|
}
|
|
168
206
|
}
|
package/src/Schema.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { OPERATION } from './encoding/spec';
|
|
2
|
-
import { DEFAULT_VIEW_TAG, DefinitionType } from "./annotations";
|
|
2
|
+
import { DEFAULT_VIEW_TAG, type DefinitionType } from "./annotations";
|
|
3
3
|
|
|
4
4
|
import { NonFunctionPropNames, ToJSON } from './types/HelperTypes';
|
|
5
5
|
|
|
6
|
-
import { ChangeTree, Ref } from './encoder/ChangeTree';
|
|
7
|
-
import { $changes, $decoder, $deleteByIndex, $encoder, $filter, $getByIndex, $track } from './types/symbols';
|
|
6
|
+
import { ChangeSet, ChangeTree, Ref } from './encoder/ChangeTree';
|
|
7
|
+
import { $changes, $decoder, $deleteByIndex, $descriptors, $encoder, $filter, $getByIndex, $track } from './types/symbols';
|
|
8
8
|
import { StateView } from './encoder/StateView';
|
|
9
9
|
|
|
10
10
|
import { encodeSchemaOperation } from './encoder/EncodeOperation';
|
|
@@ -15,11 +15,12 @@ import { getIndent } from './utils';
|
|
|
15
15
|
/**
|
|
16
16
|
* Schema encoder / decoder
|
|
17
17
|
*/
|
|
18
|
-
export
|
|
19
|
-
|
|
18
|
+
export class Schema {
|
|
20
19
|
static [$encoder] = encodeSchemaOperation;
|
|
21
20
|
static [$decoder] = decodeSchemaOperation;
|
|
22
21
|
|
|
22
|
+
// public [$changes]: ChangeTree;
|
|
23
|
+
|
|
23
24
|
/**
|
|
24
25
|
* Assign the property descriptors required to track changes on this instance.
|
|
25
26
|
* @param instance
|
|
@@ -31,37 +32,7 @@ export abstract class Schema {
|
|
|
31
32
|
writable: true
|
|
32
33
|
});
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
// Define property descriptors
|
|
37
|
-
for (const field in metadata) {
|
|
38
|
-
if (metadata[field].descriptor) {
|
|
39
|
-
// for encoder
|
|
40
|
-
Object.defineProperty(instance, `_${field}`, {
|
|
41
|
-
value: undefined,
|
|
42
|
-
writable: true,
|
|
43
|
-
enumerable: false,
|
|
44
|
-
configurable: true,
|
|
45
|
-
});
|
|
46
|
-
Object.defineProperty(instance, field, metadata[field].descriptor);
|
|
47
|
-
|
|
48
|
-
} else {
|
|
49
|
-
// for decoder
|
|
50
|
-
Object.defineProperty(instance, field, {
|
|
51
|
-
value: undefined,
|
|
52
|
-
writable: true,
|
|
53
|
-
enumerable: true,
|
|
54
|
-
configurable: true,
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Object.defineProperty(instance, field, {
|
|
59
|
-
// ...instance.constructor[Symbol.metadata][field].descriptor
|
|
60
|
-
// });
|
|
61
|
-
// if (args[0]?.hasOwnProperty(field)) {
|
|
62
|
-
// instance[field] = args[0][field];
|
|
63
|
-
// }
|
|
64
|
-
}
|
|
35
|
+
Object.defineProperties(instance, instance.constructor[Symbol.metadata]?.[$descriptors] || {});
|
|
65
36
|
}
|
|
66
37
|
|
|
67
38
|
static is(type: DefinitionType) {
|
|
@@ -88,7 +59,7 @@ export abstract class Schema {
|
|
|
88
59
|
*/
|
|
89
60
|
static [$filter] (ref: Schema, index: number, view: StateView) {
|
|
90
61
|
const metadata: Metadata = ref.constructor[Symbol.metadata];
|
|
91
|
-
const tag = metadata[
|
|
62
|
+
const tag = metadata[index]?.tag;
|
|
92
63
|
|
|
93
64
|
if (view === undefined) {
|
|
94
65
|
// shared pass/encode: encode if doesn't have a tag
|
|
@@ -111,13 +82,17 @@ export abstract class Schema {
|
|
|
111
82
|
|
|
112
83
|
// allow inherited classes to have a constructor
|
|
113
84
|
constructor(...args: any[]) {
|
|
85
|
+
//
|
|
86
|
+
// inline
|
|
87
|
+
// Schema.initialize(this);
|
|
88
|
+
//
|
|
114
89
|
Schema.initialize(this);
|
|
115
90
|
|
|
116
91
|
//
|
|
117
92
|
// Assign initial values
|
|
118
93
|
//
|
|
119
94
|
if (args[0]) {
|
|
120
|
-
|
|
95
|
+
Object.assign(this, args[0]);
|
|
121
96
|
}
|
|
122
97
|
}
|
|
123
98
|
|
|
@@ -135,21 +110,25 @@ export abstract class Schema {
|
|
|
135
110
|
* @param operation OPERATION to perform (detected automatically)
|
|
136
111
|
*/
|
|
137
112
|
public setDirty<K extends NonFunctionPropNames<this>>(property: K | number, operation?: OPERATION) {
|
|
113
|
+
const metadata: Metadata = this.constructor[Symbol.metadata];
|
|
138
114
|
this[$changes].change(
|
|
139
|
-
|
|
115
|
+
metadata[metadata[property as string]].index,
|
|
140
116
|
operation
|
|
141
117
|
);
|
|
142
118
|
}
|
|
143
119
|
|
|
144
120
|
clone (): this {
|
|
145
121
|
const cloned = new ((this as any).constructor);
|
|
146
|
-
const metadata = this.constructor[Symbol.metadata];
|
|
122
|
+
const metadata: Metadata = this.constructor[Symbol.metadata];
|
|
147
123
|
|
|
148
124
|
//
|
|
149
125
|
// TODO: clone all properties, not only annotated ones
|
|
150
126
|
//
|
|
151
127
|
// for (const field in this) {
|
|
152
|
-
for (const
|
|
128
|
+
for (const fieldIndex in metadata) {
|
|
129
|
+
// const field = metadata[metadata[fieldIndex]].name;
|
|
130
|
+
const field = metadata[fieldIndex as any as number].name;
|
|
131
|
+
|
|
153
132
|
if (
|
|
154
133
|
typeof (this[field]) === "object" &&
|
|
155
134
|
typeof (this[field]?.clone) === "function"
|
|
@@ -162,15 +141,16 @@ export abstract class Schema {
|
|
|
162
141
|
cloned[field] = this[field];
|
|
163
142
|
}
|
|
164
143
|
}
|
|
144
|
+
|
|
165
145
|
return cloned;
|
|
166
146
|
}
|
|
167
147
|
|
|
168
148
|
toJSON () {
|
|
169
|
-
const metadata = this.constructor[Symbol.metadata];
|
|
170
|
-
|
|
171
149
|
const obj: unknown = {};
|
|
172
|
-
|
|
173
|
-
|
|
150
|
+
const metadata = this.constructor[Symbol.metadata];
|
|
151
|
+
for (const index in metadata) {
|
|
152
|
+
const field = metadata[index];
|
|
153
|
+
const fieldName = field.name;
|
|
174
154
|
if (!field.deprecated && this[fieldName] !== null && typeof (this[fieldName]) !== "undefined") {
|
|
175
155
|
obj[fieldName] = (typeof (this[fieldName]['toJSON']) === "function")
|
|
176
156
|
? this[fieldName]['toJSON']()
|
|
@@ -185,11 +165,13 @@ export abstract class Schema {
|
|
|
185
165
|
}
|
|
186
166
|
|
|
187
167
|
protected [$getByIndex](index: number) {
|
|
188
|
-
|
|
168
|
+
const metadata: Metadata = this.constructor[Symbol.metadata];
|
|
169
|
+
return this[metadata[index].name];
|
|
189
170
|
}
|
|
190
171
|
|
|
191
172
|
protected [$deleteByIndex](index: number) {
|
|
192
|
-
this
|
|
173
|
+
const metadata: Metadata = this.constructor[Symbol.metadata];
|
|
174
|
+
this[metadata[index].name] = undefined;
|
|
193
175
|
}
|
|
194
176
|
|
|
195
177
|
static debugRefIds(instance: Ref, jsonContents: boolean = true, level: number = 0) {
|
|
@@ -199,7 +181,7 @@ export abstract class Schema {
|
|
|
199
181
|
const contents = (jsonContents) ? ` - ${JSON.stringify(ref.toJSON())}` : "";
|
|
200
182
|
|
|
201
183
|
let output = "";
|
|
202
|
-
output += `${getIndent(level)}${ref.constructor.name} (${ref[$changes].refId})${contents}\n`;
|
|
184
|
+
output += `${getIndent(level)}${ref.constructor.name} (refId: ${ref[$changes].refId})${contents}\n`;
|
|
203
185
|
|
|
204
186
|
changeTree.forEachChild((childChangeTree) =>
|
|
205
187
|
output += this.debugRefIds(childChangeTree.ref, jsonContents, level + 1));
|
|
@@ -216,31 +198,41 @@ export abstract class Schema {
|
|
|
216
198
|
* @returns
|
|
217
199
|
*/
|
|
218
200
|
static debugChanges(instance: Ref, isEncodeAll: boolean = false) {
|
|
219
|
-
const changeTree = instance[$changes];
|
|
201
|
+
const changeTree: ChangeTree = instance[$changes];
|
|
220
202
|
|
|
221
203
|
const changeSet = (isEncodeAll) ? changeTree.allChanges : changeTree.changes;
|
|
222
204
|
const changeSetName = (isEncodeAll) ? "allChanges" : "changes";
|
|
223
205
|
|
|
224
206
|
let output = `${instance.constructor.name} (${changeTree.refId}) -> .${changeSetName}:\n`;
|
|
225
207
|
|
|
226
|
-
function dumpChangeSet(changeSet:
|
|
227
|
-
|
|
228
|
-
.
|
|
229
|
-
.forEach((
|
|
230
|
-
|
|
231
|
-
|
|
208
|
+
function dumpChangeSet(changeSet: ChangeSet) {
|
|
209
|
+
changeSet.operations
|
|
210
|
+
.filter(op => op)
|
|
211
|
+
.forEach((index) => {
|
|
212
|
+
const operation = changeTree.indexedOperations[index];
|
|
213
|
+
console.log({ index, operation })
|
|
214
|
+
output += `- [${index}]: ${OPERATION[operation]} (${JSON.stringify(changeTree.getValue(Number(index), isEncodeAll))})\n`
|
|
215
|
+
});
|
|
232
216
|
}
|
|
233
217
|
|
|
234
218
|
dumpChangeSet(changeSet);
|
|
235
219
|
|
|
236
220
|
// display filtered changes
|
|
237
|
-
if (
|
|
221
|
+
if (
|
|
222
|
+
!isEncodeAll &&
|
|
223
|
+
changeTree.filteredChanges &&
|
|
224
|
+
(changeTree.filteredChanges.operations).filter(op => op).length > 0
|
|
225
|
+
) {
|
|
238
226
|
output += `${instance.constructor.name} (${changeTree.refId}) -> .filteredChanges:\n`;
|
|
239
227
|
dumpChangeSet(changeTree.filteredChanges);
|
|
240
228
|
}
|
|
241
229
|
|
|
242
230
|
// display filtered changes
|
|
243
|
-
if (
|
|
231
|
+
if (
|
|
232
|
+
isEncodeAll &&
|
|
233
|
+
changeTree.allFilteredChanges &&
|
|
234
|
+
(changeTree.allFilteredChanges.operations).filter(op => op).length > 0
|
|
235
|
+
) {
|
|
244
236
|
output += `${instance.constructor.name} (${changeTree.refId}) -> .allFilteredChanges:\n`;
|
|
245
237
|
dumpChangeSet(changeTree.allFilteredChanges);
|
|
246
238
|
}
|
|
@@ -248,16 +240,19 @@ export abstract class Schema {
|
|
|
248
240
|
return output;
|
|
249
241
|
}
|
|
250
242
|
|
|
251
|
-
static debugChangesDeep(ref: Ref) {
|
|
243
|
+
static debugChangesDeep(ref: Ref, changeSetName: "changes" | "allChanges" | "allFilteredChanges" | "filteredChanges" = "changes") {
|
|
252
244
|
let output = "";
|
|
253
245
|
|
|
254
246
|
const rootChangeTree = ref[$changes];
|
|
247
|
+
const root = rootChangeTree.root;
|
|
255
248
|
const changeTrees: Map<ChangeTree, ChangeTree[]> = new Map();
|
|
256
249
|
|
|
257
250
|
let totalInstances = 0;
|
|
258
251
|
let totalOperations = 0;
|
|
259
252
|
|
|
260
|
-
for (const [
|
|
253
|
+
for (const [refId, changes] of Object.entries(root[changeSetName])) {
|
|
254
|
+
const changeTree = root.changeTrees[refId];
|
|
255
|
+
|
|
261
256
|
let includeChangeTree = false;
|
|
262
257
|
let parentChangeTrees: ChangeTree[] = [];
|
|
263
258
|
let parentChangeTree = changeTree.parent?.[$changes];
|
|
@@ -278,7 +273,7 @@ export abstract class Schema {
|
|
|
278
273
|
|
|
279
274
|
if (includeChangeTree) {
|
|
280
275
|
totalInstances += 1;
|
|
281
|
-
totalOperations += changes.
|
|
276
|
+
totalOperations += Object.keys(changes).length;
|
|
282
277
|
changeTrees.set(changeTree, parentChangeTrees.reverse());
|
|
283
278
|
}
|
|
284
279
|
}
|
|
@@ -299,17 +294,17 @@ export abstract class Schema {
|
|
|
299
294
|
}
|
|
300
295
|
});
|
|
301
296
|
|
|
302
|
-
const changes = changeTree.
|
|
297
|
+
const changes = changeTree.indexedOperations;
|
|
303
298
|
const level = parentChangeTrees.length;
|
|
304
299
|
const indent = getIndent(level);
|
|
305
300
|
|
|
306
301
|
const parentIndex = (level > 0) ? `(${changeTree.parentIndex}) ` : "";
|
|
307
|
-
output += `${indent}${parentIndex}${changeTree.ref.constructor.name} (refId: ${changeTree.refId}) - changes: ${changes.
|
|
302
|
+
output += `${indent}${parentIndex}${changeTree.ref.constructor.name} (refId: ${changeTree.refId}) - changes: ${Object.keys(changes).length}\n`;
|
|
308
303
|
|
|
309
|
-
for (const
|
|
304
|
+
for (const index in changes) {
|
|
305
|
+
const operation = changes[index];
|
|
310
306
|
output += `${getIndent(level + 1)}${OPERATION[operation]}: ${index}\n`;
|
|
311
307
|
}
|
|
312
|
-
|
|
313
308
|
}
|
|
314
309
|
|
|
315
310
|
return `${output}`;
|