@colyseus/schema 3.0.61 → 3.0.63

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 (101) hide show
  1. package/build/cjs/index.js +27 -79
  2. package/build/cjs/index.js.map +1 -1
  3. package/build/esm/index.mjs +27 -79
  4. package/build/esm/index.mjs.map +1 -1
  5. package/build/umd/index.js +27 -79
  6. package/lib/Metadata.d.ts +2 -2
  7. package/lib/Metadata.js.map +1 -1
  8. package/lib/Reflection.js +2 -1
  9. package/lib/Reflection.js.map +1 -1
  10. package/lib/Schema.d.ts +14 -14
  11. package/lib/Schema.js +4 -7
  12. package/lib/Schema.js.map +1 -1
  13. package/lib/annotations.d.ts +37 -5
  14. package/lib/annotations.js +17 -7
  15. package/lib/annotations.js.map +1 -1
  16. package/lib/codegen/api.js.map +1 -1
  17. package/lib/codegen/argv.d.ts +1 -1
  18. package/lib/codegen/argv.js.map +1 -1
  19. package/lib/codegen/cli.js.map +1 -1
  20. package/lib/codegen/languages/cpp.js.map +1 -1
  21. package/lib/codegen/languages/csharp.js.map +1 -1
  22. package/lib/codegen/languages/haxe.js.map +1 -1
  23. package/lib/codegen/languages/java.js.map +1 -1
  24. package/lib/codegen/languages/js.js.map +1 -1
  25. package/lib/codegen/languages/lua.js.map +1 -1
  26. package/lib/codegen/languages/ts.js.map +1 -1
  27. package/lib/codegen/parser.js +11 -0
  28. package/lib/codegen/parser.js.map +1 -1
  29. package/lib/codegen/types.d.ts +1 -1
  30. package/lib/codegen/types.js.map +1 -1
  31. package/lib/decoder/DecodeOperation.d.ts +2 -2
  32. package/lib/decoder/DecodeOperation.js.map +1 -1
  33. package/lib/decoder/Decoder.js.map +1 -1
  34. package/lib/decoder/ReferenceTracker.js.map +1 -1
  35. package/lib/decoder/strategy/StateCallbacks.js.map +1 -1
  36. package/lib/encoder/ChangeTree.d.ts +6 -1
  37. package/lib/encoder/ChangeTree.js.map +1 -1
  38. package/lib/encoder/EncodeOperation.js.map +1 -1
  39. package/lib/encoder/Encoder.d.ts +0 -1
  40. package/lib/encoder/Encoder.js +0 -21
  41. package/lib/encoder/Encoder.js.map +1 -1
  42. package/lib/encoder/StateView.js.map +1 -1
  43. package/lib/encoding/decode.js +1 -22
  44. package/lib/encoding/decode.js.map +1 -1
  45. package/lib/encoding/encode.d.ts +1 -23
  46. package/lib/encoding/encode.js +1 -22
  47. package/lib/encoding/encode.js.map +1 -1
  48. package/lib/index.d.ts +3 -2
  49. package/lib/index.js.map +1 -1
  50. package/lib/types/HelperTypes.d.ts +14 -5
  51. package/lib/types/HelperTypes.js.map +1 -1
  52. package/lib/types/TypeContext.js.map +1 -1
  53. package/lib/types/custom/ArraySchema.d.ts +9 -5
  54. package/lib/types/custom/ArraySchema.js.map +1 -1
  55. package/lib/types/custom/CollectionSchema.d.ts +8 -4
  56. package/lib/types/custom/CollectionSchema.js.map +1 -1
  57. package/lib/types/custom/MapSchema.d.ts +8 -6
  58. package/lib/types/custom/MapSchema.js +3 -0
  59. package/lib/types/custom/MapSchema.js.map +1 -1
  60. package/lib/types/custom/SetSchema.d.ts +8 -4
  61. package/lib/types/custom/SetSchema.js.map +1 -1
  62. package/lib/types/registry.js.map +1 -1
  63. package/lib/utils.js.map +1 -1
  64. package/lib/v3_bench.js.map +1 -1
  65. package/package.json +2 -2
  66. package/src/Metadata.ts +2 -2
  67. package/src/Reflection.ts +5 -4
  68. package/src/Schema.ts +35 -37
  69. package/src/annotations.ts +93 -30
  70. package/src/codegen/api.ts +1 -1
  71. package/src/codegen/argv.ts +5 -5
  72. package/src/codegen/cli.ts +1 -1
  73. package/src/codegen/languages/cpp.ts +5 -4
  74. package/src/codegen/languages/csharp.ts +2 -2
  75. package/src/codegen/languages/haxe.ts +2 -2
  76. package/src/codegen/languages/java.ts +2 -2
  77. package/src/codegen/languages/js.ts +3 -2
  78. package/src/codegen/languages/lua.ts +3 -2
  79. package/src/codegen/languages/ts.ts +3 -2
  80. package/src/codegen/parser.ts +12 -0
  81. package/src/codegen/types.ts +2 -2
  82. package/src/decoder/DecodeOperation.ts +21 -21
  83. package/src/decoder/Decoder.ts +3 -3
  84. package/src/decoder/ReferenceTracker.ts +7 -5
  85. package/src/decoder/strategy/StateCallbacks.ts +10 -10
  86. package/src/encoder/ChangeTree.ts +21 -15
  87. package/src/encoder/EncodeOperation.ts +4 -4
  88. package/src/encoder/Encoder.ts +0 -24
  89. package/src/encoder/StateView.ts +3 -2
  90. package/src/encoding/decode.ts +2 -0
  91. package/src/encoding/encode.ts +3 -1
  92. package/src/index.ts +5 -2
  93. package/src/types/HelperTypes.ts +29 -7
  94. package/src/types/TypeContext.ts +1 -1
  95. package/src/types/custom/ArraySchema.ts +12 -10
  96. package/src/types/custom/CollectionSchema.ts +9 -6
  97. package/src/types/custom/MapSchema.ts +12 -8
  98. package/src/types/custom/SetSchema.ts +9 -6
  99. package/src/types/registry.ts +2 -2
  100. package/src/utils.ts +2 -4
  101. package/src/v3_bench.ts +1 -1
