@colyseus/schema 2.0.32 → 3.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/build/cjs/index.js +3614 -2634
  2. package/build/cjs/index.js.map +1 -1
  3. package/build/esm/index.mjs +3324 -2445
  4. package/build/esm/index.mjs.map +1 -1
  5. package/build/umd/index.js +3614 -2634
  6. package/lib/Decoder.d.ts +16 -0
  7. package/lib/Decoder.js +182 -0
  8. package/lib/Decoder.js.map +1 -0
  9. package/lib/Encoder.d.ts +13 -0
  10. package/lib/Encoder.js +79 -0
  11. package/lib/Encoder.js.map +1 -0
  12. package/lib/Metadata.d.ts +36 -0
  13. package/lib/Metadata.js +91 -0
  14. package/lib/Metadata.js.map +1 -0
  15. package/lib/Reflection.d.ts +7 -5
  16. package/lib/Reflection.js +62 -58
  17. package/lib/Reflection.js.map +1 -1
  18. package/lib/Schema.d.ts +39 -51
  19. package/lib/Schema.js +189 -731
  20. package/lib/Schema.js.map +1 -1
  21. package/lib/annotations.d.ts +26 -45
  22. package/lib/annotations.js +363 -194
  23. package/lib/annotations.js.map +1 -1
  24. package/lib/changes/ChangeSet.d.ts +12 -0
  25. package/lib/changes/ChangeSet.js +35 -0
  26. package/lib/changes/ChangeSet.js.map +1 -0
  27. package/lib/changes/DecodeOperation.d.ts +15 -0
  28. package/lib/changes/DecodeOperation.js +186 -0
  29. package/lib/changes/DecodeOperation.js.map +1 -0
  30. package/lib/changes/EncodeOperation.d.ts +18 -0
  31. package/lib/changes/EncodeOperation.js +130 -0
  32. package/lib/changes/EncodeOperation.js.map +1 -0
  33. package/lib/changes/consts.d.ts +14 -0
  34. package/lib/changes/consts.js +18 -0
  35. package/lib/changes/consts.js.map +1 -0
  36. package/lib/decoder/DecodeOperation.d.ts +24 -0
  37. package/lib/decoder/DecodeOperation.js +256 -0
  38. package/lib/decoder/DecodeOperation.js.map +1 -0
  39. package/lib/decoder/Decoder.d.ts +21 -0
  40. package/lib/decoder/Decoder.js +114 -0
  41. package/lib/decoder/Decoder.js.map +1 -0
  42. package/lib/decoder/ReferenceTracker.d.ts +26 -0
  43. package/lib/decoder/ReferenceTracker.js +131 -0
  44. package/lib/decoder/ReferenceTracker.js.map +1 -0
  45. package/lib/decoder/strategy/RawChanges.d.ts +3 -0
  46. package/lib/decoder/strategy/RawChanges.js +8 -0
  47. package/lib/decoder/strategy/RawChanges.js.map +1 -0
  48. package/lib/decoder/strategy/StateCallbacks.d.ts +20 -0
  49. package/lib/decoder/strategy/StateCallbacks.js +240 -0
  50. package/lib/decoder/strategy/StateCallbacks.js.map +1 -0
  51. package/lib/decoding/decode.d.ts +48 -0
  52. package/lib/decoding/decode.js +267 -0
  53. package/lib/decoding/decode.js.map +1 -0
  54. package/lib/ecs.d.ts +11 -0
  55. package/lib/ecs.js +160 -0
  56. package/lib/ecs.js.map +1 -0
  57. package/lib/encoder/ChangeTree.d.ts +72 -0
  58. package/lib/encoder/ChangeTree.js +384 -0
  59. package/lib/encoder/ChangeTree.js.map +1 -0
  60. package/lib/encoder/EncodeOperation.d.ts +25 -0
  61. package/lib/encoder/EncodeOperation.js +156 -0
  62. package/lib/encoder/EncodeOperation.js.map +1 -0
  63. package/lib/encoder/Encoder.d.ts +23 -0
  64. package/lib/encoder/Encoder.js +192 -0
  65. package/lib/encoder/Encoder.js.map +1 -0
  66. package/lib/encoder/StateView.d.ts +21 -0
  67. package/lib/encoder/StateView.js +196 -0
  68. package/lib/encoder/StateView.js.map +1 -0
  69. package/lib/encoding/assert.d.ts +9 -0
  70. package/lib/encoding/assert.js +47 -0
  71. package/lib/encoding/assert.js.map +1 -0
  72. package/lib/encoding/decode.js +1 -1
  73. package/lib/encoding/decode.js.map +1 -1
  74. package/lib/encoding/encode.d.ts +17 -16
  75. package/lib/encoding/encode.js +88 -81
  76. package/lib/encoding/encode.js.map +1 -1
  77. package/lib/encoding/spec.d.ts +25 -0
  78. package/lib/encoding/spec.js +30 -0
  79. package/lib/encoding/spec.js.map +1 -0
  80. package/lib/index.d.ts +18 -10
  81. package/lib/index.js +39 -17
  82. package/lib/index.js.map +1 -1
  83. package/lib/symbol.shim.d.ts +6 -0
  84. package/lib/symbol.shim.js +4 -0
  85. package/lib/symbol.shim.js.map +1 -0
  86. package/lib/types/ArraySchema.d.ts +1 -1
  87. package/lib/types/ArraySchema.js +0 -7
  88. package/lib/types/ArraySchema.js.map +1 -1
  89. package/lib/types/HelperTypes.d.ts +10 -2
  90. package/lib/types/HelperTypes.js.map +1 -1
  91. package/lib/types/custom/ArraySchema.d.ts +245 -0
  92. package/lib/types/custom/ArraySchema.js +659 -0
  93. package/lib/types/custom/ArraySchema.js.map +1 -0
  94. package/lib/types/custom/CollectionSchema.d.ts +42 -0
  95. package/lib/types/custom/CollectionSchema.js +165 -0
  96. package/lib/types/custom/CollectionSchema.js.map +1 -0
  97. package/lib/types/custom/MapSchema.d.ts +43 -0
  98. package/lib/types/custom/MapSchema.js +200 -0
  99. package/lib/types/custom/MapSchema.js.map +1 -0
  100. package/lib/types/custom/SetSchema.d.ts +39 -0
  101. package/lib/types/custom/SetSchema.js +177 -0
  102. package/lib/types/custom/SetSchema.js.map +1 -0
  103. package/lib/types/registry.d.ts +6 -0
  104. package/lib/types/registry.js +19 -0
  105. package/lib/types/registry.js.map +1 -0
  106. package/lib/types/symbols.d.ts +29 -0
  107. package/lib/types/symbols.js +33 -0
  108. package/lib/types/symbols.js.map +1 -0
  109. package/lib/types/utils.d.ts +0 -8
  110. package/lib/types/utils.js +1 -33
  111. package/lib/types/utils.js.map +1 -1
  112. package/lib/usage.d.ts +1 -0
  113. package/lib/usage.js +22 -0
  114. package/lib/usage.js.map +1 -0
  115. package/lib/utils.d.ts +13 -2
  116. package/lib/utils.js +36 -15
  117. package/lib/utils.js.map +1 -1
  118. package/lib/v3.d.ts +1 -0
  119. package/lib/v3.js +427 -0
  120. package/lib/v3.js.map +1 -0
  121. package/lib/v3_bench.d.ts +1 -0
  122. package/lib/v3_bench.js +130 -0
  123. package/lib/v3_bench.js.map +1 -0
  124. package/lib/v3_experiment.d.ts +1 -0
  125. package/lib/v3_experiment.js +407 -0
  126. package/lib/v3_experiment.js.map +1 -0
  127. package/package.json +5 -5
  128. package/src/Metadata.ts +135 -0
  129. package/src/Reflection.ts +75 -66
  130. package/src/Schema.ts +213 -931
  131. package/src/annotations.ts +430 -243
  132. package/src/decoder/DecodeOperation.ts +372 -0
  133. package/src/decoder/Decoder.ts +155 -0
  134. package/src/decoder/ReferenceTracker.ts +151 -0
  135. package/src/decoder/strategy/RawChanges.ts +9 -0
  136. package/src/decoder/strategy/StateCallbacks.ts +326 -0
  137. package/src/encoder/ChangeTree.ts +492 -0
  138. package/src/encoder/EncodeOperation.ts +237 -0
  139. package/src/encoder/Encoder.ts +246 -0
  140. package/src/encoder/StateView.ts +229 -0
  141. package/src/encoding/assert.ts +58 -0
  142. package/src/encoding/decode.ts +1 -1
  143. package/src/encoding/encode.ts +88 -82
  144. package/src/encoding/spec.ts +29 -0
  145. package/src/index.ts +22 -19
  146. package/src/symbol.shim.ts +12 -0
  147. package/src/types/HelperTypes.ts +16 -2
  148. package/src/types/{ArraySchema.ts → custom/ArraySchema.ts} +342 -248
  149. package/src/types/{CollectionSchema.ts → custom/CollectionSchema.ts} +56 -46
  150. package/src/types/{MapSchema.ts → custom/MapSchema.ts} +88 -115
  151. package/src/types/{SetSchema.ts → custom/SetSchema.ts} +58 -47
  152. package/src/types/{typeRegistry.ts → registry.ts} +6 -6
  153. package/src/types/symbols.ts +36 -0
  154. package/src/types/utils.ts +0 -46
  155. package/src/utils.ts +50 -21
  156. package/src/v3_bench.ts +107 -0
  157. package/src/changes/ChangeTree.ts +0 -295
  158. package/src/changes/ReferenceTracker.ts +0 -91
  159. package/src/filters/index.ts +0 -23
  160. package/src/spec.ts +0 -49
