@colyseus/schema 3.0.0-alpha.9 → 3.0.1

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 (202) hide show
  1. package/README.md +148 -62
  2. package/bin/schema-debug +94 -0
  3. package/build/cjs/index.js +2222 -1513
  4. package/build/cjs/index.js.map +1 -1
  5. package/build/esm/index.mjs +2223 -1516
  6. package/build/esm/index.mjs.map +1 -1
  7. package/build/umd/index.js +2225 -1516
  8. package/lib/Metadata.d.ts +21 -9
  9. package/lib/Metadata.js +169 -32
  10. package/lib/Metadata.js.map +1 -1
  11. package/lib/Reflection.d.ts +19 -4
  12. package/lib/Reflection.js +66 -31
  13. package/lib/Reflection.js.map +1 -1
  14. package/lib/Schema.d.ts +12 -5
  15. package/lib/Schema.js +57 -56
  16. package/lib/Schema.js.map +1 -1
  17. package/lib/annotations.d.ts +31 -34
  18. package/lib/annotations.js +110 -160
  19. package/lib/annotations.js.map +1 -1
  20. package/lib/codegen/api.js +1 -2
  21. package/lib/codegen/api.js.map +1 -1
  22. package/lib/codegen/languages/cpp.js +1 -2
  23. package/lib/codegen/languages/cpp.js.map +1 -1
  24. package/lib/codegen/languages/csharp.js +9 -46
  25. package/lib/codegen/languages/csharp.js.map +1 -1
  26. package/lib/codegen/languages/haxe.js +4 -2
  27. package/lib/codegen/languages/haxe.js.map +1 -1
  28. package/lib/codegen/languages/java.js +1 -2
  29. package/lib/codegen/languages/java.js.map +1 -1
  30. package/lib/codegen/languages/js.js +1 -2
  31. package/lib/codegen/languages/js.js.map +1 -1
  32. package/lib/codegen/languages/lua.js +23 -25
  33. package/lib/codegen/languages/lua.js.map +1 -1
  34. package/lib/codegen/languages/ts.js +1 -2
  35. package/lib/codegen/languages/ts.js.map +1 -1
  36. package/lib/codegen/parser.js +85 -3
  37. package/lib/codegen/parser.js.map +1 -1
  38. package/lib/codegen/types.js +6 -3
  39. package/lib/codegen/types.js.map +1 -1
  40. package/lib/decoder/DecodeOperation.d.ts +3 -4
  41. package/lib/decoder/DecodeOperation.js +35 -17
  42. package/lib/decoder/DecodeOperation.js.map +1 -1
  43. package/lib/decoder/Decoder.d.ts +5 -6
  44. package/lib/decoder/Decoder.js +10 -10
  45. package/lib/decoder/Decoder.js.map +1 -1
  46. package/lib/decoder/ReferenceTracker.js +4 -2
  47. package/lib/decoder/ReferenceTracker.js.map +1 -1
  48. package/lib/decoder/strategy/RawChanges.js +1 -2
  49. package/lib/decoder/strategy/RawChanges.js.map +1 -1
  50. package/lib/decoder/strategy/StateCallbacks.d.ts +44 -11
  51. package/lib/decoder/strategy/StateCallbacks.js +74 -64
  52. package/lib/decoder/strategy/StateCallbacks.js.map +1 -1
  53. package/lib/encoder/ChangeTree.d.ts +28 -20
  54. package/lib/encoder/ChangeTree.js +242 -188
  55. package/lib/encoder/ChangeTree.js.map +1 -1
  56. package/lib/encoder/EncodeOperation.d.ts +3 -6
  57. package/lib/encoder/EncodeOperation.js +51 -65
  58. package/lib/encoder/EncodeOperation.js.map +1 -1
  59. package/lib/encoder/Encoder.d.ts +8 -7
  60. package/lib/encoder/Encoder.js +128 -79
  61. package/lib/encoder/Encoder.js.map +1 -1
  62. package/lib/encoder/Root.d.ts +22 -0
  63. package/lib/encoder/Root.js +81 -0
  64. package/lib/encoder/Root.js.map +1 -0
  65. package/lib/encoder/StateView.d.ts +7 -7
  66. package/lib/encoder/StateView.js +72 -74
  67. package/lib/encoder/StateView.js.map +1 -1
  68. package/lib/encoding/assert.d.ts +7 -6
  69. package/lib/encoding/assert.js +13 -5
  70. package/lib/encoding/assert.js.map +1 -1
  71. package/lib/encoding/decode.d.ts +36 -19
  72. package/lib/encoding/decode.js +54 -84
  73. package/lib/encoding/decode.js.map +1 -1
  74. package/lib/encoding/encode.d.ts +36 -18
  75. package/lib/encoding/encode.js +61 -48
  76. package/lib/encoding/encode.js.map +1 -1
  77. package/lib/encoding/spec.d.ts +4 -5
  78. package/lib/encoding/spec.js +1 -2
  79. package/lib/encoding/spec.js.map +1 -1
  80. package/lib/index.d.ts +10 -9
  81. package/lib/index.js +24 -17
  82. package/lib/index.js.map +1 -1
  83. package/lib/types/HelperTypes.d.ts +34 -2
  84. package/lib/types/HelperTypes.js.map +1 -1
  85. package/lib/types/TypeContext.d.ts +29 -0
  86. package/lib/types/TypeContext.js +151 -0
  87. package/lib/types/TypeContext.js.map +1 -0
  88. package/lib/types/custom/ArraySchema.d.ts +2 -2
  89. package/lib/types/custom/ArraySchema.js +33 -22
  90. package/lib/types/custom/ArraySchema.js.map +1 -1
  91. package/lib/types/custom/CollectionSchema.d.ts +2 -2
  92. package/lib/types/custom/CollectionSchema.js +1 -0
  93. package/lib/types/custom/CollectionSchema.js.map +1 -1
  94. package/lib/types/custom/MapSchema.d.ts +18 -16
  95. package/lib/types/custom/MapSchema.js +12 -4
  96. package/lib/types/custom/MapSchema.js.map +1 -1
  97. package/lib/types/custom/SetSchema.d.ts +2 -2
  98. package/lib/types/custom/SetSchema.js +1 -0
  99. package/lib/types/custom/SetSchema.js.map +1 -1
  100. package/lib/types/registry.d.ts +8 -1
  101. package/lib/types/registry.js +23 -6
  102. package/lib/types/registry.js.map +1 -1
  103. package/lib/types/symbols.d.ts +8 -5
  104. package/lib/types/symbols.js +9 -6
  105. package/lib/types/symbols.js.map +1 -1
  106. package/lib/types/utils.js +1 -2
  107. package/lib/types/utils.js.map +1 -1
  108. package/lib/utils.js +9 -7
  109. package/lib/utils.js.map +1 -1
  110. package/package.json +19 -18
  111. package/src/Metadata.ts +190 -42
  112. package/src/Reflection.ts +76 -38
  113. package/src/Schema.ts +72 -70
  114. package/src/annotations.ts +156 -202
  115. package/src/codegen/languages/csharp.ts +8 -47
  116. package/src/codegen/languages/haxe.ts +4 -0
  117. package/src/codegen/languages/lua.ts +19 -27
  118. package/src/codegen/parser.ts +107 -0
  119. package/src/codegen/types.ts +1 -0
  120. package/src/decoder/DecodeOperation.ts +43 -15
  121. package/src/decoder/Decoder.ts +12 -10
  122. package/src/decoder/ReferenceTracker.ts +5 -3
  123. package/src/decoder/strategy/StateCallbacks.ts +152 -81
  124. package/src/encoder/ChangeTree.ts +282 -209
  125. package/src/encoder/EncodeOperation.ts +78 -78
  126. package/src/encoder/Encoder.ts +152 -88
  127. package/src/encoder/Root.ts +93 -0
  128. package/src/encoder/StateView.ts +80 -88
  129. package/src/encoding/assert.ts +17 -8
  130. package/src/encoding/decode.ts +73 -93
  131. package/src/encoding/encode.ts +76 -45
  132. package/src/encoding/spec.ts +3 -5
  133. package/src/index.ts +12 -20
  134. package/src/types/HelperTypes.ts +54 -2
  135. package/src/types/TypeContext.ts +175 -0
  136. package/src/types/custom/ArraySchema.ts +49 -19
  137. package/src/types/custom/CollectionSchema.ts +1 -0
  138. package/src/types/custom/MapSchema.ts +30 -17
  139. package/src/types/custom/SetSchema.ts +1 -0
  140. package/src/types/registry.ts +22 -3
  141. package/src/types/symbols.ts +10 -7
  142. package/src/utils.ts +7 -3
  143. package/lib/Decoder.d.ts +0 -16
  144. package/lib/Decoder.js +0 -182
  145. package/lib/Decoder.js.map +0 -1
  146. package/lib/Encoder.d.ts +0 -13
  147. package/lib/Encoder.js +0 -79
  148. package/lib/Encoder.js.map +0 -1
  149. package/lib/changes/ChangeSet.d.ts +0 -12
  150. package/lib/changes/ChangeSet.js +0 -35
  151. package/lib/changes/ChangeSet.js.map +0 -1
  152. package/lib/changes/ChangeTree.d.ts +0 -53
  153. package/lib/changes/ChangeTree.js +0 -202
  154. package/lib/changes/ChangeTree.js.map +0 -1
  155. package/lib/changes/DecodeOperation.d.ts +0 -15
  156. package/lib/changes/DecodeOperation.js +0 -186
  157. package/lib/changes/DecodeOperation.js.map +0 -1
  158. package/lib/changes/EncodeOperation.d.ts +0 -18
  159. package/lib/changes/EncodeOperation.js +0 -130
  160. package/lib/changes/EncodeOperation.js.map +0 -1
  161. package/lib/changes/ReferenceTracker.d.ts +0 -14
  162. package/lib/changes/ReferenceTracker.js +0 -83
  163. package/lib/changes/ReferenceTracker.js.map +0 -1
  164. package/lib/changes/consts.d.ts +0 -14
  165. package/lib/changes/consts.js +0 -18
  166. package/lib/changes/consts.js.map +0 -1
  167. package/lib/decoding/decode.d.ts +0 -48
  168. package/lib/decoding/decode.js +0 -267
  169. package/lib/decoding/decode.js.map +0 -1
  170. package/lib/ecs.d.ts +0 -11
  171. package/lib/ecs.js +0 -160
  172. package/lib/ecs.js.map +0 -1
  173. package/lib/filters/index.d.ts +0 -8
  174. package/lib/filters/index.js +0 -24
  175. package/lib/filters/index.js.map +0 -1
  176. package/lib/spec.d.ts +0 -13
  177. package/lib/spec.js +0 -42
  178. package/lib/spec.js.map +0 -1
  179. package/lib/types/ArraySchema.d.ts +0 -238
  180. package/lib/types/ArraySchema.js +0 -555
  181. package/lib/types/ArraySchema.js.map +0 -1
  182. package/lib/types/CollectionSchema.d.ts +0 -35
  183. package/lib/types/CollectionSchema.js +0 -150
  184. package/lib/types/CollectionSchema.js.map +0 -1
  185. package/lib/types/MapSchema.d.ts +0 -38
  186. package/lib/types/MapSchema.js +0 -215
  187. package/lib/types/MapSchema.js.map +0 -1
  188. package/lib/types/SetSchema.d.ts +0 -32
  189. package/lib/types/SetSchema.js +0 -162
  190. package/lib/types/SetSchema.js.map +0 -1
  191. package/lib/types/typeRegistry.d.ts +0 -5
  192. package/lib/types/typeRegistry.js +0 -13
  193. package/lib/types/typeRegistry.js.map +0 -1
  194. package/lib/usage.d.ts +0 -1
  195. package/lib/usage.js +0 -22
  196. package/lib/usage.js.map +0 -1
  197. package/lib/v3.d.ts +0 -1
  198. package/lib/v3.js +0 -427
  199. package/lib/v3.js.map +0 -1
  200. package/lib/v3_experiment.d.ts +0 -1
  201. package/lib/v3_experiment.js +0 -407
  202. package/lib/v3_experiment.js.map +0 -1