@@ -1,7 +1,7 @@
1
1
  import argv from "./argv";
2
2
  import { generate } from "./api";
3
3
 
4
- const supportedTargets = {
4
+ const supportedTargets: Record<string, string> = {
5
5
  csharp: 'generate for C#/Unity',
6
6
  cpp: 'generate for C++',
7
7
  haxe: 'generate for Haxe',
@@ -1,7 +1,7 @@
1
1
  import { Class, Property, File, getCommentHeader, getInheritanceTree, Context } from "../types";
2
2
  import { GenerateOptions } from "../api";
3
3
 
4
- const typeMaps = {
4
+ const typeMaps: { [key: string]: string } = {
5
5
  "string": "string",
6
6
  "number": "varint_t",
7
7
  "boolean": "bool",
@@ -17,7 +17,7 @@ const typeMaps = {
17
17
  "float64": "float64_t",
18
18
  }
19
19
 
20
- const typeInitializer = {
20
+ const typeInitializer: { [key: string]: string } = {
21
21
  "string": '""',
22
22
  "number": "0",
23
23
  "boolean": "false",
@@ -37,11 +37,12 @@ const typeInitializer = {
37
37
  * C++ Code Generator
38
38
  */
39
39
 
40
- const capitalize = (s) => {
40
+ const capitalize = (s: string) => {
41
41
  if (typeof s !== 'string') return ''
42
42
  return s.charAt(0).toUpperCase() + s.slice(1);
43
43
  }
44
- const distinct = (value, index, self) => self.indexOf(value) === index;
44
+ const distinct = (value: string, index: number, self: string[]) =>
45
+ self.indexOf(value) === index;
45
46
 
46
47
  export function generate (context: Context, options: GenerateOptions): File[] {
47
48
  return context.classes.map(klass => ({
@@ -9,7 +9,7 @@ import {
9
9
  import { GenerateOptions } from "../api";
10
10
  import { Context } from "../types";
11
11
 
12
- const typeMaps = {
12
+ const typeMaps: { [key: string]: string } = {
13
13
  "string": "string",
14
14
  "number": "float",
15
15
  "boolean": "bool",
@@ -28,7 +28,7 @@ const typeMaps = {
28
28
  /**
29
29
  * C# Code Generator
30
30
  */
31
- const capitalize = (s) => {
31
+ const capitalize = (s: string) => {
32
32
  if (typeof s !== 'string') return ''
33
33
  return s.charAt(0).toUpperCase() + s.slice(1);
34
34
  }
@@ -1,7 +1,7 @@
1
1
  import { Class, Property, File, getCommentHeader, Context } from "../types";
2
2
  import { GenerateOptions } from "../api";
3
3
 
4
- const typeMaps = {
4
+ const typeMaps: { [key: string]: string } = {
5
5
  "string": "String",
6
6
  "number": "Dynamic",
7
7
  "boolean": "Bool",
@@ -17,7 +17,7 @@ const typeMaps = {
17
17
  "float64": "Float",
18
18
  }
19
19
 
20
- const typeInitializer = {
20
+ const typeInitializer: { [key: string]: string } = {
21
21
  "string": '""',
22
22
  "number": "0",
23
23
  "boolean": "false",
@@ -1,7 +1,7 @@
1
1
  import { Class, Property, File, getCommentHeader, Context } from "../types";
2
2
  import { GenerateOptions } from "../api";
3
3
 
4
- const typeMaps = {
4
+ const typeMaps: { [key: string]: string } = {
5
5
  "string": "String",
6
6
  "number": "float",
7
7
  "boolean": "boolean",
@@ -17,7 +17,7 @@ const typeMaps = {
17
17
  "float64": "double",
18
18
  }
19
19
 
20
- const typeInitializer = {
20
+ const typeInitializer: { [key: string]: string } = {
21
21
  "string": '""',
22
22
  "number": "0",
23
23
  "boolean": "false",
@@ -1,7 +1,7 @@
1
1
  import { Class, Property, File, getCommentHeader, getInheritanceTree, Context } from "../types";
2
2
  import { GenerateOptions } from "../api";
3
3
 
4
- const typeMaps = {
4
+ const typeMaps: { [key: string]: string } = {
5
5
  "string": "string",
6
6
  "number": "number",
7
7
  "boolean": "boolean",
@@ -17,7 +17,8 @@ const typeMaps = {
17
17
  "float64": "number",
18
18
  }
19
19
 
20
- const distinct = (value, index, self) => self.indexOf(value) === index;
20
+ const distinct = (value: string, index: number, self: string[]) =>
21
+ self.indexOf(value) === index;
21
22
 
22
23
  export function generate (context: Context, options: GenerateOptions): File[] {
23
24
  return context.classes.map(klass => ({
@@ -7,7 +7,7 @@ import { GenerateOptions } from "../api";
7
7
  - Support importing Schema dependencies
8
8
  */
9
9
 
10
- const typeMaps = {
10
+ const typeMaps: { [key: string]: string } = {
11
11
  "string": "string",
12
12
  "number": "number",
13
13
  "boolean": "boolean",
@@ -23,7 +23,8 @@ const typeMaps = {
23
23
  "float64": "number",
24
24
  }
25
25
 
26
- const distinct = (value, index, self) => self.indexOf(value) === index;
26
+ const distinct = (value: string, index: number, self: string[]) =>
27
+ self.indexOf(value) === index;
27
28
 
28
29
  export function generate (context: Context, options: GenerateOptions): File[] {
29
30
  return context.classes.map(klass => ({
@@ -1,7 +1,7 @@
1
1
  import { Class, Property, File, getCommentHeader, getInheritanceTree, Context, Interface } from "../types";
2
2
  import { GenerateOptions } from "../api";
3
3
 
4
- const typeMaps = {
4
+ const typeMaps: { [key: string]: string } = {
5
5
  "string": "string",
6
6
  "number": "number",
7
7
  "boolean": "boolean",
@@ -17,7 +17,8 @@ const typeMaps = {
17
17
  "float64": "number",
18
18
  }
19
19
 
20
- const distinct = (value, index, self) => self.indexOf(value) === index;
20
+ const distinct = (value: string, index: number, self: string[]) =>
21
+ self.indexOf(value) === index;
21
22
 
22
23
  export function generate (context: Context, options: GenerateOptions): File[] {
23
24
  return [
@@ -162,6 +162,18 @@ function inspectNode(node: ts.Node, context: Context, decoratorName: string) {
162
162
  ? node.parent.parent as ts.CallExpression
163
163
  : node.parent as ts.CallExpression;
164
164
 
165
+ /**
166
+ * Skip if @codegen-ignore comment is found before the call expression
167
+ * TODO: currently, if @codegen-ignore is on the file, it will skip all the setFields calls.
168
+ */
169
+ const sourceFile = node.getSourceFile();
170
+ const fullText = sourceFile.getFullText();
171
+ const nodeStart = callExpression.getFullStart();
172
+ const textBeforeNode = fullText.substring(0, nodeStart);
173
+ if (textBeforeNode.includes('@codegen-ignore')) {
174
+ break;
175
+ }
176
+
165
177
  if (callExpression.kind !== ts.SyntaxKind.CallExpression) {
166
178
  break;
167
179
  }
@@ -89,7 +89,7 @@ export interface IStructure {
89
89
  context: Context;
90
90
  name: string;
91
91
  properties: Property[];
92
- addProperty(property: Property);
92
+ addProperty(property: Property): void;
93
93
  }
94
94
 
95
95
  export class Interface implements IStructure {
@@ -97,7 +97,7 @@ export class Interface implements IStructure {
97
97
  name: string;
98
98
  properties: Property[] = [];
99
99
 
100
- addProperty(property: Property) {
100
+ addProperty(property: Property): void {
101
101
  if (property.type.indexOf("[]") >= 0) {
102
102
  // is array!
103
103
  property.childType = property.type.match(/([^\[]+)/i)[1];
@@ -33,10 +33,10 @@ export type DecodeOperation<T extends Schema = any> = (
33
33
  allChanges: DataChange[],
34
34
  ) => number | void;
35
35
 
36
- export function decodeValue(
36
+ export function decodeValue<T extends Ref>(
37
37
  decoder: Decoder,
38
38
  operation: OPERATION,
39
- ref: Ref,
39
+ ref: T,
40
40
  index: number,
41
41
  type: any,
42
42
  bytes: Buffer,
@@ -44,7 +44,7 @@ export function decodeValue(
44
44
  allChanges: DataChange[],
45
45
  ) {
46
46
  const $root = decoder.root;
47
- const previousValue = ref[$getByIndex](index);
47
+ const previousValue = (ref as any)[$getByIndex](index) as T;
48
48
 
49
49
  let value: any;
50
50
 
@@ -58,7 +58,7 @@ export function decodeValue(
58
58
  // Delete operations
59
59
  //
60
60
  if (operation !== OPERATION.DELETE_AND_ADD) {
61
- ref[$deleteByIndex](index);
61
+ (ref as any)[$deleteByIndex](index);
62
62
  }
63
63
 
64
64
  value = undefined;
@@ -93,7 +93,7 @@ export function decodeValue(
93
93
  //
94
94
  // primitive value (number, string, boolean, etc)
95
95
  //
96
- value = decode[type as string](bytes, it);
96
+ value = (decode as any)[type](bytes, it);
97
97
 
98
98
  } else {
99
99
  const typeDef = getType(Object.keys(type)[0]);
@@ -113,7 +113,7 @@ export function decodeValue(
113
113
  //
114
114
  // enqueue onRemove if structure has been replaced.
115
115
  //
116
- const entries: IterableIterator<[any, any]> = previousValue.entries();
116
+ const entries: IterableIterator<[any, any]> = (previousValue as any).entries();
117
117
  let iter: IteratorResult<[any, any]>;
118
118
  while ((iter = entries.next()) && !iter.done) {
119
119
  const [key, value] = iter.value;
@@ -146,15 +146,15 @@ export function decodeValue(
146
146
  return { value, previousValue };
147
147
  }
148
148
 
149
- export const decodeSchemaOperation: DecodeOperation = function (
149
+ export const decodeSchemaOperation: DecodeOperation = function <T extends Schema>(
150
150
  decoder: Decoder<any>,
151
151
  bytes: Buffer,
152
152
  it: Iterator,
153
- ref: Ref,
153
+ ref: T,
154
154
  allChanges: DataChange[],
155
155
  ) {
156
156
  const first_byte = bytes[it.offset++];
157
- const metadata: Metadata = ref.constructor[Symbol.metadata];
157
+ const metadata: Metadata = (ref.constructor as typeof Schema)[Symbol.metadata];
158
158
 
159
159
  // "compressed" index + operation
160
160
  const operation = (first_byte >> 6) << 6
@@ -179,7 +179,7 @@ export const decodeSchemaOperation: DecodeOperation = function (
179
179
  );
180
180
 
181
181
  if (value !== null && value !== undefined) {
182
- ref[field.name] = value;
182
+ ref[field.name as keyof T] = value;
183
183
  }
184
184
 
185
185
  // add change
@@ -218,20 +218,20 @@ export const decodeKeyValueOperation: DecodeOperation = function (
218
218
  }
219
219
 
220
220
  const index = decode.number(bytes, it);
221
- const type = ref[$childType];
221
+ const type = (ref as any)[$childType];
222
222
 
223
223
  let dynamicIndex: number | string;
224
224
 
225
225
  if ((operation & OPERATION.ADD) === OPERATION.ADD) { // ADD or DELETE_AND_ADD
226
- if (typeof(ref['set']) === "function") {
226
+ if (typeof((ref as any)['set']) === "function") {
227
227
  dynamicIndex = decode.string(bytes, it); // MapSchema
228
- ref['setIndex'](index, dynamicIndex);
228
+ (ref as any)['setIndex'](index, dynamicIndex);
229
229
  } else {
230
230
  dynamicIndex = index; // ArraySchema
231
231
  }
232
232
  } else {
233
233
  // get dynamic index from "ref"
234
- dynamicIndex = ref['getIndex'](index);
234
+ dynamicIndex = (ref as any)['getIndex'](index);
235
235
  }
236
236
 
237
237
  const { value, previousValue } = decodeValue(
@@ -246,20 +246,20 @@ export const decodeKeyValueOperation: DecodeOperation = function (
246
246
  );
247
247
 
248
248
  if (value !== null && value !== undefined) {
249
- if (typeof(ref['set']) === "function") {
249
+ if (typeof((ref as any)['set']) === "function") {
250
250
  // MapSchema
251
- (ref as MapSchema)['$items'].set(dynamicIndex as string, value);
251
+ (ref as any)['$items'].set(dynamicIndex as string, value);
252
252
 
253
- } else if (typeof(ref['$setAt']) === "function") {
253
+ } else if (typeof((ref as any)['$setAt']) === "function") {
254
254
  // ArraySchema
255
- (ref as ArraySchema)['$setAt'](index, value, operation);
255
+ (ref as any)['$setAt'](index, value, operation);
256
256
 
257
- } else if (typeof(ref['add']) === "function") {
257
+ } else if (typeof((ref as any)['add']) === "function") {
258
258
  // CollectionSchema && SetSchema
259
- const index = (ref as CollectionSchema).add(value);
259
+ const index = (ref as any).add(value);
260
260
 
261
261
  if (typeof(index) === "number") {
262
- ref['setIndex'](index, index);
262
+ (ref as any)['setIndex'](index, index);
263
263
  }
264
264
  }
265
265
  }
@@ -58,7 +58,7 @@ export class Decoder<T extends Schema = any> {
58
58
  if (bytes[it.offset] == SWITCH_TO_STRUCTURE) {
59
59
  it.offset++;
60
60
 
61
- ref[$onDecodeEnd]?.()
61
+ (ref as any)[$onDecodeEnd]?.()
62
62
 
63
63
  const nextRefId = decode.number(bytes, it);
64
64
  const nextRef = $root.refs.get(nextRefId);
@@ -91,7 +91,7 @@ export class Decoder<T extends Schema = any> {
91
91
  }
92
92
 
93
93
  // FIXME: DRY with SWITCH_TO_STRUCTURE block.
94
- ref[$onDecodeEnd]?.()
94
+ (ref as any)[$onDecodeEnd]?.()
95
95
 
96
96
  // trigger changes
97
97
  this.triggerChanges?.(allChanges);
@@ -136,7 +136,7 @@ export class Decoder<T extends Schema = any> {
136
136
  }
137
137
 
138
138
  removeChildRefs(ref: Collection, allChanges: DataChange[]) {
139
- const needRemoveRef = typeof (ref[$childType]) !== "string";
139
+ const needRemoveRef = typeof ((ref as any)[$childType]) !== "string";
140
140
  const refId = this.root.refIds.get(ref as Ref);
141
141
 
142
142
  ref.forEach((value: any, key: any) => {
@@ -2,9 +2,11 @@ import { Metadata } from "../Metadata";
2
2
  import { $childType } from "../types/symbols";
3
3
  import { Ref } from "../encoder/ChangeTree";
4
4
  import { spliceOne } from "../types/utils";
5
- import type { MapSchema } from "../types/custom/MapSchema";
6
5
  import { OPERATION } from "../encoding/spec";
7
6
 
7
+ import type { MapSchema } from "../types/custom/MapSchema";
8
+ import type { Schema } from "../Schema";
9
+
8
10
  class DecodingWarning extends Error {
9
11
  constructor(message: string) {
10
12
  super(message);
@@ -98,18 +100,18 @@ export class ReferenceTracker {
98
100
  //
99
101
  // Ensure child schema instances have their references removed as well.
100
102
  //
101
- if (ref.constructor[Symbol.metadata] !== undefined) {
102
- const metadata: Metadata = ref.constructor[Symbol.metadata];
103
+ if ((ref.constructor as typeof Schema)[Symbol.metadata] !== undefined) {
104
+ const metadata: Metadata = (ref.constructor as typeof Schema)[Symbol.metadata];
103
105
  for (const index in metadata) {
104
106
  const field = metadata[index as any as number].name;
105
- const childRefId = typeof(ref[field]) === "object" && this.refIds.get(ref[field]);
107
+ const childRefId = typeof(ref[field as keyof Ref]) === "object" && this.refIds.get((ref as any)[field]);
106
108
  if (childRefId && !this.deletedRefs.has(childRefId)) {
107
109
  this.removeRef(childRefId);
108
110
  }
109
111
  }
110
112
 
111
113
  } else {
112
- if (typeof (ref[$childType]) === "function") {
114
+ if (typeof ((ref as any)[$childType]) === "function") {
113
115
  Array.from((ref as MapSchema).values())
114
116
  .forEach((child) => {
115
117
  const childRefId = this.refIds.get(child);
@@ -19,7 +19,7 @@ import type { CollectionSchema } from "../../types/custom/CollectionSchema";
19
19
 
20
20
  /**
21
21
  * TODO: define a schema interface, which even having duplicate definitions, it could be used to get the callback proxy.
22
- *
22
+ *
23
23
  * ```ts
24
24
  * export type SchemaCallbackProxy<RoomState> = (<T extends Schema>(instance: T) => CallbackProxy<T>);
25
25
  * ```
@@ -228,7 +228,7 @@ export function getDecoderStateCallbacks<T extends Schema>(decoder: Decoder<T>):
228
228
  let metadata: Metadata = context.instance?.constructor[Symbol.metadata] || metadataOrType;
229
229
  let isCollection = (
230
230
  (context.instance && typeof (context.instance['forEach']) === "function") ||
231
- (metadataOrType && typeof (metadataOrType[Symbol.metadata]) === "undefined")
231
+ (metadataOrType && typeof ((metadataOrType as typeof Schema)[Symbol.metadata]) === "undefined")
232
232
  );
233
233
 
234
234
  if (metadata && !isCollection) {
@@ -327,7 +327,7 @@ export function getDecoderStateCallbacks<T extends Schema>(decoder: Decoder<T>):
327
327
 
328
328
  } else {
329
329
  // accessing the function
330
- return target[prop];
330
+ return target[prop as keyof typeof target];
331
331
  }
332
332
  },
333
333
  has(target, prop: string) { return metadata[prop] !== undefined; },
@@ -346,7 +346,7 @@ export function getDecoderStateCallbacks<T extends Schema>(decoder: Decoder<T>):
346
346
  (ref as CollectionSchema).forEach((v, k) => callback(v, k));
347
347
  }
348
348
 
349
- return $root.addCallback($root.refIds.get(ref), OPERATION.ADD, (value, key) => {
349
+ return $root.addCallback($root.refIds.get(ref), OPERATION.ADD, (value: any, key: any) => {
350
350
  onAddCalls.set(callback, true);
351
351
  currentOnAddCallback = callback;
352
352
  callback(value, key);
@@ -364,7 +364,7 @@ export function getDecoderStateCallbacks<T extends Schema>(decoder: Decoder<T>):
364
364
  };
365
365
 
366
366
  return new Proxy({
367
- onAdd: function(callback: (value, key) => void, immediate: boolean = true) {
367
+ onAdd: function(callback: (value: any, key: any) => void, immediate: boolean = true) {
368
368
  //
369
369
  // https://github.com/colyseus/schema/issues/147
370
370
  // If parent instance has "onAdd" registered, avoid triggering immediate callback.
@@ -384,7 +384,7 @@ export function getDecoderStateCallbacks<T extends Schema>(decoder: Decoder<T>):
384
384
  return () => detachCallback();
385
385
  }
386
386
  },
387
- onRemove: function(callback: (value, key) => void) {
387
+ onRemove: function(callback: (value: any, key: any) => void) {
388
388
  if (context.instance) {
389
389
  return onRemove(context.instance, callback);
390
390
 
@@ -399,7 +399,7 @@ export function getDecoderStateCallbacks<T extends Schema>(decoder: Decoder<T>):
399
399
  return () => detachCallback();
400
400
  }
401
401
  },
402
- onChange: function(callback: (value, key) => void) {
402
+ onChange: function(callback: (value: any, key: any) => void) {
403
403
  if (context.instance) {
404
404
  return onChange(context.instance, callback);
405
405
 
@@ -416,12 +416,12 @@ export function getDecoderStateCallbacks<T extends Schema>(decoder: Decoder<T>):
416
416
  },
417
417
  }, {
418
418
  get(target, prop: string) {
419
- if (!target[prop]) {
419
+ if (!target[prop as keyof typeof target]) {
420
420
  throw new Error(`Can't access '${prop}' through callback proxy. access the instance directly.`);
421
421
  }
422
- return target[prop];
422
+ return target[prop as keyof typeof target];
423
423
  },
424
- has(target, prop) { return target[prop] !== undefined; },
424
+ has(target, prop) { return target[prop as keyof typeof target] !== undefined; },
425
425
  set(_, _1, _2) { throw new Error("not allowed"); },
426
426
  deleteProperty(_, _1) { throw new Error("not allowed"); },
427
427
  });
@@ -1,6 +1,6 @@
1
1
  import { OPERATION } from "../encoding/spec";
2
2
  import { Schema } from "../Schema";
3
- import { $changes, $childType, $decoder, $onEncodeEnd, $encoder, $getByIndex, $refTypeFieldIndexes, $viewFieldIndexes } from "../types/symbols";
3
+ import { $changes, $childType, $decoder, $onEncodeEnd, $encoder, $getByIndex, $refTypeFieldIndexes, $viewFieldIndexes, type $deleteByIndex } from "../types/symbols";
4
4
 
5
5
  import type { MapSchema } from "../types/custom/MapSchema";
6
6
  import type { ArraySchema } from "../types/custom/ArraySchema";
@@ -21,6 +21,12 @@ declare global {
21
21
  }
22
22
  }
23
23
 
24
+ export interface IRef {
25
+ [$changes]?: ChangeTree;
26
+ [$getByIndex]?: (index: number, isEncodeAll?: boolean) => any;
27
+ [$deleteByIndex]?: (index: number) => void;
28
+ }
29
+
24
30
  export type Ref = Schema
25
31
  | ArraySchema
26
32
  | MapSchema
@@ -76,7 +82,7 @@ export function setOperationAtIndex(changeSet: ChangeSet, index: number) {
76
82
  }
77
83
 
78
84
  export function deleteOperationAtIndex(changeSet: ChangeSet, index: number | string) {
79
- let operationsIndex = changeSet.indexes[index];
85
+ let operationsIndex = changeSet.indexes[index as any as number];
80
86
  if (operationsIndex === undefined) {
81
87
  //
82
88
  // if index is not found, we need to find the last operation
@@ -88,7 +94,7 @@ export function deleteOperationAtIndex(changeSet: ChangeSet, index: number | str
88
94
  index = Object.entries(changeSet.indexes).find(([_, value]) => value === operationsIndex)?.[0];
89
95
  }
90
96
  changeSet.operations[operationsIndex] = undefined;
91
- delete changeSet.indexes[index];
97
+ delete changeSet.indexes[index as any as number];
92
98
  }
93
99
 
94
100
  export function debugChangeSet(label: string, changeSet: ChangeSet) {
@@ -155,7 +161,7 @@ export class ChangeTree<T extends Ref = any> {
155
161
 
156
162
  constructor(ref: T) {
157
163
  this.ref = ref;
158
- this.metadata = ref.constructor[Symbol.metadata];
164
+ this.metadata = (ref.constructor as typeof Schema)[Symbol.metadata];
159
165
 
160
166
  //
161
167
  // Does this structure have "filters" declared?
@@ -227,8 +233,8 @@ export class ChangeTree<T extends Ref = any> {
227
233
  //
228
234
  // assign same parent on child structures
229
235
  //
230
- if (this.ref[$childType]) {
231
- if (typeof (this.ref[$childType]) !== "string") {
236
+ if ((this.ref as any)[$childType]) {
237
+ if (typeof ((this.ref as any)[$childType]) !== "string") {
232
238
  // MapSchema / ArraySchema, etc.
233
239
  for (const [key, value] of (this.ref as MapSchema).entries()) {
234
240
  callback(value[$changes], this.indexes?.[key] ?? key);
@@ -238,7 +244,7 @@ export class ChangeTree<T extends Ref = any> {
238
244
  } else {
239
245
  for (const index of this.metadata?.[$refTypeFieldIndexes] ?? []) {
240
246
  const field = this.metadata[index as any as number];
241
- const value = this.ref[field.name];
247
+ const value = this.ref[field.name as keyof Ref];
242
248
  if (!value) { continue; }
243
249
  callback(value[$changes], index);
244
250
  }
@@ -303,8 +309,8 @@ export class ChangeTree<T extends Ref = any> {
303
309
  ? this.filteredChanges
304
310
  : this.changes;
305
311
 
306
- const newIndexedOperations = {};
307
- const newIndexes = {};
312
+ const newIndexedOperations: any = {};
313
+ const newIndexes: { [index: number]: number } = {};
308
314
  for (const index in this.indexedOperations) {
309
315
  newIndexedOperations[Number(index) + shiftIndex] = this.indexedOperations[index];
310
316
  newIndexes[Number(index) + shiftIndex] = changeSet.indexes[index];
@@ -331,7 +337,7 @@ export class ChangeTree<T extends Ref = any> {
331
337
  }
332
338
 
333
339
  private _shiftAllChangeIndexes(shiftIndex: number, startIndex: number = 0, changeSet: ChangeSet) {
334
- const newIndexes = {};
340
+ const newIndexes: { [index: number]: number } = {};
335
341
  let newKey = 0;
336
342
  for (const key in changeSet.indexes) {
337
343
  newIndexes[newKey++] = changeSet.indexes[key];
@@ -369,7 +375,7 @@ export class ChangeTree<T extends Ref = any> {
369
375
  // - { map: "string" } => "string"
370
376
  // - { set: "string" } => "string"
371
377
  //
372
- this.ref[$childType] || // ArraySchema | MapSchema | SetSchema | CollectionSchema
378
+ (this.ref as any)[$childType] || // ArraySchema | MapSchema | SetSchema | CollectionSchema
373
379
  this.metadata[index].type // Schema
374
380
  );
375
381
  }
@@ -385,7 +391,7 @@ export class ChangeTree<T extends Ref = any> {
385
391
  //
386
392
  // `isEncodeAll` param is only used by ArraySchema
387
393
  //
388
- return this.ref[$getByIndex](index, isEncodeAll);
394
+ return (this.ref as any)[$getByIndex](index, isEncodeAll);
389
395
  }
390
396
 
391
397
  delete(index: number, operation?: OPERATION, allChangesIndex = index) {
@@ -444,7 +450,7 @@ export class ChangeTree<T extends Ref = any> {
444
450
  this[changeSetName] = createChangeSet();
445
451
 
446
452
  // ArraySchema and MapSchema have a custom "encode end" method
447
- this.ref[$onEncodeEnd]?.();
453
+ (this.ref as any)[$onEncodeEnd]?.();
448
454
 
449
455
  // Not a new instance anymore
450
456
  this.isNew = false;
@@ -456,7 +462,7 @@ export class ChangeTree<T extends Ref = any> {
456
462
  // Remove cached key to ensure ADD operations is unsed instead of
457
463
  // REPLACE in case same key is used on next patches.
458
464
  //
459
- this.ref[$onEncodeEnd]?.();
465
+ (this.ref as any)[$onEncodeEnd]?.();
460
466
 
461
467
  this.indexedOperations = {};
462
468
  this.changes = createChangeSet(this.changes.queueRootNode);
@@ -534,7 +540,7 @@ export class ChangeTree<T extends Ref = any> {
534
540
  //
535
541
  const refType = Metadata.isValidInstance(this.ref)
536
542
  ? this.ref.constructor
537
- : this.ref[$childType];
543
+ : (this.ref as any)[$childType];
538
544
 
539
545
  let parentChangeTree: ChangeTree;
540
546
 
@@ -32,7 +32,7 @@ export function encodeValue(
32
32
  it: Iterator,
33
33
  ) {
34
34
  if (typeof (type) === "string") {
35
- encode[type]?.(bytes, value, it);
35
+ (encode as any)[type]?.(bytes, value, it);
36
36
 
37
37
  } else if (type[Symbol.metadata] !== undefined) {
38
38
  //
@@ -59,10 +59,10 @@ export function encodeValue(
59
59
  * Used for Schema instances.
60
60
  * @private
61
61
  */
62
- export const encodeSchemaOperation: EncodeOperation = function (
62
+ export const encodeSchemaOperation: EncodeOperation = function <T extends Schema> (
63
63
  encoder: Encoder,
64
64
  bytes: Buffer,
65
- changeTree: ChangeTree<Schema>,
65
+ changeTree: ChangeTree<T>,
66
66
  index: number,
67
67
  operation: OPERATION,
68
68
  it: Iterator,
@@ -86,7 +86,7 @@ export const encodeSchemaOperation: EncodeOperation = function (
86
86
  encoder,
87
87
  bytes,
88
88
  metadata[index].type,
89
- ref[field.name],
89
+ ref[field.name as keyof T],
90
90
  operation,
91
91
  it
92
92
  );
@@ -167,30 +167,6 @@ export class Encoder<T extends Schema = any> {
167
167
  ]);
168
168
  }
169
169
 
170
- debugChanges(field: "changes" | "allFilteredChanges" | "allChanges" | "filteredChanges") {
171
- const rootChangeSet = (typeof (field) === "string")
172
- ? this.root[field]
173
- : field;
174
-
175
- let current = rootChangeSet.next;
176
- while (current) {
177
- const changeTree = current.changeTree;
178
- const changeSet = changeTree[field];
179
-
180
- const metadata: Metadata = changeTree.ref.constructor[Symbol.metadata];
181
- console.log("->", { ref: changeTree.ref.constructor.name, refId: changeTree.refId, changes: Object.keys(changeSet).length });
182
- for (const index in changeSet) {
183
- const op = changeSet[index];
184
- console.log(" ->", {
185
- index,
186
- field: metadata?.[index],
187
- op: OPERATION[op],
188
- });
189
- }
190
- current = current.next;
191
- }
192
- }
193
-
194
170
  encodeView(view: StateView, sharedOffset: number, it: Iterator, bytes = this.sharedBuffer) {
195
171
  const viewOffset = it.offset;
196
172