@colyseus/schema 3.0.0-alpha.34 → 3.0.0-alpha.36
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 +612 -408
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +612 -408
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +612 -408
- package/lib/Metadata.d.ts +6 -6
- package/lib/Metadata.js +48 -21
- package/lib/Metadata.js.map +1 -1
- package/lib/Reflection.d.ts +17 -2
- package/lib/Reflection.js +19 -6
- package/lib/Reflection.js.map +1 -1
- package/lib/Schema.js +24 -17
- package/lib/Schema.js.map +1 -1
- package/lib/annotations.d.ts +1 -1
- package/lib/annotations.js +13 -16
- package/lib/annotations.js.map +1 -1
- package/lib/bench_encode.js +12 -5
- package/lib/bench_encode.js.map +1 -1
- package/lib/debug.js +1 -2
- package/lib/debug.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 +97 -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 +51 -27
- package/src/Reflection.ts +21 -8
- package/src/Schema.ts +33 -25
- package/src/annotations.ts +14 -18
- package/src/bench_encode.ts +15 -6
- package/src/debug.ts +1 -2
- package/src/decoder/Decoder.ts +1 -1
- package/src/encoder/ChangeTree.ts +220 -115
- package/src/encoder/EncodeOperation.ts +5 -4
- package/src/encoder/Encoder.ts +115 -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
package/src/Metadata.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { getPropertyDescriptor, type DefinitionType } from "./annotations";
|
|
2
|
+
import { Schema } from "./Schema";
|
|
2
3
|
import { getType } from "./types/registry";
|
|
3
|
-
import { $descriptors } from "./types/symbols";
|
|
4
|
+
import { $decoder, $descriptors, $encoder, $fieldIndexesByViewTag, $numFields, $refTypeFieldIndexes, $track, $viewFieldIndexes } from "./types/symbols";
|
|
5
|
+
import { TypeContext } from "./types/TypeContext";
|
|
4
6
|
|
|
5
7
|
export type MetadataField = {
|
|
6
8
|
type: DefinitionType,
|
|
@@ -12,10 +14,10 @@ export type MetadataField = {
|
|
|
12
14
|
};
|
|
13
15
|
|
|
14
16
|
export type Metadata =
|
|
15
|
-
{ [
|
|
16
|
-
{ [
|
|
17
|
-
{ [
|
|
18
|
-
{ [
|
|
17
|
+
{ [$numFields]: number; } & // number of fields
|
|
18
|
+
{ [$viewFieldIndexes]: number[]; } & // all field indexes with "view" tag
|
|
19
|
+
{ [$fieldIndexesByViewTag]: {[tag: number]: number[]}; } & // field indexes by "view" tag
|
|
20
|
+
{ [$refTypeFieldIndexes]: number[]; } & // all field indexes containing Ref types (Schema, ArraySchema, MapSchema, etc)
|
|
19
21
|
{ [field: number]: MetadataField; } & // index => field name
|
|
20
22
|
{ [field: string]: number; } & // field name => field metadata
|
|
21
23
|
{ [$descriptors]: { [field: string]: PropertyDescriptor } } // property descriptors
|
|
@@ -61,7 +63,7 @@ export const Metadata = {
|
|
|
61
63
|
}
|
|
62
64
|
|
|
63
65
|
// map -1 as last field index
|
|
64
|
-
Object.defineProperty(metadata,
|
|
66
|
+
Object.defineProperty(metadata, $numFields, {
|
|
65
67
|
value: index,
|
|
66
68
|
enumerable: false,
|
|
67
69
|
configurable: true
|
|
@@ -76,14 +78,14 @@ export const Metadata = {
|
|
|
76
78
|
|
|
77
79
|
// if child Ref/complex type, add to -4
|
|
78
80
|
if (typeof (metadata[index].type) !== "string") {
|
|
79
|
-
if (metadata[
|
|
80
|
-
Object.defineProperty(metadata,
|
|
81
|
+
if (metadata[$refTypeFieldIndexes] === undefined) {
|
|
82
|
+
Object.defineProperty(metadata, $refTypeFieldIndexes, {
|
|
81
83
|
value: [],
|
|
82
84
|
enumerable: false,
|
|
83
85
|
configurable: true,
|
|
84
86
|
});
|
|
85
87
|
}
|
|
86
|
-
metadata[
|
|
88
|
+
metadata[$refTypeFieldIndexes].push(index);
|
|
87
89
|
}
|
|
88
90
|
},
|
|
89
91
|
|
|
@@ -94,35 +96,55 @@ export const Metadata = {
|
|
|
94
96
|
// add 'tag' to the field
|
|
95
97
|
field.tag = tag;
|
|
96
98
|
|
|
97
|
-
if (!metadata[
|
|
99
|
+
if (!metadata[$viewFieldIndexes]) {
|
|
98
100
|
// -2: all field indexes with "view" tag
|
|
99
|
-
Object.defineProperty(metadata,
|
|
101
|
+
Object.defineProperty(metadata, $viewFieldIndexes, {
|
|
100
102
|
value: [],
|
|
101
103
|
enumerable: false,
|
|
102
104
|
configurable: true
|
|
103
105
|
});
|
|
104
106
|
|
|
105
107
|
// -3: field indexes by "view" tag
|
|
106
|
-
Object.defineProperty(metadata,
|
|
108
|
+
Object.defineProperty(metadata, $fieldIndexesByViewTag, {
|
|
107
109
|
value: {},
|
|
108
110
|
enumerable: false,
|
|
109
111
|
configurable: true
|
|
110
112
|
});
|
|
111
113
|
}
|
|
112
114
|
|
|
113
|
-
metadata[
|
|
115
|
+
metadata[$viewFieldIndexes].push(index);
|
|
114
116
|
|
|
115
|
-
if (!metadata[
|
|
116
|
-
metadata[
|
|
117
|
+
if (!metadata[$fieldIndexesByViewTag][tag]) {
|
|
118
|
+
metadata[$fieldIndexesByViewTag][tag] = [];
|
|
117
119
|
}
|
|
118
120
|
|
|
119
|
-
metadata[
|
|
121
|
+
metadata[$fieldIndexesByViewTag][tag].push(index);
|
|
120
122
|
},
|
|
121
123
|
|
|
122
124
|
setFields(target: any, fields: { [field: string]: DefinitionType }) {
|
|
123
|
-
|
|
125
|
+
// for inheritance support
|
|
126
|
+
const constructor = target.prototype.constructor;
|
|
127
|
+
TypeContext.register(constructor);
|
|
128
|
+
|
|
129
|
+
const parentClass = Object.getPrototypeOf(constructor);
|
|
130
|
+
const parentMetadata = parentClass && parentClass[Symbol.metadata];
|
|
131
|
+
const metadata = Metadata.initialize(constructor, parentMetadata);
|
|
132
|
+
|
|
133
|
+
// Use Schema's methods if not defined in the class
|
|
134
|
+
if (!constructor[$track]) { constructor[$track] = Schema[$track]; }
|
|
135
|
+
if (!constructor[$encoder]) { constructor[$encoder] = Schema[$encoder]; }
|
|
136
|
+
if (!constructor[$decoder]) { constructor[$decoder] = Schema[$decoder]; }
|
|
137
|
+
if (!constructor.prototype.toJSON) { constructor.prototype.toJSON = Schema.prototype.toJSON; }
|
|
138
|
+
|
|
139
|
+
//
|
|
140
|
+
// detect index for this field, considering inheritance
|
|
141
|
+
//
|
|
142
|
+
let fieldIndex = metadata[$numFields] // current structure already has fields defined
|
|
143
|
+
?? (parentMetadata && parentMetadata[$numFields]) // parent structure has fields defined
|
|
144
|
+
?? -1; // no fields defined
|
|
145
|
+
|
|
146
|
+
fieldIndex++;
|
|
124
147
|
|
|
125
|
-
let index = 0;
|
|
126
148
|
for (const field in fields) {
|
|
127
149
|
const type = fields[field];
|
|
128
150
|
|
|
@@ -133,14 +155,16 @@ export const Metadata = {
|
|
|
133
155
|
|
|
134
156
|
Metadata.addField(
|
|
135
157
|
metadata,
|
|
136
|
-
|
|
158
|
+
fieldIndex,
|
|
137
159
|
field,
|
|
138
160
|
type,
|
|
139
|
-
getPropertyDescriptor(`_${field}`,
|
|
161
|
+
getPropertyDescriptor(`_${field}`, fieldIndex, type, complexTypeKlass)
|
|
140
162
|
);
|
|
141
163
|
|
|
142
|
-
|
|
164
|
+
fieldIndex++;
|
|
143
165
|
}
|
|
166
|
+
|
|
167
|
+
return target;
|
|
144
168
|
},
|
|
145
169
|
|
|
146
170
|
isDeprecated(metadata: any, field: string) {
|
|
@@ -154,7 +178,7 @@ export const Metadata = {
|
|
|
154
178
|
//
|
|
155
179
|
const metadata = {};
|
|
156
180
|
klass[Symbol.metadata] = metadata;
|
|
157
|
-
Object.defineProperty(metadata,
|
|
181
|
+
Object.defineProperty(metadata, $numFields, {
|
|
158
182
|
value: 0,
|
|
159
183
|
enumerable: false,
|
|
160
184
|
configurable: true,
|
|
@@ -172,7 +196,7 @@ export const Metadata = {
|
|
|
172
196
|
// assign parent metadata to current
|
|
173
197
|
Object.assign(metadata, parentMetadata);
|
|
174
198
|
|
|
175
|
-
for (let i = 0; i <= parentMetadata[
|
|
199
|
+
for (let i = 0; i <= parentMetadata[$numFields]; i++) {
|
|
176
200
|
const fieldName = parentMetadata[i].name;
|
|
177
201
|
Object.defineProperty(metadata, fieldName, {
|
|
178
202
|
value: parentMetadata[fieldName],
|
|
@@ -181,8 +205,8 @@ export const Metadata = {
|
|
|
181
205
|
});
|
|
182
206
|
}
|
|
183
207
|
|
|
184
|
-
Object.defineProperty(metadata,
|
|
185
|
-
value: parentMetadata[
|
|
208
|
+
Object.defineProperty(metadata, $numFields, {
|
|
209
|
+
value: parentMetadata[$numFields],
|
|
186
210
|
enumerable: false,
|
|
187
211
|
configurable: true,
|
|
188
212
|
writable: true,
|
|
@@ -198,14 +222,14 @@ export const Metadata = {
|
|
|
198
222
|
isValidInstance(klass: any) {
|
|
199
223
|
return (
|
|
200
224
|
klass.constructor[Symbol.metadata] &&
|
|
201
|
-
Object.prototype.hasOwnProperty.call(klass.constructor[Symbol.metadata],
|
|
225
|
+
Object.prototype.hasOwnProperty.call(klass.constructor[Symbol.metadata], $numFields) as boolean
|
|
202
226
|
);
|
|
203
227
|
},
|
|
204
228
|
|
|
205
229
|
getFields(klass: any) {
|
|
206
230
|
const metadata: Metadata = klass[Symbol.metadata];
|
|
207
231
|
const fields = {};
|
|
208
|
-
for (let i = 0; i <= metadata[
|
|
232
|
+
for (let i = 0; i <= metadata[$numFields]; i++) {
|
|
209
233
|
fields[metadata[i].name] = metadata[i].type;
|
|
210
234
|
}
|
|
211
235
|
return fields;
|
package/src/Reflection.ts
CHANGED
|
@@ -25,11 +25,16 @@ export class ReflectionType extends Schema {
|
|
|
25
25
|
export class Reflection extends Schema {
|
|
26
26
|
@type([ ReflectionType ]) types: ArraySchema<ReflectionType> = new ArraySchema<ReflectionType>();
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Encodes the TypeContext of an Encoder into a buffer.
|
|
30
|
+
*
|
|
31
|
+
* @param context TypeContext instance
|
|
32
|
+
* @param it
|
|
33
|
+
* @returns
|
|
34
|
+
*/
|
|
35
|
+
static encode(context: TypeContext, it: Iterator = { offset: 0 }) {
|
|
31
36
|
const reflection = new Reflection();
|
|
32
|
-
const
|
|
37
|
+
const reflectionEncoder = new Encoder(reflection);
|
|
33
38
|
|
|
34
39
|
const buildType = (currentType: ReflectionType, metadata: Metadata) => {
|
|
35
40
|
for (const fieldIndex in metadata) {
|
|
@@ -98,11 +103,18 @@ export class Reflection extends Schema {
|
|
|
98
103
|
buildType(type, klass[Symbol.metadata]);
|
|
99
104
|
}
|
|
100
105
|
|
|
101
|
-
const buf =
|
|
106
|
+
const buf = reflectionEncoder.encodeAll(it);
|
|
102
107
|
return Buffer.from(buf, 0, it.offset);
|
|
103
108
|
}
|
|
104
109
|
|
|
105
|
-
|
|
110
|
+
/**
|
|
111
|
+
* Decodes the TypeContext from a buffer into a Decoder instance.
|
|
112
|
+
*
|
|
113
|
+
* @param bytes Reflection.encode() output
|
|
114
|
+
* @param it
|
|
115
|
+
* @returns Decoder instance
|
|
116
|
+
*/
|
|
117
|
+
static decode<T extends Schema = Schema>(bytes: Buffer, it?: Iterator): Decoder<T> {
|
|
106
118
|
const reflection = new Reflection();
|
|
107
119
|
|
|
108
120
|
const reflectionDecoder = new Decoder(reflection);
|
|
@@ -160,7 +172,8 @@ export class Reflection extends Schema {
|
|
|
160
172
|
});
|
|
161
173
|
});
|
|
162
174
|
|
|
163
|
-
|
|
164
|
-
|
|
175
|
+
const state: T = new (typeContext.get(0) as unknown as any)();
|
|
176
|
+
|
|
177
|
+
return new Decoder<T>(state, typeContext);
|
|
165
178
|
}
|
|
166
179
|
}
|
package/src/Schema.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { DEFAULT_VIEW_TAG, DefinitionType } from "./annotations";
|
|
|
3
3
|
|
|
4
4
|
import { NonFunctionPropNames, ToJSON } from './types/HelperTypes';
|
|
5
5
|
|
|
6
|
-
import { ChangeTree, Ref } from './encoder/ChangeTree';
|
|
6
|
+
import { ChangeSet, ChangeTree, Ref } from './encoder/ChangeTree';
|
|
7
7
|
import { $changes, $decoder, $deleteByIndex, $descriptors, $encoder, $filter, $getByIndex, $track } from './types/symbols';
|
|
8
8
|
import { StateView } from './encoder/StateView';
|
|
9
9
|
|
|
@@ -19,6 +19,8 @@ export abstract class Schema {
|
|
|
19
19
|
static [$encoder] = encodeSchemaOperation;
|
|
20
20
|
static [$decoder] = decodeSchemaOperation;
|
|
21
21
|
|
|
22
|
+
// public [$changes]: ChangeTree;
|
|
23
|
+
|
|
22
24
|
/**
|
|
23
25
|
* Assign the property descriptors required to track changes on this instance.
|
|
24
26
|
* @param instance
|
|
@@ -84,14 +86,7 @@ export abstract class Schema {
|
|
|
84
86
|
// inline
|
|
85
87
|
// Schema.initialize(this);
|
|
86
88
|
//
|
|
87
|
-
|
|
88
|
-
Object.defineProperty(this, $changes, {
|
|
89
|
-
value: new ChangeTree(this),
|
|
90
|
-
enumerable: false,
|
|
91
|
-
writable: true
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
Object.defineProperties(this, this.constructor[Symbol.metadata]?.[$descriptors] || {});
|
|
89
|
+
Schema.initialize(this);
|
|
95
90
|
|
|
96
91
|
//
|
|
97
92
|
// Assign initial values
|
|
@@ -187,7 +182,7 @@ export abstract class Schema {
|
|
|
187
182
|
const contents = (jsonContents) ? ` - ${JSON.stringify(ref.toJSON())}` : "";
|
|
188
183
|
|
|
189
184
|
let output = "";
|
|
190
|
-
output += `${getIndent(level)}${ref.constructor.name} (${ref[$changes].refId})${contents}\n`;
|
|
185
|
+
output += `${getIndent(level)}${ref.constructor.name} (refId: ${ref[$changes].refId})${contents}\n`;
|
|
191
186
|
|
|
192
187
|
changeTree.forEachChild((childChangeTree) =>
|
|
193
188
|
output += this.debugRefIds(childChangeTree.ref, jsonContents, level + 1));
|
|
@@ -204,31 +199,41 @@ export abstract class Schema {
|
|
|
204
199
|
* @returns
|
|
205
200
|
*/
|
|
206
201
|
static debugChanges(instance: Ref, isEncodeAll: boolean = false) {
|
|
207
|
-
const changeTree = instance[$changes];
|
|
202
|
+
const changeTree: ChangeTree = instance[$changes];
|
|
208
203
|
|
|
209
204
|
const changeSet = (isEncodeAll) ? changeTree.allChanges : changeTree.changes;
|
|
210
205
|
const changeSetName = (isEncodeAll) ? "allChanges" : "changes";
|
|
211
206
|
|
|
212
207
|
let output = `${instance.constructor.name} (${changeTree.refId}) -> .${changeSetName}:\n`;
|
|
213
208
|
|
|
214
|
-
function dumpChangeSet(changeSet:
|
|
215
|
-
|
|
216
|
-
.
|
|
217
|
-
.forEach((
|
|
218
|
-
|
|
219
|
-
|
|
209
|
+
function dumpChangeSet(changeSet: ChangeSet) {
|
|
210
|
+
changeSet.operations
|
|
211
|
+
.filter(op => op)
|
|
212
|
+
.forEach((index) => {
|
|
213
|
+
const operation = changeTree.indexedOperations[index];
|
|
214
|
+
console.log({ index, operation })
|
|
215
|
+
output += `- [${index}]: ${OPERATION[operation]} (${JSON.stringify(changeTree.getValue(Number(index), isEncodeAll))})\n`
|
|
216
|
+
});
|
|
220
217
|
}
|
|
221
218
|
|
|
222
219
|
dumpChangeSet(changeSet);
|
|
223
220
|
|
|
224
221
|
// display filtered changes
|
|
225
|
-
if (
|
|
222
|
+
if (
|
|
223
|
+
!isEncodeAll &&
|
|
224
|
+
changeTree.filteredChanges &&
|
|
225
|
+
(changeTree.filteredChanges.operations).filter(op => op).length > 0
|
|
226
|
+
) {
|
|
226
227
|
output += `${instance.constructor.name} (${changeTree.refId}) -> .filteredChanges:\n`;
|
|
227
228
|
dumpChangeSet(changeTree.filteredChanges);
|
|
228
229
|
}
|
|
229
230
|
|
|
230
231
|
// display filtered changes
|
|
231
|
-
if (
|
|
232
|
+
if (
|
|
233
|
+
isEncodeAll &&
|
|
234
|
+
changeTree.allFilteredChanges &&
|
|
235
|
+
(changeTree.allFilteredChanges.operations).filter(op => op).length > 0
|
|
236
|
+
) {
|
|
232
237
|
output += `${instance.constructor.name} (${changeTree.refId}) -> .allFilteredChanges:\n`;
|
|
233
238
|
dumpChangeSet(changeTree.allFilteredChanges);
|
|
234
239
|
}
|
|
@@ -240,12 +245,15 @@ export abstract class Schema {
|
|
|
240
245
|
let output = "";
|
|
241
246
|
|
|
242
247
|
const rootChangeTree = ref[$changes];
|
|
248
|
+
const root = rootChangeTree.root;
|
|
243
249
|
const changeTrees: Map<ChangeTree, ChangeTree[]> = new Map();
|
|
244
250
|
|
|
245
251
|
let totalInstances = 0;
|
|
246
252
|
let totalOperations = 0;
|
|
247
253
|
|
|
248
|
-
for (const [
|
|
254
|
+
for (const [refId, changes] of Object.entries(root[changeSetName])) {
|
|
255
|
+
const changeTree = root.changeTrees[refId];
|
|
256
|
+
|
|
249
257
|
let includeChangeTree = false;
|
|
250
258
|
let parentChangeTrees: ChangeTree[] = [];
|
|
251
259
|
let parentChangeTree = changeTree.parent?.[$changes];
|
|
@@ -266,7 +274,7 @@ export abstract class Schema {
|
|
|
266
274
|
|
|
267
275
|
if (includeChangeTree) {
|
|
268
276
|
totalInstances += 1;
|
|
269
|
-
totalOperations += changes.
|
|
277
|
+
totalOperations += Object.keys(changes).length;
|
|
270
278
|
changeTrees.set(changeTree, parentChangeTrees.reverse());
|
|
271
279
|
}
|
|
272
280
|
}
|
|
@@ -287,17 +295,17 @@ export abstract class Schema {
|
|
|
287
295
|
}
|
|
288
296
|
});
|
|
289
297
|
|
|
290
|
-
const changes = changeTree.
|
|
298
|
+
const changes = changeTree.indexedOperations;
|
|
291
299
|
const level = parentChangeTrees.length;
|
|
292
300
|
const indent = getIndent(level);
|
|
293
301
|
|
|
294
302
|
const parentIndex = (level > 0) ? `(${changeTree.parentIndex}) ` : "";
|
|
295
|
-
output += `${indent}${parentIndex}${changeTree.ref.constructor.name} (refId: ${changeTree.refId}) - changes: ${changes.
|
|
303
|
+
output += `${indent}${parentIndex}${changeTree.ref.constructor.name} (refId: ${changeTree.refId}) - changes: ${Object.keys(changes).length}\n`;
|
|
296
304
|
|
|
297
|
-
for (const
|
|
305
|
+
for (const index in changes) {
|
|
306
|
+
const operation = changes[index];
|
|
298
307
|
output += `${getIndent(level + 1)}${OPERATION[operation]}: ${index}\n`;
|
|
299
308
|
}
|
|
300
|
-
|
|
301
309
|
}
|
|
302
310
|
|
|
303
311
|
return `${output}`;
|
package/src/annotations.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Schema } from './Schema';
|
|
|
3
3
|
import { ArraySchema } from './types/custom/ArraySchema';
|
|
4
4
|
import { MapSchema } from './types/custom/MapSchema';
|
|
5
5
|
import { Metadata } from "./Metadata";
|
|
6
|
-
import { $changes, $childType, $descriptors, $track } from "./types/symbols";
|
|
6
|
+
import { $changes, $childType, $descriptors, $numFields, $track } from "./types/symbols";
|
|
7
7
|
import { TypeDefinition, getType } from "./types/registry";
|
|
8
8
|
import { OPERATION } from "./encoding/spec";
|
|
9
9
|
import { TypeContext } from "./types/TypeContext";
|
|
@@ -45,12 +45,8 @@ export interface TypeOptions {
|
|
|
45
45
|
|
|
46
46
|
export const DEFAULT_VIEW_TAG = -1;
|
|
47
47
|
|
|
48
|
-
export function entity(constructor
|
|
49
|
-
|
|
50
|
-
// for inheritance support
|
|
51
|
-
TypeContext.register(constructor);
|
|
52
|
-
}
|
|
53
|
-
|
|
48
|
+
export function entity(constructor) {
|
|
49
|
+
TypeContext.register(constructor);
|
|
54
50
|
return constructor;
|
|
55
51
|
}
|
|
56
52
|
|
|
@@ -82,8 +78,8 @@ export function entity(constructor, context: ClassDecoratorContext) {
|
|
|
82
78
|
// // detect index for this field, considering inheritance
|
|
83
79
|
// //
|
|
84
80
|
// const parent = Object.getPrototypeOf(context.metadata);
|
|
85
|
-
// let fieldIndex: number = context.metadata[
|
|
86
|
-
// ?? (parent && parent[
|
|
81
|
+
// let fieldIndex: number = context.metadata[$numFields] // current structure already has fields defined
|
|
82
|
+
// ?? (parent && parent[$numFields]) // parent structure has fields defined
|
|
87
83
|
// ?? -1; // no fields defined
|
|
88
84
|
// fieldIndex++;
|
|
89
85
|
|
|
@@ -237,8 +233,8 @@ export function view<T> (tag: number = DEFAULT_VIEW_TAG) {
|
|
|
237
233
|
// //
|
|
238
234
|
// metadata[fieldIndex] = {
|
|
239
235
|
// type: undefined,
|
|
240
|
-
// index: (metadata[
|
|
241
|
-
// ?? (parentMetadata && parentMetadata[
|
|
236
|
+
// index: (metadata[$numFields] // current structure already has fields defined
|
|
237
|
+
// ?? (parentMetadata && parentMetadata[$numFields]) // parent structure has fields defined
|
|
242
238
|
// ?? -1) + 1 // no fields defined
|
|
243
239
|
// }
|
|
244
240
|
// }
|
|
@@ -265,8 +261,8 @@ export function unreliable<T> (target: T, field: string) {
|
|
|
265
261
|
// //
|
|
266
262
|
// metadata[field] = {
|
|
267
263
|
// type: undefined,
|
|
268
|
-
// index: (metadata[
|
|
269
|
-
// ?? (parentMetadata && parentMetadata[
|
|
264
|
+
// index: (metadata[$numFields] // current structure already has fields defined
|
|
265
|
+
// ?? (parentMetadata && parentMetadata[$numFields]) // parent structure has fields defined
|
|
270
266
|
// ?? -1) + 1 // no fields defined
|
|
271
267
|
// }
|
|
272
268
|
// }
|
|
@@ -319,8 +315,8 @@ export function type (
|
|
|
319
315
|
//
|
|
320
316
|
// detect index for this field, considering inheritance
|
|
321
317
|
//
|
|
322
|
-
fieldIndex = metadata[
|
|
323
|
-
?? (parentMetadata && parentMetadata[
|
|
318
|
+
fieldIndex = metadata[$numFields] // current structure already has fields defined
|
|
319
|
+
?? (parentMetadata && parentMetadata[$numFields]) // parent structure has fields defined
|
|
324
320
|
?? -1; // no fields defined
|
|
325
321
|
fieldIndex++;
|
|
326
322
|
}
|
|
@@ -368,7 +364,7 @@ export function getPropertyDescriptor(
|
|
|
368
364
|
return {
|
|
369
365
|
get: function () { return this[fieldCached]; },
|
|
370
366
|
set: function (this: Schema, value: any) {
|
|
371
|
-
const previousValue = this[fieldCached]
|
|
367
|
+
const previousValue = this[fieldCached] ?? undefined;
|
|
372
368
|
|
|
373
369
|
// skip if value is the same as cached.
|
|
374
370
|
if (value === previousValue) { return; }
|
|
@@ -454,8 +450,8 @@ export function deprecated(throws: boolean = true): PropertyDecorator {
|
|
|
454
450
|
// //
|
|
455
451
|
// metadata[field] = {
|
|
456
452
|
// type: undefined,
|
|
457
|
-
// index: (metadata[
|
|
458
|
-
// ?? (parentMetadata && parentMetadata[
|
|
453
|
+
// index: (metadata[$numFields] // current structure already has fields defined
|
|
454
|
+
// ?? (parentMetadata && parentMetadata[$numFields]) // parent structure has fields defined
|
|
459
455
|
// ?? -1) + 1 // no fields defined
|
|
460
456
|
// }
|
|
461
457
|
// }
|
package/src/bench_encode.ts
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { nanoid } from "nanoid";
|
|
2
2
|
import { Schema, type, MapSchema, ArraySchema, Encoder } from ".";
|
|
3
|
-
import * as benchmark from "benchmark";
|
|
4
|
-
|
|
5
|
-
const suite = new benchmark.Suite();
|
|
6
3
|
|
|
7
4
|
class Attribute extends Schema {
|
|
8
5
|
@type("string") name: string;
|
|
@@ -66,8 +63,13 @@ now = Date.now();
|
|
|
66
63
|
// }
|
|
67
64
|
// console.log(Date.now() - now);
|
|
68
65
|
|
|
66
|
+
const total = 100;
|
|
69
67
|
const allEncodes = Date.now();
|
|
70
|
-
|
|
68
|
+
|
|
69
|
+
let avgTimeToEncode = 0;
|
|
70
|
+
let avgTimeToMakeChanges = 0;
|
|
71
|
+
|
|
72
|
+
for (let i = 0; i < total; i++) {
|
|
71
73
|
now = Date.now();
|
|
72
74
|
for (let j = 0; j < 50; j++) {
|
|
73
75
|
const player = new Player();
|
|
@@ -87,13 +89,20 @@ for (let i = 0; i < 100; i++) {
|
|
|
87
89
|
player.items.set(`item-${k}`, item);
|
|
88
90
|
}
|
|
89
91
|
}
|
|
90
|
-
|
|
92
|
+
const timeToMakeChanges = Date.now() - now;
|
|
93
|
+
console.log("time to make changes:", timeToMakeChanges);
|
|
94
|
+
avgTimeToMakeChanges += timeToMakeChanges;
|
|
91
95
|
|
|
92
96
|
now = Date.now();
|
|
93
97
|
encoder.encode();
|
|
94
98
|
encoder.discardChanges();
|
|
95
|
-
|
|
99
|
+
|
|
100
|
+
const timeToEncode = Date.now() - now;
|
|
101
|
+
console.log("time to encode:", timeToEncode);
|
|
102
|
+
avgTimeToEncode += timeToEncode;
|
|
96
103
|
}
|
|
104
|
+
console.log("avg time to encode:", (avgTimeToEncode) / total);
|
|
105
|
+
console.log("avg time to make changes:", (avgTimeToMakeChanges) / total);
|
|
97
106
|
console.log("time for all encodes:", Date.now() - allEncodes);
|
|
98
107
|
|
|
99
108
|
console.log(Array.from(encoder.encodeAll()).length, "bytes");
|
package/src/debug.ts
CHANGED
|
@@ -42,8 +42,7 @@ contents.split("\n").forEach((line) => {
|
|
|
42
42
|
isCommentBlock = false;
|
|
43
43
|
|
|
44
44
|
if (line.startsWith("handshake:") && !decoder) {
|
|
45
|
-
|
|
46
|
-
decoder = new Decoder(state);
|
|
45
|
+
decoder = Reflection.decode(getBuffer(line));
|
|
47
46
|
|
|
48
47
|
} else if (line.startsWith("state:")) {
|
|
49
48
|
decode(getBuffer(line));
|