@colyseus/schema 3.0.0-alpha.37 → 3.0.0-alpha.39
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/build/cjs/index.js +142 -32
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +142 -33
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +142 -32
- package/lib/Metadata.d.ts +3 -2
- package/lib/Metadata.js +57 -15
- package/lib/Metadata.js.map +1 -1
- package/lib/Reflection.d.ts +4 -3
- package/lib/Reflection.js +36 -11
- package/lib/Reflection.js.map +1 -1
- package/lib/Schema.d.ts +2 -2
- package/lib/Schema.js.map +1 -1
- package/lib/annotations.d.ts +29 -12
- package/lib/annotations.js +36 -3
- package/lib/annotations.js.map +1 -1
- package/lib/codegen/parser.js +83 -0
- package/lib/codegen/parser.js.map +1 -1
- package/lib/codegen/types.js +3 -0
- package/lib/codegen/types.js.map +1 -1
- package/lib/decoder/DecodeOperation.js +4 -0
- package/lib/decoder/DecodeOperation.js.map +1 -1
- package/lib/decoder/strategy/StateCallbacks.js.map +1 -1
- package/lib/encoder/EncodeOperation.js +2 -2
- package/lib/encoder/EncodeOperation.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -1
- package/lib/types/HelperTypes.d.ts +34 -2
- package/lib/types/HelperTypes.js.map +1 -1
- package/lib/types/TypeContext.js +9 -1
- package/lib/types/TypeContext.js.map +1 -1
- package/package.json +1 -1
- package/src/Metadata.ts +62 -16
- package/src/Reflection.ts +43 -16
- package/src/Schema.ts +2 -3
- package/src/annotations.ts +68 -18
- package/src/codegen/parser.ts +107 -0
- package/src/codegen/types.ts +1 -0
- package/src/decoder/DecodeOperation.ts +4 -0
- package/src/decoder/strategy/StateCallbacks.ts +1 -1
- package/src/encoder/EncodeOperation.ts +4 -2
- package/src/index.ts +1 -1
- package/src/types/HelperTypes.ts +54 -2
- package/src/types/TypeContext.ts +11 -1
package/build/cjs/index.js
CHANGED
|
@@ -115,7 +115,7 @@ class TypeContext {
|
|
|
115
115
|
// Workaround to allow using an empty Schema (with no `@type()` fields)
|
|
116
116
|
//
|
|
117
117
|
if (schema[Symbol.metadata] === undefined) {
|
|
118
|
-
Metadata.
|
|
118
|
+
Metadata.initialize(schema);
|
|
119
119
|
}
|
|
120
120
|
this.schemas.set(schema, typeid);
|
|
121
121
|
return true;
|
|
@@ -131,6 +131,14 @@ class TypeContext {
|
|
|
131
131
|
TypeContext.inheritedTypes.get(klass)?.forEach((child) => {
|
|
132
132
|
this.discoverTypes(child, parentIndex, parentFieldViewTag);
|
|
133
133
|
});
|
|
134
|
+
// add parent classes
|
|
135
|
+
let parent = klass;
|
|
136
|
+
while ((parent = Object.getPrototypeOf(parent)) &&
|
|
137
|
+
parent !== Schema && // stop at root (Schema)
|
|
138
|
+
parent !== Function.prototype // stop at root (non-Schema)
|
|
139
|
+
) {
|
|
140
|
+
this.discoverTypes(parent);
|
|
141
|
+
}
|
|
134
142
|
const metadata = (klass[Symbol.metadata] ??= {});
|
|
135
143
|
// if any schema/field has filters, mark "context" as having filters.
|
|
136
144
|
if (metadata[$viewFieldIndexes]) {
|
|
@@ -169,6 +177,13 @@ class TypeContext {
|
|
|
169
177
|
}
|
|
170
178
|
}
|
|
171
179
|
|
|
180
|
+
function getNormalizedType(type) {
|
|
181
|
+
return (Array.isArray(type))
|
|
182
|
+
? { array: type[0] }
|
|
183
|
+
: (typeof (type['type']) !== "undefined")
|
|
184
|
+
? type['type']
|
|
185
|
+
: type;
|
|
186
|
+
}
|
|
172
187
|
const Metadata = {
|
|
173
188
|
addField(metadata, index, name, type, descriptor) {
|
|
174
189
|
if (index > 64) {
|
|
@@ -176,14 +191,16 @@ const Metadata = {
|
|
|
176
191
|
}
|
|
177
192
|
metadata[index] = Object.assign(metadata[index] || {}, // avoid overwriting previous field metadata (@owned / @deprecated)
|
|
178
193
|
{
|
|
179
|
-
type: (
|
|
180
|
-
? { array: type[0] }
|
|
181
|
-
: type,
|
|
194
|
+
type: getNormalizedType(type),
|
|
182
195
|
index,
|
|
183
196
|
name,
|
|
184
197
|
});
|
|
185
198
|
// create "descriptors" map
|
|
186
|
-
metadata
|
|
199
|
+
Object.defineProperty(metadata, $descriptors, {
|
|
200
|
+
value: metadata[$descriptors] || {},
|
|
201
|
+
enumerable: false,
|
|
202
|
+
configurable: true,
|
|
203
|
+
});
|
|
187
204
|
if (descriptor) {
|
|
188
205
|
// for encoder
|
|
189
206
|
metadata[$descriptors][name] = descriptor;
|
|
@@ -258,7 +275,7 @@ const Metadata = {
|
|
|
258
275
|
TypeContext.register(constructor);
|
|
259
276
|
const parentClass = Object.getPrototypeOf(constructor);
|
|
260
277
|
const parentMetadata = parentClass && parentClass[Symbol.metadata];
|
|
261
|
-
const metadata = Metadata.initialize(constructor
|
|
278
|
+
const metadata = Metadata.initialize(constructor);
|
|
262
279
|
// Use Schema's methods if not defined in the class
|
|
263
280
|
if (!constructor[$track]) {
|
|
264
281
|
constructor[$track] = Schema[$track];
|
|
@@ -281,11 +298,15 @@ const Metadata = {
|
|
|
281
298
|
fieldIndex++;
|
|
282
299
|
for (const field in fields) {
|
|
283
300
|
const type = fields[field];
|
|
301
|
+
const normalizedType = getNormalizedType(type);
|
|
284
302
|
// FIXME: this code is duplicated from @type() annotation
|
|
285
303
|
const complexTypeKlass = (Array.isArray(type))
|
|
286
304
|
? getType("array")
|
|
287
305
|
: (typeof (Object.keys(type)[0]) === "string") && getType(Object.keys(type)[0]);
|
|
288
|
-
|
|
306
|
+
const childType = (complexTypeKlass)
|
|
307
|
+
? Object.values(type)[0]
|
|
308
|
+
: normalizedType;
|
|
309
|
+
Metadata.addField(metadata, fieldIndex, field, type, getPropertyDescriptor(`_${field}`, fieldIndex, childType, complexTypeKlass));
|
|
289
310
|
fieldIndex++;
|
|
290
311
|
}
|
|
291
312
|
return target;
|
|
@@ -306,24 +327,52 @@ const Metadata = {
|
|
|
306
327
|
configurable: true,
|
|
307
328
|
});
|
|
308
329
|
},
|
|
309
|
-
initialize(constructor
|
|
330
|
+
initialize(constructor) {
|
|
331
|
+
const parentClass = Object.getPrototypeOf(constructor);
|
|
332
|
+
const parentMetadata = parentClass[Symbol.metadata];
|
|
310
333
|
let metadata = constructor[Symbol.metadata] ?? Object.create(null);
|
|
311
334
|
// make sure inherited classes have their own metadata object.
|
|
312
|
-
if (
|
|
335
|
+
if (parentClass !== Schema && metadata === parentMetadata) {
|
|
313
336
|
metadata = Object.create(null);
|
|
314
337
|
if (parentMetadata) {
|
|
338
|
+
//
|
|
315
339
|
// assign parent metadata to current
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
340
|
+
//
|
|
341
|
+
Object.setPrototypeOf(metadata, parentMetadata);
|
|
342
|
+
// $numFields
|
|
343
|
+
Object.defineProperty(metadata, $numFields, {
|
|
344
|
+
value: parentMetadata[$numFields],
|
|
345
|
+
enumerable: false,
|
|
346
|
+
configurable: true,
|
|
347
|
+
writable: true,
|
|
348
|
+
});
|
|
349
|
+
// $viewFieldIndexes / $fieldIndexesByViewTag
|
|
350
|
+
if (parentMetadata[$viewFieldIndexes] !== undefined) {
|
|
351
|
+
Object.defineProperty(metadata, $viewFieldIndexes, {
|
|
352
|
+
value: [...parentMetadata[$viewFieldIndexes]],
|
|
321
353
|
enumerable: false,
|
|
322
354
|
configurable: true,
|
|
355
|
+
writable: true,
|
|
356
|
+
});
|
|
357
|
+
Object.defineProperty(metadata, $fieldIndexesByViewTag, {
|
|
358
|
+
value: { ...parentMetadata[$fieldIndexesByViewTag] },
|
|
359
|
+
enumerable: false,
|
|
360
|
+
configurable: true,
|
|
361
|
+
writable: true,
|
|
323
362
|
});
|
|
324
363
|
}
|
|
325
|
-
|
|
326
|
-
|
|
364
|
+
// $refTypeFieldIndexes
|
|
365
|
+
if (parentMetadata[$refTypeFieldIndexes] !== undefined) {
|
|
366
|
+
Object.defineProperty(metadata, $refTypeFieldIndexes, {
|
|
367
|
+
value: [...parentMetadata[$refTypeFieldIndexes]],
|
|
368
|
+
enumerable: false,
|
|
369
|
+
configurable: true,
|
|
370
|
+
writable: true,
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
// $descriptors
|
|
374
|
+
Object.defineProperty(metadata, $descriptors, {
|
|
375
|
+
value: { ...parentMetadata[$descriptors] },
|
|
327
376
|
enumerable: false,
|
|
328
377
|
configurable: true,
|
|
329
378
|
writable: true,
|
|
@@ -1098,7 +1147,6 @@ const encodeSchemaOperation = function (encoder, bytes, changeTree, index, opera
|
|
|
1098
1147
|
return;
|
|
1099
1148
|
}
|
|
1100
1149
|
const ref = changeTree.ref;
|
|
1101
|
-
// const metadata: Metadata = ref.constructor[Symbol.metadata];
|
|
1102
1150
|
const field = metadata[index];
|
|
1103
1151
|
// TODO: inline this function call small performance gain
|
|
1104
1152
|
encodeValue(encoder, bytes, metadata[index].type, ref[field.name], operation, it);
|
|
@@ -1173,7 +1221,8 @@ const encodeArray = function (encoder, bytes, changeTree, field, operation, it,
|
|
|
1173
1221
|
// encode operation
|
|
1174
1222
|
bytes[it.offset++] = operation & 255;
|
|
1175
1223
|
// custom operations
|
|
1176
|
-
if (operation === exports.OPERATION.CLEAR
|
|
1224
|
+
if (operation === exports.OPERATION.CLEAR ||
|
|
1225
|
+
operation === exports.OPERATION.REVERSE) {
|
|
1177
1226
|
return;
|
|
1178
1227
|
}
|
|
1179
1228
|
// encode index
|
|
@@ -1651,6 +1700,10 @@ const decodeArray = function (decoder, bytes, it, ref, allChanges) {
|
|
|
1651
1700
|
ref.clear();
|
|
1652
1701
|
return;
|
|
1653
1702
|
}
|
|
1703
|
+
else if (operation === exports.OPERATION.REVERSE) {
|
|
1704
|
+
ref.reverse();
|
|
1705
|
+
return;
|
|
1706
|
+
}
|
|
1654
1707
|
else if (operation === exports.OPERATION.DELETE_BY_REFID) {
|
|
1655
1708
|
// TODO: refactor here, try to follow same flow as below
|
|
1656
1709
|
const refId = number(bytes, it);
|
|
@@ -2770,13 +2823,13 @@ function type(type, options) {
|
|
|
2770
2823
|
// for inheritance support
|
|
2771
2824
|
TypeContext.register(constructor);
|
|
2772
2825
|
const parentClass = Object.getPrototypeOf(constructor);
|
|
2773
|
-
const parentMetadata = parentClass
|
|
2774
|
-
const metadata = Metadata.initialize(constructor
|
|
2826
|
+
const parentMetadata = parentClass[Symbol.metadata];
|
|
2827
|
+
const metadata = Metadata.initialize(constructor);
|
|
2775
2828
|
let fieldIndex = metadata[field];
|
|
2776
2829
|
/**
|
|
2777
2830
|
* skip if descriptor already exists for this field (`@deprecated()`)
|
|
2778
2831
|
*/
|
|
2779
|
-
if (metadata[fieldIndex]) {
|
|
2832
|
+
if (metadata[fieldIndex] !== undefined) {
|
|
2780
2833
|
if (metadata[fieldIndex].deprecated) {
|
|
2781
2834
|
// do not create accessors for deprecated properties.
|
|
2782
2835
|
return;
|
|
@@ -2926,6 +2979,37 @@ function defineTypes(target, fields, options) {
|
|
|
2926
2979
|
}
|
|
2927
2980
|
return target;
|
|
2928
2981
|
}
|
|
2982
|
+
function schema(fields, name, inherits = Schema) {
|
|
2983
|
+
const defaultValues = {};
|
|
2984
|
+
const viewTagFields = {};
|
|
2985
|
+
for (let fieldName in fields) {
|
|
2986
|
+
const field = fields[fieldName];
|
|
2987
|
+
if (typeof (field) === "object") {
|
|
2988
|
+
if (field['default'] !== undefined) {
|
|
2989
|
+
defaultValues[fieldName] = field['default'];
|
|
2990
|
+
}
|
|
2991
|
+
if (field['view'] !== undefined) {
|
|
2992
|
+
viewTagFields[fieldName] = (typeof (field['view']) === "boolean")
|
|
2993
|
+
? DEFAULT_VIEW_TAG
|
|
2994
|
+
: field['view'];
|
|
2995
|
+
}
|
|
2996
|
+
}
|
|
2997
|
+
}
|
|
2998
|
+
const klass = Metadata.setFields(class extends inherits {
|
|
2999
|
+
constructor(...args) {
|
|
3000
|
+
args[0] = Object.assign({}, defaultValues, args[0]);
|
|
3001
|
+
super(...args);
|
|
3002
|
+
}
|
|
3003
|
+
}, fields);
|
|
3004
|
+
for (let fieldName in viewTagFields) {
|
|
3005
|
+
view(viewTagFields[fieldName])(klass.prototype, fieldName);
|
|
3006
|
+
}
|
|
3007
|
+
if (name) {
|
|
3008
|
+
Object.defineProperty(klass, "name", { value: name });
|
|
3009
|
+
}
|
|
3010
|
+
klass.extends = (fields, name) => schema(fields, name, klass);
|
|
3011
|
+
return klass;
|
|
3012
|
+
}
|
|
2929
3013
|
|
|
2930
3014
|
function getIndent(level) {
|
|
2931
3015
|
return (new Array(level).fill(0)).map((_, i) => (i === level - 1) ? `└─ ` : ` `).join("");
|
|
@@ -4173,13 +4257,20 @@ class Reflection extends Schema {
|
|
|
4173
4257
|
/**
|
|
4174
4258
|
* Encodes the TypeContext of an Encoder into a buffer.
|
|
4175
4259
|
*
|
|
4176
|
-
* @param
|
|
4260
|
+
* @param encoder Encoder instance
|
|
4177
4261
|
* @param it
|
|
4178
4262
|
* @returns
|
|
4179
4263
|
*/
|
|
4180
|
-
static encode(
|
|
4264
|
+
static encode(encoder, it = { offset: 0 }) {
|
|
4265
|
+
const context = encoder.context;
|
|
4181
4266
|
const reflection = new Reflection();
|
|
4182
4267
|
const reflectionEncoder = new Encoder(reflection);
|
|
4268
|
+
// rootType is usually the first schema passed to the Encoder
|
|
4269
|
+
// (unless it inherits from another schema)
|
|
4270
|
+
const rootType = context.schemas.get(encoder.state.constructor);
|
|
4271
|
+
if (rootType > 0) {
|
|
4272
|
+
reflection.rootType = rootType;
|
|
4273
|
+
}
|
|
4183
4274
|
const buildType = (currentType, metadata) => {
|
|
4184
4275
|
for (const fieldIndex in metadata) {
|
|
4185
4276
|
const index = Number(fieldIndex);
|
|
@@ -4253,18 +4344,14 @@ class Reflection extends Schema {
|
|
|
4253
4344
|
const parentClass = typeContext.get(reflectionType.extendsId) ?? Schema;
|
|
4254
4345
|
const schema = class _ extends parentClass {
|
|
4255
4346
|
};
|
|
4256
|
-
const parentMetadata = parentClass[Symbol.metadata];
|
|
4257
4347
|
// register for inheritance support
|
|
4258
4348
|
TypeContext.register(schema);
|
|
4259
|
-
// for inheritance support
|
|
4260
|
-
Metadata.initialize(schema
|
|
4349
|
+
// // for inheritance support
|
|
4350
|
+
// Metadata.initialize(schema);
|
|
4261
4351
|
typeContext.add(schema, reflectionType.id);
|
|
4262
4352
|
}, {});
|
|
4263
|
-
//
|
|
4264
|
-
|
|
4265
|
-
const schemaType = typeContext.get(reflectionType.id);
|
|
4266
|
-
const metadata = schemaType[Symbol.metadata];
|
|
4267
|
-
const parentFieldIndex = 0;
|
|
4353
|
+
// define fields
|
|
4354
|
+
const addFields = (metadata, reflectionType, parentFieldIndex) => {
|
|
4268
4355
|
reflectionType.fields.forEach((field, i) => {
|
|
4269
4356
|
const fieldIndex = parentFieldIndex + i;
|
|
4270
4357
|
if (field.referencedType !== undefined) {
|
|
@@ -4287,14 +4374,36 @@ class Reflection extends Schema {
|
|
|
4287
4374
|
Metadata.addField(metadata, fieldIndex, field.name, field.type);
|
|
4288
4375
|
}
|
|
4289
4376
|
});
|
|
4377
|
+
};
|
|
4378
|
+
// 2nd pass, set fields
|
|
4379
|
+
reflection.types.forEach((reflectionType) => {
|
|
4380
|
+
const schema = typeContext.get(reflectionType.id);
|
|
4381
|
+
// for inheritance support
|
|
4382
|
+
const metadata = Metadata.initialize(schema);
|
|
4383
|
+
const inheritedTypes = [];
|
|
4384
|
+
let parentType = reflectionType;
|
|
4385
|
+
do {
|
|
4386
|
+
inheritedTypes.push(parentType);
|
|
4387
|
+
parentType = reflection.types.find((t) => t.id === parentType.extendsId);
|
|
4388
|
+
} while (parentType);
|
|
4389
|
+
let parentFieldIndex = 0;
|
|
4390
|
+
inheritedTypes.reverse().forEach((reflectionType) => {
|
|
4391
|
+
// add fields from all inherited classes
|
|
4392
|
+
// TODO: refactor this to avoid adding fields from parent classes
|
|
4393
|
+
addFields(metadata, reflectionType, parentFieldIndex);
|
|
4394
|
+
parentFieldIndex += reflectionType.fields.length;
|
|
4395
|
+
});
|
|
4290
4396
|
});
|
|
4291
|
-
const state = new (typeContext.get(0))();
|
|
4397
|
+
const state = new (typeContext.get(reflection.rootType || 0))();
|
|
4292
4398
|
return new Decoder(state, typeContext);
|
|
4293
4399
|
}
|
|
4294
4400
|
}
|
|
4295
4401
|
__decorate([
|
|
4296
4402
|
type([ReflectionType])
|
|
4297
4403
|
], Reflection.prototype, "types", void 0);
|
|
4404
|
+
__decorate([
|
|
4405
|
+
type("number")
|
|
4406
|
+
], Reflection.prototype, "rootType", void 0);
|
|
4298
4407
|
|
|
4299
4408
|
function getDecoderStateCallbacks(decoder) {
|
|
4300
4409
|
const $root = decoder.root;
|
|
@@ -4767,6 +4876,7 @@ exports.encodeSchemaOperation = encodeSchemaOperation;
|
|
|
4767
4876
|
exports.getDecoderStateCallbacks = getDecoderStateCallbacks;
|
|
4768
4877
|
exports.getRawChangesCallback = getRawChangesCallback;
|
|
4769
4878
|
exports.registerType = registerType;
|
|
4879
|
+
exports.schema = schema;
|
|
4770
4880
|
exports.type = type;
|
|
4771
4881
|
exports.view = view;
|
|
4772
4882
|
//# sourceMappingURL=index.js.map
|