@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/esm/index.mjs
CHANGED
|
@@ -113,7 +113,7 @@ class TypeContext {
|
|
|
113
113
|
// Workaround to allow using an empty Schema (with no `@type()` fields)
|
|
114
114
|
//
|
|
115
115
|
if (schema[Symbol.metadata] === undefined) {
|
|
116
|
-
Metadata.
|
|
116
|
+
Metadata.initialize(schema);
|
|
117
117
|
}
|
|
118
118
|
this.schemas.set(schema, typeid);
|
|
119
119
|
return true;
|
|
@@ -129,6 +129,14 @@ class TypeContext {
|
|
|
129
129
|
TypeContext.inheritedTypes.get(klass)?.forEach((child) => {
|
|
130
130
|
this.discoverTypes(child, parentIndex, parentFieldViewTag);
|
|
131
131
|
});
|
|
132
|
+
// add parent classes
|
|
133
|
+
let parent = klass;
|
|
134
|
+
while ((parent = Object.getPrototypeOf(parent)) &&
|
|
135
|
+
parent !== Schema && // stop at root (Schema)
|
|
136
|
+
parent !== Function.prototype // stop at root (non-Schema)
|
|
137
|
+
) {
|
|
138
|
+
this.discoverTypes(parent);
|
|
139
|
+
}
|
|
132
140
|
const metadata = (klass[Symbol.metadata] ??= {});
|
|
133
141
|
// if any schema/field has filters, mark "context" as having filters.
|
|
134
142
|
if (metadata[$viewFieldIndexes]) {
|
|
@@ -167,6 +175,13 @@ class TypeContext {
|
|
|
167
175
|
}
|
|
168
176
|
}
|
|
169
177
|
|
|
178
|
+
function getNormalizedType(type) {
|
|
179
|
+
return (Array.isArray(type))
|
|
180
|
+
? { array: type[0] }
|
|
181
|
+
: (typeof (type['type']) !== "undefined")
|
|
182
|
+
? type['type']
|
|
183
|
+
: type;
|
|
184
|
+
}
|
|
170
185
|
const Metadata = {
|
|
171
186
|
addField(metadata, index, name, type, descriptor) {
|
|
172
187
|
if (index > 64) {
|
|
@@ -174,14 +189,16 @@ const Metadata = {
|
|
|
174
189
|
}
|
|
175
190
|
metadata[index] = Object.assign(metadata[index] || {}, // avoid overwriting previous field metadata (@owned / @deprecated)
|
|
176
191
|
{
|
|
177
|
-
type: (
|
|
178
|
-
? { array: type[0] }
|
|
179
|
-
: type,
|
|
192
|
+
type: getNormalizedType(type),
|
|
180
193
|
index,
|
|
181
194
|
name,
|
|
182
195
|
});
|
|
183
196
|
// create "descriptors" map
|
|
184
|
-
metadata
|
|
197
|
+
Object.defineProperty(metadata, $descriptors, {
|
|
198
|
+
value: metadata[$descriptors] || {},
|
|
199
|
+
enumerable: false,
|
|
200
|
+
configurable: true,
|
|
201
|
+
});
|
|
185
202
|
if (descriptor) {
|
|
186
203
|
// for encoder
|
|
187
204
|
metadata[$descriptors][name] = descriptor;
|
|
@@ -256,7 +273,7 @@ const Metadata = {
|
|
|
256
273
|
TypeContext.register(constructor);
|
|
257
274
|
const parentClass = Object.getPrototypeOf(constructor);
|
|
258
275
|
const parentMetadata = parentClass && parentClass[Symbol.metadata];
|
|
259
|
-
const metadata = Metadata.initialize(constructor
|
|
276
|
+
const metadata = Metadata.initialize(constructor);
|
|
260
277
|
// Use Schema's methods if not defined in the class
|
|
261
278
|
if (!constructor[$track]) {
|
|
262
279
|
constructor[$track] = Schema[$track];
|
|
@@ -279,11 +296,15 @@ const Metadata = {
|
|
|
279
296
|
fieldIndex++;
|
|
280
297
|
for (const field in fields) {
|
|
281
298
|
const type = fields[field];
|
|
299
|
+
const normalizedType = getNormalizedType(type);
|
|
282
300
|
// FIXME: this code is duplicated from @type() annotation
|
|
283
301
|
const complexTypeKlass = (Array.isArray(type))
|
|
284
302
|
? getType("array")
|
|
285
303
|
: (typeof (Object.keys(type)[0]) === "string") && getType(Object.keys(type)[0]);
|
|
286
|
-
|
|
304
|
+
const childType = (complexTypeKlass)
|
|
305
|
+
? Object.values(type)[0]
|
|
306
|
+
: normalizedType;
|
|
307
|
+
Metadata.addField(metadata, fieldIndex, field, type, getPropertyDescriptor(`_${field}`, fieldIndex, childType, complexTypeKlass));
|
|
287
308
|
fieldIndex++;
|
|
288
309
|
}
|
|
289
310
|
return target;
|
|
@@ -304,24 +325,52 @@ const Metadata = {
|
|
|
304
325
|
configurable: true,
|
|
305
326
|
});
|
|
306
327
|
},
|
|
307
|
-
initialize(constructor
|
|
328
|
+
initialize(constructor) {
|
|
329
|
+
const parentClass = Object.getPrototypeOf(constructor);
|
|
330
|
+
const parentMetadata = parentClass[Symbol.metadata];
|
|
308
331
|
let metadata = constructor[Symbol.metadata] ?? Object.create(null);
|
|
309
332
|
// make sure inherited classes have their own metadata object.
|
|
310
|
-
if (
|
|
333
|
+
if (parentClass !== Schema && metadata === parentMetadata) {
|
|
311
334
|
metadata = Object.create(null);
|
|
312
335
|
if (parentMetadata) {
|
|
336
|
+
//
|
|
313
337
|
// assign parent metadata to current
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
338
|
+
//
|
|
339
|
+
Object.setPrototypeOf(metadata, parentMetadata);
|
|
340
|
+
// $numFields
|
|
341
|
+
Object.defineProperty(metadata, $numFields, {
|
|
342
|
+
value: parentMetadata[$numFields],
|
|
343
|
+
enumerable: false,
|
|
344
|
+
configurable: true,
|
|
345
|
+
writable: true,
|
|
346
|
+
});
|
|
347
|
+
// $viewFieldIndexes / $fieldIndexesByViewTag
|
|
348
|
+
if (parentMetadata[$viewFieldIndexes] !== undefined) {
|
|
349
|
+
Object.defineProperty(metadata, $viewFieldIndexes, {
|
|
350
|
+
value: [...parentMetadata[$viewFieldIndexes]],
|
|
319
351
|
enumerable: false,
|
|
320
352
|
configurable: true,
|
|
353
|
+
writable: true,
|
|
354
|
+
});
|
|
355
|
+
Object.defineProperty(metadata, $fieldIndexesByViewTag, {
|
|
356
|
+
value: { ...parentMetadata[$fieldIndexesByViewTag] },
|
|
357
|
+
enumerable: false,
|
|
358
|
+
configurable: true,
|
|
359
|
+
writable: true,
|
|
321
360
|
});
|
|
322
361
|
}
|
|
323
|
-
|
|
324
|
-
|
|
362
|
+
// $refTypeFieldIndexes
|
|
363
|
+
if (parentMetadata[$refTypeFieldIndexes] !== undefined) {
|
|
364
|
+
Object.defineProperty(metadata, $refTypeFieldIndexes, {
|
|
365
|
+
value: [...parentMetadata[$refTypeFieldIndexes]],
|
|
366
|
+
enumerable: false,
|
|
367
|
+
configurable: true,
|
|
368
|
+
writable: true,
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
// $descriptors
|
|
372
|
+
Object.defineProperty(metadata, $descriptors, {
|
|
373
|
+
value: { ...parentMetadata[$descriptors] },
|
|
325
374
|
enumerable: false,
|
|
326
375
|
configurable: true,
|
|
327
376
|
writable: true,
|
|
@@ -1096,7 +1145,6 @@ const encodeSchemaOperation = function (encoder, bytes, changeTree, index, opera
|
|
|
1096
1145
|
return;
|
|
1097
1146
|
}
|
|
1098
1147
|
const ref = changeTree.ref;
|
|
1099
|
-
// const metadata: Metadata = ref.constructor[Symbol.metadata];
|
|
1100
1148
|
const field = metadata[index];
|
|
1101
1149
|
// TODO: inline this function call small performance gain
|
|
1102
1150
|
encodeValue(encoder, bytes, metadata[index].type, ref[field.name], operation, it);
|
|
@@ -1171,7 +1219,8 @@ const encodeArray = function (encoder, bytes, changeTree, field, operation, it,
|
|
|
1171
1219
|
// encode operation
|
|
1172
1220
|
bytes[it.offset++] = operation & 255;
|
|
1173
1221
|
// custom operations
|
|
1174
|
-
if (operation === OPERATION.CLEAR
|
|
1222
|
+
if (operation === OPERATION.CLEAR ||
|
|
1223
|
+
operation === OPERATION.REVERSE) {
|
|
1175
1224
|
return;
|
|
1176
1225
|
}
|
|
1177
1226
|
// encode index
|
|
@@ -1649,6 +1698,10 @@ const decodeArray = function (decoder, bytes, it, ref, allChanges) {
|
|
|
1649
1698
|
ref.clear();
|
|
1650
1699
|
return;
|
|
1651
1700
|
}
|
|
1701
|
+
else if (operation === OPERATION.REVERSE) {
|
|
1702
|
+
ref.reverse();
|
|
1703
|
+
return;
|
|
1704
|
+
}
|
|
1652
1705
|
else if (operation === OPERATION.DELETE_BY_REFID) {
|
|
1653
1706
|
// TODO: refactor here, try to follow same flow as below
|
|
1654
1707
|
const refId = number(bytes, it);
|
|
@@ -2768,13 +2821,13 @@ function type(type, options) {
|
|
|
2768
2821
|
// for inheritance support
|
|
2769
2822
|
TypeContext.register(constructor);
|
|
2770
2823
|
const parentClass = Object.getPrototypeOf(constructor);
|
|
2771
|
-
const parentMetadata = parentClass
|
|
2772
|
-
const metadata = Metadata.initialize(constructor
|
|
2824
|
+
const parentMetadata = parentClass[Symbol.metadata];
|
|
2825
|
+
const metadata = Metadata.initialize(constructor);
|
|
2773
2826
|
let fieldIndex = metadata[field];
|
|
2774
2827
|
/**
|
|
2775
2828
|
* skip if descriptor already exists for this field (`@deprecated()`)
|
|
2776
2829
|
*/
|
|
2777
|
-
if (metadata[fieldIndex]) {
|
|
2830
|
+
if (metadata[fieldIndex] !== undefined) {
|
|
2778
2831
|
if (metadata[fieldIndex].deprecated) {
|
|
2779
2832
|
// do not create accessors for deprecated properties.
|
|
2780
2833
|
return;
|
|
@@ -2924,6 +2977,37 @@ function defineTypes(target, fields, options) {
|
|
|
2924
2977
|
}
|
|
2925
2978
|
return target;
|
|
2926
2979
|
}
|
|
2980
|
+
function schema(fields, name, inherits = Schema) {
|
|
2981
|
+
const defaultValues = {};
|
|
2982
|
+
const viewTagFields = {};
|
|
2983
|
+
for (let fieldName in fields) {
|
|
2984
|
+
const field = fields[fieldName];
|
|
2985
|
+
if (typeof (field) === "object") {
|
|
2986
|
+
if (field['default'] !== undefined) {
|
|
2987
|
+
defaultValues[fieldName] = field['default'];
|
|
2988
|
+
}
|
|
2989
|
+
if (field['view'] !== undefined) {
|
|
2990
|
+
viewTagFields[fieldName] = (typeof (field['view']) === "boolean")
|
|
2991
|
+
? DEFAULT_VIEW_TAG
|
|
2992
|
+
: field['view'];
|
|
2993
|
+
}
|
|
2994
|
+
}
|
|
2995
|
+
}
|
|
2996
|
+
const klass = Metadata.setFields(class extends inherits {
|
|
2997
|
+
constructor(...args) {
|
|
2998
|
+
args[0] = Object.assign({}, defaultValues, args[0]);
|
|
2999
|
+
super(...args);
|
|
3000
|
+
}
|
|
3001
|
+
}, fields);
|
|
3002
|
+
for (let fieldName in viewTagFields) {
|
|
3003
|
+
view(viewTagFields[fieldName])(klass.prototype, fieldName);
|
|
3004
|
+
}
|
|
3005
|
+
if (name) {
|
|
3006
|
+
Object.defineProperty(klass, "name", { value: name });
|
|
3007
|
+
}
|
|
3008
|
+
klass.extends = (fields, name) => schema(fields, name, klass);
|
|
3009
|
+
return klass;
|
|
3010
|
+
}
|
|
2927
3011
|
|
|
2928
3012
|
function getIndent(level) {
|
|
2929
3013
|
return (new Array(level).fill(0)).map((_, i) => (i === level - 1) ? `└─ ` : ` `).join("");
|
|
@@ -4171,13 +4255,20 @@ class Reflection extends Schema {
|
|
|
4171
4255
|
/**
|
|
4172
4256
|
* Encodes the TypeContext of an Encoder into a buffer.
|
|
4173
4257
|
*
|
|
4174
|
-
* @param
|
|
4258
|
+
* @param encoder Encoder instance
|
|
4175
4259
|
* @param it
|
|
4176
4260
|
* @returns
|
|
4177
4261
|
*/
|
|
4178
|
-
static encode(
|
|
4262
|
+
static encode(encoder, it = { offset: 0 }) {
|
|
4263
|
+
const context = encoder.context;
|
|
4179
4264
|
const reflection = new Reflection();
|
|
4180
4265
|
const reflectionEncoder = new Encoder(reflection);
|
|
4266
|
+
// rootType is usually the first schema passed to the Encoder
|
|
4267
|
+
// (unless it inherits from another schema)
|
|
4268
|
+
const rootType = context.schemas.get(encoder.state.constructor);
|
|
4269
|
+
if (rootType > 0) {
|
|
4270
|
+
reflection.rootType = rootType;
|
|
4271
|
+
}
|
|
4181
4272
|
const buildType = (currentType, metadata) => {
|
|
4182
4273
|
for (const fieldIndex in metadata) {
|
|
4183
4274
|
const index = Number(fieldIndex);
|
|
@@ -4251,18 +4342,14 @@ class Reflection extends Schema {
|
|
|
4251
4342
|
const parentClass = typeContext.get(reflectionType.extendsId) ?? Schema;
|
|
4252
4343
|
const schema = class _ extends parentClass {
|
|
4253
4344
|
};
|
|
4254
|
-
const parentMetadata = parentClass[Symbol.metadata];
|
|
4255
4345
|
// register for inheritance support
|
|
4256
4346
|
TypeContext.register(schema);
|
|
4257
|
-
// for inheritance support
|
|
4258
|
-
Metadata.initialize(schema
|
|
4347
|
+
// // for inheritance support
|
|
4348
|
+
// Metadata.initialize(schema);
|
|
4259
4349
|
typeContext.add(schema, reflectionType.id);
|
|
4260
4350
|
}, {});
|
|
4261
|
-
//
|
|
4262
|
-
|
|
4263
|
-
const schemaType = typeContext.get(reflectionType.id);
|
|
4264
|
-
const metadata = schemaType[Symbol.metadata];
|
|
4265
|
-
const parentFieldIndex = 0;
|
|
4351
|
+
// define fields
|
|
4352
|
+
const addFields = (metadata, reflectionType, parentFieldIndex) => {
|
|
4266
4353
|
reflectionType.fields.forEach((field, i) => {
|
|
4267
4354
|
const fieldIndex = parentFieldIndex + i;
|
|
4268
4355
|
if (field.referencedType !== undefined) {
|
|
@@ -4285,14 +4372,36 @@ class Reflection extends Schema {
|
|
|
4285
4372
|
Metadata.addField(metadata, fieldIndex, field.name, field.type);
|
|
4286
4373
|
}
|
|
4287
4374
|
});
|
|
4375
|
+
};
|
|
4376
|
+
// 2nd pass, set fields
|
|
4377
|
+
reflection.types.forEach((reflectionType) => {
|
|
4378
|
+
const schema = typeContext.get(reflectionType.id);
|
|
4379
|
+
// for inheritance support
|
|
4380
|
+
const metadata = Metadata.initialize(schema);
|
|
4381
|
+
const inheritedTypes = [];
|
|
4382
|
+
let parentType = reflectionType;
|
|
4383
|
+
do {
|
|
4384
|
+
inheritedTypes.push(parentType);
|
|
4385
|
+
parentType = reflection.types.find((t) => t.id === parentType.extendsId);
|
|
4386
|
+
} while (parentType);
|
|
4387
|
+
let parentFieldIndex = 0;
|
|
4388
|
+
inheritedTypes.reverse().forEach((reflectionType) => {
|
|
4389
|
+
// add fields from all inherited classes
|
|
4390
|
+
// TODO: refactor this to avoid adding fields from parent classes
|
|
4391
|
+
addFields(metadata, reflectionType, parentFieldIndex);
|
|
4392
|
+
parentFieldIndex += reflectionType.fields.length;
|
|
4393
|
+
});
|
|
4288
4394
|
});
|
|
4289
|
-
const state = new (typeContext.get(0))();
|
|
4395
|
+
const state = new (typeContext.get(reflection.rootType || 0))();
|
|
4290
4396
|
return new Decoder(state, typeContext);
|
|
4291
4397
|
}
|
|
4292
4398
|
}
|
|
4293
4399
|
__decorate([
|
|
4294
4400
|
type([ReflectionType])
|
|
4295
4401
|
], Reflection.prototype, "types", void 0);
|
|
4402
|
+
__decorate([
|
|
4403
|
+
type("number")
|
|
4404
|
+
], Reflection.prototype, "rootType", void 0);
|
|
4296
4405
|
|
|
4297
4406
|
function getDecoderStateCallbacks(decoder) {
|
|
4298
4407
|
const $root = decoder.root;
|
|
@@ -4731,5 +4840,5 @@ registerType("array", { constructor: ArraySchema });
|
|
|
4731
4840
|
registerType("set", { constructor: SetSchema });
|
|
4732
4841
|
registerType("collection", { constructor: CollectionSchema, });
|
|
4733
4842
|
|
|
4734
|
-
export { $changes, $childType, $decoder, $deleteByIndex, $encoder, $filter, $getByIndex, $track, ArraySchema, ChangeTree, CollectionSchema, Decoder, Encoder, MapSchema, Metadata, OPERATION, Reflection, ReflectionField, ReflectionType, Schema, SetSchema, StateView, TypeContext, decode, decodeKeyValueOperation, decodeSchemaOperation, defineTypes, deprecated, dumpChanges, encode, encodeArray as encodeKeyValueOperation, encodeSchemaOperation, getDecoderStateCallbacks, getRawChangesCallback, registerType, type, view };
|
|
4843
|
+
export { $changes, $childType, $decoder, $deleteByIndex, $encoder, $filter, $getByIndex, $track, ArraySchema, ChangeTree, CollectionSchema, Decoder, Encoder, MapSchema, Metadata, OPERATION, Reflection, ReflectionField, ReflectionType, Schema, SetSchema, StateView, TypeContext, decode, decodeKeyValueOperation, decodeSchemaOperation, defineTypes, deprecated, dumpChanges, encode, encodeArray as encodeKeyValueOperation, encodeSchemaOperation, getDecoderStateCallbacks, getRawChangesCallback, registerType, schema, type, view };
|
|
4735
4844
|
//# sourceMappingURL=index.mjs.map
|