@@ -1,6 +1,6 @@
1
- import { $changes, $childType, $decoder, $deleteByIndex, $onEncodeEnd, $encoder, $filter, $getByIndex, $onDecodeEnd, $isNew } from "../symbols";
1
+ import { $changes, $childType, $decoder, $deleteByIndex, $onEncodeEnd, $encoder, $filter, $getByIndex, $onDecodeEnd } from "../symbols";
2
2
  import type { Schema } from "../../Schema";
3
- import { ChangeTree } from "../../encoder/ChangeTree";
3
+ import { ChangeTree, setOperationAtIndex } from "../../encoder/ChangeTree";
4
4
  import { OPERATION } from "../../encoding/spec";
5
5
  import { registerType } from "../registry";
6
6
  import { Collection } from "../HelperTypes";
@@ -8,6 +8,7 @@ import { Collection } from "../HelperTypes";
8
8
  import { encodeArray } from "../../encoder/EncodeOperation";
9
9
  import { decodeArray } from "../../decoder/DecodeOperation";
10
10
  import type { StateView } from "../../encoder/StateView";
11
+ import { assertInstanceType } from "../../encoding/assert";
11
12
 
12
13
  const DEFAULT_SORT = (a: any, b: any) => {
13
14
  const A = a.toString();
@@ -69,6 +70,7 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
69
70
  get: (obj, prop) => {
70
71
  if (
71
72
  typeof (prop) !== "symbol" &&
73
+ // FIXME: d8 accuses this as low performance
72
74
  !isNaN(prop as any) // https://stackoverflow.com/a/175787/892698
73
75
  ) {
74
76
  return this.items[prop];
@@ -85,8 +87,10 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
85
87
 
86
88
  } else {
87
89
  if (setValue[$changes]) {
90
+ assertInstanceType(setValue, obj[$childType] as typeof Schema, obj, key);
91
+
88
92
  if (obj.items[key as unknown as number] !== undefined) {
89
- if (setValue[$changes][$isNew]) {
93
+ if (setValue[$changes].isNew) {
90
94
  this[$changes].indexedOperation(Number(key), OPERATION.MOVE_AND_ADD);
91
95
 
92
96
  } else {
@@ -96,9 +100,10 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
96
100
  this[$changes].indexedOperation(Number(key), OPERATION.MOVE);
97
101
  }
98
102
  }
99
- } else if (setValue[$changes][$isNew]) {
103
+ } else if (setValue[$changes].isNew) {
100
104
  this[$changes].indexedOperation(Number(key), OPERATION.ADD);
101
105
  }
106
+
102
107
  } else {
103
108
  obj.$changeAt(Number(key), setValue);
104
109
  }
@@ -133,7 +138,11 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
133
138
  });
134
139
 
135
140
  this[$changes] = new ChangeTree(proxy);
136
- this.push.apply(this, items);
141
+ this[$changes].indexes = {};
142
+
143
+ if (items.length > 0) {
144
+ this.push(...items);
145
+ }
137
146
 
138
147
  return proxy;
139
148
  }
