@colyseus/schema 3.0.53 → 3.0.55

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.
@@ -1,4 +1,4 @@
1
- import type { Definition, DefinitionType, PrimitiveType, RawPrimitiveType } from "../annotations";
1
+ import type { Definition, DefinitionType, PrimitiveType } from "../annotations";
2
2
  import type { Schema } from "../Schema";
3
3
  import type { ArraySchema } from "./custom/ArraySchema";
4
4
  import type { CollectionSchema } from "./custom/CollectionSchema";
@@ -13,24 +13,38 @@ export interface Collection<K = any, V = any, IT = V> {
13
13
  export type InferValueType<T extends DefinitionType> = T extends "string" ? string : T extends "number" ? number : T extends "int8" ? number : T extends "uint8" ? number : T extends "int16" ? number : T extends "uint16" ? number : T extends "int32" ? number : T extends "uint32" ? number : T extends "int64" ? number : T extends "uint64" ? number : T extends "float32" ? number : T extends "float64" ? number : T extends "boolean" ? boolean : T extends {
14
14
  type: infer ChildType extends Constructor;
15
15
  } ? InstanceType<ChildType> : T extends {
16
- type: infer ChildType extends PrimitiveType;
17
- } ? ChildType : T extends Array<infer ChildType extends Constructor> ? InstanceType<ChildType>[] : T extends Array<infer ChildType extends RawPrimitiveType> ? ChildType[] : T extends {
16
+ type: Array<infer ChildType>;
17
+ } ? (ChildType extends Record<string | number, string | number> ? ChildType[keyof ChildType][] : ChildType[]) : T extends {
18
+ type: {
19
+ map: infer ChildType;
20
+ };
21
+ } ? (ChildType extends Record<string | number, string | number> ? MapSchema<ChildType[keyof ChildType]> : MapSchema<ChildType>) : T extends {
22
+ type: {
23
+ set: infer ChildType;
24
+ };
25
+ } ? (ChildType extends Record<string | number, string | number> ? SetSchema<ChildType[keyof ChildType]> : SetSchema<ChildType>) : T extends {
26
+ type: {
27
+ collection: infer ChildType;
28
+ };
29
+ } ? (ChildType extends Record<string | number, string | number> ? CollectionSchema<ChildType[keyof ChildType]> : CollectionSchema<ChildType>) : T extends {
30
+ type: infer ChildType;
31
+ } ? (ChildType extends Record<string | number, string | number> ? ChildType[keyof ChildType] : ChildType) : T extends Array<infer ChildType extends Constructor> ? InstanceType<ChildType>[] : T extends Array<infer ChildType> ? (ChildType extends Record<string | number, string | number> ? ChildType[keyof ChildType][] : ChildType[]) : T extends {
18
32
  array: infer ChildType extends Constructor;
19
33
  } ? InstanceType<ChildType>[] : T extends {
20
- array: infer ChildType extends PrimitiveType;
21
- } ? ChildType[] : T extends {
34
+ array: infer ChildType;
35
+ } ? (ChildType extends Record<string | number, string | number> ? ChildType[keyof ChildType][] : ChildType[]) : T extends {
22
36
  map: infer ChildType extends Constructor;
23
37
  } ? MapSchema<InstanceType<ChildType>> : T extends {
24
- map: infer ChildType extends PrimitiveType;
25
- } ? MapSchema<ChildType> : T extends {
38
+ map: infer ChildType;
39
+ } ? (ChildType extends Record<string | number, string | number> ? MapSchema<ChildType[keyof ChildType]> : MapSchema<ChildType>) : T extends {
26
40
  set: infer ChildType extends Constructor;
27
41
  } ? SetSchema<InstanceType<ChildType>> : T extends {
28
- set: infer ChildType extends PrimitiveType;
29
- } ? SetSchema<ChildType> : T extends {
42
+ set: infer ChildType;
43
+ } ? (ChildType extends Record<string | number, string | number> ? SetSchema<ChildType[keyof ChildType]> : SetSchema<ChildType>) : T extends {
30
44
  collection: infer ChildType extends Constructor;
31
45
  } ? CollectionSchema<InstanceType<ChildType>> : T extends {
32
- collection: infer ChildType extends PrimitiveType;
33
- } ? CollectionSchema<ChildType> : T extends Constructor ? InstanceType<T> : T extends PrimitiveType ? T : never;
46
+ collection: infer ChildType;
47
+ } ? (ChildType extends Record<string | number, string | number> ? CollectionSchema<ChildType[keyof ChildType]> : CollectionSchema<ChildType>) : T extends Constructor ? InstanceType<T> : T extends Record<string | number, string | number> ? T[keyof T] : T extends PrimitiveType ? T : never;
34
48
  export type InferSchemaInstanceType<T extends Definition> = {
35
49
  [K in keyof T]: InferValueType<T[K]>;
36
50
  } & Schema;
