@colyseus/schema 3.0.0-alpha.37 → 3.0.0-alpha.38

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.
package/src/Metadata.ts CHANGED
@@ -41,7 +41,11 @@ export const Metadata = {
41
41
  );
42
42
 
43
43
  // create "descriptors" map
44
- metadata[$descriptors] ??= {};
44
+ Object.defineProperty(metadata, $descriptors, {
45
+ value: metadata[$descriptors] || {},
46
+ enumerable: false,
47
+ configurable: true,
48
+ });
45
49
 
46
50
  if (descriptor) {
47
51
  // for encoder
@@ -128,7 +132,7 @@ export const Metadata = {
128
132
 
129
133
  const parentClass = Object.getPrototypeOf(constructor);
130
134
  const parentMetadata = parentClass && parentClass[Symbol.metadata];
131
- const metadata = Metadata.initialize(constructor, parentMetadata);
135
+ const metadata = Metadata.initialize(constructor);
132
136
 
133
137
  // Use Schema's methods if not defined in the class
134
138
  if (!constructor[$track]) { constructor[$track] = Schema[$track]; }
@@ -185,28 +189,71 @@ export const Metadata = {
185
189
  });
186
190
  },
187
191
 
188
- initialize(constructor: any, parentMetadata?: Metadata) {
192
+ initialize(constructor: any) {
193
+ const parentClass = Object.getPrototypeOf(constructor);
194
+ const parentMetadata: Metadata = parentClass[Symbol.metadata];
195
+
189
196
  let metadata: Metadata = constructor[Symbol.metadata] ?? Object.create(null);
190
197
 
191
198
  // make sure inherited classes have their own metadata object.
192
- if (constructor[Symbol.metadata] === parentMetadata) {
199
+ if (parentClass !== Schema && metadata === parentMetadata) {
193
200
  metadata = Object.create(null);
194
201
 
195
202
  if (parentMetadata) {
203
+ //
196
204
  // assign parent metadata to current
197
- Object.assign(metadata, parentMetadata);
205
+ //
206
+ Object.setPrototypeOf(metadata, parentMetadata);
207
+
208
+ // Object.keys(parentMetadata).forEach((fieldIndex) => {
209
+ // const index = Number(fieldIndex);
210
+ // const field = parentMetadata[index];
211
+ // metadata[index] = field;
212
+
213
+ // // Object.defineProperty(metadata, field.name, {
214
+ // // value: index,
215
+ // // enumerable: false,
216
+ // // configurable: true,
217
+ // // });
218
+ // });
219
+
220
+ // $numFields
221
+ Object.defineProperty(metadata, $numFields, {
222
+ value: parentMetadata[$numFields],
223
+ enumerable: false,
224
+ configurable: true,
225
+ writable: true,
226
+ });
198
227
 
199
- for (let i = 0; i <= parentMetadata[$numFields]; i++) {
200
- const fieldName = parentMetadata[i].name;
201
- Object.defineProperty(metadata, fieldName, {
202
- value: parentMetadata[fieldName],
228
+ // $viewFieldIndexes / $fieldIndexesByViewTag
229
+ if (parentMetadata[$viewFieldIndexes] !== undefined) {
230
+ Object.defineProperty(metadata, $viewFieldIndexes, {
231
+ value: [...parentMetadata[$viewFieldIndexes]],
203
232
  enumerable: false,
204
233
  configurable: true,
234
+ writable: true,
235
+ });
236
+ Object.defineProperty(metadata, $fieldIndexesByViewTag, {
237
+ value: { ...parentMetadata[$fieldIndexesByViewTag] },
238
+ enumerable: false,
239
+ configurable: true,
240
+ writable: true,
205
241
  });
206
242
  }
207
243
 
208
- Object.defineProperty(metadata, $numFields, {
209
- value: parentMetadata[$numFields],
244
+ // $refTypeFieldIndexes
245
+ if (parentMetadata[$refTypeFieldIndexes] !== undefined) {
246
+ Object.defineProperty(metadata, $refTypeFieldIndexes, {
247
+ value: [...parentMetadata[$refTypeFieldIndexes]],
248
+ enumerable: false,
249
+ configurable: true,
250
+ writable: true,
251
+ });
252
+ }
253
+
254
+ // $descriptors
255
+ Object.defineProperty(metadata, $descriptors, {
256
+ value: { ...parentMetadata[$descriptors] },
210
257
  enumerable: false,
211
258
  configurable: true,
212
259
  writable: true,
package/src/Reflection.ts CHANGED
@@ -6,6 +6,7 @@ import { Iterator } from "./encoding/decode";
6
6
  import { Encoder } from "./encoder/Encoder";
7
7
  import { Decoder } from "./decoder/Decoder";
8
8
  import { Schema } from "./Schema";
9
+ import { $numFields } from "./types/symbols";
9
10
 
10
11
  /**
11
12
  * Reflection
@@ -127,24 +128,17 @@ export class Reflection extends Schema {
127
128
  const parentClass: typeof Schema = typeContext.get(reflectionType.extendsId) ?? Schema;
128
129
  const schema: typeof Schema = class _ extends parentClass {};
129
130
 
130
- const parentMetadata = parentClass[Symbol.metadata];
131
-
132
131
  // register for inheritance support
133
132
  TypeContext.register(schema);
134
133
 
135
- // for inheritance support
136
- Metadata.initialize(schema, parentMetadata);
134
+ // // for inheritance support
135
+ // Metadata.initialize(schema);
137
136
 
138
137
  typeContext.add(schema, reflectionType.id);
139
138
  }, {});
140
139
 
141
- // 2nd pass, set fields
142
- reflection.types.forEach((reflectionType) => {
143
- const schemaType = typeContext.get(reflectionType.id);
144
- const metadata = schemaType[Symbol.metadata];
145
-
146
- const parentFieldIndex = 0;
147
-
140
+ // define fields
141
+ const addFields = (metadata: Metadata, reflectionType: ReflectionType, parentFieldIndex: number) => {
148
142
  reflectionType.fields.forEach((field, i) => {
149
143
  const fieldIndex = parentFieldIndex + i;
150
144
 
@@ -170,6 +164,31 @@ export class Reflection extends Schema {
170
164
  Metadata.addField(metadata, fieldIndex, field.name, field.type as PrimitiveType);
171
165
  }
172
166
  });
167
+ };
168
+
169
+ // 2nd pass, set fields
170
+ reflection.types.forEach((reflectionType) => {
171
+ const schema = typeContext.get(reflectionType.id);
172
+
173
+ // for inheritance support
174
+ const metadata = Metadata.initialize(schema);
175
+
176
+ const inheritedTypes: ReflectionType[] = [];
177
+
178
+ let parentType: ReflectionType = reflectionType;
179
+ do {
180
+ inheritedTypes.push(parentType);
181
+ parentType = reflection.types.find((t) => t.id === parentType.extendsId);
182
+ } while (parentType);
183
+
184
+ let parentFieldIndex = 0;
185
+
186
+ inheritedTypes.reverse().forEach((reflectionType) => {
187
+ // add fields from all inherited classes
188
+ // TODO: refactor this to avoid adding fields from parent classes
189
+ addFields(metadata, reflectionType, parentFieldIndex);
190
+ parentFieldIndex += reflectionType.fields.length;
191
+ });
173
192
  });
174
193
 
175
194
  const state: T = new (typeContext.get(0) as unknown as any)();
@@ -286,15 +286,15 @@ export function type (
286
286
  TypeContext.register(constructor);
287
287
 
288
288
  const parentClass = Object.getPrototypeOf(constructor);
289
- const parentMetadata = parentClass && parentClass[Symbol.metadata];
290
- const metadata = Metadata.initialize(constructor, parentMetadata);
289
+ const parentMetadata = parentClass[Symbol.metadata];
290
+ const metadata = Metadata.initialize(constructor);
291
291
 
292
292
  let fieldIndex: number = metadata[field];
293
293
 
294
294
  /**
295
295
  * skip if descriptor already exists for this field (`@deprecated()`)
296
296
  */
297
- if (metadata[fieldIndex]) {
297
+ if (metadata[fieldIndex] !== undefined) {
298
298
  if (metadata[fieldIndex].deprecated) {
299
299
  // do not create accessors for deprecated properties.
300
300
  return;