@@ -155,15 +164,23 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
155
164
  push(...values: V[]) {
156
165
  let length = this.tmpItems.length;
157
166
 
158
- values.forEach((value, i) => {
159
- // skip null values
167
+ const changeTree = this[$changes];
168
+
169
+ // values.forEach((value, i) => {
170
+
171
+ for (let i = 0, l = values.length; i < values.length; i++, length++) {
172
+ const value = values[i];
173
+
160
174
  if (value === undefined || value === null) {
175
+ // skip null values
161
176
  return;
177
+
178
+ } else if (typeof (value) === "object" && this[$childType]) {
179
+ assertInstanceType(value as any, this[$childType] as typeof Schema, this, i);
180
+ // TODO: move value[$changes]?.setParent() to this block.
162
181
  }
163
182
 
164
- const changeTree = this[$changes];
165
183
  changeTree.indexedOperation(length, OPERATION.ADD, this.items.length);
166
- // changeTree.indexes[length] = length;
167
184
 
168
185
  this.items.push(value);
169
186
  this.tmpItems.push(value);
@@ -173,9 +190,10 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
173
190
  // (to avoid encoding "refId" operations before parent's "ADD" operation)
174
191
  //
175
192
  value[$changes]?.setParent(this, changeTree.root, length);
193
+ }
176
194
 
177
- length++;
178
- });
195
+ // length++;
196
+ // });
179
197
 
180
198
  return length;
181
199
  }
@@ -202,6 +220,8 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
202
220
  this[$changes].delete(index, undefined, this.items.length - 1);
203
221
 
204
222
  // this.tmpItems[index] = undefined;
223
+ // this.tmpItems.pop();
224
+
205
225
  this.deletedIndexes[index] = true;
206
226
 
207
227
  return this.items.pop();
@@ -263,10 +283,12 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
263
283
 
