@colyseus/schema 3.0.0-alpha.3 → 3.0.0-alpha.31

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 (134) hide show
  1. package/README.md +131 -61
  2. package/build/cjs/index.js +966 -563
  3. package/build/cjs/index.js.map +1 -1
  4. package/build/esm/index.mjs +965 -562
  5. package/build/esm/index.mjs.map +1 -1
  6. package/build/umd/index.js +966 -563
  7. package/lib/Metadata.d.ts +15 -4
  8. package/lib/Metadata.js +86 -18
  9. package/lib/Metadata.js.map +1 -1
  10. package/lib/Reflection.d.ts +2 -3
  11. package/lib/Reflection.js +24 -28
  12. package/lib/Reflection.js.map +1 -1
  13. package/lib/Schema.d.ts +2 -2
  14. package/lib/Schema.js +28 -41
  15. package/lib/Schema.js.map +1 -1
  16. package/lib/annotations.d.ts +1 -21
  17. package/lib/annotations.js +73 -153
  18. package/lib/annotations.js.map +1 -1
  19. package/lib/bench_encode.d.ts +1 -0
  20. package/lib/bench_encode.js +142 -0
  21. package/lib/bench_encode.js.map +1 -0
  22. package/lib/codegen/api.js +1 -2
  23. package/lib/codegen/api.js.map +1 -1
  24. package/lib/codegen/languages/cpp.js +1 -2
  25. package/lib/codegen/languages/cpp.js.map +1 -1
  26. package/lib/codegen/languages/csharp.js +1 -2
  27. package/lib/codegen/languages/csharp.js.map +1 -1
  28. package/lib/codegen/languages/haxe.js +1 -2
  29. package/lib/codegen/languages/haxe.js.map +1 -1
  30. package/lib/codegen/languages/java.js +1 -2
  31. package/lib/codegen/languages/java.js.map +1 -1
  32. package/lib/codegen/languages/js.js +1 -2
  33. package/lib/codegen/languages/js.js.map +1 -1
  34. package/lib/codegen/languages/lua.js +1 -2
  35. package/lib/codegen/languages/lua.js.map +1 -1
  36. package/lib/codegen/languages/ts.js +1 -2
  37. package/lib/codegen/languages/ts.js.map +1 -1
  38. package/lib/codegen/parser.js +2 -3
  39. package/lib/codegen/parser.js.map +1 -1
  40. package/lib/codegen/types.js +3 -3
  41. package/lib/codegen/types.js.map +1 -1
  42. package/lib/debug.d.ts +1 -0
  43. package/lib/debug.js +52 -0
  44. package/lib/debug.js.map +1 -0
  45. package/lib/decoder/DecodeOperation.d.ts +0 -1
  46. package/lib/decoder/DecodeOperation.js +23 -11
  47. package/lib/decoder/DecodeOperation.js.map +1 -1
  48. package/lib/decoder/Decoder.d.ts +6 -7
  49. package/lib/decoder/Decoder.js +8 -8
  50. package/lib/decoder/Decoder.js.map +1 -1
  51. package/lib/decoder/ReferenceTracker.js +3 -2
  52. package/lib/decoder/ReferenceTracker.js.map +1 -1
  53. package/lib/decoder/strategy/RawChanges.js +1 -2
  54. package/lib/decoder/strategy/RawChanges.js.map +1 -1
  55. package/lib/decoder/strategy/StateCallbacks.d.ts +44 -11
  56. package/lib/decoder/strategy/StateCallbacks.js +75 -65
  57. package/lib/decoder/strategy/StateCallbacks.js.map +1 -1
  58. package/lib/encoder/ChangeTree.d.ts +9 -19
  59. package/lib/encoder/ChangeTree.js +129 -145
  60. package/lib/encoder/ChangeTree.js.map +1 -1
  61. package/lib/encoder/EncodeOperation.d.ts +1 -5
  62. package/lib/encoder/EncodeOperation.js +74 -58
  63. package/lib/encoder/EncodeOperation.js.map +1 -1
  64. package/lib/encoder/Encoder.d.ts +10 -8
  65. package/lib/encoder/Encoder.js +89 -56
  66. package/lib/encoder/Encoder.js.map +1 -1
  67. package/lib/encoder/Root.d.ts +17 -0
  68. package/lib/encoder/Root.js +44 -0
  69. package/lib/encoder/Root.js.map +1 -0
  70. package/lib/encoder/StateView.d.ts +2 -2
  71. package/lib/encoder/StateView.js +49 -59
  72. package/lib/encoder/StateView.js.map +1 -1
  73. package/lib/encoding/assert.d.ts +2 -1
  74. package/lib/encoding/assert.js +5 -5
  75. package/lib/encoding/assert.js.map +1 -1
  76. package/lib/encoding/decode.js +21 -22
  77. package/lib/encoding/decode.js.map +1 -1
  78. package/lib/encoding/encode.d.ts +2 -2
  79. package/lib/encoding/encode.js +40 -39
  80. package/lib/encoding/encode.js.map +1 -1
  81. package/lib/encoding/spec.d.ts +2 -1
  82. package/lib/encoding/spec.js +1 -0
  83. package/lib/encoding/spec.js.map +1 -1
  84. package/lib/index.d.ts +6 -3
  85. package/lib/index.js +18 -13
  86. package/lib/index.js.map +1 -1
  87. package/lib/types/TypeContext.d.ts +23 -0
  88. package/lib/types/TypeContext.js +102 -0
  89. package/lib/types/TypeContext.js.map +1 -0
  90. package/lib/types/custom/ArraySchema.d.ts +2 -2
  91. package/lib/types/custom/ArraySchema.js +6 -9
  92. package/lib/types/custom/ArraySchema.js.map +1 -1
  93. package/lib/types/custom/CollectionSchema.js +1 -0
  94. package/lib/types/custom/CollectionSchema.js.map +1 -1
  95. package/lib/types/custom/MapSchema.js +5 -0
  96. package/lib/types/custom/MapSchema.js.map +1 -1
  97. package/lib/types/custom/SetSchema.js +1 -0
  98. package/lib/types/custom/SetSchema.js.map +1 -1
  99. package/lib/types/registry.js +3 -4
  100. package/lib/types/registry.js.map +1 -1
  101. package/lib/types/symbols.d.ts +1 -0
  102. package/lib/types/symbols.js +2 -1
  103. package/lib/types/symbols.js.map +1 -1
  104. package/lib/types/utils.js +1 -2
  105. package/lib/types/utils.js.map +1 -1
  106. package/lib/utils.js +3 -4
  107. package/lib/utils.js.map +1 -1
  108. package/package.json +5 -5
  109. package/src/Metadata.ts +104 -26
  110. package/src/Reflection.ts +26 -28
  111. package/src/Schema.ts +35 -47
  112. package/src/annotations.ts +82 -176
  113. package/src/bench_encode.ts +121 -0
  114. package/src/debug.ts +56 -0
  115. package/src/decoder/DecodeOperation.ts +28 -11
  116. package/src/decoder/Decoder.ts +13 -11
  117. package/src/decoder/ReferenceTracker.ts +3 -2
  118. package/src/decoder/strategy/StateCallbacks.ts +152 -81
  119. package/src/encoder/ChangeTree.ts +147 -166
  120. package/src/encoder/EncodeOperation.ts +93 -70
  121. package/src/encoder/Encoder.ts +111 -65
  122. package/src/encoder/Root.ts +51 -0
  123. package/src/encoder/StateView.ts +53 -69
  124. package/src/encoding/assert.ts +4 -3
  125. package/src/encoding/decode.ts +1 -2
  126. package/src/encoding/encode.ts +25 -22
  127. package/src/encoding/spec.ts +1 -0
  128. package/src/index.ts +8 -14
  129. package/src/types/TypeContext.ts +122 -0
  130. package/src/types/custom/ArraySchema.ts +10 -2
  131. package/src/types/custom/CollectionSchema.ts +1 -0
  132. package/src/types/custom/MapSchema.ts +6 -0
  133. package/src/types/custom/SetSchema.ts +1 -0
  134. package/src/types/symbols.ts +2 -0