@@ -1,42 +1,56 @@
1
- import { ChangeTree } from "../changes/ChangeTree";
2
- import { OPERATION } from "../spec";
3
- import { SchemaDecoderCallbacks } from "../Schema";
4
- import { addCallback, removeChildRefs } from "./utils";
5
- import { DataChange } from "..";
1
+ import { OPERATION } from "../../encoding/spec";
2
+ import { registerType } from "../registry";
3
+ import { $changes, $childType, $decoder, $deleteByIndex, $encoder, $filter, $getByIndex } from "../symbols";
4
+ import { Collection } from "../HelperTypes";
5
+ import { ChangeTree } from "../../encoder/ChangeTree";
6
+ import { encodeKeyValueOperation } from "../../encoder/EncodeOperation";
7
+ import { decodeKeyValueOperation } from "../../decoder/DecodeOperation";
8
+ import type { StateView } from "../../encoder/StateView";
6
9
 
7
- export class SetSchema<V=any> implements SchemaDecoderCallbacks {
8
- protected $changes: ChangeTree = new ChangeTree(this);
10
+ export class SetSchema<V=any> implements Collection<number, V> {
9
11
 
10
12
  protected $items: Map<number, V> = new Map<number, V>();
11
13
  protected $indexes: Map<number, number> = new Map<number, number>();
12
14
 
13
15
  protected $refId: number = 0;
14
16
 
15
- //
16
- // Decoding callbacks
17
- //
18
- public $callbacks: { [operation: number]: Array<(item: V, key: string) => void> };
19
- public onAdd(callback: (item: V, key: string) => void, triggerAll: boolean = true) {
20
- return addCallback(
21
- (this.$callbacks || (this.$callbacks = [])),
22
- OPERATION.ADD,
23
- callback,
24
- (triggerAll)
25
- ? this.$items
26
- : undefined
17
+ static [$encoder] = encodeKeyValueOperation;
18
+ static [$decoder] = decodeKeyValueOperation;
19
+
20
+ /**
21
+ * Determine if a property must be filtered.
22
+ * - If returns false, the property is NOT going to be encoded.
23
+ * - If returns true, the property is going to be encoded.
24
+ *
25
+ * Encoding with "filters" happens in two steps:
26
+ * - First, the encoder iterates over all "not owned" properties and encodes them.
27
+ * - Then, the encoder iterates over all "owned" properties per instance and encodes them.
28
+ */
29
+ static [$filter] (ref: SetSchema, index: number, view: StateView) {
30
+ return (
31
+ !view ||
32
+ typeof (ref[$childType]) === "string" ||
33
+ view.items.has(ref[$getByIndex](index)[$changes])
27
34
  );
28
35
  }
29
- public onRemove(callback: (item: V, key: string) => void) { return addCallback(this.$callbacks || (this.$callbacks = []), OPERATION.DELETE, callback); }
30
- public onChange(callback: (item: V, key: string) => void) { return addCallback(this.$callbacks || (this.$callbacks = []), OPERATION.REPLACE, callback); }
31
36
 
32
37
  static is(type: any) {
33
38
  return type['set'] !== undefined;
34
39
  }
35
40
 
36
41
  constructor (initialValues?: Array<V>) {
42
+ this[$changes] = new ChangeTree(this);
43
+
37
44
  if (initialValues) {
38
45
  initialValues.forEach((v) => this.add(v));
39
46
  }
47
+
48
+ Object.defineProperty(this, $childType, {
49
+ value: undefined,
50
+ enumerable: false,
51
+ writable: true,
52
+ configurable: true,
53
+ });
40
54
  }
41
55
 
42
56
  add(value: V) {
@@ -46,18 +60,18 @@ export class SetSchema<V=any> implements SchemaDecoderCallbacks {
46
60
  // set "index" for reference.
47
61
  const index = this.$refId++;
48
62
 
49
- if ((value['$changes']) !== undefined) {
50
- (value['$changes'] as ChangeTree).setParent(this, this.$changes.root, index);
63
+ if ((value[$changes]) !== undefined) {
64
+ value[$changes].setParent(this, this[$changes].root, index);
51
65
  }
52
66
 
53
- const operation = this.$changes.indexes[index]?.op ?? OPERATION.ADD;
67
+ const operation = this[$changes].indexes[index]?.op ?? OPERATION.ADD;
54
68
 
55
- this.$changes.indexes[index] = index;
69
+ this[$changes].indexes[index] = index;
56
70
 
57
71
  this.$indexes.set(index, index);
58
72
  this.$items.set(index, value);
59
73
 
60
- this.$changes.change(index, operation);
74
+ this[$changes].change(index, operation);
61
75
  return index;
62
76
  }
63
77
 
@@ -83,36 +97,26 @@ export class SetSchema<V=any> implements SchemaDecoderCallbacks {
83
97
  return false;
84
98
  }
85
99
 
86
- this.$changes.delete(index);
100
+ this[$changes].delete(index);
87
101
  this.$indexes.delete(index);
88
102
 
89
103
  return this.$items.delete(index);
90
104
  }
91
105
 
92
- clear(changes?: DataChange[]) {
106
+ clear() {
107
+ const changeTree = this[$changes];
108
+
93
109
  // discard previous operations.
94
- this.$changes.discard(true, true);
95
- this.$changes.indexes = {};
110
+ changeTree.discard(true);
111
+ changeTree.indexes = {};
96
112
 
97
113
  // clear previous indexes
98
114
  this.$indexes.clear();
99
115
 
100
- //
101
- // When decoding:
102
- // - enqueue items for DELETE callback.
103
- // - flag child items for garbage collection.
104
- //
105
- if (changes) {
106
- removeChildRefs.call(this, changes);
107
- }
108
-
109
116
  // clear items
110
117
  this.$items.clear();
111
118
 
112
- this.$changes.operation({ index: 0, op: OPERATION.CLEAR });
113
-
114
- // touch all structures until reach root
115
- this.$changes.touchParents();
119
+ changeTree.operation(OPERATION.CLEAR);
116
120
  }
117
121
 
118
122
  has (value: V): boolean {
@@ -144,6 +148,11 @@ export class SetSchema<V=any> implements SchemaDecoderCallbacks {
144
148
  return this.$items.size;
145
149
  }
146
150
 
151
+ /** Iterator */
152
+ [Symbol.iterator](): IterableIterator<V> {
153
+ return this.$items.values();
154
+ }
155
+
147
156
  protected setIndex(index: number, key: number) {
148
157
  this.$indexes.set(index, key);
149
158
  }
@@ -152,11 +161,11 @@ export class SetSchema<V=any> implements SchemaDecoderCallbacks {
152
161
  return this.$indexes.get(index);
153
162
  }
154
163
 
155
- protected getByIndex(index: number) {
164
+ protected [$getByIndex](index: number) {
156
165
  return this.$items.get(this.$indexes.get(index));
157
166
  }
158
167
 
159
- protected deleteByIndex(index: number) {
168
+ protected [$deleteByIndex](index: number) {
160
169
  const key = this.$indexes.get(index);
161
170
  this.$items.delete(key);
162
171
  this.$indexes.delete(index);
@@ -194,7 +203,7 @@ export class SetSchema<V=any> implements SchemaDecoderCallbacks {
194
203
  // server-side
195
204
  cloned = new SetSchema();
196
205
  this.forEach((value) => {
197
- if (value['$changes']) {
206
+ if (value[$changes]) {
198
207
  cloned.add(value['clone']());
199
208
  } else {
200
209
  cloned.add(value);
@@ -205,4 +214,6 @@ export class SetSchema<V=any> implements SchemaDecoderCallbacks {
205
214
  return cloned;
206
215
  }
207
216
 
208
- }
217
+ }
218
+
219
+ registerType("set", { constructor: SetSchema });
@@ -1,19 +1,19 @@
1
1
  export interface TypeDefinition {
2
2
  constructor: any,
3
-
4
- // //
5
- // // TODO: deprecate proxy on next version
6
- // // the proxy is used for compatibility with versions <1.0.0 of @colyseus/schema
7
- // //
8
- // getProxy?: any,
9
3
  }
10
4
 
11
5
  const registeredTypes: {[identifier: string] : TypeDefinition} = {};
6
+ const identifiers = new Map<any, string>();
12
7
 
13
8
  export function registerType(identifier: string, definition: TypeDefinition) {
9
+ identifiers.set(definition.constructor, identifier);
14
10
  registeredTypes[identifier] = definition;
15
11
  }
16
12
 
13
+ export function getIdentifier(klass: any): string {
14
+ return identifiers.get(klass);
15
+ }
16
+
17
17
  export function getType(identifier: string): TypeDefinition {
18
18
  return registeredTypes[identifier];
19
19
  }
@@ -0,0 +1,36 @@
1
+ export const $track = Symbol("$track");
2
+ export const $encoder = Symbol("$encoder");
3
+ export const $decoder = Symbol("$decoder");
4
+
5
+ export const $filter = Symbol("$filter");
6
+
7
+ export const $getByIndex = Symbol("$getByIndex");
8
+ export const $deleteByIndex = Symbol("$deleteByIndex");
9
+
10
+ /**
11
+ * Used to hold ChangeTree instances whitin the structures
12
+ */
13
+ export const $changes = Symbol('$changes');
14
+
15
+ /**
16
+ * Used to keep track of the type of the child elements of a collection
17
+ * (MapSchema, ArraySchema, etc.)
18
+ */
19
+ export const $childType = Symbol('$childType');
20
+
21
+ /**
22
+ * Special ChangeTree property to identify new instances
23
+ * (Once they're encoded, they're not new anymore)
24
+ */
25
+ export const $isNew = Symbol("$isNew");
26
+
27
+ /**
28
+ * Optional "discard" method for custom types (ArraySchema)
29
+ * (Discards changes for next serialization)
30
+ */
31
+ export const $onEncodeEnd = Symbol('$onEncodeEnd');
32
+
33
+ /**
34
+ * When decoding, this method is called after the instance is fully decoded
35
+ */
36
+ export const $onDecodeEnd = Symbol("$onDecodeEnd");
@@ -1,49 +1,3 @@
1
- import { CollectionSchema, DataChange } from "..";
2
- import { OPERATION } from "../spec";
3
-
4
- export function addCallback(
5
- $callbacks: { [op: number]: Function[] },
6
- op: OPERATION,
7
- callback: (item: any, key: any) => void,
8
- existing?: { forEach(callback: (item: any, key: any) => void): void; }
9
- ) {
10
- // initialize list of callbacks
11
- if (!$callbacks[op]) {
12
- $callbacks[op] = [];
13
- }
14
-
15
- $callbacks[op].push(callback);
16
-
17
- //
18
- // Trigger callback for existing elements
19
- // - OPERATION.ADD
20
- // - OPERATION.REPLACE
21
- //
22
- existing?.forEach((item, key) => callback(item, key));
23
-
24
- return () => spliceOne($callbacks[op], $callbacks[op].indexOf(callback));
25
- }
26
-
27
-
28
- export function removeChildRefs(this: CollectionSchema, changes: DataChange[]) {
29
- const needRemoveRef = (typeof (this.$changes.getType()) !== "string");
30
-
31
- this.$items.forEach((item: any, key: any) => {
32
- changes.push({
33
- refId: this.$changes.refId,
34
- op: OPERATION.DELETE,
35
- field: key,
36
- value: undefined,
37
- previousValue: item
38
- });
39
-
40
- if (needRemoveRef) {
41
- this.$changes.root.removeRef(item['$changes'].refId);
42
- }
43
- });
44
- }
45
-
46
-
47
1
  export function spliceOne(arr: any[], index: number): boolean {
48
2
  // manually splice an array
49
3
  if (index === -1 || index >= arr.length) {
package/src/utils.ts CHANGED
@@ -1,28 +1,57 @@
1
- import { Schema } from "./Schema";
2
- import { ChangeTree } from "./changes/ChangeTree";
3
-
4
- export function dumpChanges(schema: Schema) {
5
- const changeTrees: ChangeTree[] = [schema['$changes']];
6
- let numChangeTrees = 1;
7
-
8
- const dump = {};
9
- let currentStructure = dump;
1
+ import type { Schema } from "./Schema";
2
+ import { OPERATION } from "./encoding/spec";
3
+ import { $changes } from "./types/symbols";
4
+
5
+ type ChangeItem = [string, number | string, any?];
6
+
7
+ interface ChangeDump {
8
+ ops: {
9
+ ADD?: number;
10
+ REMOVE?: number;
11
+ REPLACE?: number;
12
+ },
13
+ refs: string[],
14
+ }
10
15
 
11
- for (let i = 0; i < numChangeTrees; i++) {
12
- const changeTree = changeTrees[i];
16
+ export function getIndent(level: number) {
17
+ return (new Array(level).fill(0)).map((_, i) =>
18
+ (i === level - 1) ? `└─ ` : ` `
19
+ ).join("");
20
+ }
13
21
 
14
- changeTree.changes.forEach((change) => {
15
- const ref = changeTree.ref;
16
- const fieldIndex = change.index;
22
+ export function dumpChanges(schema: Schema) {
23
+ const $root = schema[$changes].root;
24
+
25
+ const dump: ChangeDump = {
26
+ ops: {},
27
+ refs: []
28
+ };
29
+
30
+ $root.changes.forEach((operations, changeTree) => {
31
+ dump.refs.push(`refId#${changeTree.refId}`);
32
+ operations.forEach((op, index) => {
33
+ const opName = OPERATION[op];
34
+ if (!dump.ops[opName]) { dump.ops[opName] = 0; }
35
+ dump.ops[OPERATION[op]]++;
36
+ });
37
+ });
17
38
 
18
- const field = ((ref as Schema)['_definition'])
19
- ? ref['_definition'].fieldsByIndex[fieldIndex]
20
- : ref['$indexes'].get(fieldIndex);
39
+ return dump;
40
+ }
21
41
 
22
- currentStructure[field] = changeTree.getValue(fieldIndex);
23
- });
42
+ export function getNextPowerOf2(number: number) {
43
+ // If number is already a power of 2, return it
44
+ if ((number & (number - 1)) === 0) {
45
+ return number;
46
+ }
24
47
 
48
+ // Find the position of the most significant bit
49
+ let msbPosition = 0;
50
+ while (number > 0) {
51
+ number >>= 1;
52
+ msbPosition++;
25
53
  }
26
54
 
27
- return dump;
28
- }
55
+ // Return the next power of 2
56
+ return 1 << msbPosition;
57
+ }
@@ -0,0 +1,107 @@
1
+ import { Schema, type, MapSchema, ArraySchema, Reflection, Encoder, Decoder } from "./index";
2
+
3
+ // globalThis.interval = setInterval(() => {}, 1000);
4
+
5
+ // class Item extends Schema {
6
+ // @type("string") name: string;
7
+ // }
8
+
9
+ // class RootState extends Schema {
10
+ // @type([Item]) items = new ArraySchema<Item>();
11
+ // }
12
+ // const state = new RootState();
13
+ // state.items.push(new Item().assign({ name: "hello" }));
14
+
15
+ // console.log("Encoded:", state.encode());
16
+
17
+ class Vec3 extends Schema {
18
+ @type("number") x: number;
19
+ @type("number") y: number;
20
+ @type("number") z: number;
21
+ }
22
+
23
+ class Base extends Schema {}
24
+
25
+ class Entity extends Schema {
26
+ @type(Vec3) position = new Vec3().assign({ x: 0, y: 0, z: 0 });
27
+ }
28
+
29
+ class Player extends Entity {
30
+ @type(Vec3) rotation = new Vec3().assign({ x: 0, y: 0, z: 0 });
31
+ @type("string") secret: string = "private info only for this player";
32
+ }
33
+
34
+ class State extends Schema {
35
+ // @type({ map: Base }) players = new MapSchema<Entity>();
36
+ @type("number") num: number = 0;
37
+ @type("string") str = "Hello world!";
38
+ // @type(Entity) entity = new Player().assign({
39
+ // position: new Vec3().assign({ x: 1, y: 2, z: 3 }),
40
+ // rotation: new Vec3().assign({ x: 4, y: 5, z: 6 }),
41
+ // });
42
+ @type({ map: Entity }) entities = new MapSchema();
43
+ }
44
+
45
+ const state = new State();
46
+
47
+ state.entities.set("one", new Player().assign({
48
+ position: new Vec3().assign({ x: 1, y: 2, z: 3 }),
49
+ rotation: new Vec3().assign({ x: 1, y: 2, z: 3 }),
50
+ }));
51
+
52
+ state.entities.set("two", new Player().assign({
53
+ position: new Vec3().assign({ x: 4, y: 5, z: 6 }),
54
+ rotation: new Vec3().assign({ x: 7, y: 8, z: 9 }),
55
+ }));
56
+
57
+ const encoder = new Encoder(state);
58
+ let encoded = encoder.encode();
59
+ console.log(`(${encoded.length})`, [...encoded]);
60
+
61
+ globalThis.perform = function() {
62
+ for (let i = 0; i < 500000; i++) {
63
+ encoder.encodeAll();
64
+ }
65
+ }
66
+
67
+ function logTime(label: string, callback: Function) {
68
+ const time = Date.now();
69
+ for (let i = 0; i < 500000; i++) {
70
+ callback();
71
+ }
72
+ console.log(`${label}:`, Date.now() - time);
73
+ }
74
+ logTime("encode time", () => encoder.encodeAll());
75
+
76
+ const decoder = new Decoder(new State());
77
+ logTime("decode time", () => decoder.decode(encoded));
78
+
79
+ // const time = Date.now();
80
+ // console.profile();
81
+ // for (let i = 0; i < 300000; i++) {
82
+ // state.encodeAll();
83
+ // }
84
+ // console.profileEnd();
85
+ // console.log("encode time:", Date.now() - time);
86
+
87
+ // const decoded = Reflection.decode(Reflection.encode(state));
88
+ // decoded.decode(encoded);
89
+ //
90
+ // console.log(decoded.toJSON());
91
+ //
92
+ // const rotation = state.entity.rotation;
93
+ // rotation.x = 100;
94
+ //
95
+ // encoded = state.encode();
96
+ // console.log({encoded});
97
+ //
98
+ // decoded.decode(encoded);
99
+ // console.log(decoded.toJSON());
100
+
101
+ // const time = Date.now();
102
+ // for (let i = 0; i < 300000; i++) {
103
+ // const state = new State();
104
+ // state.encode();
105
+ // }
106
+ // console.log("encode time:", Date.now() - time);
107
+