264
284
  clear() {
265
285
  // skip if already clear
266
- if (this.items.length === 0) { return; }
286
+ if (this.items.length === 0) {
287
+ return;
288
+ }
267
289
 
268
290
  // discard previous operations.
269
- const changeTree = this[$changes]
291
+ const changeTree = this[$changes];
270
292
 
271
293
  // discard children
272
294
  changeTree.forEachChild((changeTree, _) => {
@@ -278,9 +300,12 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
278
300
  //
279
301
  // TODO: do not use [$changes] at decoding time.
280
302
  //
281
- changeTree.root?.changes.delete(changeTree);
282
- changeTree.root?.allChanges.delete(changeTree);
283
- changeTree.root?.allFilteredChanges.delete(changeTree);
303
+ const root = changeTree.root;
304
+ if (root !== undefined) {
305
+ root.removeChangeFromChangeSet("changes", changeTree);
306
+ root.removeChangeFromChangeSet("allChanges", changeTree);
307
+ root.removeChangeFromChangeSet("allFilteredChanges", changeTree);
308
+ }
284
309
  });
285
310
 
286
311
  changeTree.discard(true);
@@ -331,6 +356,8 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
331
356
  changeTree.delete(index);
332
357
  changeTree.shiftAllChangeIndexes(-1, index);
333
358
 
359
+ // this.deletedIndexes[index] = true;
360
+
334
361
  return this.items.shift();
335
362
  }
336
363
 
@@ -430,9 +457,11 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
430
457
 
431
458
  // new index
432
459
  if (changeTree.isFiltered) {
433
- changeTree.filteredChanges.set(this.items.length, OPERATION.ADD);
460
+ setOperationAtIndex(changeTree.filteredChanges, this.items.length);
461
+ // changeTree.filteredChanges[this.items.length] = OPERATION.ADD;
434
462
  } else {
435
- changeTree.allChanges.set(this.items.length, OPERATION.ADD);
463
+ setOperationAtIndex(changeTree.allChanges, this.items.length);
464
+ // changeTree.allChanges[this.items.length] = OPERATION.ADD;
436
465
  }
437
466
 
438
467
  // FIXME: should we use OPERATION.MOVE here instead?
@@ -471,6 +500,7 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
471
500
  * @param thisArg An object to which the this keyword can refer in the callbackfn function.
472
501
  * If thisArg is omitted, undefined is used as the this value.
473
502
  */
503
+ every<S extends V>(predicate: (value: V, index: number, array: V[]) => value is S, thisArg?: any): this is S[];
474
504
  every(callbackfn: (value: V, index: number, array: V[]) => unknown, thisArg?: any): boolean {
475
505
  return this.items.every(callbackfn, thisArg);
476
506
  }
@@ -690,7 +720,7 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
690
720
  //
691
721
  // ES2023
692
722
  //