package/lib/Metadata.d.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  import { type DefinitionType } from "./annotations";
2
+ import { $descriptors } from "./types/symbols";
2
3
  export type MetadataField = {
3
4
  type: DefinitionType;
5
+ name: string;
4
6
  index: number;
5
7
  tag?: number;
6
8
  unreliable?: boolean;
7
9
  deprecated?: boolean;
8
- descriptor?: PropertyDescriptor;
9
10
  };
10
11
  export type Metadata = {
11
12
  [-1]: number;
@@ -19,18 +20,28 @@ export type Metadata = {
19
20
  };
20
21
  } & // field indexes by "view" tag
21
22
  {
22
- [field: number]: string;
23
+ [-4]: number[];
24
+ } & // all field indexes containing Ref types (Schema, ArraySchema, MapSchema, etc)
25
+ {
26
+ [field: number]: MetadataField;
23
27
  } & // index => field name
24
28
  {
25
- [field: string]: MetadataField;
29
+ [field: string]: number;
30
+ } & // field name => field metadata
31
+ {
32
+ [$descriptors]: {
33
+ [field: string]: PropertyDescriptor;
34
+ };
26
35
  };
27
36
  export declare const Metadata: {
28
- addField(metadata: any, index: number, field: string, type: DefinitionType, descriptor?: PropertyDescriptor): void;
37
+ addField(metadata: any, index: number, name: string, type: DefinitionType, descriptor?: PropertyDescriptor): void;
29
38
  setTag(metadata: Metadata, fieldName: string, tag: number): void;
30
39
  setFields(target: any, fields: {
31
40
  [field: string]: DefinitionType;
32
41
  }): void;
33
42
  isDeprecated(metadata: any, field: string): boolean;
43
+ init(klass: any): void;
44
+ initialize(constructor: any, parentMetadata?: Metadata): Metadata;
34
45
  isValidInstance(klass: any): boolean;
35
46
  getFields(klass: any): {};
36
47
  };
package/lib/Metadata.js CHANGED
@@ -3,35 +3,69 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Metadata = void 0;
4
4
  const annotations_1 = require("./annotations");
5
5
  const registry_1 = require("./types/registry");
