@colyseus/schema 3.0.0-alpha.4 → 3.0.0-alpha.41

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 (146) hide show
  1. package/README.md +148 -62
  2. package/bin/schema-debug +94 -0
  3. package/build/cjs/index.js +2201 -1507
  4. package/build/cjs/index.js.map +1 -1
  5. package/build/esm/index.mjs +2198 -1506
  6. package/build/esm/index.mjs.map +1 -1
  7. package/build/umd/index.js +2208 -1514
  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 -32
  13. package/lib/Reflection.js.map +1 -1
  14. package/lib/Schema.d.ts +4 -4
  15. package/lib/Schema.js +44 -50
  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/bench_encode.d.ts +1 -0
  21. package/lib/bench_encode.js +130 -0
  22. package/lib/bench_encode.js.map +1 -0
  23. package/lib/codegen/api.js +1 -2
  24. package/lib/codegen/api.js.map +1 -1
  25. package/lib/codegen/languages/cpp.js +1 -2
  26. package/lib/codegen/languages/cpp.js.map +1 -1
  27. package/lib/codegen/languages/csharp.js +2 -46
  28. package/lib/codegen/languages/csharp.js.map +1 -1
  29. package/lib/codegen/languages/haxe.js +1 -2
  30. package/lib/codegen/languages/haxe.js.map +1 -1
  31. package/lib/codegen/languages/java.js +1 -2
  32. package/lib/codegen/languages/java.js.map +1 -1
  33. package/lib/codegen/languages/js.js +1 -2
  34. package/lib/codegen/languages/js.js.map +1 -1
  35. package/lib/codegen/languages/lua.js +1 -2
  36. package/lib/codegen/languages/lua.js.map +1 -1
  37. package/lib/codegen/languages/ts.js +1 -2
  38. package/lib/codegen/languages/ts.js.map +1 -1
  39. package/lib/codegen/parser.js +85 -3
  40. package/lib/codegen/parser.js.map +1 -1
  41. package/lib/codegen/types.js +6 -3
  42. package/lib/codegen/types.js.map +1 -1
  43. package/lib/debug.d.ts +1 -0
  44. package/lib/debug.js +51 -0
  45. package/lib/debug.js.map +1 -0
  46. package/lib/decoder/DecodeOperation.d.ts +3 -4
  47. package/lib/decoder/DecodeOperation.js +37 -19
  48. package/lib/decoder/DecodeOperation.js.map +1 -1
  49. package/lib/decoder/Decoder.d.ts +6 -7
  50. package/lib/decoder/Decoder.js +14 -14
  51. package/lib/decoder/Decoder.js.map +1 -1
  52. package/lib/decoder/ReferenceTracker.js +3 -2
  53. package/lib/decoder/ReferenceTracker.js.map +1 -1
  54. package/lib/decoder/strategy/RawChanges.js +1 -2
  55. package/lib/decoder/strategy/RawChanges.js.map +1 -1
  56. package/lib/decoder/strategy/StateCallbacks.d.ts +44 -11
  57. package/lib/decoder/strategy/StateCallbacks.js +75 -65
  58. package/lib/decoder/strategy/StateCallbacks.js.map +1 -1
  59. package/lib/encoder/ChangeTree.d.ts +27 -21
  60. package/lib/encoder/ChangeTree.js +246 -186
  61. package/lib/encoder/ChangeTree.js.map +1 -1
  62. package/lib/encoder/EncodeOperation.d.ts +3 -6
  63. package/lib/encoder/EncodeOperation.js +51 -65
  64. package/lib/encoder/EncodeOperation.js.map +1 -1
  65. package/lib/encoder/Encoder.d.ts +9 -8
  66. package/lib/encoder/Encoder.js +168 -91
  67. package/lib/encoder/Encoder.js.map +1 -1
  68. package/lib/encoder/Root.d.ts +22 -0
  69. package/lib/encoder/Root.js +81 -0
  70. package/lib/encoder/Root.js.map +1 -0
  71. package/lib/encoder/StateView.d.ts +7 -7
  72. package/lib/encoder/StateView.js +70 -74
  73. package/lib/encoder/StateView.js.map +1 -1
  74. package/lib/encoding/assert.d.ts +7 -6
  75. package/lib/encoding/assert.js +13 -5
  76. package/lib/encoding/assert.js.map +1 -1
  77. package/lib/encoding/decode.d.ts +35 -20
  78. package/lib/encoding/decode.js +43 -87
  79. package/lib/encoding/decode.js.map +1 -1
  80. package/lib/encoding/encode.d.ts +36 -17
  81. package/lib/encoding/encode.js +82 -68
  82. package/lib/encoding/encode.js.map +1 -1
  83. package/lib/encoding/spec.d.ts +4 -5
  84. package/lib/encoding/spec.js +1 -2
  85. package/lib/encoding/spec.js.map +1 -1
  86. package/lib/index.d.ts +10 -9
  87. package/lib/index.js +24 -17
  88. package/lib/index.js.map +1 -1
  89. package/lib/types/HelperTypes.d.ts +34 -2
  90. package/lib/types/HelperTypes.js.map +1 -1
  91. package/lib/types/TypeContext.d.ts +23 -0
  92. package/lib/types/TypeContext.js +111 -0
  93. package/lib/types/TypeContext.js.map +1 -0
  94. package/lib/types/custom/ArraySchema.d.ts +2 -2
  95. package/lib/types/custom/ArraySchema.js +33 -22
  96. package/lib/types/custom/ArraySchema.js.map +1 -1
  97. package/lib/types/custom/CollectionSchema.js +1 -0
  98. package/lib/types/custom/CollectionSchema.js.map +1 -1
  99. package/lib/types/custom/MapSchema.d.ts +3 -1
  100. package/lib/types/custom/MapSchema.js +12 -4
  101. package/lib/types/custom/MapSchema.js.map +1 -1
  102. package/lib/types/custom/SetSchema.js +1 -0
  103. package/lib/types/custom/SetSchema.js.map +1 -1
  104. package/lib/types/registry.d.ts +8 -1
  105. package/lib/types/registry.js +23 -6
  106. package/lib/types/registry.js.map +1 -1
  107. package/lib/types/symbols.d.ts +8 -5
  108. package/lib/types/symbols.js +9 -6
  109. package/lib/types/symbols.js.map +1 -1
  110. package/lib/types/utils.js +1 -2
  111. package/lib/types/utils.js.map +1 -1
  112. package/lib/utils.js +9 -7
  113. package/lib/utils.js.map +1 -1
  114. package/package.json +7 -6
  115. package/src/Metadata.ts +190 -42
  116. package/src/Reflection.ts +77 -39
  117. package/src/Schema.ts +59 -64
  118. package/src/annotations.ts +156 -202
  119. package/src/bench_encode.ts +108 -0
  120. package/src/codegen/languages/csharp.ts +1 -47
  121. package/src/codegen/parser.ts +107 -0
  122. package/src/codegen/types.ts +1 -0
  123. package/src/debug.ts +55 -0
  124. package/src/decoder/DecodeOperation.ts +46 -18
  125. package/src/decoder/Decoder.ts +17 -15
  126. package/src/decoder/ReferenceTracker.ts +3 -2
  127. package/src/decoder/strategy/StateCallbacks.ts +153 -82
  128. package/src/encoder/ChangeTree.ts +286 -202
  129. package/src/encoder/EncodeOperation.ts +78 -78
  130. package/src/encoder/Encoder.ts +202 -97
  131. package/src/encoder/Root.ts +93 -0
  132. package/src/encoder/StateView.ts +76 -88
  133. package/src/encoding/assert.ts +17 -8
  134. package/src/encoding/decode.ts +62 -97
  135. package/src/encoding/encode.ts +99 -65
  136. package/src/encoding/spec.ts +3 -5
  137. package/src/index.ts +12 -20
  138. package/src/types/HelperTypes.ts +54 -2
  139. package/src/types/TypeContext.ts +133 -0
  140. package/src/types/custom/ArraySchema.ts +49 -19
  141. package/src/types/custom/CollectionSchema.ts +1 -0
  142. package/src/types/custom/MapSchema.ts +18 -5
  143. package/src/types/custom/SetSchema.ts +1 -0
  144. package/src/types/registry.ts +22 -3
  145. package/src/types/symbols.ts +10 -7
  146. package/src/utils.ts +7 -3
