@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
package/lib/utils.js
CHANGED
|
@@ -14,15 +14,18 @@ function dumpChanges(schema) {
|
|
|
14
14
|
ops: {},
|
|
15
15
|
refs: []
|
|
16
16
|
};
|
|
17
|
-
$root.changes
|
|
17
|
+
// for (const refId in $root.changes) {
|
|
18
|
+
$root.changes.forEach(changeTree => {
|
|
19
|
+
const changes = changeTree.indexedOperations;
|
|
18
20
|
dump.refs.push(`refId#${changeTree.refId}`);
|
|
19
|
-
|
|
21
|
+
for (const index in changes) {
|
|
22
|
+
const op = changes[index];
|
|
20
23
|
const opName = spec_1.OPERATION[op];
|
|
21
24
|
if (!dump.ops[opName]) {
|
|
22
25
|
dump.ops[opName] = 0;
|
|
23
26
|
}
|
|
24
27
|
dump.ops[spec_1.OPERATION[op]]++;
|
|
25
|
-
}
|
|
28
|
+
}
|
|
26
29
|
});
|
|
27
30
|
return dump;
|
|
28
31
|
}
|
package/lib/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;AAeA,8BAIC;AAED,
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;AAeA,8BAIC;AAED,kCAsBC;AAED,0CAeC;AA3DD,0CAA4C;AAC5C,6CAA2C;AAa3C,SAAgB,SAAS,CAAC,KAAa;IACnC,OAAO,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAC3C,CAAC,CAAC,KAAK,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CACpC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACf,CAAC;AAED,SAAgB,WAAW,CAAC,MAAc;IACtC,MAAM,KAAK,GAAG,MAAM,CAAC,kBAAQ,CAAC,CAAC,IAAI,CAAC;IAEpC,MAAM,IAAI,GAAe;QACrB,GAAG,EAAE,EAAE;QACP,IAAI,EAAE,EAAE;KACX,CAAC;IAEF,uCAAuC;IACvC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE;QAC/B,MAAM,OAAO,GAAG,UAAU,CAAC,iBAAiB,CAAC;QAE7C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;QAC5C,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC1B,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;YAC1B,MAAM,MAAM,GAAG,gBAAS,CAAC,EAAE,CAAC,CAAC;YAC7B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAAC,CAAC;YAChD,IAAI,CAAC,GAAG,CAAC,gBAAS,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAC9B,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,SAAgB,eAAe,CAAC,MAAc;IAC1C,+CAA+C;IAC/C,IAAI,CAAC,MAAM,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,gDAAgD;IAChD,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,OAAO,MAAM,GAAG,CAAC,EAAE,CAAC;QAChB,MAAM,KAAK,CAAC,CAAC;QACb,WAAW,EAAE,CAAC;IAClB,CAAC;IAED,6BAA6B;IAC7B,OAAO,CAAC,IAAI,WAAW,CAAC;AAC5B,CAAC","sourcesContent":["import type { Schema } from \"./Schema\";\nimport { OPERATION } from \"./encoding/spec\";\nimport { $changes } from \"./types/symbols\";\n\ntype ChangeItem = [string, number | string, any?];\n\ninterface ChangeDump {\n ops: {\n ADD?: number;\n REMOVE?: number;\n REPLACE?: number;\n },\n refs: string[],\n}\n\nexport function getIndent(level: number) {\n return (new Array(level).fill(0)).map((_, i) =>\n (i === level - 1) ? `└─ ` : ` `\n ).join(\"\");\n}\n\nexport function dumpChanges(schema: Schema) {\n const $root = schema[$changes].root;\n\n const dump: ChangeDump = {\n ops: {},\n refs: []\n };\n\n // for (const refId in $root.changes) {\n $root.changes.forEach(changeTree => {\n const changes = changeTree.indexedOperations;\n\n dump.refs.push(`refId#${changeTree.refId}`);\n for (const index in changes) {\n const op = changes[index];\n const opName = OPERATION[op];\n if (!dump.ops[opName]) { dump.ops[opName] = 0; }\n dump.ops[OPERATION[op]]++;\n }\n });\n\n return dump;\n}\n\nexport function getNextPowerOf2(number: number) {\n // If number is already a power of 2, return it\n if ((number & (number - 1)) === 0) {\n return number;\n }\n\n // Find the position of the most significant bit\n let msbPosition = 0;\n while (number > 0) {\n number >>= 1;\n msbPosition++;\n }\n\n // Return the next power of 2\n return 1 << msbPosition;\n}"]}
|
package/package.json
CHANGED
package/src/Metadata.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getPropertyDescriptor, type DefinitionType } from "./annotations";
|
|
2
2
|
import { getType } from "./types/registry";
|
|
3
|
-
import { $descriptors } from "./types/symbols";
|
|
3
|
+
import { $descriptors, $fieldIndexesByViewTag, $numFields, $refTypeFieldIndexes, $viewFieldIndexes } from "./types/symbols";
|
|
4
4
|
|
|
5
5
|
export type MetadataField = {
|
|
6
6
|
type: DefinitionType,
|
|
@@ -12,10 +12,10 @@ export type MetadataField = {
|
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
export type Metadata =
|
|
15
|
-
{ [
|
|
16
|
-
{ [
|
|
17
|
-
{ [
|
|
18
|
-
{ [
|
|
15
|
+
{ [$numFields]: number; } & // number of fields
|
|
16
|
+
{ [$viewFieldIndexes]: number[]; } & // all field indexes with "view" tag
|
|
17
|
+
{ [$fieldIndexesByViewTag]: {[tag: number]: number[]}; } & // field indexes by "view" tag
|
|
18
|
+
{ [$refTypeFieldIndexes]: number[]; } & // all field indexes containing Ref types (Schema, ArraySchema, MapSchema, etc)
|
|
19
19
|
{ [field: number]: MetadataField; } & // index => field name
|
|
20
20
|
{ [field: string]: number; } & // field name => field metadata
|
|
21
21
|
{ [$descriptors]: { [field: string]: PropertyDescriptor } } // property descriptors
|
|
@@ -61,7 +61,7 @@ export const Metadata = {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
// map -1 as last field index
|
|
64
|
-
Object.defineProperty(metadata,
|
|
64
|
+
Object.defineProperty(metadata, $numFields, {
|
|
65
65
|
value: index,
|
|
66
66
|
enumerable: false,
|
|
67
67
|
configurable: true
|
|
@@ -76,14 +76,14 @@ export const Metadata = {
|
|
|
76
76
|
|
|
77
77
|
// if child Ref/complex type, add to -4
|
|
78
78
|
if (typeof (metadata[index].type) !== "string") {
|
|
79
|
-
if (metadata[
|
|
80
|
-
Object.defineProperty(metadata,
|
|
79
|
+
if (metadata[$refTypeFieldIndexes] === undefined) {
|
|
80
|
+
Object.defineProperty(metadata, $refTypeFieldIndexes, {
|
|
81
81
|
value: [],
|
|
82
82
|
enumerable: false,
|
|
83
83
|
configurable: true,
|
|
84
84
|
});
|
|
85
85
|
}
|
|
86
|
-
metadata[
|
|
86
|
+
metadata[$refTypeFieldIndexes].push(index);
|
|
87
87
|
}
|
|
88
88
|
},
|
|
89
89
|
|
|
@@ -94,29 +94,29 @@ export const Metadata = {
|
|
|
94
94
|
// add 'tag' to the field
|
|
95
95
|
field.tag = tag;
|
|
96
96
|
|
|
97
|
-
if (!metadata[
|
|
97
|
+
if (!metadata[$viewFieldIndexes]) {
|
|
98
98
|
// -2: all field indexes with "view" tag
|
|
99
|
-
Object.defineProperty(metadata,
|
|
99
|
+
Object.defineProperty(metadata, $viewFieldIndexes, {
|
|
100
100
|
value: [],
|
|
101
101
|
enumerable: false,
|
|
102
102
|
configurable: true
|
|
103
103
|
});
|
|
104
104
|
|
|
105
105
|
// -3: field indexes by "view" tag
|
|
106
|
-
Object.defineProperty(metadata,
|
|
106
|
+
Object.defineProperty(metadata, $fieldIndexesByViewTag, {
|
|
107
107
|
value: {},
|
|
108
108
|
enumerable: false,
|
|
109
109
|
configurable: true
|
|
110
110
|
});
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
metadata[
|
|
113
|
+
metadata[$viewFieldIndexes].push(index);
|
|
114
114
|
|
|
115
|
-
if (!metadata[
|
|
116
|
-
metadata[
|
|
115
|
+
if (!metadata[$fieldIndexesByViewTag][tag]) {
|
|
116
|
+
metadata[$fieldIndexesByViewTag][tag] = [];
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
metadata[
|
|
119
|
+
metadata[$fieldIndexesByViewTag][tag].push(index);
|
|
120
120
|
},
|
|
121
121
|
|
|
122
122
|
setFields(target: any, fields: { [field: string]: DefinitionType }) {
|
|
@@ -154,7 +154,7 @@ export const Metadata = {
|
|
|
154
154
|
//
|
|
155
155
|
const metadata = {};
|
|
156
156
|
klass[Symbol.metadata] = metadata;
|
|
157
|
-
Object.defineProperty(metadata,
|
|
157
|
+
Object.defineProperty(metadata, $numFields, {
|
|
158
158
|
value: 0,
|
|
159
159
|
enumerable: false,
|
|
160
160
|
configurable: true,
|
|
@@ -172,7 +172,7 @@ export const Metadata = {
|
|
|
172
172
|
// assign parent metadata to current
|
|
173
173
|
Object.assign(metadata, parentMetadata);
|
|
174
174
|
|
|
175
|
-
for (let i = 0; i <= parentMetadata[
|
|
175
|
+
for (let i = 0; i <= parentMetadata[$numFields]; i++) {
|
|
176
176
|
const fieldName = parentMetadata[i].name;
|
|
177
177
|
Object.defineProperty(metadata, fieldName, {
|
|
178
178
|
value: parentMetadata[fieldName],
|
|
@@ -181,8 +181,8 @@ export const Metadata = {
|
|
|
181
181
|
});
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
Object.defineProperty(metadata,
|
|
185
|
-
value: parentMetadata[
|
|
184
|
+
Object.defineProperty(metadata, $numFields, {
|
|
185
|
+
value: parentMetadata[$numFields],
|
|
186
186
|
enumerable: false,
|
|
187
187
|
configurable: true,
|
|
188
188
|
writable: true,
|
|
@@ -198,14 +198,14 @@ export const Metadata = {
|
|
|
198
198
|
isValidInstance(klass: any) {
|
|
199
199
|
return (
|
|
200
200
|
klass.constructor[Symbol.metadata] &&
|
|
201
|
-
Object.prototype.hasOwnProperty.call(klass.constructor[Symbol.metadata],
|
|
201
|
+
Object.prototype.hasOwnProperty.call(klass.constructor[Symbol.metadata], $numFields) as boolean
|
|
202
202
|
);
|
|
203
203
|
},
|
|
204
204
|
|
|
205
205
|
getFields(klass: any) {
|
|
206
206
|
const metadata: Metadata = klass[Symbol.metadata];
|
|
207
207
|
const fields = {};
|
|
208
|
-
for (let i = 0; i <= metadata[
|
|
208
|
+
for (let i = 0; i <= metadata[$numFields]; i++) {
|
|
209
209
|
fields[metadata[i].name] = metadata[i].type;
|
|
210
210
|
}
|
|
211
211
|
return fields;
|
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";
|
|
@@ -82,8 +82,8 @@ export function entity(constructor, context: ClassDecoratorContext) {
|
|
|
82
82
|
// // detect index for this field, considering inheritance
|
|
83
83
|
// //
|
|
84
84
|
// const parent = Object.getPrototypeOf(context.metadata);
|
|
85
|
-
// let fieldIndex: number = context.metadata[
|
|
86
|
-
// ?? (parent && parent[
|
|
85
|
+
// let fieldIndex: number = context.metadata[$numFields] // current structure already has fields defined
|
|
86
|
+
// ?? (parent && parent[$numFields]) // parent structure has fields defined
|
|
87
87
|
// ?? -1; // no fields defined
|
|
88
88
|
// fieldIndex++;
|
|
89
89
|
|
|
@@ -237,8 +237,8 @@ export function view<T> (tag: number = DEFAULT_VIEW_TAG) {
|
|
|
237
237
|
// //
|
|
238
238
|
// metadata[fieldIndex] = {
|
|
239
239
|
// type: undefined,
|
|
240
|
-
// index: (metadata[
|
|
241
|
-
// ?? (parentMetadata && parentMetadata[
|
|
240
|
+
// index: (metadata[$numFields] // current structure already has fields defined
|
|
241
|
+
// ?? (parentMetadata && parentMetadata[$numFields]) // parent structure has fields defined
|
|
242
242
|
// ?? -1) + 1 // no fields defined
|
|
243
243
|
// }
|
|
244
244
|
// }
|
|
@@ -265,8 +265,8 @@ export function unreliable<T> (target: T, field: string) {
|
|
|
265
265
|
// //
|
|
266
266
|
// metadata[field] = {
|
|
267
267
|
// type: undefined,
|
|
268
|
-
// index: (metadata[
|
|
269
|
-
// ?? (parentMetadata && parentMetadata[
|
|
268
|
+
// index: (metadata[$numFields] // current structure already has fields defined
|
|
269
|
+
// ?? (parentMetadata && parentMetadata[$numFields]) // parent structure has fields defined
|
|
270
270
|
// ?? -1) + 1 // no fields defined
|
|
271
271
|
// }
|
|
272
272
|
// }
|
|
@@ -319,8 +319,8 @@ export function type (
|
|
|
319
319
|
//
|
|
320
320
|
// detect index for this field, considering inheritance
|
|
321
321
|
//
|
|
322
|
-
fieldIndex = metadata[
|
|
323
|
-
?? (parentMetadata && parentMetadata[
|
|
322
|
+
fieldIndex = metadata[$numFields] // current structure already has fields defined
|
|
323
|
+
?? (parentMetadata && parentMetadata[$numFields]) // parent structure has fields defined
|
|
324
324
|
?? -1; // no fields defined
|
|
325
325
|
fieldIndex++;
|
|
326
326
|
}
|
|
@@ -368,7 +368,7 @@ export function getPropertyDescriptor(
|
|
|
368
368
|
return {
|
|
369
369
|
get: function () { return this[fieldCached]; },
|
|
370
370
|
set: function (this: Schema, value: any) {
|
|
371
|
-
const previousValue = this[fieldCached]
|
|
371
|
+
const previousValue = this[fieldCached] ?? undefined;
|
|
372
372
|
|
|
373
373
|
// skip if value is the same as cached.
|
|
374
374
|
if (value === previousValue) { return; }
|
|
@@ -454,8 +454,8 @@ export function deprecated(throws: boolean = true): PropertyDecorator {
|
|
|
454
454
|
// //
|
|
455
455
|
// metadata[field] = {
|
|
456
456
|
// type: undefined,
|
|
457
|
-
// index: (metadata[
|
|
458
|
-
// ?? (parentMetadata && parentMetadata[
|
|
457
|
+
// index: (metadata[$numFields] // current structure already has fields defined
|
|
458
|
+
// ?? (parentMetadata && parentMetadata[$numFields]) // parent structure has fields defined
|
|
459
459
|
// ?? -1) + 1 // no fields defined
|
|
460
460
|
// }
|
|
461
461
|
// }
|
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");
|