6
+ const symbols_1 = require("./types/symbols");
6
7
  exports.Metadata = {
7
- addField(metadata, index, field, type, descriptor) {
8
+ addField(metadata, index, name, type, descriptor) {
8
9
  if (index > 64) {
9
- throw new Error(`Can't define field '${field}'.\nSchema instances may only have up to 64 fields.`);
10
+ throw new Error(`Can't define field '${name}'.\nSchema instances may only have up to 64 fields.`);
10
11
  }
11
- metadata[field] = Object.assign(metadata[field] || {}, // avoid overwriting previous field metadata (@owned / @deprecated)
12
+ metadata[index] = Object.assign(metadata[index] || {}, // avoid overwriting previous field metadata (@owned / @deprecated)
12
13
  {
13
14
  type: (Array.isArray(type))
14
15
  ? { array: type[0] }
15
16
  : type,
16
17
  index,
17
- descriptor,
18
+ name,
18
19
  });
20
+ // create "descriptors" map
21
+ metadata[symbols_1.$descriptors] ??= {};
22
+ if (descriptor) {
23
+ // for encoder
24
+ metadata[symbols_1.$descriptors][name] = descriptor;
25
+ metadata[symbols_1.$descriptors][`_${name}`] = {
26
+ value: undefined,
27
+ writable: true,
28
+ enumerable: false,
29
+ configurable: true,
30
+ };
31
+ }
32
+ else {
33
+ // for decoder
34
+ metadata[symbols_1.$descriptors][name] = {
35
+ value: undefined,
36
+ writable: true,
37
+ enumerable: true,
38
+ configurable: true,
39
+ };
40
+ }
19
41
  // map -1 as last field index
20
42
  Object.defineProperty(metadata, -1, {
21
43
  value: index,
22
44
  enumerable: false,
23
45
  configurable: true
24
46
  });
25
- // map index => field name (non enumerable)
26
- Object.defineProperty(metadata, index, {
27
- value: field,
47
+ // map field name => index (non enumerable)
48
+ Object.defineProperty(metadata, name, {
49
+ value: index,
28
50
  enumerable: false,
29
51
  configurable: true,
30
52
  });
53
+ // if child Ref/complex type, add to -4
54
+ if (typeof (metadata[index].type) !== "string") {
55
+ if (metadata[-4] === undefined) {
56
+ Object.defineProperty(metadata, -4, {
57
+ value: [],
58
+ enumerable: false,
59
+ configurable: true,
60
+ });
61
+ }
62
+ metadata[-4].push(index);
63
+ }
31
64
  },
32
65
  setTag(metadata, fieldName, tag) {
66
+ const index = metadata[fieldName];
67
+ const field = metadata[index];
33
68
  // add 'tag' to the field
34
- const field = metadata[fieldName];
35
69
  field.tag = tag;
36
70
  if (!metadata[-2]) {
37
71
  // -2: all field indexes with "view" tag
@@ -47,20 +81,14 @@ exports.Metadata = {
47
81
  configurable: true
48
82
  });
49
83
  }
50
- metadata[-2].push(field.index);
84
+ metadata[-2].push(index);
51
85
  if (!metadata[-3][tag]) {
52
86
  metadata[-3][tag] = [];
53
87
  }
54
- metadata[-3][tag].push(field.index);
88
+ metadata[-3][tag].push(index);
55
89
  },
56
90
  setFields(target, fields) {
57
91
  const metadata = (target.prototype.constructor[Symbol.metadata] ??= {});
58
- // target[$track] = function (changeTree, index: number, operation: OPERATION = OPERATION.ADD) {
59
- // changeTree.change(index, operation, encodeSchemaOperation);
60
- // };
61
- // target[$encoder] = encodeSchemaOperation;
62
- // target[$decoder] = decodeSchemaOperation;
63
- // if (!target.prototype.toJSON) { target.prototype.toJSON = Schema.prototype.toJSON; }
64
92
  let index = 0;
65
93
  for (const field in fields) {
66
94
  const type = fields[field];
@@ -68,13 +96,53 @@ exports.Metadata = {
68
96
  const complexTypeKlass = (Array.isArray(type))
69
97
  ? (0, registry_1.getType)("array")
70
98
  : (typeof (Object.keys(type)[0]) === "string") && (0, registry_1.getType)(Object.keys(type)[0]);
71
- exports.Metadata.addField(metadata, index, field, type, (0, annotations_1.getPropertyDescriptor)(`_${field}`, index, type, complexTypeKlass, metadata, field));
99
+ exports.Metadata.addField(metadata, index, field, type, (0, annotations_1.getPropertyDescriptor)(`_${field}`, index, type, complexTypeKlass));
72
100
  index++;
73
101
  }
74
102
  },
75
103
  isDeprecated(metadata, field) {
76
104
  return metadata[field].deprecated === true;
77
105
  },
106
+ init(klass) {
107
+ //
108
+ // Used only to initialize an empty Schema (Encoder#constructor)
109
+ // TODO: remove/refactor this...
110
+ //
111
+ const metadata = {};
112
+ klass[Symbol.metadata] = metadata;
113
+ Object.defineProperty(metadata, -1, {
114
+ value: 0,
115
+ enumerable: false,
116
+ configurable: true,
117
+ });
118
+ },
119
+ initialize(constructor, parentMetadata) {
120
+ let metadata = constructor[Symbol.metadata] ?? Object.create(null);
121
+ // make sure inherited classes have their own metadata object.
122
+ if (constructor[Symbol.metadata] === parentMetadata) {
123
+ metadata = Object.create(null);
124
+ if (parentMetadata) {
125
+ // assign parent metadata to current
126
+ Object.assign(metadata, parentMetadata);
127
+ for (let i = 0; i <= parentMetadata[-1]; i++) {
128
+ const fieldName = parentMetadata[i].name;
129
+ Object.defineProperty(metadata, fieldName, {
130
+ value: parentMetadata[fieldName],
131
+ enumerable: false,
132
+ configurable: true,
133
+ });
134
+ }
135
+ Object.defineProperty(metadata, -1, {
136
+ value: parentMetadata[-1],
137
+ enumerable: false,
138
+ configurable: true,
139
+ writable: true,
140
+ });
141
+ }
142
+ }
143
+ constructor[Symbol.metadata] = metadata;
144
+ return metadata;
145
+ },
78
146
  isValidInstance(klass) {
79
147
  return (klass.constructor[Symbol.metadata] &&
80
148
  Object.prototype.hasOwnProperty.call(klass.constructor[Symbol.metadata], -1));
@@ -83,7 +151,7 @@ exports.Metadata = {
83
151
  const metadata = klass[Symbol.metadata];
84
152
  const fields = {};
85
153
  for (let i = 0; i <= metadata[-1]; i++) {
86
- fields[metadata[i]] = metadata[metadata[i]].type;
154
+ fields[metadata[i].name] = metadata[i].type;
87
155
  }
88
156
  return fields;
89
157
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Metadata.js","sourceRoot":"","sources":["../src/Metadata.ts"],"names":[],"mappings":"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","sourcesContent":["import { getPropertyDescriptor, type DefinitionType } from \"./annotations\";\nimport { getType } from \"./types/registry\";\n\nexport type MetadataField = {\n type: DefinitionType,\n index: number,\n tag?: number,\n unreliable?: boolean,\n deprecated?: boolean,\n descriptor?: PropertyDescriptor,\n};\n\nexport type Metadata =\n { [-1]: number; } & // number of fields\n { [-2]: number[]; } & // all field indexes with \"view\" tag\n { [-3]: {[tag: number]: number[]}; } & // field indexes by \"view\" tag\n { [field: number]: string; } & // index => field name\n { [field: string]: MetadataField; } // field name => field metadata\n\nexport const Metadata = {\n\n addField(metadata: any, index: number, field: string, type: DefinitionType, descriptor?: PropertyDescriptor) {\n if (index > 64) {\n throw new Error(`Can't define field '${field}'.\\nSchema instances may only have up to 64 fields.`);\n }\n\n metadata[field] = Object.assign(\n metadata[field] || {}, // avoid overwriting previous field metadata (@owned / @deprecated)\n {\n type: (Array.isArray(type))\n ? { array: type[0] }\n : type,\n index,\n descriptor,\n }\n );\n\n // map -1 as last field index\n Object.defineProperty(metadata, -1, {\n value: index,\n enumerable: false,\n configurable: true\n });\n\n // map index => field name (non enumerable)\n Object.defineProperty(metadata, index, {\n value: field,\n enumerable: false,\n configurable: true,\n });\n },\n\n setTag(metadata: Metadata, fieldName: string, tag: number) {\n // add 'tag' to the field\n const field = metadata[fieldName];\n field.tag = tag;\n\n if (!metadata[-2]) {\n // -2: all field indexes with \"view\" tag\n Object.defineProperty(metadata, -2, {\n value: [],\n enumerable: false,\n configurable: true\n });\n\n // -3: field indexes by \"view\" tag\n Object.defineProperty(metadata, -3, {\n value: {},\n enumerable: false,\n configurable: true\n });\n }\n\n metadata[-2].push(field.index);\n\n if (!metadata[-3][tag]) {\n metadata[-3][tag] = [];\n }\n\n metadata[-3][tag].push(field.index);\n },\n\n setFields(target: any, fields: { [field: string]: DefinitionType }) {\n const metadata = (target.prototype.constructor[Symbol.metadata] ??= {});\n\n // target[$track] = function (changeTree, index: number, operation: OPERATION = OPERATION.ADD) {\n // changeTree.change(index, operation, encodeSchemaOperation);\n // };\n\n // target[$encoder] = encodeSchemaOperation;\n // target[$decoder] = decodeSchemaOperation;\n\n // if (!target.prototype.toJSON) { target.prototype.toJSON = Schema.prototype.toJSON; }\n\n let index = 0;\n for (const field in fields) {\n const type = fields[field];\n\n // FIXME: this code is duplicated from @type() annotation\n const complexTypeKlass = (Array.isArray(type))\n ? getType(\"array\")\n : (typeof(Object.keys(type)[0]) === \"string\") && getType(Object.keys(type)[0]);\n\n Metadata.addField(\n metadata,\n index,\n field,\n type,\n getPropertyDescriptor(`_${field}`, index, type, complexTypeKlass, metadata, field)\n );\n\n index++;\n }\n },\n\n isDeprecated(metadata: any, field: string) {\n return metadata[field].deprecated === true;\n },\n\n isValidInstance(klass: any) {\n return (\n klass.constructor[Symbol.metadata] &&\n Object.prototype.hasOwnProperty.call(klass.constructor[Symbol.metadata], -1) as boolean\n );\n },\n\n getFields(klass: any) {\n const metadata = klass[Symbol.metadata];\n const fields = {};\n for (let i = 0; i <= metadata[-1]; i++) {\n fields[metadata[i]] = metadata[metadata[i]].type;\n }\n return fields;\n }\n}"]}
1
+ {"version":3,"file":"Metadata.js","sourceRoot":"","sources":["../src/Metadata.ts"],"names":[],"mappings":"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","sourcesContent":["import { getPropertyDescriptor, type DefinitionType } from \"./annotations\";\nimport { getType } from \"./types/registry\";\nimport { $descriptors } from \"./types/symbols\";\n\nexport type MetadataField = {\n type: DefinitionType,\n name: string,\n index: number,\n tag?: number,\n unreliable?: boolean,\n deprecated?: boolean,\n};\n\nexport type Metadata =\n { [-1]: number; } & // number of fields\n { [-2]: number[]; } & // all field indexes with \"view\" tag\n { [-3]: {[tag: number]: number[]}; } & // field indexes by \"view\" tag\n { [-4]: number[]; } & // all field indexes containing Ref types (Schema, ArraySchema, MapSchema, etc)\n { [field: number]: MetadataField; } & // index => field name\n { [field: string]: number; } & // field name => field metadata\n { [$descriptors]: { [field: string]: PropertyDescriptor } } // property descriptors\n\nexport const Metadata = {\n\n addField(metadata: any, index: number, name: string, type: DefinitionType, descriptor?: PropertyDescriptor) {\n if (index > 64) {\n throw new Error(`Can't define field '${name}'.\\nSchema instances may only have up to 64 fields.`);\n }\n\n metadata[index] = Object.assign(\n metadata[index] || {}, // avoid overwriting previous field metadata (@owned / @deprecated)\n {\n type: (Array.isArray(type))\n ? { array: type[0] }\n : type,\n index,\n name,\n }\n );\n\n // create \"descriptors\" map\n metadata[$descriptors] ??= {};\n\n if (descriptor) {\n // for encoder\n metadata[$descriptors][name] = descriptor;\n metadata[$descriptors][`_${name}`] = {\n value: undefined,\n writable: true,\n enumerable: false,\n configurable: true,\n };\n } else {\n // for decoder\n metadata[$descriptors][name] = {\n value: undefined,\n writable: true,\n enumerable: true,\n configurable: true,\n };\n }\n\n // map -1 as last field index\n Object.defineProperty(metadata, -1, {\n value: index,\n enumerable: false,\n configurable: true\n });\n\n // map field name => index (non enumerable)\n Object.defineProperty(metadata, name, {\n value: index,\n enumerable: false,\n configurable: true,\n });\n\n // if child Ref/complex type, add to -4\n if (typeof (metadata[index].type) !== \"string\") {\n if (metadata[-4] === undefined) {\n Object.defineProperty(metadata, -4, {\n value: [],\n enumerable: false,\n configurable: true,\n });\n }\n metadata[-4].push(index);\n }\n },\n\n setTag(metadata: Metadata, fieldName: string, tag: number) {\n const index = metadata[fieldName];\n const field = metadata[index];\n\n // add 'tag' to the field\n field.tag = tag;\n\n if (!metadata[-2]) {\n // -2: all field indexes with \"view\" tag\n Object.defineProperty(metadata, -2, {\n value: [],\n enumerable: false,\n configurable: true\n });\n\n // -3: field indexes by \"view\" tag\n Object.defineProperty(metadata, -3, {\n value: {},\n enumerable: false,\n configurable: true\n });\n }\n\n metadata[-2].push(index);\n\n if (!metadata[-3][tag]) {\n metadata[-3][tag] = [];\n }\n\n metadata[-3][tag].push(index);\n },\n\n setFields(target: any, fields: { [field: string]: DefinitionType }) {\n const metadata = (target.prototype.constructor[Symbol.metadata] ??= {});\n\n let index = 0;\n for (const field in fields) {\n const type = fields[field];\n\n // FIXME: this code is duplicated from @type() annotation\n const complexTypeKlass = (Array.isArray(type))\n ? getType(\"array\")\n : (typeof(Object.keys(type)[0]) === \"string\") && getType(Object.keys(type)[0]);\n\n Metadata.addField(\n metadata,\n index,\n field,\n type,\n getPropertyDescriptor(`_${field}`, index, type, complexTypeKlass)\n );\n\n index++;\n }\n },\n\n isDeprecated(metadata: any, field: string) {\n return metadata[field].deprecated === true;\n },\n\n init(klass: any) {\n //\n // Used only to initialize an empty Schema (Encoder#constructor)\n // TODO: remove/refactor this...\n //\n const metadata = {};\n klass[Symbol.metadata] = metadata;\n Object.defineProperty(metadata, -1, {\n value: 0,\n enumerable: false,\n configurable: true,\n });\n },\n\n initialize(constructor: any, parentMetadata?: Metadata) {\n let metadata: Metadata = constructor[Symbol.metadata] ?? Object.create(null);\n\n // make sure inherited classes have their own metadata object.\n if (constructor[Symbol.metadata] === parentMetadata) {\n metadata = Object.create(null);\n\n if (parentMetadata) {\n // assign parent metadata to current\n Object.assign(metadata, parentMetadata);\n\n for (let i = 0; i <= parentMetadata[-1]; i++) {\n const fieldName = parentMetadata[i].name;\n Object.defineProperty(metadata, fieldName, {\n value: parentMetadata[fieldName],\n enumerable: false,\n configurable: true,\n });\n }\n\n Object.defineProperty(metadata, -1, {\n value: parentMetadata[-1],\n enumerable: false,\n configurable: true,\n writable: true,\n });\n }\n }\n\n constructor[Symbol.metadata] = metadata;\n\n return metadata;\n },\n\n isValidInstance(klass: any) {\n return (\n klass.constructor[Symbol.metadata] &&\n Object.prototype.hasOwnProperty.call(klass.constructor[Symbol.metadata], -1) as boolean\n );\n },\n\n getFields(klass: any) {\n const metadata: Metadata = klass[Symbol.metadata];\n const fields = {};\n for (let i = 0; i <= metadata[-1]; i++) {\n fields[metadata[i].name] = metadata[i].type;\n }\n return fields;\n }\n}"]}
@@ -1,5 +1,4 @@
1
- /// <reference types="node" />
2
- import { TypeContext } from "./annotations";
1
+ import { TypeContext } from "./types/TypeContext";
3
2
  import { ArraySchema } from "./types/custom/ArraySchema";
4
3
  import { Iterator } from "./encoding/decode";
5
4
  import { Schema } from "./Schema";
@@ -18,6 +17,6 @@ export declare class ReflectionType extends Schema {
18
17
  }
19
18
  export declare class Reflection extends Schema {
20
19
  types: ArraySchema<ReflectionType>;
21
- static encode(instance: Schema, context?: TypeContext): Buffer;
20
+ static encode(instance: Schema, context?: TypeContext, it?: Iterator): Buffer;
22
21
  static decode<T extends Schema = Schema>(bytes: Buffer, it?: Iterator): T;
23
22
  }
package/lib/Reflection.js CHANGED
@@ -8,6 +8,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.Reflection = exports.ReflectionType = exports.ReflectionField = void 0;
10
10
  const annotations_1 = require("./annotations");
11
+ const TypeContext_1 = require("./types/TypeContext");
11
12
  const Metadata_1 = require("./Metadata");
12
13
  const ArraySchema_1 = require("./types/custom/ArraySchema");
13
14
  const Encoder_1 = require("./encoder/Encoder");
@@ -49,14 +50,14 @@ class Reflection extends Schema_1.Schema {
49
50
  super(...arguments);
50
51
  this.types = new ArraySchema_1.ArraySchema();
51
52
  }
52
- static encode(instance, context) {
53
- if (!context) {
54
- context = new annotations_1.TypeContext(instance.constructor);
55
- }
53
+ static encode(instance, context, it = { offset: 0 }) {
54
+ context ??= new TypeContext_1.TypeContext(instance.constructor);
56
55
  const reflection = new Reflection();
57
56
  const encoder = new Encoder_1.Encoder(reflection);
58
57
  const buildType = (currentType, metadata) => {
59
- for (const fieldName in metadata) {
58
+ for (const fieldIndex in metadata) {
59
+ const index = Number(fieldIndex);
60
+ const fieldName = metadata[index].name;
60
61
  // skip fields from parent classes
61
62
  if (!Object.prototype.hasOwnProperty.call(metadata, fieldName)) {
62
63
  continue;
@@ -64,7 +65,7 @@ class Reflection extends Schema_1.Schema {
64
65
  const field = new ReflectionField();
65
66
  field.name = fieldName;
66
67
  let fieldType;
67
- const type = metadata[fieldName].type;
68
+ const type = metadata[index].type;
68
69
  if (typeof (type) === "string") {
69
70
  fieldType = type;
70
71
  }
@@ -106,7 +107,6 @@ class Reflection extends Schema_1.Schema {
106
107
  }
107
108
  buildType(type, klass[Symbol.metadata]);
108
109
  }
109
- const it = { offset: 0 };
110
110
  const buf = encoder.encodeAll(it);
111
111
  return Buffer.from(buf, 0, it.offset);
112
112
  }
@@ -114,53 +114,49 @@ class Reflection extends Schema_1.Schema {
114
114
  const reflection = new Reflection();
115
115
  const reflectionDecoder = new Decoder_1.Decoder(reflection);
116
116
  reflectionDecoder.decode(bytes, it);
117
- const context = new annotations_1.TypeContext();
118
- const schemaTypes = reflection.types.reduce((types, reflectionType) => {
119
- const parentKlass = types[reflectionType.extendsId] || Schema_1.Schema;
120
- const schema = class _ extends parentKlass {
117
+ const typeContext = new TypeContext_1.TypeContext();
118
+ // 1st pass, initialize metadata + inheritance
119
+ reflection.types.forEach((reflectionType) => {
120
+ const parentClass = typeContext.get(reflectionType.extendsId) ?? Schema_1.Schema;
121
+ const schema = class _ extends parentClass {
121
122
  };
122
- // const _metadata = Object.create(_classSuper[Symbol.metadata] ?? null);
123
- const _metadata = parentKlass && parentKlass[Symbol.metadata] || Object.create(null);
124
- Object.defineProperty(schema, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
123
+ const parentMetadata = parentClass[Symbol.metadata];
125
124
  // register for inheritance support
126
- annotations_1.TypeContext.register(schema);
127
- const typeid = reflectionType.id;
128
- types[typeid] = schema;
129
- context.add(schema, typeid);
130
- return types;
125
+ TypeContext_1.TypeContext.register(schema);
126
+ // for inheritance support
127
+ Metadata_1.Metadata.initialize(schema, parentMetadata);
128
+ typeContext.add(schema, reflectionType.id);
131
129
  }, {});
130
+ // 2nd pass, set fields
132
131
  reflection.types.forEach((reflectionType) => {
133
- const schemaType = schemaTypes[reflectionType.id];
132
+ const schemaType = typeContext.get(reflectionType.id);
134
133
  const metadata = schemaType[Symbol.metadata];
135
- const parentKlass = reflection.types[reflectionType.extendsId];
136
- const parentFieldIndex = parentKlass && parentKlass.fields.length || 0;
134
+ const parentFieldIndex = 0;
137
135
  reflectionType.fields.forEach((field, i) => {
138
136
  const fieldIndex = parentFieldIndex + i;
139
137
  if (field.referencedType !== undefined) {
140
138
  let fieldType = field.type;
141
- let refType = schemaTypes[field.referencedType];
139
+ let refType = typeContext.get(field.referencedType);
142
140
  // map or array of primitive type (-1)
143
141
  if (!refType) {
144
142
  const typeInfo = field.type.split(":");
145
143
  fieldType = typeInfo[0];
146
- refType = typeInfo[1];
144
+ refType = typeInfo[1]; // string
147
145
  }
148
146
  if (fieldType === "ref") {
149
- // type(refType)(schemaType.prototype, field.name);
150
147
  Metadata_1.Metadata.addField(metadata, fieldIndex, field.name, refType);
151
148
  }
152
149
  else {
153
- // type({ [fieldType]: refType } as DefinitionType)(schemaType.prototype, field.name);
154
150
  Metadata_1.Metadata.addField(metadata, fieldIndex, field.name, { [fieldType]: refType });
155
151
  }
156
152
  }
157
153
  else {
158
- // type(field.type as PrimitiveType)(schemaType.prototype, field.name);
159
154
  Metadata_1.Metadata.addField(metadata, fieldIndex, field.name, field.type);
160
155
  }
161
156
  });
162
157
  });
163
- return new (schemaTypes[0])();
158
+ // @ts-ignore
159
+ return new (typeContext.get(0))();
164
160
  }
165
161
  }
166
162
  exports.Reflection = Reflection;
@@ -1 +1 @@
1
- {"version":3,"file":"Reflection.js","sourceRoot":"","sources":["../src/Reflection.ts"],"names":[],"mappings":"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","sourcesContent":["import { type, PrimitiveType, DefinitionType, TypeContext } from \"./annotations\";\nimport { Metadata } from \"./Metadata\";\nimport { ArraySchema } from \"./types/custom/ArraySchema\";\nimport { Iterator } from \"./encoding/decode\";\nimport { Encoder } from \"./encoder/Encoder\";\nimport { Decoder } from \"./decoder/Decoder\";\nimport { Schema } from \"./Schema\";\n\n/**\n * Reflection\n */\nexport class ReflectionField extends Schema {\n @type(\"string\") name: string;\n @type(\"string\") type: string;\n @type(\"number\") referencedType: number;\n}\n\nexport class ReflectionType extends Schema {\n @type(\"number\") id: number;\n @type(\"number\") extendsId: number;\n @type([ ReflectionField ]) fields = new ArraySchema<ReflectionField>();\n}\n\nexport class Reflection extends Schema {\n @type([ ReflectionType ]) types: ArraySchema<ReflectionType> = new ArraySchema<ReflectionType>();\n\n static encode (instance: Schema, context?: TypeContext) {\n if (!context) {\n context = new TypeContext(instance.constructor as typeof Schema);\n }\n\n const reflection = new Reflection();\n const encoder = new Encoder(reflection);\n\n const buildType = (currentType: ReflectionType, metadata: Metadata) => {\n for (const fieldName in metadata) {\n // skip fields from parent classes\n if (!Object.prototype.hasOwnProperty.call(metadata, fieldName)) {\n continue;\n }\n\n const field = new ReflectionField();\n field.name = fieldName;\n\n let fieldType: string;\n\n const type = metadata[fieldName].type;\n\n if (typeof (type) === \"string\") {\n fieldType = type;\n\n } else {\n let childTypeSchema: typeof Schema;\n\n //\n // TODO: refactor below.\n //\n if (Schema.is(type)) {\n fieldType = \"ref\";\n childTypeSchema = type as typeof Schema;\n\n } else {\n fieldType = Object.keys(type)[0];\n\n if (typeof(type[fieldType]) === \"string\") {\n fieldType += \":\" + type[fieldType]; // array:string\n\n } else {\n childTypeSchema = type[fieldType];\n }\n }\n\n field.referencedType = (childTypeSchema)\n ? context.getTypeId(childTypeSchema)\n : -1;\n }\n\n field.type = fieldType;\n currentType.fields.push(field);\n }\n\n reflection.types.push(currentType);\n }\n\n for (let typeid in context.types) {\n const klass = context.types[typeid];\n const type = new ReflectionType();\n type.id = Number(typeid);\n\n // support inheritance\n const inheritFrom = Object.getPrototypeOf(klass);\n if (inheritFrom !== Schema) {\n type.extendsId = context.schemas.get(inheritFrom);\n }\n\n buildType(type, klass[Symbol.metadata]);\n }\n\n const it = { offset: 0 };\n const buf = encoder.encodeAll(it);\n return Buffer.from(buf, 0, it.offset);\n }\n\n static decode<T extends Schema = Schema>(bytes: Buffer, it?: Iterator): T {\n const reflection = new Reflection();\n\n const reflectionDecoder = new Decoder(reflection);\n reflectionDecoder.decode(bytes, it);\n\n const context = new TypeContext();\n\n const schemaTypes = reflection.types.reduce((types, reflectionType) => {\n const parentKlass: typeof Schema = types[reflectionType.extendsId] || Schema;\n const schema: typeof Schema = class _ extends parentKlass {};\n\n // const _metadata = Object.create(_classSuper[Symbol.metadata] ?? null);\n const _metadata = parentKlass && parentKlass[Symbol.metadata] || Object.create(null);\n Object.defineProperty(schema, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata })\n\n // register for inheritance support\n TypeContext.register(schema);\n\n const typeid = reflectionType.id;\n types[typeid] = schema\n context.add(schema, typeid);\n return types;\n }, {});\n\n reflection.types.forEach((reflectionType) => {\n const schemaType = schemaTypes[reflectionType.id];\n const metadata = schemaType[Symbol.metadata];\n\n const parentKlass = reflection.types[reflectionType.extendsId];\n const parentFieldIndex = parentKlass && parentKlass.fields.length || 0;\n\n reflectionType.fields.forEach((field, i) => {\n const fieldIndex = parentFieldIndex + i;\n\n if (field.referencedType !== undefined) {\n let fieldType = field.type;\n let refType = schemaTypes[field.referencedType];\n\n // map or array of primitive type (-1)\n if (!refType) {\n const typeInfo = field.type.split(\":\");\n fieldType = typeInfo[0];\n refType = typeInfo[1];\n }\n\n if (fieldType === \"ref\") {\n // type(refType)(schemaType.prototype, field.name);\n Metadata.addField(metadata, fieldIndex, field.name, refType);\n\n } else {\n // type({ [fieldType]: refType } as DefinitionType)(schemaType.prototype, field.name);\n Metadata.addField(metadata, fieldIndex, field.name, { [fieldType]: refType } as DefinitionType);\n }\n\n } else {\n // type(field.type as PrimitiveType)(schemaType.prototype, field.name);\n Metadata.addField(metadata, fieldIndex, field.name, field.type as PrimitiveType);\n }\n });\n });\n\n return new (schemaTypes[0])();\n }\n}\n"]}
1
+ {"version":3,"file":"Reflection.js","sourceRoot":"","sources":["../src/Reflection.ts"],"names":[],"mappings":"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","sourcesContent":["import { type, PrimitiveType, DefinitionType } from \"./annotations\";\nimport { TypeContext } from \"./types/TypeContext\";\nimport { Metadata } from \"./Metadata\";\nimport { ArraySchema } from \"./types/custom/ArraySchema\";\nimport { Iterator } from \"./encoding/decode\";\nimport { Encoder } from \"./encoder/Encoder\";\nimport { Decoder } from \"./decoder/Decoder\";\nimport { Schema } from \"./Schema\";\n\n/**\n * Reflection\n */\nexport class ReflectionField extends Schema {\n @type(\"string\") name: string;\n @type(\"string\") type: string;\n @type(\"number\") referencedType: number;\n}\n\nexport class ReflectionType extends Schema {\n @type(\"number\") id: number;\n @type(\"number\") extendsId: number;\n @type([ ReflectionField ]) fields = new ArraySchema<ReflectionField>();\n}\n\nexport class Reflection extends Schema {\n @type([ ReflectionType ]) types: ArraySchema<ReflectionType> = new ArraySchema<ReflectionType>();\n\n static encode(instance: Schema, context?: TypeContext, it: Iterator = { offset: 0 }) {\n context ??= new TypeContext(instance.constructor as typeof Schema);\n\n const reflection = new Reflection();\n const encoder = new Encoder(reflection);\n\n const buildType = (currentType: ReflectionType, metadata: Metadata) => {\n for (const fieldIndex in metadata) {\n const index = Number(fieldIndex);\n const fieldName = metadata[index].name;\n\n // skip fields from parent classes\n if (!Object.prototype.hasOwnProperty.call(metadata, fieldName)) {\n continue;\n }\n\n const field = new ReflectionField();\n field.name = fieldName;\n\n let fieldType: string;\n\n const type = metadata[index].type;\n\n if (typeof (type) === \"string\") {\n fieldType = type;\n\n } else {\n let childTypeSchema: typeof Schema;\n\n //\n // TODO: refactor below.\n //\n if (Schema.is(type)) {\n fieldType = \"ref\";\n childTypeSchema = type as typeof Schema;\n\n } else {\n fieldType = Object.keys(type)[0];\n\n if (typeof(type[fieldType]) === \"string\") {\n fieldType += \":\" + type[fieldType]; // array:string\n\n } else {\n childTypeSchema = type[fieldType];\n }\n }\n\n field.referencedType = (childTypeSchema)\n ? context.getTypeId(childTypeSchema)\n : -1;\n }\n\n field.type = fieldType;\n currentType.fields.push(field);\n }\n\n reflection.types.push(currentType);\n }\n\n for (let typeid in context.types) {\n const klass = context.types[typeid];\n const type = new ReflectionType();\n type.id = Number(typeid);\n\n // support inheritance\n const inheritFrom = Object.getPrototypeOf(klass);\n if (inheritFrom !== Schema) {\n type.extendsId = context.schemas.get(inheritFrom);\n }\n\n buildType(type, klass[Symbol.metadata]);\n }\n\n const buf = encoder.encodeAll(it);\n return Buffer.from(buf, 0, it.offset);\n }\n\n static decode<T extends Schema = Schema>(bytes: Buffer, it?: Iterator): T {\n const reflection = new Reflection();\n\n const reflectionDecoder = new Decoder(reflection);\n reflectionDecoder.decode(bytes, it);\n\n const typeContext = new TypeContext();\n\n // 1st pass, initialize metadata + inheritance\n reflection.types.forEach((reflectionType) => {\n const parentClass: typeof Schema = typeContext.get(reflectionType.extendsId) ?? Schema;\n const schema: typeof Schema = class _ extends parentClass {};\n\n const parentMetadata = parentClass[Symbol.metadata];\n\n // register for inheritance support\n TypeContext.register(schema);\n\n // for inheritance support\n Metadata.initialize(schema, parentMetadata);\n\n typeContext.add(schema, reflectionType.id);\n }, {});\n\n // 2nd pass, set fields\n reflection.types.forEach((reflectionType) => {\n const schemaType = typeContext.get(reflectionType.id);\n const metadata = schemaType[Symbol.metadata];\n\n const parentFieldIndex = 0;\n\n reflectionType.fields.forEach((field, i) => {\n const fieldIndex = parentFieldIndex + i;\n\n if (field.referencedType !== undefined) {\n let fieldType = field.type;\n let refType: PrimitiveType = typeContext.get(field.referencedType);\n\n // map or array of primitive type (-1)\n if (!refType) {\n const typeInfo = field.type.split(\":\");\n fieldType = typeInfo[0];\n refType = typeInfo[1] as PrimitiveType; // string\n }\n\n if (fieldType === \"ref\") {\n Metadata.addField(metadata, fieldIndex, field.name, refType);\n\n } else {\n Metadata.addField(metadata, fieldIndex, field.name, { [fieldType]: refType } as DefinitionType);\n }\n\n } else {\n Metadata.addField(metadata, fieldIndex, field.name, field.type as PrimitiveType);\n }\n });\n });\n\n // @ts-ignore\n return new (typeContext.get(0))();\n }\n}\n"]}
package/lib/Schema.d.ts CHANGED
@@ -42,7 +42,7 @@ export declare abstract class Schema {
42
42
  */
43
43
  setDirty<K extends NonFunctionPropNames<this>>(property: K | number, operation?: OPERATION): void;
44
44
  clone(): this;
45
- toJSON(): ToJSON<this>;
45
+ toJSON(): ToJSON<typeof this>;
46
46
  discardAllChanges(): void;
47
47
  protected [$getByIndex](index: number): any;
48
48
  protected [$deleteByIndex](index: number): void;
@@ -56,5 +56,5 @@ export declare abstract class Schema {
56
56
  * @returns
57
57
  */
58
58
  static debugChanges(instance: Ref, isEncodeAll?: boolean): string;
59
- static debugChangesDeep(ref: Ref): string;
59
+ static debugChangesDeep(ref: Ref, changeSetName?: "changes" | "allChanges" | "allFilteredChanges" | "filteredChanges"): string;
60
60
  }
package/lib/Schema.js CHANGED
@@ -25,35 +25,7 @@ class Schema {
25
25
  enumerable: false,
26
26
  writable: true
27
27
  });
28
- const metadata = instance.constructor[Symbol.metadata];
29
- // Define property descriptors
30
- for (const field in metadata) {
31
- if (metadata[field].descriptor) {
32
- // for encoder
33
- Object.defineProperty(instance, `_${field}`, {
34
- value: undefined,
35
- writable: true,
36
- enumerable: false,
37
- configurable: true,
38
- });
39
- Object.defineProperty(instance, field, metadata[field].descriptor);
40
- }
41
- else {
42
- // for decoder
43
- Object.defineProperty(instance, field, {
44
- value: undefined,
45
- writable: true,
46
- enumerable: true,
47
- configurable: true,
48
- });
49
- }
50
- // Object.defineProperty(instance, field, {
51
- // ...instance.constructor[Symbol.metadata][field].descriptor
52
- // });
53
- // if (args[0]?.hasOwnProperty(field)) {
54
- // instance[field] = args[0][field];
55
- // }
56
- }
28
+ Object.defineProperties(instance, instance.constructor[Symbol.metadata]?.[symbols_1.$descriptors] || {});
57
29
  }
58
30
  static is(type) {
59
31
  return typeof (type[Symbol.metadata]) === "object";
@@ -77,7 +49,7 @@ class Schema {
77
49
  */
78
50
  static [symbols_1.$filter](ref, index, view) {
79
51
  const metadata = ref.constructor[Symbol.metadata];
80
- const tag = metadata[metadata[index]].tag;
52
+ const tag = metadata[index]?.tag;
81
53
  if (view === undefined) {
82
54
  // shared pass/encode: encode if doesn't have a tag
83
55
  return tag === undefined;
@@ -98,12 +70,21 @@ class Schema {
98
70
  }
99
71
  // allow inherited classes to have a constructor
100
72
  constructor(...args) {
101
- Schema.initialize(this);
73
+ //
74
+ // inline
75
+ // Schema.initialize(this);
76
+ //
77
+ Object.defineProperty(this, symbols_1.$changes, {
78
+ value: new ChangeTree_1.ChangeTree(this),
79
+ enumerable: false,
80
+ writable: true
81
+ });
82
+ Object.defineProperties(this, this.constructor[Symbol.metadata]?.[symbols_1.$descriptors] || {});
102
83
  //
103
84
  // Assign initial values
104
85
  //
105
86
  if (args[0]) {
106
- this.assign(args[0]);
87
+ Object.assign(this, args[0]);
107
88
  }
108
89
  }
109
90
  assign(props) {
@@ -117,7 +98,8 @@ class Schema {
117
98
  * @param operation OPERATION to perform (detected automatically)
118
99
  */
119
100
  setDirty(property, operation) {
120
- this[symbols_1.$changes].change(this.constructor[Symbol.metadata][property].index, operation);
101
+ const metadata = this.constructor[Symbol.metadata];
102
+ this[symbols_1.$changes].change(metadata[metadata[property]].index, operation);
121
103
  }
122
104
  clone() {
123
105
  const cloned = new (this.constructor);
@@ -126,7 +108,9 @@ class Schema {
126
108
  // TODO: clone all properties, not only annotated ones
127
109
  //
128
110
  // for (const field in this) {
129
- for (const field in metadata) {
111
+ for (const fieldIndex in metadata) {
112
+ // const field = metadata[metadata[fieldIndex]].name;
113
+ const field = metadata[fieldIndex].name;
130
114
  if (typeof (this[field]) === "object" &&
131
115
  typeof (this[field]?.clone) === "function") {
132
116
  // deep clone
@@ -140,10 +124,11 @@ class Schema {
140
124
  return cloned;
141
125
  }
142
126
  toJSON() {
143
- const metadata = this.constructor[Symbol.metadata];
144
127
  const obj = {};
145
- for (const fieldName in metadata) {
146
- const field = metadata[fieldName];
128
+ const metadata = this.constructor[Symbol.metadata];
129
+ for (const index in metadata) {
130
+ const field = metadata[index];
131
+ const fieldName = field.name;
147
132
  if (!field.deprecated && this[fieldName] !== null && typeof (this[fieldName]) !== "undefined") {
148
133
  obj[fieldName] = (typeof (this[fieldName]['toJSON']) === "function")
149
134
  ? this[fieldName]['toJSON']()
@@ -156,10 +141,12 @@ class Schema {
156
141
  this[symbols_1.$changes].discardAll();
157
142
  }
158
143
  [symbols_1.$getByIndex](index) {
159
- return this[this.constructor[Symbol.metadata][index]];
144
+ const metadata = this.constructor[Symbol.metadata];
145
+ return this[metadata[index].name];
160
146
  }
161
147
  [symbols_1.$deleteByIndex](index) {
162
- this[this.constructor[Symbol.metadata][index]] = undefined;
148
+ const metadata = this.constructor[Symbol.metadata];
149
+ this[metadata[index].name] = undefined;
163
150
  }
164
151
  static debugRefIds(instance, jsonContents = true, level = 0) {
165
152
  const ref = instance;
@@ -201,13 +188,13 @@ class Schema {
201
188
  }
202
189
  return output;
203
190
  }
204
- static debugChangesDeep(ref) {
191
+ static debugChangesDeep(ref, changeSetName = "changes") {
205
192
  let output = "";
206
193
  const rootChangeTree = ref[symbols_1.$changes];
207
194
  const changeTrees = new Map();
208
195
  let totalInstances = 0;
209
196
  let totalOperations = 0;
210
- for (const [changeTree, changes] of (rootChangeTree.root.changes.entries())) {
197
+ for (const [changeTree, changes] of (rootChangeTree.root[changeSetName].entries())) {
211
198
  let includeChangeTree = false;
212
199
  let parentChangeTrees = [];
213
200
  let parentChangeTree = changeTree.parent?.[symbols_1.$changes];