693
- with(index: number, value: V): V[] {
723
+ with(index: number, value: V): ArraySchema<V> {
694
724
  const copy = this.items.slice();
695
725
  copy[index] = value;
696
726
  return new ArraySchema(...copy);
@@ -41,6 +41,7 @@ export class CollectionSchema<V=any> implements Collection<K, V>{
41
41
 
42
42
  constructor (initialValues?: Array<V>) {
43
43
  this[$changes] = new ChangeTree(this);
44
+ this[$changes].indexes = {};
44
45
 
45
46
  if (initialValues) {
46
47
  initialValues.forEach((v) => this.add(v));
@@ -1,4 +1,4 @@
1
- import { $changes, $childType, $decoder, $deleteByIndex, $onEncodeEnd, $encoder, $filter, $getByIndex } from "../symbols";
1
+ import { $changes, $childType, $decoder, $deleteByIndex, $onEncodeEnd, $encoder, $filter, $getByIndex, $numFields } from "../symbols";
2
2
  import { ChangeTree } from "../../encoder/ChangeTree";
3
3
  import { OPERATION } from "../../encoding/spec";
4
4
  import { registerType } from "../registry";
@@ -6,12 +6,16 @@ import { Collection } from "../HelperTypes";
6
6
  import { decodeKeyValueOperation } from "../../decoder/DecodeOperation";
7
7
  import { encodeKeyValueOperation } from "../../encoder/EncodeOperation";
8
8
  import type { StateView } from "../../encoder/StateView";
9
+ import type { Schema } from "../../Schema";
10
+ import { assertInstanceType } from "../../encoding/assert";
9
11
 
10
- export class MapSchema<V=any, K extends string = string> implements Map<K, V>, Collection<K, V, [K, V]> {
12
+ export class MapSchema<V=any> implements Map<string, V>, Collection<string, V, [string, V]> {
11
13
  protected childType: new () => V;
12
14
 
13
- protected $items: Map<K, V> = new Map<K, V>();
14
- protected $indexes: Map<number, K> = new Map<number, K>();
15
+ protected $items: Map<string, V> = new Map<string, V>();
16
+ protected $indexes: Map<number, string> = new Map<number, string>();
17
+
18
+ protected [$changes]: ChangeTree;
15
19
 
16
20
  static [$encoder] = encodeKeyValueOperation;
17
21
  static [$decoder] = decodeKeyValueOperation;
@@ -37,8 +41,9 @@ export class MapSchema<V=any, K extends string = string> implements Map<K, V>, C
37
41
  return type['map'] !== undefined;
38
42
  }
39
43
 
40
- constructor (initialValues?: Map<K, V> | Record<K, V>) {
44
+ constructor (initialValues?: Map<string, V> | Record<string, V>) {
41
45
  this[$changes] = new ChangeTree(this);
46
+ this[$changes].indexes = {};
42
47
 
43
48
  if (initialValues) {
44
49
  if (
@@ -63,19 +68,22 @@ export class MapSchema<V=any, K extends string = string> implements Map<K, V>, C
63
68
  }
64
69
 
65
70
  /** Iterator */
66
- [Symbol.iterator](): IterableIterator<[K, V]> { return this.$items[Symbol.iterator](); }
71
+ [Symbol.iterator](): IterableIterator<[string, V]> { return this.$items[Symbol.iterator](); }
67
72
  get [Symbol.toStringTag]() { return this.$items[Symbol.toStringTag] }
68
73
 
69
74
  static get [Symbol.species]() { return MapSchema; }
70
75
 
71
- set(key: K, value: V) {
76
+ set(key: string, value: V) {
72
77
  if (value === undefined || value === null) {
73
78
  throw new Error(`MapSchema#set('${key}', ${value}): trying to set ${value} value on '${key}'.`);
79
+
80
+ } else if (typeof(value) === "object" && this[$childType]) {
81
+ assertInstanceType(value as any, this[$childType] as typeof Schema, this, key);
74
82
  }
75
83
 
76
84
  // Force "key" as string
77
85
  // See: https://github.com/colyseus/colyseus/issues/561#issuecomment-1646733468
78
- key = key.toString() as K;
86
+ key = key.toString() as string;
79
87
 
80
88
  const changeTree = this[$changes];
81
89
 
@@ -84,7 +92,7 @@ export class MapSchema<V=any, K extends string = string> implements Map<K, V>, C
84
92
 
85
93
  const index = (isReplace)
86
94
  ? changeTree.indexes[key]
87
- : changeTree.indexes[-1] ?? 0;
95
+ : changeTree.indexes[$numFields] ?? 0;
88
96
 
89
97
  let operation: OPERATION = (isReplace)
90
98
  ? OPERATION.REPLACE
@@ -99,7 +107,7 @@ export class MapSchema<V=any, K extends string = string> implements Map<K, V>, C
99
107
  if (!isReplace) {
100
108
  this.$indexes.set(index, key);
101
109
  changeTree.indexes[key] = index;
102
- changeTree.indexes[-1] = index + 1;
110
+ changeTree.indexes[$numFields] = index + 1;
103
111
 
104
112
  } else if (
105
113
  !isRef &&
@@ -130,11 +138,11 @@ export class MapSchema<V=any, K extends string = string> implements Map<K, V>, C
130
138
  return this;
131
139
  }
132
140
 
133
- get(key: K): V | undefined {
141
+ get(key: string): V | undefined {
134
142
  return this.$items.get(key);
135
143
  }
136
144
 
137
- delete(key: K) {
145
+ delete(key: string) {
138
146
  const index = this[$changes].indexes[key];
139
147
 
140
148
  this[$changes].delete(index);
@@ -158,11 +166,11 @@ export class MapSchema<V=any, K extends string = string> implements Map<K, V>, C
158
166
  changeTree.operation(OPERATION.CLEAR);
159
167
  }
160
168
 
161
- has (key: K) {
169
+ has (key: string) {
162
170
  return this.$items.has(key);
163
171
  }
164
172
 
165
- forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void) {
173
+ forEach(callbackfn: (value: V, key: string, map: Map<string, V>) => void) {
166
174
  this.$items.forEach(callbackfn);
167
175
  }
168
176
 
@@ -182,7 +190,7 @@ export class MapSchema<V=any, K extends string = string> implements Map<K, V>, C
182
190
  return this.$items.size;
183
191
  }
184
192
 
185
- protected setIndex(index: number, key: K) {
193
+ protected setIndex(index: number, key: string) {
186
194
  this.$indexes.set(index, key);
187
195
  }
188
196
 
@@ -202,8 +210,13 @@ export class MapSchema<V=any, K extends string = string> implements Map<K, V>, C
202
210
 
203
211
  protected [$onEncodeEnd]() {
204
212
  const changeTree = this[$changes];
205
- const changes = changeTree.changes.entries();
206
- for (const [fieldIndex, operation] of changes) {
213
+ const keys = Object.keys(changeTree.indexedOperations);
214
+
215
+ for (let i = 0, len = keys.length; i < len; i++) {
216
+ const key = keys[i];
217
+ const fieldIndex = Number(key);
218
+ const operation = changeTree.indexedOperations[key];
219
+
207
220
  if (operation === OPERATION.DELETE) {
208
221
  const index = this[$getByIndex](fieldIndex) as string;
209
222
  delete changeTree.indexes[index];
@@ -40,6 +40,7 @@ export class SetSchema<V=any> implements Collection<number, V> {
40
40
 
41
41
  constructor (initialValues?: Array<V>) {
42
42
  this[$changes] = new ChangeTree(this);
43
+ this[$changes].indexes = {};
43
44
 
44
45
  if (initialValues) {
45
46
  initialValues.forEach((v) => this.add(v));
@@ -1,13 +1,24 @@
1
+ import { DefinitionType, type } from "../annotations";
2
+ import { BufferLike, encode } from "../encoding/encode";
3
+ import { decode, Iterator } from "../encoding/decode";
4
+
1
5
  export interface TypeDefinition {
2
- constructor: any,
6
+ constructor?: any,
7
+ encode?: (bytes: BufferLike, value: any, it: Iterator) => any;
8
+ decode?: (bytes: BufferLike, it: Iterator) => any;
3
9
  }
4
10
 
5
11
  const registeredTypes: {[identifier: string] : TypeDefinition} = {};
6
12
  const identifiers = new Map<any, string>();
7
13
 
8
14
  export function registerType(identifier: string, definition: TypeDefinition) {
9
- identifiers.set(definition.constructor, identifier);
10
- registeredTypes[identifier] = definition;
15
+ if (definition.constructor) {
16
+ identifiers.set(definition.constructor, identifier);
17
+ registeredTypes[identifier] = definition;
18
+ }
19
+
20
+ if (definition.encode) { encode[identifier] = definition.encode; }
21
+ if (definition.decode) { decode[identifier] = definition.decode; }
11
22
  }
12
23
 
13
24
  export function getIdentifier(klass: any): string {
@@ -17,3 +28,11 @@ export function getIdentifier(klass: any): string {
17
28
  export function getType(identifier: string): TypeDefinition {
18
29
  return registeredTypes[identifier];
19
30
  }
31
+
32
+ export function defineCustomTypes<T extends {[key: string]: TypeDefinition}>(types: T) {
33
+ for (const identifier in types) {
34
+ registerType(identifier, types[identifier]);
35
+ }
36
+
37
+ return (t: keyof T) => type(t as DefinitionType);
38
+ }
@@ -18,12 +18,6 @@ export const $changes = Symbol('$changes');
18
18
  */
19
19
  export const $childType = Symbol('$childType');
20
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
21
  /**
28
22
  * Optional "discard" method for custom types (ArraySchema)
29
23
  * (Discards changes for next serialization)
@@ -33,4 +27,13 @@ export const $onEncodeEnd = Symbol('$onEncodeEnd');
33
27
  /**
34
28
  * When decoding, this method is called after the instance is fully decoded
35
29
  */
36
- export const $onDecodeEnd = Symbol("$onDecodeEnd");
30
+ export const $onDecodeEnd = Symbol("$onDecodeEnd");
31
+
32
+ /**
33
+ * Metadata
34
+ */
35
+ export const $descriptors = Symbol("$descriptors");
36
+ export const $numFields = "$__numFields";
37
+ export const $refTypeFieldIndexes = "$__refTypeFieldIndexes";
38
+ export const $viewFieldIndexes = "$__viewFieldIndexes";
39
+ export const $fieldIndexesByViewTag = "$__fieldIndexesByViewTag";
package/src/utils.ts CHANGED
@@ -27,13 +27,17 @@ export function dumpChanges(schema: Schema) {
27
27
  refs: []
28
28
  };
29
29
 
30
- $root.changes.forEach((operations, changeTree) => {
30
+ // for (const refId in $root.changes) {
31
+ $root.changes.forEach(changeTree => {
32
+ const changes = changeTree.indexedOperations;
33
+
31
34
  dump.refs.push(`refId#${changeTree.refId}`);
32
- operations.forEach((op, index) => {
35
+ for (const index in changes) {
36
+ const op = changes[index];
33
37
  const opName = OPERATION[op];
34
38
  if (!dump.ops[opName]) { dump.ops[opName] = 0; }
35
39
  dump.ops[OPERATION[op]]++;
36
- });
40
+ }
37
41
  });
38
42
 
39
43
  return dump;
package/lib/Decoder.d.ts DELETED
@@ -1,16 +0,0 @@
1
- import { TypeContext } from "./annotations";
2
- import { DataChange, Schema } from "./Schema";
3
- import { Ref } from "./changes/ChangeTree";
4
- import { Iterator } from "./encoding/decode";
5
- import { ReferenceTracker } from "./changes/ReferenceTracker";
6
- export declare class Decoder<T extends Schema = any> {
7
- context: TypeContext;
8
- root: T;
9
- refs: ReferenceTracker;
10
- currentRefId: number;
11
- constructor(root: T, context?: TypeContext);
12
- protected setRoot(root: T): void;
13
- decode(bytes: number[], it?: Iterator, ref?: Ref): DataChange<any, string>[];
14
- getInstanceType(bytes: number[], it: Iterator, defaultType: typeof Schema): typeof Schema;
15
- createInstanceOfType(type: typeof Schema): Schema;
16
- }
package/lib/Decoder.js DELETED
@@ -1,182 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Decoder = void 0;
4
- const annotations_1 = require("./annotations");
5
- const consts_1 = require("./changes/consts");
6
- const decode = require("./encoding/decode");
7
- const spec_1 = require("./spec");
8
- const ReferenceTracker_1 = require("./changes/ReferenceTracker");
9
- const DecodeOperation_1 = require("./changes/DecodeOperation");
10
- class Decoder {
11
- constructor(root, context) {
12
- this.currentRefId = 0;
13
- this.setRoot(root);
14
- this.context = context || new annotations_1.TypeContext(root.constructor);
15
- // console.log(">>>>>>>>>>>>>>>> Decoder types");
16
- // this.context.schemas.forEach((id, schema) => {
17
- // console.log("type:", id, schema.name, Object.keys(schema[Symbol.metadata]));
18
- // });
19
- }
20
- setRoot(root) {
21
- this.root = root;
22
- this.refs = new ReferenceTracker_1.ReferenceTracker();
23
- this.refs.addRef(0, root);
24
- }
25
- decode(bytes, it = { offset: 0 }, ref = this.root) {
26
- // console.log("------------------- DECODE -------------------");
27
- const allChanges = [];
28
- const $root = this.refs;
29
- const totalBytes = bytes.length;
30
- this.currentRefId = 0;
31
- while (it.offset < totalBytes) {
32
- //
33
- // Peek ahead, check if it's a switch to a different structure
34
- //
35
- if (bytes[it.offset] == spec_1.SWITCH_TO_STRUCTURE) {
36
- it.offset++;
37
- this.currentRefId = decode.number(bytes, it);
38
- const nextRef = $root.refs.get(this.currentRefId);
39
- //
40
- // Trying to access a reference that haven't been decoded yet.
41
- //
42
- if (!nextRef) {
43
- throw new Error(`"refId" not found: ${this.currentRefId}`);
44
- }
45
- ref = nextRef;
46
- continue;
47
- }
48
- const decoder = ref['constructor'][consts_1.$decoder];
49
- const result = decoder(this, bytes, it, ref, allChanges);
50
- if (result === DecodeOperation_1.DecodeState.DEFINITION_MISMATCH) {
51
- console.warn("@colyseus/schema: definition mismatch");
52
- //
53
- // keep skipping next bytes until reaches a known structure
54
- // by local decoder.
55
- //
56
- const nextIterator = { offset: it.offset };
57
- while (it.offset < totalBytes) {
58
- if (decode.switchStructureCheck(bytes, it)) {
59
- nextIterator.offset = it.offset + 1;
60
- if ($root.refs.has(decode.number(bytes, nextIterator))) {
61
- break;
62
- }
63
- }
64
- it.offset++;
65
- }
66
- continue;
67
- }
68
- }
69
- // FIXME: trigger callbacks
70
- // this._triggerChanges(allChanges);
71
- // drop references of unused schemas
72
- $root.garbageCollectDeletedRefs();
73
- return allChanges;
74
- }
75
- /*
76
- private _triggerChanges(changes: DataChange[]) {
77
- const uniqueRefIds = new Set<number>();
78
- const $refs = this.refs.refs;
79
-
80
- for (let i = 0; i < changes.length; i++) {
81
- const change = changes[i];
82
- const refId = change.refId;
83
- const ref = $refs.get(refId);
84
- const $callbacks: Schema['$callbacks'] | SchemaDecoderCallbacks['$callbacks'] = ref['$callbacks'];
85
-
86
- //
87
- // trigger onRemove on child structure.
88
- //
89
- if (
90
- (change.op & OPERATION.DELETE) === OPERATION.DELETE &&
91
- change.previousValue instanceof Schema
92
- ) {
93
- change.previousValue['$callbacks']?.[OPERATION.DELETE]?.forEach(callback => callback());
94
- }
95
-
96
- // no callbacks defined, skip this structure!
97
- if (!$callbacks) { continue; }
98
-
99
- if (ref instanceof Schema) {
100
- if (!uniqueRefIds.has(refId)) {
101
- try {
102
- // trigger onChange
103
- ($callbacks as Schema['$callbacks'])?.[OPERATION.REPLACE]?.forEach(callback =>
104
- callback());
105
-
106
- } catch (e) {
107
- Schema.onError(e);
108
- }
109
- }
110
-
111
- try {
112
- if ($callbacks.hasOwnProperty(change.field)) {
113
- $callbacks[change.field]?.forEach((callback) =>
114
- callback(change.value, change.previousValue));
115
- }
116
-
117
- } catch (e) {
118
- Schema.onError(e);
119
- }
120
-
121
- } else {
122
- // is a collection of items
123
-
124
- if (change.op === OPERATION.ADD && change.previousValue === undefined) {
125
- // triger onAdd
126
- $callbacks[OPERATION.ADD]?.forEach(callback =>
127
- callback(change.value, change.dynamicIndex ?? change.field));
128
-
129
- } else if (change.op === OPERATION.DELETE) {
130
- //
131
- // FIXME: `previousValue` should always be available.
132
- // ADD + DELETE operations are still encoding DELETE operation.
133
- //
134
- if (change.previousValue !== undefined) {
135
- // triger onRemove
136
- $callbacks[OPERATION.DELETE]?.forEach(callback =>
137
- callback(change.previousValue, change.dynamicIndex ?? change.field));
138
- }
139
-
140
- } else if (change.op === OPERATION.DELETE_AND_ADD) {
141
- // triger onRemove
142
- if (change.previousValue !== undefined) {
143
- $callbacks[OPERATION.DELETE]?.forEach(callback =>
144
- callback(change.previousValue, change.dynamicIndex ?? change.field));
145
- }
146
-
147
- // triger onAdd
148
- $callbacks[OPERATION.ADD]?.forEach(callback =>
149
- callback(change.value, change.dynamicIndex ?? change.field));
150
- }
151
-
152
- // trigger onChange
153
- if (change.value !== change.previousValue) {
154
- $callbacks[OPERATION.REPLACE]?.forEach(callback =>
155
- callback(change.value, change.dynamicIndex ?? change.field));
156
- }
157
- }
158
-
159
- uniqueRefIds.add(refId);
160
- }
161
-
162
- }
163
- */
164
- getInstanceType(bytes, it, defaultType) {
165
- let type;
166
- if (bytes[it.offset] === spec_1.TYPE_ID) {
167
- it.offset++;
168
- const type_id = decode.number(bytes, it);
169
- type = this.context.get(type_id);
170
- }
171
- return type || defaultType;
172
- }
173
- createInstanceOfType(type) {
174
- // let instance: Schema = new (type as any)();
175
- // // assign root on $changes
176
- // instance[$changes].root = this.root[$changes].root;
177
- // return instance;
178
- return new type();
179
- }
180
- }
181
- exports.Decoder = Decoder;
182
- //# sourceMappingURL=Decoder.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Decoder.js","sourceRoot":"","sources":["../src/Decoder.ts"],"names":[],"mappings":"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","sourcesContent":["import { Metadata } from \"./Metadata\";\nimport { TypeContext } from \"./annotations\";\nimport { $childType, $decoder } from \"./changes/consts\";\nimport { DataChange, Schema, SchemaDecoderCallbacks } from \"./Schema\";\nimport { CollectionSchema } from \"./types/CollectionSchema\";\nimport { MapSchema } from \"./types/MapSchema\";\nimport { SetSchema } from \"./types/SetSchema\";\nimport { ArraySchema } from \"./types/ArraySchema\";\n\nimport * as decode from \"./encoding/decode\";\nimport { getType } from './types/typeRegistry';\nimport { SWITCH_TO_STRUCTURE, TYPE_ID, OPERATION } from './spec';\nimport { Ref } from \"./changes/ChangeTree\";\nimport { Iterator } from \"./encoding/decode\";\nimport { ReferenceTracker } from \"./changes/ReferenceTracker\";\nimport { DecodeState } from \"./changes/DecodeOperation\";\n\nexport class Decoder<T extends Schema = any> {\n context: TypeContext;\n\n root: T;\n refs: ReferenceTracker;\n\n currentRefId: number = 0;\n\n constructor(root: T, context?: TypeContext) {\n this.setRoot(root);\n this.context = context || new TypeContext(root.constructor as typeof Schema);\n\n // console.log(\">>>>>>>>>>>>>>>> Decoder types\");\n // this.context.schemas.forEach((id, schema) => {\n // console.log(\"type:\", id, schema.name, Object.keys(schema[Symbol.metadata]));\n // });\n }\n\n protected setRoot(root: T) {\n this.root = root;\n this.refs = new ReferenceTracker();\n this.refs.addRef(0, root);\n }\n\n decode(\n bytes: number[],\n it: Iterator = { offset: 0 },\n ref: Ref = this.root,\n ) {\n // console.log(\"------------------- DECODE -------------------\");\n const allChanges: DataChange[] = [];\n\n const $root = this.refs;\n const totalBytes = bytes.length;\n\n this.currentRefId = 0;\n\n while (it.offset < totalBytes) {\n //\n // Peek ahead, check if it's a switch to a different structure\n //\n if (bytes[it.offset] == SWITCH_TO_STRUCTURE) {\n it.offset++;\n\n this.currentRefId = decode.number(bytes, it);\n const nextRef = $root.refs.get(this.currentRefId) as Schema;\n\n //\n // Trying to access a reference that haven't been decoded yet.\n //\n if (!nextRef) { throw new Error(`\"refId\" not found: ${this.currentRefId}`); }\n ref = nextRef;\n\n continue;\n }\n\n const decoder = ref['constructor'][$decoder];\n const result = decoder(this, bytes, it, ref, allChanges);\n\n if (result === DecodeState.DEFINITION_MISMATCH) {\n console.warn(\"@colyseus/schema: definition mismatch\");\n\n //\n // keep skipping next bytes until reaches a known structure\n // by local decoder.\n //\n const nextIterator: decode.Iterator = { offset: it.offset };\n while (it.offset < totalBytes) {\n if (decode.switchStructureCheck(bytes, it)) {\n nextIterator.offset = it.offset + 1;\n if ($root.refs.has(decode.number(bytes, nextIterator))) {\n break;\n }\n }\n\n it.offset++;\n }\n continue;\n }\n }\n\n // FIXME: trigger callbacks\n // this._triggerChanges(allChanges);\n\n // drop references of unused schemas\n $root.garbageCollectDeletedRefs();\n\n return allChanges;\n }\n\n /*\n private _triggerChanges(changes: DataChange[]) {\n const uniqueRefIds = new Set<number>();\n const $refs = this.refs.refs;\n\n for (let i = 0; i < changes.length; i++) {\n const change = changes[i];\n const refId = change.refId;\n const ref = $refs.get(refId);\n const $callbacks: Schema['$callbacks'] | SchemaDecoderCallbacks['$callbacks'] = ref['$callbacks'];\n\n //\n // trigger onRemove on child structure.\n //\n if (\n (change.op & OPERATION.DELETE) === OPERATION.DELETE &&\n change.previousValue instanceof Schema\n ) {\n change.previousValue['$callbacks']?.[OPERATION.DELETE]?.forEach(callback => callback());\n }\n\n // no callbacks defined, skip this structure!\n if (!$callbacks) { continue; }\n\n if (ref instanceof Schema) {\n if (!uniqueRefIds.has(refId)) {\n try {\n // trigger onChange\n ($callbacks as Schema['$callbacks'])?.[OPERATION.REPLACE]?.forEach(callback =>\n callback());\n\n } catch (e) {\n Schema.onError(e);\n }\n }\n\n try {\n if ($callbacks.hasOwnProperty(change.field)) {\n $callbacks[change.field]?.forEach((callback) =>\n callback(change.value, change.previousValue));\n }\n\n } catch (e) {\n Schema.onError(e);\n }\n\n } else {\n // is a collection of items\n\n if (change.op === OPERATION.ADD && change.previousValue === undefined) {\n // triger onAdd\n $callbacks[OPERATION.ADD]?.forEach(callback =>\n callback(change.value, change.dynamicIndex ?? change.field));\n\n } else if (change.op === OPERATION.DELETE) {\n //\n // FIXME: `previousValue` should always be available.\n // ADD + DELETE operations are still encoding DELETE operation.\n //\n if (change.previousValue !== undefined) {\n // triger onRemove\n $callbacks[OPERATION.DELETE]?.forEach(callback =>\n callback(change.previousValue, change.dynamicIndex ?? change.field));\n }\n\n } else if (change.op === OPERATION.DELETE_AND_ADD) {\n // triger onRemove\n if (change.previousValue !== undefined) {\n $callbacks[OPERATION.DELETE]?.forEach(callback =>\n callback(change.previousValue, change.dynamicIndex ?? change.field));\n }\n\n // triger onAdd\n $callbacks[OPERATION.ADD]?.forEach(callback =>\n callback(change.value, change.dynamicIndex ?? change.field));\n }\n\n // trigger onChange\n if (change.value !== change.previousValue) {\n $callbacks[OPERATION.REPLACE]?.forEach(callback =>\n callback(change.value, change.dynamicIndex ?? change.field));\n }\n }\n\n uniqueRefIds.add(refId);\n }\n\n }\n */\n\n getInstanceType(bytes: number[], it: Iterator, defaultType: typeof Schema): typeof Schema {\n let type: typeof Schema;\n\n if (bytes[it.offset] === TYPE_ID) {\n it.offset++;\n const type_id = decode.number(bytes, it);\n type = this.context.get(type_id);\n }\n\n return type || defaultType;\n }\n\n createInstanceOfType (type: typeof Schema): Schema {\n // let instance: Schema = new (type as any)();\n\n // // assign root on $changes\n // instance[$changes].root = this.root[$changes].root;\n\n // return instance;\n return new (type as any)();\n }\n\n}\n\n"]}
package/lib/Encoder.d.ts DELETED
@@ -1,13 +0,0 @@
1
- import type { Schema } from "./Schema";
2
- import { TypeContext } from "./annotations";
3
- import { Root } from "./changes/ChangeTree";
4
- export declare class Encoder<T extends Schema = any> {
5
- context: TypeContext;
6
- root: T;
7
- $root: Root;
8
- constructor(root: T);
9
- protected setRoot(root: T): void;
10
- encode(encodeAll?: boolean, bytes?: number[], useFilters?: boolean): number[];
11
- encodeAll(useFilters?: boolean): number[];
12
- tryEncodeTypeId(bytes: number[], baseType: typeof Schema, targetType: typeof Schema): void;
13
- }