@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.
Files changed (71) hide show
  1. package/bin/schema-debug +4 -3
  2. package/build/cjs/index.js +612 -408
  3. package/build/cjs/index.js.map +1 -1
  4. package/build/esm/index.mjs +612 -408
  5. package/build/esm/index.mjs.map +1 -1
  6. package/build/umd/index.js +612 -408
  7. package/lib/Metadata.d.ts +6 -6
  8. package/lib/Metadata.js +48 -21
  9. package/lib/Metadata.js.map +1 -1
  10. package/lib/Reflection.d.ts +17 -2
  11. package/lib/Reflection.js +19 -6
  12. package/lib/Reflection.js.map +1 -1
  13. package/lib/Schema.js +24 -17
  14. package/lib/Schema.js.map +1 -1
  15. package/lib/annotations.d.ts +1 -1
  16. package/lib/annotations.js +13 -16
  17. package/lib/annotations.js.map +1 -1
  18. package/lib/bench_encode.js +12 -5
  19. package/lib/bench_encode.js.map +1 -1
  20. package/lib/debug.js +1 -2
  21. package/lib/debug.js.map +1 -1
  22. package/lib/decoder/Decoder.js +1 -1
  23. package/lib/decoder/Decoder.js.map +1 -1
  24. package/lib/encoder/ChangeTree.d.ts +23 -7
  25. package/lib/encoder/ChangeTree.js +183 -106
  26. package/lib/encoder/ChangeTree.js.map +1 -1
  27. package/lib/encoder/EncodeOperation.d.ts +2 -1
  28. package/lib/encoder/EncodeOperation.js +2 -2
  29. package/lib/encoder/EncodeOperation.js.map +1 -1
  30. package/lib/encoder/Encoder.d.ts +3 -5
  31. package/lib/encoder/Encoder.js +97 -61
  32. package/lib/encoder/Encoder.js.map +1 -1
  33. package/lib/encoder/Root.d.ts +12 -7
  34. package/lib/encoder/Root.js +41 -20
  35. package/lib/encoder/Root.js.map +1 -1
  36. package/lib/encoder/StateView.d.ts +5 -5
  37. package/lib/encoder/StateView.js +29 -23
  38. package/lib/encoder/StateView.js.map +1 -1
  39. package/lib/encoding/encode.js +12 -9
  40. package/lib/encoding/encode.js.map +1 -1
  41. package/lib/types/TypeContext.js +2 -1
  42. package/lib/types/TypeContext.js.map +1 -1
  43. package/lib/types/custom/ArraySchema.js +27 -13
  44. package/lib/types/custom/ArraySchema.js.map +1 -1
  45. package/lib/types/custom/MapSchema.d.ts +3 -1
  46. package/lib/types/custom/MapSchema.js +7 -4
  47. package/lib/types/custom/MapSchema.js.map +1 -1
  48. package/lib/types/symbols.d.ts +8 -6
  49. package/lib/types/symbols.js +9 -7
  50. package/lib/types/symbols.js.map +1 -1
  51. package/lib/utils.js +6 -3
  52. package/lib/utils.js.map +1 -1
  53. package/package.json +1 -1
  54. package/src/Metadata.ts +51 -27
  55. package/src/Reflection.ts +21 -8
  56. package/src/Schema.ts +33 -25
  57. package/src/annotations.ts +14 -18
  58. package/src/bench_encode.ts +15 -6
  59. package/src/debug.ts +1 -2
  60. package/src/decoder/Decoder.ts +1 -1
  61. package/src/encoder/ChangeTree.ts +220 -115
  62. package/src/encoder/EncodeOperation.ts +5 -4
  63. package/src/encoder/Encoder.ts +115 -68
  64. package/src/encoder/Root.ts +41 -21
  65. package/src/encoder/StateView.ts +32 -28
  66. package/src/encoding/encode.ts +12 -9
  67. package/src/types/TypeContext.ts +2 -1
  68. package/src/types/custom/ArraySchema.ts +39 -17
  69. package/src/types/custom/MapSchema.ts +12 -5
  70. package/src/types/symbols.ts +10 -9
  71. 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