@@ -1,17 +1,15 @@
1
1
  import { OPERATION } from "../encoding/spec";
2
- import { $changes } from "../types/symbols";
3
- import { getType } from "../types/registry";
2
+ import { $changes, $childType, $getByIndex } from "../types/symbols";
4
3
 
5
- import * as encode from "../encoding/encode";
6
- import { EncodeSchemaError, assertInstanceType, assertType } from "../encoding/assert";
4
+ import { encode } from "../encoding/encode";
7
5
 
8
6
  import type { ChangeTree, Ref } from "./ChangeTree";
9
7
  import type { Encoder } from "./Encoder";
10
8
  import type { Schema } from "../Schema";
11
- import type { PrimitiveType } from "../annotations";
12
9
 
13
10
  import type { Iterator } from "../encoding/decode";
14
11
  import type { ArraySchema } from "../types/custom/ArraySchema";
12
+ import type { Metadata } from "../Metadata";
15
13
 
16
14
  export type EncodeOperation<T extends Ref = any> = (
17
15
  encoder: Encoder,
@@ -22,43 +20,21 @@ export type EncodeOperation<T extends Ref = any> = (
22
20
  it: Iterator,
23
21
  isEncodeAll: boolean,
24
22
  hasView: boolean,
23
+ metadata?: Metadata,
25
24
  ) => void;
26
25
 
27
- export function encodePrimitiveType(
28
- type: PrimitiveType,
29
- bytes: Buffer,
30
- value: any,
31
- klass: Schema,
32
- field: string | number,
33
- it: Iterator,
34
- ) {
35
- assertType(value, type as string, klass, field);
36
-
37
- const encodeFunc = encode[type as string];
38
-
39
- if (encodeFunc) {
40
- encodeFunc(bytes, value, it);
41
- // encodeFunc(bytes, value);
42
-
43
- } else {
44
- throw new EncodeSchemaError(`a '${type}' was expected, but ${value} was provided in ${klass.constructor.name}#${field}`);
45
- }
46
- };
47
-
48
26
  export function encodeValue(
49
27
  encoder: Encoder,
50
28
  bytes: Buffer,
51
- ref: Ref,
52
29
  type: any,
53
30
  value: any,
54
- field: string | number,
55
31
  operation: OPERATION,
56
32
  it: Iterator,
57
33
  ) {
58
- if (type[Symbol.metadata] !== undefined) {
59
- // TODO: move this to the `@type()` annotation
60
- assertInstanceType(value, type as typeof Schema, ref as Schema, field);
34
+ if (typeof (type) === "string") {
35
+ encode[type]?.(bytes, value, it);
61
36
 
37
+ } else if (type[Symbol.metadata] !== undefined) {
62
38
  //
63
39
  // Encode refId for this instance.
64
40
  // The actual instance is going to be encoded on next `changeTree` iteration.
@@ -70,23 +46,7 @@ export function encodeValue(
70
46
  encoder.tryEncodeTypeId(bytes, type as typeof Schema, value.constructor as typeof Schema, it);
71
47
  }
72
48
 
73
- } else if (typeof (type) === "string") {
74
- //
75
- // Primitive values
76
- //
77
- encodePrimitiveType(type as PrimitiveType, bytes, value, ref as Schema, field, it);
78
-
79
49
  } else {
80
- //
81
- // Custom type (MapSchema, ArraySchema, etc)
82
- //
83
- const definition = getType(Object.keys(type)[0]);
84
-
85
- //
86
- // ensure a ArraySchema has been provided
87
- //
88
- assertInstanceType(ref[field], definition.constructor, ref as Schema, field);
89
-
90
50
  //
91
51
  // Encode refId for this instance.
92
52
  // The actual instance is going to be encoded on next `changeTree` iteration.
@@ -106,14 +66,10 @@ export const encodeSchemaOperation: EncodeOperation = function (
106
66
  index: number,
107
67
  operation: OPERATION,
108
68
  it: Iterator,
69
+ _: any,
70
+ __: any,
71
+ metadata: Metadata,
109
72
  ) {
110
- const ref = changeTree.ref;
111
- const metadata = ref['constructor'][Symbol.metadata];
112
-
113
- const field = metadata[index];
114
- const type = metadata[field].type;
115
- const value = ref[field];
116
-
117
73
  // "compress" field index + operation
118
74
  bytes[it.offset++] = (index | operation) & 255;
119
75
 
@@ -122,8 +78,18 @@ export const encodeSchemaOperation: EncodeOperation = function (
122
78
  return;
123
79
  }
124
80
 
81
+ const ref = changeTree.ref;
82
+ const field = metadata[index];
83
+
125
84
  // TODO: inline this function call small performance gain
126
- encodeValue(encoder, bytes, ref, type, value, field, operation, it);
85
+ encodeValue(
86
+ encoder,
87
+ bytes,
88
+ metadata[index].type,
89
+ ref[field.name],
90
+ operation,
91
+ it
92
+ );
127
93
  }
128
94
 
129
95
  /**
@@ -134,12 +100,10 @@ export const encodeKeyValueOperation: EncodeOperation = function (
134
100
  encoder: Encoder,
135
101
  bytes: Buffer,
136
102
  changeTree: ChangeTree,
137
- field: number,
103
+ index: number,
138
104
  operation: OPERATION,
139
105
  it: Iterator,
140
106
  ) {
141
- const ref = changeTree.ref;
142
-
143
107
  // encode operation
144
108
  bytes[it.offset++] = operation & 255;
145
109
 
@@ -149,31 +113,53 @@ export const encodeKeyValueOperation: EncodeOperation = function (
149
113
  }
150
114
 
151
115
  // encode index
152
- encode.number(bytes, field, it);
116
+ encode.number(bytes, index, it);
153
117
 
154
118
  // Do not encode value for DELETE operations
155
119
  if (operation === OPERATION.DELETE) {
156
120
  return;
157
121
  }
158
122
 
123
+ const ref = changeTree.ref;
124
+
159
125
  //
160
126
  // encode "alias" for dynamic fields (maps)
161
127
  //
162
- if ((operation & OPERATION.ADD) == OPERATION.ADD) { // ADD or DELETE_AND_ADD
128
+ if ((operation & OPERATION.ADD) === OPERATION.ADD) { // ADD or DELETE_AND_ADD
163
129
  if (typeof(ref['set']) === "function") {
164
130
  //
165
131
  // MapSchema dynamic key
166
132
  //
167
- const dynamicIndex = changeTree.ref['$indexes'].get(field);
133
+ const dynamicIndex = changeTree.ref['$indexes'].get(index);
168
134
  encode.string(bytes, dynamicIndex, it);
169
135
  }
170
136
  }
171
137
 
172
- const type = changeTree.getType(field);
173
- const value = changeTree.getValue(field);
138
+ const type = ref[$childType];
139
+ const value = ref[$getByIndex](index);
140
+
141
+ // try { throw new Error(); } catch (e) {
142
+ // // only print if not coming from Reflection.ts
143
+ // if (!e.stack.includes("src/Reflection.ts")) {
144
+ // console.log("encodeKeyValueOperation -> ", {
145
+ // ref: changeTree.ref.constructor.name,
146
+ // field,
147
+ // operation: OPERATION[operation],
148
+ // value: value?.toJSON(),
149
+ // items: ref.toJSON(),
150
+ // });
151
+ // }
152
+ // }
174
153
 
175
154
  // TODO: inline this function call small performance gain
176
- encodeValue(encoder, bytes, ref, type, value, field, operation, it);
155
+ encodeValue(
156
+ encoder,
157
+ bytes,
158
+ type,
159
+ value,
160
+ operation,
161
+ it
162
+ );
177
163
  }
178
164
 
179
165
  /**
@@ -191,30 +177,37 @@ export const encodeArray: EncodeOperation = function (
191
177
  hasView: boolean,
192
178
  ) {
193
179
  const ref = changeTree.ref;
180
+ const useOperationByRefId = hasView && changeTree.isFiltered && (typeof (changeTree.getType(field)) !== "string");
194
181
 
195
- if (
196
- hasView &&
197
- operation === OPERATION.DELETE &&
198
- typeof (changeTree.getType(field)) !== "string"
199
- ) {
200
- // encode delete by refId (array of schemas)
201
- bytes[it.offset++] = OPERATION.DELETE_BY_REFID;
202
- const value = ref['tmpItems'][field];
203
- const refId = value[$changes].refId;
204
- encode.number(bytes, refId, it);
205
- return;
182
+ let refOrIndex: number;
183
+
184
+ if (useOperationByRefId) {
185
+ refOrIndex = ref['tmpItems'][field][$changes].refId;
186
+
187
+ if (operation === OPERATION.DELETE) {
188
+ operation = OPERATION.DELETE_BY_REFID;
189
+
190
+ } else if (operation === OPERATION.ADD) {
191
+ operation = OPERATION.ADD_BY_REFID;
192
+ }
193
+
194
+ } else {
195
+ refOrIndex = field;
206
196
  }
207
197
 
208
198
  // encode operation
209
199
  bytes[it.offset++] = operation & 255;
210
200
 
211
201
  // custom operations
212
- if (operation === OPERATION.CLEAR) {
202
+ if (
203
+ operation === OPERATION.CLEAR ||
204
+ operation === OPERATION.REVERSE
205
+ ) {
213
206
  return;
214
207
  }
215
208
 
216
209
  // encode index
217
- encode.number(bytes, field, it);
210
+ encode.number(bytes, refOrIndex, it);
218
211
 
219
212
  // Do not encode value for DELETE operations
220
213
  if (operation === OPERATION.DELETE) {
@@ -233,5 +226,12 @@ export const encodeArray: EncodeOperation = function (
233
226
  // });
234
227
 
235
228
  // TODO: inline this function call small performance gain
236
- encodeValue(encoder, bytes, ref, type, value, field, operation, it);
229
+ encodeValue(
230
+ encoder,
231
+ bytes,
232
+ type,
233
+ value,
234
+ operation,
235
+ it
236
+ );
237
237
  }