@@ -1 +1 @@
1
- {"version":3,"file":"HelperTypes.js","sourceRoot":"","sources":["../../src/types/HelperTypes.ts"],"names":[],"mappings":"","sourcesContent":["import type { Definition, DefinitionType, PrimitiveType, RawPrimitiveType } from \"../annotations\";\nimport type { Schema } from \"../Schema\";\nimport type { ArraySchema } from \"./custom/ArraySchema\";\nimport type { CollectionSchema } from \"./custom/CollectionSchema\";\nimport type { MapSchema } from \"./custom/MapSchema\";\nimport type { SetSchema } from \"./custom/SetSchema\";\n\nexport type Constructor<T = {}> = new (...args: any[]) => T;\n\nexport interface Collection<K = any, V = any, IT = V> {\n [Symbol.iterator](): IterableIterator<IT>;\n forEach(callback: Function);\n entries(): IterableIterator<[K, V]>;\n}\n\nexport type InferValueType<T extends DefinitionType> =\n T extends \"string\" ? string\n : T extends \"number\" ? number\n : T extends \"int8\" ? number\n : T extends \"uint8\" ? number\n : T extends \"int16\" ? number\n : T extends \"uint16\" ? number\n : T extends \"int32\" ? number\n : T extends \"uint32\" ? number\n : T extends \"int64\" ? number\n : T extends \"uint64\" ? number\n : T extends \"float32\" ? number\n : T extends \"float64\" ? number\n : T extends \"boolean\" ? boolean\n\n : T extends { type: infer ChildType extends Constructor } ? InstanceType<ChildType>\n : T extends { type: infer ChildType extends PrimitiveType } ? ChildType\n\n : T extends Array<infer ChildType extends Constructor> ? InstanceType<ChildType>[]\n : T extends Array<infer ChildType extends RawPrimitiveType> ? ChildType[]\n\n : T extends { array: infer ChildType extends Constructor } ? InstanceType<ChildType>[]\n : T extends { array: infer ChildType extends PrimitiveType } ? ChildType[]\n\n : T extends { map: infer ChildType extends Constructor } ? MapSchema<InstanceType<ChildType>>\n : T extends { map: infer ChildType extends PrimitiveType } ? MapSchema<ChildType>\n\n : T extends { set: infer ChildType extends Constructor } ? SetSchema<InstanceType<ChildType>>\n : T extends { set: infer ChildType extends PrimitiveType } ? SetSchema<ChildType>\n\n : T extends { collection: infer ChildType extends Constructor } ? CollectionSchema<InstanceType<ChildType>>\n : T extends { collection: infer ChildType extends PrimitiveType } ? CollectionSchema<ChildType>\n\n : T extends Constructor ? InstanceType<T>\n : T extends PrimitiveType ? T\n\n : never;\n\nexport type InferSchemaInstanceType<T extends Definition> = {\n [K in keyof T]: InferValueType<T[K]>\n} & Schema;\n\nexport type DefinedSchemaType<T extends Definition, P extends typeof Schema> = {\n new (): InferSchemaInstanceType<T> & InstanceType<P>;\n} & typeof Schema;\n\nexport type NonFunctionProps<T> = Omit<T, {\n [K in keyof T]: T[K] extends Function ? K : never;\n}[keyof T]>;\n\nexport type NonFunctionPropNames<T> = {\n [K in keyof T]: T[K] extends Function ? never : K\n}[keyof T];\n\nexport type NonFunctionNonPrimitivePropNames<T> = {\n [K in keyof T]: T[K] extends Function\n ? never\n : T[K] extends number | string | boolean\n ? never\n : K\n}[keyof T];\n\nexport type ToJSON<T> = NonFunctionProps<{\n [K in keyof T]: T[K] extends MapSchema<infer U>\n ? Record<string, U>\n : T[K] extends Map<string, infer U>\n ? Record<string, U>\n : T[K] extends ArraySchema<infer U>\n ? U[]\n : T[K]\n}>;"]}
1
+ {"version":3,"file":"HelperTypes.js","sourceRoot":"","sources":["../../src/types/HelperTypes.ts"],"names":[],"mappings":"","sourcesContent":["import type { Definition, DefinitionType, PrimitiveType, RawPrimitiveType } from \"../annotations\";\nimport type { Schema } from \"../Schema\";\nimport type { ArraySchema } from \"./custom/ArraySchema\";\nimport type { CollectionSchema } from \"./custom/CollectionSchema\";\nimport type { MapSchema } from \"./custom/MapSchema\";\nimport type { SetSchema } from \"./custom/SetSchema\";\n\nexport type Constructor<T = {}> = new (...args: any[]) => T;\n\nexport interface Collection<K = any, V = any, IT = V> {\n [Symbol.iterator](): IterableIterator<IT>;\n forEach(callback: Function);\n entries(): IterableIterator<[K, V]>;\n}\n\nexport type InferValueType<T extends DefinitionType> =\n T extends \"string\" ? string\n : T extends \"number\" ? number\n : T extends \"int8\" ? number\n : T extends \"uint8\" ? number\n : T extends \"int16\" ? number\n : T extends \"uint16\" ? number\n : T extends \"int32\" ? number\n : T extends \"uint32\" ? number\n : T extends \"int64\" ? number\n : T extends \"uint64\" ? number\n : T extends \"float32\" ? number\n : T extends \"float64\" ? number\n : T extends \"boolean\" ? boolean\n\n // Handle { type: ... } patterns\n : T extends { type: infer ChildType extends Constructor } ? InstanceType<ChildType>\n : T extends { type: Array<infer ChildType> } ? (ChildType extends Record<string | number, string | number> ? ChildType[keyof ChildType][] : ChildType[]) // TS ENUM\n : T extends { type: { map: infer ChildType } } ? (ChildType extends Record<string | number, string | number> ? MapSchema<ChildType[keyof ChildType]> : MapSchema<ChildType>) // TS ENUM\n : T extends { type: { set: infer ChildType } } ? (ChildType extends Record<string | number, string | number> ? SetSchema<ChildType[keyof ChildType]> : SetSchema<ChildType>) // TS ENUM\n : T extends { type: { collection: infer ChildType } } ? (ChildType extends Record<string | number, string | number> ? CollectionSchema<ChildType[keyof ChildType]> : CollectionSchema<ChildType>) // TS ENUM\n : T extends { type: infer ChildType } ? (ChildType extends Record<string | number, string | number> ? ChildType[keyof ChildType] : ChildType) // TS ENUM\n\n // Handle direct array patterns\n : T extends Array<infer ChildType extends Constructor> ? InstanceType<ChildType>[]\n : T extends Array<infer ChildType> ? (ChildType extends Record<string | number, string | number> ? ChildType[keyof ChildType][] : ChildType[]) // TS ENUM\n\n // Handle collection object patterns\n : T extends { array: infer ChildType extends Constructor } ? InstanceType<ChildType>[]\n : T extends { array: infer ChildType } ? (ChildType extends Record<string | number, string | number> ? ChildType[keyof ChildType][] : ChildType[]) // TS ENUM\n\n : T extends { map: infer ChildType extends Constructor } ? MapSchema<InstanceType<ChildType>>\n : T extends { map: infer ChildType } ? (ChildType extends Record<string | number, string | number> ? MapSchema<ChildType[keyof ChildType]> : MapSchema<ChildType>) // TS ENUM\n\n : T extends { set: infer ChildType extends Constructor } ? SetSchema<InstanceType<ChildType>>\n : T extends { set: infer ChildType } ? (ChildType extends Record<string | number, string | number> ? SetSchema<ChildType[keyof ChildType]> : SetSchema<ChildType>) // TS ENUM\n\n : T extends { collection: infer ChildType extends Constructor } ? CollectionSchema<InstanceType<ChildType>>\n : T extends { collection: infer ChildType } ? (ChildType extends Record<string | number, string | number> ? CollectionSchema<ChildType[keyof ChildType]> : CollectionSchema<ChildType>) // TS ENUM\n\n // Handle direct types\n : T extends Constructor ? InstanceType<T>\n : T extends Record<string | number, string | number> ? T[keyof T] // TS ENUM\n : T extends PrimitiveType ? T\n\n : never;\n\nexport type InferSchemaInstanceType<T extends Definition> = {\n [K in keyof T]: InferValueType<T[K]>\n} & Schema;\n\nexport type DefinedSchemaType<T extends Definition, P extends typeof Schema> = {\n new (): InferSchemaInstanceType<T> & InstanceType<P>;\n} & typeof Schema;\n\nexport type NonFunctionProps<T> = Omit<T, {\n [K in keyof T]: T[K] extends Function ? K : never;\n}[keyof T]>;\n\nexport type NonFunctionPropNames<T> = {\n [K in keyof T]: T[K] extends Function ? never : K\n}[keyof T];\n\nexport type NonFunctionNonPrimitivePropNames<T> = {\n [K in keyof T]: T[K] extends Function\n ? never\n : T[K] extends number | string | boolean\n ? never\n : K\n}[keyof T];\n\nexport type ToJSON<T> = NonFunctionProps<{\n [K in keyof T]: T[K] extends MapSchema<infer U>\n ? Record<string, U>\n : T[K] extends Map<string, infer U>\n ? Record<string, U>\n : T[K] extends ArraySchema<infer U>\n ? U[]\n : T[K]\n}>;"]}
@@ -95,15 +95,7 @@ class TypeContext {
95
95
  if (typeof (fieldType) === "string") {
96
96
  continue;
97
97
  }
98
- if (Array.isArray(fieldType)) {
99
- const type = fieldType[0];
100
- // skip primitive types
101
- if (type === "string") {
102
- continue;
103
- }
104
- this.discoverTypes(type, klass, index, parentHasViewTag || fieldHasViewTag);
105
- }
106
- else if (typeof (fieldType) === "function") {
98
+ if (typeof (fieldType) === "function") {
107
99
  this.discoverTypes(fieldType, klass, index, parentHasViewTag || fieldHasViewTag);
108
100
  }
109
101
  else {
@@ -1 +1 @@
1
- {"version":3,"file":"TypeContext.js","sourceRoot":"","sources":["../../src/types/TypeContext.ts"],"names":[],"mappings":"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","sourcesContent":["import { Metadata } from \"../Metadata\";\nimport { Schema } from \"../Schema\";\nimport { $viewFieldIndexes } from \"./symbols\";\n\nexport class TypeContext {\n types: { [id: number]: typeof Schema; } = {};\n schemas = new Map<typeof Schema, number>();\n\n hasFilters: boolean = false;\n parentFiltered: {[typeIdAndParentIndex: string]: boolean} = {};\n\n /**\n * For inheritance support\n * Keeps track of which classes extends which. (parent -> children)\n */\n static inheritedTypes = new Map<typeof Schema, Set<typeof Schema>>();\n static cachedContexts = new Map<typeof Schema, TypeContext>();\n\n static register(target: typeof Schema) {\n const parent = Object.getPrototypeOf(target);\n if (parent !== Schema) {\n let inherits = TypeContext.inheritedTypes.get(parent);\n if (!inherits) {\n inherits = new Set<typeof Schema>();\n TypeContext.inheritedTypes.set(parent, inherits);\n }\n inherits.add(target);\n }\n }\n\n static cache (rootClass: typeof Schema) {\n let context = TypeContext.cachedContexts.get(rootClass);\n if (!context) {\n context = new TypeContext(rootClass);\n TypeContext.cachedContexts.set(rootClass, context);\n }\n return context;\n }\n\n constructor(rootClass?: typeof Schema) {\n if (rootClass) {\n this.discoverTypes(rootClass);\n }\n }\n\n has(schema: typeof Schema) {\n return this.schemas.has(schema);\n }\n\n get(typeid: number) {\n return this.types[typeid];\n }\n\n add(schema: typeof Schema, typeid = this.schemas.size) {\n // skip if already registered\n if (this.schemas.has(schema)) {\n return false;\n }\n\n this.types[typeid] = schema;\n\n //\n // Workaround to allow using an empty Schema (with no `@type()` fields)\n //\n if (schema[Symbol.metadata] === undefined) {\n Metadata.initialize(schema);\n }\n\n this.schemas.set(schema, typeid);\n return true;\n }\n\n getTypeId(klass: typeof Schema) {\n return this.schemas.get(klass);\n }\n\n private discoverTypes(klass: typeof Schema, parentType?: typeof Schema, parentIndex?: number, parentHasViewTag?: boolean) {\n if (parentHasViewTag) {\n this.registerFilteredByParent(klass, parentType, parentIndex);\n }\n\n // skip if already registered\n if (!this.add(klass)) { return; }\n\n // add classes inherited from this base class\n TypeContext.inheritedTypes.get(klass)?.forEach((child) => {\n this.discoverTypes(child, parentType, parentIndex, parentHasViewTag);\n });\n\n // add parent classes\n let parent: any = klass;\n while (\n (parent = Object.getPrototypeOf(parent)) &&\n parent !== Schema && // stop at root (Schema)\n parent !== Function.prototype // stop at root (non-Schema)\n ) {\n this.discoverTypes(parent);\n }\n\n const metadata: Metadata = (klass[Symbol.metadata] ??= {});\n\n // if any schema/field has filters, mark \"context\" as having filters.\n if (metadata[$viewFieldIndexes]) {\n this.hasFilters = true;\n }\n\n for (const fieldIndex in metadata) {\n const index = fieldIndex as any as number;\n\n const fieldType = metadata[index].type;\n const fieldHasViewTag = (metadata[index].tag !== undefined);\n\n if (typeof (fieldType) === \"string\") {\n continue;\n }\n\n if (Array.isArray(fieldType)) {\n const type = fieldType[0];\n\n // skip primitive types\n if (type === \"string\") {\n continue;\n }\n\n this.discoverTypes(type as typeof Schema, klass, index, parentHasViewTag || fieldHasViewTag);\n\n } else if (typeof (fieldType) === \"function\") {\n this.discoverTypes(fieldType as typeof Schema, klass, index, parentHasViewTag || fieldHasViewTag);\n\n } else {\n const type = Object.values(fieldType)[0];\n\n // skip primitive types\n if (typeof (type) === \"string\") {\n continue;\n }\n\n this.discoverTypes(type as typeof Schema, klass, index, parentHasViewTag || fieldHasViewTag);\n }\n }\n }\n\n /**\n * Keep track of which classes have filters applied.\n * Format: `${typeid}-${parentTypeid}-${parentIndex}`\n */\n private registerFilteredByParent(schema: typeof Schema, parentType?: typeof Schema, parentIndex?: number) {\n const typeid = this.schemas.get(schema) ?? this.schemas.size;\n\n let key = `${typeid}`;\n if (parentType) { key += `-${this.schemas.get(parentType)}`; }\n\n key += `-${parentIndex}`;\n this.parentFiltered[key] = true;\n }\n\n debug() {\n let parentFiltered = \"\";\n\n for (const key in this.parentFiltered) {\n const keys: number[] = key.split(\"-\").map(Number);\n const fieldIndex = keys.pop();\n\n parentFiltered += `\\n\\t\\t`;\n parentFiltered += `${key}: ${keys.reverse().map((id, i) => {\n const klass = this.types[id];\n const metadata: Metadata = klass[Symbol.metadata];\n let txt = klass.name;\n if (i === 0) { txt += `[${metadata[fieldIndex].name}]`; }\n return `${txt}`;\n }).join(\" -> \")}`;\n }\n\n return `TypeContext ->\\n` +\n `\\tSchema types: ${this.schemas.size}\\n` +\n `\\thasFilters: ${this.hasFilters}\\n` +\n `\\tparentFiltered:${parentFiltered}`;\n }\n\n}\n"]}
1
+ {"version":3,"file":"TypeContext.js","sourceRoot":"","sources":["../../src/types/TypeContext.ts"],"names":[],"mappings":"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","sourcesContent":["import { Metadata } from \"../Metadata\";\nimport { Schema } from \"../Schema\";\nimport { $viewFieldIndexes } from \"./symbols\";\n\nexport class TypeContext {\n types: { [id: number]: typeof Schema; } = {};\n schemas = new Map<typeof Schema, number>();\n\n hasFilters: boolean = false;\n parentFiltered: {[typeIdAndParentIndex: string]: boolean} = {};\n\n /**\n * For inheritance support\n * Keeps track of which classes extends which. (parent -> children)\n */\n static inheritedTypes = new Map<typeof Schema, Set<typeof Schema>>();\n static cachedContexts = new Map<typeof Schema, TypeContext>();\n\n static register(target: typeof Schema) {\n const parent = Object.getPrototypeOf(target);\n if (parent !== Schema) {\n let inherits = TypeContext.inheritedTypes.get(parent);\n if (!inherits) {\n inherits = new Set<typeof Schema>();\n TypeContext.inheritedTypes.set(parent, inherits);\n }\n inherits.add(target);\n }\n }\n\n static cache (rootClass: typeof Schema) {\n let context = TypeContext.cachedContexts.get(rootClass);\n if (!context) {\n context = new TypeContext(rootClass);\n TypeContext.cachedContexts.set(rootClass, context);\n }\n return context;\n }\n\n constructor(rootClass?: typeof Schema) {\n if (rootClass) {\n this.discoverTypes(rootClass);\n }\n }\n\n has(schema: typeof Schema) {\n return this.schemas.has(schema);\n }\n\n get(typeid: number) {\n return this.types[typeid];\n }\n\n add(schema: typeof Schema, typeid = this.schemas.size) {\n // skip if already registered\n if (this.schemas.has(schema)) {\n return false;\n }\n\n this.types[typeid] = schema;\n\n //\n // Workaround to allow using an empty Schema (with no `@type()` fields)\n //\n if (schema[Symbol.metadata] === undefined) {\n Metadata.initialize(schema);\n }\n\n this.schemas.set(schema, typeid);\n return true;\n }\n\n getTypeId(klass: typeof Schema) {\n return this.schemas.get(klass);\n }\n\n private discoverTypes(klass: typeof Schema, parentType?: typeof Schema, parentIndex?: number, parentHasViewTag?: boolean) {\n if (parentHasViewTag) {\n this.registerFilteredByParent(klass, parentType, parentIndex);\n }\n\n // skip if already registered\n if (!this.add(klass)) { return; }\n\n // add classes inherited from this base class\n TypeContext.inheritedTypes.get(klass)?.forEach((child) => {\n this.discoverTypes(child, parentType, parentIndex, parentHasViewTag);\n });\n\n // add parent classes\n let parent: any = klass;\n while (\n (parent = Object.getPrototypeOf(parent)) &&\n parent !== Schema && // stop at root (Schema)\n parent !== Function.prototype // stop at root (non-Schema)\n ) {\n this.discoverTypes(parent);\n }\n\n const metadata: Metadata = (klass[Symbol.metadata] ??= {});\n\n // if any schema/field has filters, mark \"context\" as having filters.\n if (metadata[$viewFieldIndexes]) {\n this.hasFilters = true;\n }\n\n for (const fieldIndex in metadata) {\n const index = fieldIndex as any as number;\n\n const fieldType = metadata[index].type;\n const fieldHasViewTag = (metadata[index].tag !== undefined);\n\n if (typeof (fieldType) === \"string\") {\n continue;\n }\n\n if (typeof (fieldType) === \"function\") {\n this.discoverTypes(fieldType as typeof Schema, klass, index, parentHasViewTag || fieldHasViewTag);\n\n } else {\n const type = Object.values(fieldType)[0];\n\n // skip primitive types\n if (typeof (type) === \"string\") {\n continue;\n }\n\n this.discoverTypes(type as typeof Schema, klass, index, parentHasViewTag || fieldHasViewTag);\n }\n }\n }\n\n /**\n * Keep track of which classes have filters applied.\n * Format: `${typeid}-${parentTypeid}-${parentIndex}`\n */\n private registerFilteredByParent(schema: typeof Schema, parentType?: typeof Schema, parentIndex?: number) {\n const typeid = this.schemas.get(schema) ?? this.schemas.size;\n\n let key = `${typeid}`;\n if (parentType) { key += `-${this.schemas.get(parentType)}`; }\n\n key += `-${parentIndex}`;\n this.parentFiltered[key] = true;\n }\n\n debug() {\n let parentFiltered = \"\";\n\n for (const key in this.parentFiltered) {\n const keys: number[] = key.split(\"-\").map(Number);\n const fieldIndex = keys.pop();\n\n parentFiltered += `\\n\\t\\t`;\n parentFiltered += `${key}: ${keys.reverse().map((id, i) => {\n const klass = this.types[id];\n const metadata: Metadata = klass[Symbol.metadata];\n let txt = klass.name;\n if (i === 0) { txt += `[${metadata[fieldIndex].name}]`; }\n return `${txt}`;\n }).join(\" -> \")}`;\n }\n\n return `TypeContext ->\\n` +\n `\\tSchema types: ${this.schemas.size}\\n` +\n `\\thasFilters: ${this.hasFilters}\\n` +\n `\\tparentFiltered:${parentFiltered}`;\n }\n\n}\n"]}
@@ -5,6 +5,9 @@ export interface TypeDefinition {
5
5
  encode?: (bytes: BufferLike, value: any, it: Iterator) => any;
6
6
  decode?: (bytes: BufferLike, it: Iterator) => any;
7
7
  }
8
+ export declare const registeredTypes: {
9
+ [identifier: string]: TypeDefinition;
10
+ };
8
11
  export declare function registerType(identifier: string, definition: TypeDefinition): void;
9
12
  export declare function getIdentifier(klass: any): string;
10
13
  export declare function getType(identifier: string): TypeDefinition;
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registeredTypes = void 0;
3
4
  exports.registerType = registerType;
4
5
  exports.getIdentifier = getIdentifier;
5
6
  exports.getType = getType;
@@ -7,12 +8,12 @@ exports.defineCustomTypes = defineCustomTypes;
7
8
  const annotations_1 = require("../annotations");
8
9
  const encode_1 = require("../encoding/encode");
9
10
  const decode_1 = require("../encoding/decode");
10
- const registeredTypes = {};
11
+ exports.registeredTypes = {};
11
12
  const identifiers = new Map();
12
13
  function registerType(identifier, definition) {
13
14
  if (definition.constructor) {
14
15
  identifiers.set(definition.constructor, identifier);
15
- registeredTypes[identifier] = definition;
16
+ exports.registeredTypes[identifier] = definition;
16
17
  }
17
18
  if (definition.encode) {
18
19
  encode_1.encode[identifier] = definition.encode;
@@ -25,7 +26,7 @@ function getIdentifier(klass) {
25
26
  return identifiers.get(klass);
26
27
  }
27
28
  function getType(identifier) {
28
- return registeredTypes[identifier];
29
+ return exports.registeredTypes[identifier];
29
30
  }
30
31
  function defineCustomTypes(types) {
31
32
  for (const identifier in types) {
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/types/registry.ts"],"names":[],"mappings":";;AAaA,oCAQC;AAED,sCAEC;AAED,0BAEC;AAED,8CAMC;AArCD,gDAAsD;AACtD,+CAAwD;AACxD,+CAAsD;AAQtD,MAAM,eAAe,GAA4C,EAAE,CAAC;AACpE,MAAM,WAAW,GAAG,IAAI,GAAG,EAAe,CAAC;AAE3C,SAAgB,YAAY,CAAC,UAAkB,EAAE,UAA0B;IACvE,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC;QACzB,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QACpD,eAAe,CAAC,UAAU,CAAC,GAAG,UAAU,CAAC;IAC7C,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;QAAC,eAAM,CAAC,UAAU,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC;IAAC,CAAC;IAClE,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;QAAC,eAAM,CAAC,UAAU,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC;IAAC,CAAC;AACtE,CAAC;AAED,SAAgB,aAAa,CAAC,KAAU;IACpC,OAAO,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC;AAED,SAAgB,OAAO,CAAC,UAAkB;IACtC,OAAO,eAAe,CAAC,UAAU,CAAC,CAAC;AACvC,CAAC;AAED,SAAgB,iBAAiB,CAA4C,KAAQ;IACjF,KAAK,MAAM,UAAU,IAAI,KAAK,EAAE,CAAC;QAC7B,YAAY,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;IAChD,CAAC;IAED,OAAO,CAAC,CAAU,EAAE,EAAE,CAAC,IAAA,kBAAI,EAAC,CAAmB,CAAC,CAAC;AACrD,CAAC","sourcesContent":["import { DefinitionType, type } from \"../annotations\";\nimport { BufferLike, encode } from \"../encoding/encode\";\nimport { decode, Iterator } from \"../encoding/decode\";\n\nexport interface TypeDefinition {\n constructor?: any,\n encode?: (bytes: BufferLike, value: any, it: Iterator) => any;\n decode?: (bytes: BufferLike, it: Iterator) => any;\n}\n\nconst registeredTypes: {[identifier: string] : TypeDefinition} = {};\nconst identifiers = new Map<any, string>();\n\nexport function registerType(identifier: string, definition: TypeDefinition) {\n if (definition.constructor) {\n identifiers.set(definition.constructor, identifier);\n registeredTypes[identifier] = definition;\n }\n\n if (definition.encode) { encode[identifier] = definition.encode; }\n if (definition.decode) { decode[identifier] = definition.decode; }\n}\n\nexport function getIdentifier(klass: any): string {\n return identifiers.get(klass);\n}\n\nexport function getType(identifier: string): TypeDefinition {\n return registeredTypes[identifier];\n}\n\nexport function defineCustomTypes<T extends {[key: string]: TypeDefinition}>(types: T) {\n for (const identifier in types) {\n registerType(identifier, types[identifier]);\n }\n\n return (t: keyof T) => type(t as DefinitionType);\n}"]}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/types/registry.ts"],"names":[],"mappings":";;;AAcA,oCAQC;AAED,sCAEC;AAED,0BAEC;AAED,8CAMC;AAtCD,gDAAsD;AACtD,+CAAwD;AACxD,+CAAsD;AAQzC,QAAA,eAAe,GAA4C,EAAE,CAAC;AAE3E,MAAM,WAAW,GAAG,IAAI,GAAG,EAAe,CAAC;AAE3C,SAAgB,YAAY,CAAC,UAAkB,EAAE,UAA0B;IACvE,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC;QACzB,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QACpD,uBAAe,CAAC,UAAU,CAAC,GAAG,UAAU,CAAC;IAC7C,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;QAAC,eAAM,CAAC,UAAU,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC;IAAC,CAAC;IAClE,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;QAAC,eAAM,CAAC,UAAU,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC;IAAC,CAAC;AACtE,CAAC;AAED,SAAgB,aAAa,CAAC,KAAU;IACpC,OAAO,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC;AAED,SAAgB,OAAO,CAAC,UAAkB;IACtC,OAAO,uBAAe,CAAC,UAAU,CAAC,CAAC;AACvC,CAAC;AAED,SAAgB,iBAAiB,CAA4C,KAAQ;IACjF,KAAK,MAAM,UAAU,IAAI,KAAK,EAAE,CAAC;QAC7B,YAAY,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;IAChD,CAAC;IAED,OAAO,CAAC,CAAU,EAAE,EAAE,CAAC,IAAA,kBAAI,EAAC,CAAmB,CAAC,CAAC;AACrD,CAAC","sourcesContent":["import { DefinitionType, type } from \"../annotations\";\nimport { BufferLike, encode } from \"../encoding/encode\";\nimport { decode, Iterator } from \"../encoding/decode\";\n\nexport interface TypeDefinition {\n constructor?: any,\n encode?: (bytes: BufferLike, value: any, it: Iterator) => any;\n decode?: (bytes: BufferLike, it: Iterator) => any;\n}\n\nexport const registeredTypes: {[identifier: string] : TypeDefinition} = {};\n\nconst identifiers = new Map<any, string>();\n\nexport function registerType(identifier: string, definition: TypeDefinition) {\n if (definition.constructor) {\n identifiers.set(definition.constructor, identifier);\n registeredTypes[identifier] = definition;\n }\n\n if (definition.encode) { encode[identifier] = definition.encode; }\n if (definition.decode) { decode[identifier] = definition.decode; }\n}\n\nexport function getIdentifier(klass: any): string {\n return identifiers.get(klass);\n}\n\nexport function getType(identifier: string): TypeDefinition {\n return registeredTypes[identifier];\n}\n\nexport function defineCustomTypes<T extends {[key: string]: TypeDefinition}>(types: T) {\n for (const identifier in types) {\n registerType(identifier, types[identifier]);\n }\n\n return (t: keyof T) => type(t as DefinitionType);\n}"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@colyseus/schema",
3
- "version": "3.0.53",
3
+ "version": "3.0.55",
4
4
  "description": "Binary state serializer with delta encoding for games",
5
5
  "bin": {
6
6
  "schema-codegen": "bin/schema-codegen",
package/src/Metadata.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { DefinitionType, getPropertyDescriptor } from "./annotations";
2
2
  import { Schema } from "./Schema";
3
- import { getType } from "./types/registry";
3
+ import { getType, registeredTypes } from "./types/registry";
4
4
  import { $decoder, $descriptors, $encoder, $fieldIndexesByViewTag, $numFields, $refTypeFieldIndexes, $track, $viewFieldIndexes } from "./types/symbols";
5
5
  import { TypeContext } from "./types/TypeContext";
6
6
 
@@ -23,18 +23,48 @@ export type Metadata =
23
23
  { [$descriptors]: { [field: string]: PropertyDescriptor } } // property descriptors
24
24
 
25
25
  export function getNormalizedType(type: DefinitionType): DefinitionType {
26
- return (Array.isArray(type))
27
- ? { array: type[0] }
28
- : (typeof(type['type']) !== "undefined")
29
- ? type['type']
30
- : type;
26
+ if (Array.isArray(type)) {
27
+ return { array: getNormalizedType(type[0]) };
28
+
29
+ } else if (typeof (type['type']) !== "undefined") {
30
+ return type['type'];
31
+
32
+ } else if (isTSEnum(type)) {
33
+ // Detect TS Enum type (either string or number)
34
+ return Object.keys(type).every(key => typeof type[key] === "string")
35
+ ? "string"
36
+ : "number";
37
+
38
+ } else if (typeof type === "object" && type !== null) {
39
+ // Handle collection types
40
+ const collectionType = Object.keys(type).find(k => registeredTypes[k] !== undefined);
41
+ if (collectionType) {
42
+ type[collectionType] = getNormalizedType(type[collectionType]);
43
+ return type;
44
+ }
45
+ }
46
+ return type;
31
47
  }
32
48
 
33
- // TODO: see test: "should support TypeScript enums"
34
49
  function isTSEnum(_enum: any) {
50
+ if (typeof _enum === 'function' && _enum[Symbol.metadata]) {
51
+ return false;
52
+ }
53
+
35
54
  const keys = Object.keys(_enum);
36
55
  const numericFields = keys.filter(k => /\d+/.test(k));
37
- return (numericFields.length === (keys.length / 2) && _enum[_enum[numericFields[0]]] == numericFields[0]);
56
+
57
+ // Check for number enum (has numeric keys and reverse mapping)
58
+ if (numericFields.length > 0 && numericFields.length === (keys.length / 2) && _enum[_enum[numericFields[0]]] == numericFields[0]) {
59
+ return true;
60
+ }
61
+
62
+ // Check for string enum (all values are strings and keys match values)
63
+ if (keys.length > 0 && keys.every(key => typeof _enum[key] === 'string' && _enum[key] === key)) {
64
+ return true;
65
+ }
66
+
67
+ return false;
38
68
  }
39
69
 
40
70
  export const Metadata = {
@@ -163,16 +193,14 @@ export const Metadata = {
163
193
  fieldIndex++;
164
194
 
165
195
  for (const field in fields) {
166
- const type = fields[field];
196
+ const type = getNormalizedType(fields[field]);
167
197
 
168
198
  // FIXME: this code is duplicated from @type() annotation
169
- const complexTypeKlass = (Array.isArray(type))
170
- ? getType("array")
171
- : (typeof(Object.keys(type)[0]) === "string") && getType(Object.keys(type)[0]);
199
+ const complexTypeKlass = typeof(Object.keys(type)[0]) === "string" && getType(Object.keys(type)[0]);
172
200
 
173
201
  const childType = (complexTypeKlass)
174
202
  ? Object.values(type)[0]
175
- : getNormalizedType(type);
203
+ : type;
176
204
 
177
205
  Metadata.addField(
178
206
  metadata,
@@ -2,7 +2,7 @@ import "./symbol.shim";
2
2
  import { Schema } from './Schema';
3
3
  import { ArraySchema } from './types/custom/ArraySchema';
4
4
  import { MapSchema } from './types/custom/MapSchema';
5
- import { Metadata } from "./Metadata";
5
+ import { getNormalizedType, Metadata } from "./Metadata";
6
6
  import { $changes, $childType, $descriptors, $numFields, $track } from "./types/symbols";
7
7
  import { TypeDefinition, getType } from "./types/registry";
8
8
  import { OPERATION } from "./encoding/spec";
@@ -285,6 +285,9 @@ export function type (
285
285
  throw new Error(`${constructor.name}: @type() reference provided for "${field}" is undefined. Make sure you don't have any circular dependencies.`);
286
286
  }
287
287
 
288
+ // Normalize type (enum/collection/etc)
289
+ type = getNormalizedType(type);
290
+
288
291
  // for inheritance support
289
292
  TypeContext.register(constructor);
290
293
 
@@ -339,9 +342,7 @@ export function type (
339
342
  );
340
343
 
341
344
  } else {
342
- const complexTypeKlass = (Array.isArray(type))
343
- ? getType("array")
344
- : (typeof(Object.keys(type)[0]) === "string") && getType(Object.keys(type)[0]);
345
+ const complexTypeKlass = typeof(Object.keys(type)[0]) === "string" && getType(Object.keys(type)[0]);
345
346
 
346
347
  const childType = (complexTypeKlass)
347
348
  ? Object.values(type)[0]
@@ -517,10 +518,12 @@ export function schema<T extends Definition, P extends typeof Schema = typeof Sc
517
518
  ? DEFAULT_VIEW_TAG
518
519
  : value['view'];
519
520
  }
520
- fields[fieldName] = value;
521
+
522
+ fields[fieldName] = getNormalizedType(value);
521
523
 
522
524
  // If no explicit default provided, handle automatic instantiation for collection types
523
525
  if (!Object.prototype.hasOwnProperty.call(value, 'default')) {
526
+ // TODO: remove Array.isArray() check. Use ['array'] !== undefined only.
524
527
  if (Array.isArray(value) || value['array'] !== undefined) {
525
528
  // Collection: Array → new ArraySchema()
526
529
  defaultValues[fieldName] = new ArraySchema();
@@ -550,13 +553,13 @@ export function schema<T extends Definition, P extends typeof Schema = typeof Sc
550
553
  if (Schema.is(value)) {
551
554
  // Direct Schema type: Type → new Type()
552
555
  defaultValues[fieldName] = new value();
553
- fields[fieldName] = value;
556
+ fields[fieldName] = getNormalizedType(value);
554
557
  } else {
555
558
  methods[fieldName] = value;
556
559
  }
557
560
 
558
561
  } else {
559
- fields[fieldName] = value;
562
+ fields[fieldName] = getNormalizedType(value);
560
563
  }
561
564
  }
562
565
 
@@ -78,7 +78,7 @@ export class Root {
78
78
  if (child.removeParent(changeTree.ref)) {
79
79
  if ((
80
80
  child.parentChain === undefined || // no parent, remove it
81
- (child.parentChain && this.refCount[child.refId] > 1) // parent is still in use, but has more than one reference, remove it
81
+ (child.parentChain && this.refCount[child.refId] > 0) // parent is still in use, but has more than one reference, remove it
82
82
  )) {
83
83
  this.remove(child);
84
84
 
@@ -28,25 +28,34 @@ export type InferValueType<T extends DefinitionType> =
28
28
  : T extends "float64" ? number
29
29
  : T extends "boolean" ? boolean
30
30
 
31
+ // Handle { type: ... } patterns
31
32
  : T extends { type: infer ChildType extends Constructor } ? InstanceType<ChildType>
32
- : T extends { type: infer ChildType extends PrimitiveType } ? ChildType
33
+ : T extends { type: Array<infer ChildType> } ? (ChildType extends Record<string | number, string | number> ? ChildType[keyof ChildType][] : ChildType[]) // TS ENUM
34
+ : T extends { type: { map: infer ChildType } } ? (ChildType extends Record<string | number, string | number> ? MapSchema<ChildType[keyof ChildType]> : MapSchema<ChildType>) // TS ENUM
35
+ : T extends { type: { set: infer ChildType } } ? (ChildType extends Record<string | number, string | number> ? SetSchema<ChildType[keyof ChildType]> : SetSchema<ChildType>) // TS ENUM
36
+ : T extends { type: { collection: infer ChildType } } ? (ChildType extends Record<string | number, string | number> ? CollectionSchema<ChildType[keyof ChildType]> : CollectionSchema<ChildType>) // TS ENUM
37
+ : T extends { type: infer ChildType } ? (ChildType extends Record<string | number, string | number> ? ChildType[keyof ChildType] : ChildType) // TS ENUM
33
38
 
39
+ // Handle direct array patterns
34
40
  : T extends Array<infer ChildType extends Constructor> ? InstanceType<ChildType>[]
35
- : T extends Array<infer ChildType extends RawPrimitiveType> ? ChildType[]
41
+ : T extends Array<infer ChildType> ? (ChildType extends Record<string | number, string | number> ? ChildType[keyof ChildType][] : ChildType[]) // TS ENUM
36
42
 
43
+ // Handle collection object patterns
37
44
  : T extends { array: infer ChildType extends Constructor } ? InstanceType<ChildType>[]
38
- : T extends { array: infer ChildType extends PrimitiveType } ? ChildType[]
45
+ : T extends { array: infer ChildType } ? (ChildType extends Record<string | number, string | number> ? ChildType[keyof ChildType][] : ChildType[]) // TS ENUM
39
46
 
40
47
  : T extends { map: infer ChildType extends Constructor } ? MapSchema<InstanceType<ChildType>>
41
- : T extends { map: infer ChildType extends PrimitiveType } ? MapSchema<ChildType>
48
+ : T extends { map: infer ChildType } ? (ChildType extends Record<string | number, string | number> ? MapSchema<ChildType[keyof ChildType]> : MapSchema<ChildType>) // TS ENUM
42
49
 
43
50
  : T extends { set: infer ChildType extends Constructor } ? SetSchema<InstanceType<ChildType>>
44
- : T extends { set: infer ChildType extends PrimitiveType } ? SetSchema<ChildType>
51
+ : T extends { set: infer ChildType } ? (ChildType extends Record<string | number, string | number> ? SetSchema<ChildType[keyof ChildType]> : SetSchema<ChildType>) // TS ENUM
45
52
 
46
53
  : T extends { collection: infer ChildType extends Constructor } ? CollectionSchema<InstanceType<ChildType>>
47
- : T extends { collection: infer ChildType extends PrimitiveType } ? CollectionSchema<ChildType>
54
+ : T extends { collection: infer ChildType } ? (ChildType extends Record<string | number, string | number> ? CollectionSchema<ChildType[keyof ChildType]> : CollectionSchema<ChildType>) // TS ENUM
48
55
 
56
+ // Handle direct types
49
57
  : T extends Constructor ? InstanceType<T>
58
+ : T extends Record<string | number, string | number> ? T[keyof T] // TS ENUM
50
59
  : T extends PrimitiveType ? T
51
60
 
52
61
  : never;
@@ -114,17 +114,7 @@ export class TypeContext {
114
114
  continue;
115
115
  }
116
116
 
117
- if (Array.isArray(fieldType)) {
118
- const type = fieldType[0];
119
-
120
- // skip primitive types
121
- if (type === "string") {
122
- continue;
123
- }
124
-
125
- this.discoverTypes(type as typeof Schema, klass, index, parentHasViewTag || fieldHasViewTag);
126
-
127
- } else if (typeof (fieldType) === "function") {
117
+ if (typeof (fieldType) === "function") {
128
118
  this.discoverTypes(fieldType as typeof Schema, klass, index, parentHasViewTag || fieldHasViewTag);
129
119
 
130
120
  } else {
@@ -8,7 +8,8 @@ export interface TypeDefinition {
8
8
  decode?: (bytes: BufferLike, it: Iterator) => any;
9
9
  }
10
10
 
11
- const registeredTypes: {[identifier: string] : TypeDefinition} = {};
11
+ export const registeredTypes: {[identifier: string] : TypeDefinition} = {};
12
+
12
13
  const identifiers = new Map<any, string>();
13
14
 
14
15
  export function registerType(identifier: string, definition: TypeDefinition) {