- { [-1]: number; } & // number of fields
16
- { [-2]: number[]; } & // all field indexes with "view" tag
17
- { [-3]: {[tag: number]: number[]}; } & // field indexes by "view" tag
18
- { [-4]: number[]; } & // all field indexes containing Ref types (Schema, ArraySchema, MapSchema, etc)
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, -1, {
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[-4] === undefined) {
80
- Object.defineProperty(metadata, -4, {
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[-4].push(index);
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[-2]) {
99
+ if (!metadata[$viewFieldIndexes]) {
98
100
  // -2: all field indexes with "view" tag
99
- Object.defineProperty(metadata, -2, {
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, -3, {
108
+ Object.defineProperty(metadata, $fieldIndexesByViewTag, {
107
109
  value: {},
108
110
  enumerable: false,
109
111
  configurable: true
110
112
  });
111
113
  }
112
114
 
113
- metadata[-2].push(index);
115
+ metadata[$viewFieldIndexes].push(index);
114
116
 
115
- if (!metadata[-3][tag]) {
116
- metadata[-3][tag] = [];
117
+ if (!metadata[$fieldIndexesByViewTag][tag]) {
118
+ metadata[$fieldIndexesByViewTag][tag] = [];
117
119
  }
118
120
 
119
- metadata[-3][tag].push(index);
121
+ metadata[$fieldIndexesByViewTag][tag].push(index);
120
122
  },
121
123
 
122
124
  setFields(target: any, fields: { [field: string]: DefinitionType }) {
123
- const metadata = (target.prototype.constructor[Symbol.metadata] ??= {});
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
- index,
158
+ fieldIndex,
137
159
  field,
138
160
  type,
139
- getPropertyDescriptor(`_${field}`, index, type, complexTypeKlass)
161
+ getPropertyDescriptor(`_${field}`, fieldIndex, type, complexTypeKlass)
140
162
  );
141
163
 
142
- index++;
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, -1, {
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[-1]; i++) {
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, -1, {
185
- value: parentMetadata[-1],
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], -1) as boolean
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[-1]; i++) {
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
- static encode(instance: Schema, context?: TypeContext, it: Iterator = { offset: 0 }) {
29
- context ??= new TypeContext(instance.constructor as typeof Schema);
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 encoder = new Encoder(reflection);
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 = encoder.encodeAll(it);
106
+ const buf = reflectionEncoder.encodeAll(it);
102
107
  return Buffer.from(buf, 0, it.offset);
103
108
  }
104
109
 
105
- static decode<T extends Schema = Schema>(bytes: Buffer, it?: Iterator): T {
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
- // @ts-ignore
164
- return new (typeContext.get(0))();
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: Map<number, OPERATION>) {
215
- Array.from(changeSet)
216
- .sort((a, b) => a[0] - b[0])
217
- .forEach(([index, operation]) =>
218
- output += `- [${index}]: ${OPERATION[operation]} (${JSON.stringify(changeTree.getValue(index, isEncodeAll))})\n`
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 (!isEncodeAll && changeTree.filteredChanges?.size > 0) {
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 (isEncodeAll && changeTree.allFilteredChanges?.size > 0) {
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 [changeTree, changes] of (rootChangeTree.root[changeSetName].entries())) {
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.size;
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.changes;
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.size}\n`;
303
+ output += `${indent}${parentIndex}${changeTree.ref.constructor.name} (refId: ${changeTree.refId}) - changes: ${Object.keys(changes).length}\n`;
296
304
 
297
- for (const [index, operation] of changes) {
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}`;
@@ -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, context: ClassDecoratorContext) {
49
- if (!constructor._definition) {
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[-1] // current structure already has fields defined
86
- // ?? (parent && parent[-1]) // parent structure has fields defined
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[-1] // current structure already has fields defined
241
- // ?? (parentMetadata && parentMetadata[-1]) // parent structure has fields defined
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[-1] // current structure already has fields defined
269
- // ?? (parentMetadata && parentMetadata[-1]) // parent structure has fields defined
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[-1] // current structure already has fields defined
323
- ?? (parentMetadata && parentMetadata[-1]) // parent structure has fields defined
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] || undefined;
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[-1] // current structure already has fields defined
458
- // ?? (parentMetadata && parentMetadata[-1]) // parent structure has fields defined
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
  // }
@@ -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
- for (let i = 0; i < 100; i++) {
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
- console.log("time to make changes:", Date.now() - now);
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
- console.log("time to encode:", Date.now() - now);
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
- const state = Reflection.decode(getBuffer(line));
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));
@@ -68,7 +68,7 @@ export class Decoder<T extends Schema = any> {
68
68
  ref[$onDecodeEnd]?.()
69
69
  ref = nextRef;
70
70
 
71
- decoder = ref['constructor'][$decoder];
71
+ decoder = ref.constructor[$decoder];
72
72
 
73
73
  continue;
74
74
  }