@colyseus/schema 5.0.21 → 5.0.22

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.
@@ -8,7 +8,7 @@ import type { SetSchema } from "./custom/SetSchema.js";
8
8
  import type { StreamSchema } from "./custom/StreamSchema.js";
9
9
  import type { FieldBuilder } from "./builder.js";
10
10
  export type Constructor<T = {}> = new (...args: any[]) => T;
11
- type PrimitiveStringToType<T> = T extends "string" ? string : T extends "number" | "int8" | "uint8" | "int16" | "uint16" | "int32" | "uint32" | "int64" | "uint64" | "float32" | "float64" ? number : T extends "boolean" ? boolean : T;
11
+ type PrimitiveStringToType<T> = T extends "string" ? string : T extends "number" | "int8" | "uint8" | "int16" | "uint16" | "int32" | "uint32" | "int64" | "uint64" | "float32" | "float64" ? number : T extends "bigint64" | "biguint64" ? bigint : T extends "boolean" ? boolean : T;
12
12
  /**
13
13
  * What the decoder callbacks accept as "a collection": the public shape, which
14
14
  * a plain array satisfies too — `@type([X]) items: X[]` is a common way to
@@ -23,7 +23,7 @@ export interface Collection<K = any, V = any, IT = V> extends CollectionLike<K,
23
23
  /** See {@link $resyncPrune} — every collection kind must declare its resync-sweep semantics. */
24
24
  [$resyncPrune](visited: Set<number | string>, prune: (value: V, identity: number | string) => void, keep: (value: V) => void): void;
25
25
  }
26
- export type InferValueType<T> = T extends FieldBuilder<infer V> ? V : 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 {
26
+ export type InferValueType<T> = T extends FieldBuilder<infer V> ? V : 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 "bigint64" ? bigint : T extends "biguint64" ? bigint : T extends "boolean" ? boolean : T extends {
27
27
  type: infer ChildType extends PrimitiveType;
28
28
  } ? InferValueType<ChildType> : T extends {
29
29
  type: infer ChildType extends Constructor;
@@ -76,6 +76,18 @@ export type InferValueType<T> = T extends FieldBuilder<infer V> ? V : T extends
76
76
  } ? StreamSchema<InstanceType<ChildType>> : T extends {
77
77
  stream: infer ChildType;
78
78
  } ? StreamSchema<ChildType> : T extends Constructor ? InstanceType<T> : T extends Record<string | number, string | number> ? T[keyof T] : T extends PrimitiveType ? T : never;
79
+ /**
80
+ * Codecs that can carry a `T` — {@link InferValueType} run backwards, derived
81
+ * from it so the two can't drift. Constrains the element refinement in
82
+ * `t.array<Mark>("uint8")`; `never` (an uncallable overload) when no codec
83
+ * decodes into `T`.
84
+ *
85
+ * `[T] extends [...]` is deliberate: a distributive check would let a mixed
86
+ * union like `string | number` match on either half.
87
+ */
88
+ export type CodecFor<T> = {
89
+ [K in RawPrimitiveType]: [T] extends [InferValueType<K>] ? K : never;
90
+ }[RawPrimitiveType];
79
91
  type IsOptionalBuilderKey<T, K extends keyof T> = T[K] extends FieldBuilder<unknown, boolean, infer O extends boolean> ? O : false;
80
92
  type OptionalBuilderKeys<T> = {
81
93
  [K in keyof T]-?: IsOptionalBuilderKey<T, K> extends true ? K : never;
@@ -5,7 +5,7 @@ import type { CollectionSchema } from "./custom/CollectionSchema.js";
5
5
  import type { StreamSchema } from "./custom/StreamSchema.js";
6
6
  import type { Schema } from "../Schema.js";
7
7
  import type { DefinitionType, RawPrimitiveType } from "../annotations.js";
8
- import type { InferValueType, Constructor } from "./HelperTypes.js";
8
+ import type { InferValueType, Constructor, CodecFor } from "./HelperTypes.js";
9
9
  import { $builder } from "./symbols.js";
10
10
  import { type QuantizeOptions } from "./quantize.js";
11
11
  /**
@@ -217,18 +217,22 @@ export type ChildType = RawPrimitiveType | Constructor<Schema>;
217
217
  interface ArrayFactory {
218
218
  <C extends Constructor<Schema>>(child: C): FieldBuilder<ArraySchema<InstanceType<C>>, true, false>;
219
219
  <P extends RawPrimitiveType>(child: P): FieldBuilder<ArraySchema<InferValueType<P>>, true, false>;
220
+ <T>(child: CodecFor<T>): FieldBuilder<ArraySchema<T>, true, false>;
220
221
  }
221
222
  interface MapFactory {
222
223
  <C extends Constructor<Schema>>(child: C): FieldBuilder<MapSchema<InstanceType<C>>, true, false>;
223
224
  <P extends RawPrimitiveType>(child: P): FieldBuilder<MapSchema<InferValueType<P>>, true, false>;
225
+ <T>(child: CodecFor<T>): FieldBuilder<MapSchema<T>, true, false>;
224
226
  }
225
227
  interface SetFactory {
226
228
  <C extends Constructor<Schema>>(child: C): FieldBuilder<SetSchema<InstanceType<C>>, true, false>;
227
229
  <P extends RawPrimitiveType>(child: P): FieldBuilder<SetSchema<InferValueType<P>>, true, false>;
230
+ <T>(child: CodecFor<T>): FieldBuilder<SetSchema<T>, true, false>;
228
231
  }
229
232
  interface CollectionFactory {
230
233
  <C extends Constructor<Schema>>(child: C): FieldBuilder<CollectionSchema<InstanceType<C>>, true, false>;
231
234
  <P extends RawPrimitiveType>(child: P): FieldBuilder<CollectionSchema<InferValueType<P>>, true, false>;
235
+ <T>(child: CodecFor<T>): FieldBuilder<CollectionSchema<T>, true, false>;
232
236
  }
233
237
  interface StreamFactory {
234
238
  <C extends Constructor<Schema>>(child: C): FieldBuilder<StreamSchema<InstanceType<C>>, true, false>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@colyseus/schema",
3
- "version": "5.0.21",
3
+ "version": "5.0.22",
4
4
  "description": "Automatic state replication for multiplayer games. Mutate plain objects, and every client gets a live, typed mirror through delta encoding.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -14,6 +14,7 @@ export type Constructor<T = {}> = new (...args: any[]) => T;
14
14
  type PrimitiveStringToType<T> =
15
15
  T extends "string" ? string
16
16
  : T extends "number" | "int8" | "uint8" | "int16" | "uint16" | "int32" | "uint32" | "int64" | "uint64" | "float32" | "float64" ? number
17
+ : T extends "bigint64" | "biguint64" ? bigint
17
18
  : T extends "boolean" ? boolean
18
19
  : T;
19
20
 
@@ -53,6 +54,8 @@ export type InferValueType<T> =
53
54
  : T extends "uint64" ? number
54
55
  : T extends "float32" ? number
55
56
  : T extends "float64" ? number
57
+ : T extends "bigint64" ? bigint
58
+ : T extends "biguint64" ? bigint
56
59
  : T extends "boolean" ? boolean
57
60
 
58
61
  // Handle { type: ... } patterns
@@ -95,6 +98,19 @@ export type InferValueType<T> =
95
98
 
96
99
  : never;
97
100
 
101
+ /**
102
+ * Codecs that can carry a `T` — {@link InferValueType} run backwards, derived
103
+ * from it so the two can't drift. Constrains the element refinement in
104
+ * `t.array<Mark>("uint8")`; `never` (an uncallable overload) when no codec
105
+ * decodes into `T`.
106
+ *
107
+ * `[T] extends [...]` is deliberate: a distributive check would let a mixed
108
+ * union like `string | number` match on either half.
109
+ */
110
+ export type CodecFor<T> = {
111
+ [K in RawPrimitiveType]: [T] extends [InferValueType<K>] ? K : never
112
+ }[RawPrimitiveType];
113
+
98
114
  // Keys whose builder carries the `.optional()` brand. Reads the brand rather
99
115
  // than `undefined extends V`: the latter is true for EVERY V when the consumer
100
116
  // compiles with `strictNullChecks: false`, flipping all fields optional.
@@ -5,7 +5,7 @@ import type { CollectionSchema } from "./custom/CollectionSchema.js";
5
5
  import type { StreamSchema } from "./custom/StreamSchema.js";
6
6
  import type { Schema } from "../Schema.js";
7
7
  import type { DefinitionType, RawPrimitiveType } from "../annotations.js";
8
- import type { InferValueType, Constructor } from "./HelperTypes.js";
8
+ import type { InferValueType, Constructor, CodecFor } from "./HelperTypes.js";
9
9
  import { $builder } from "./symbols.js";
10
10
  import { ARRAY_STREAM_NOT_SUPPORTED } from "../encoder/streaming.js";
11
11
  import { resolveQuantize, type QuantizeOptions } from "./quantize.js";
@@ -337,21 +337,28 @@ function resolveChild(child: ChildType): DefinitionType {
337
337
  // overloads narrow the return type for Schema/primitive children.
338
338
  // All collection factories tag `HasDefault = true` because schema() auto-
339
339
  // instantiates an empty collection when no explicit default is given.
340
+ //
341
+ // The third overload refines the ELEMENT type (`t.map<V>` — the value, never
342
+ // the key), with the same type-level-only caveat as `PrimitiveFactory` above.
340
343
  interface ArrayFactory {
341
344
  <C extends Constructor<Schema>>(child: C): FieldBuilder<ArraySchema<InstanceType<C>>, true, false>;
342
345
  <P extends RawPrimitiveType>(child: P): FieldBuilder<ArraySchema<InferValueType<P>>, true, false>;
346
+ <T>(child: CodecFor<T>): FieldBuilder<ArraySchema<T>, true, false>;
343
347
  }
344
348
  interface MapFactory {
345
349
  <C extends Constructor<Schema>>(child: C): FieldBuilder<MapSchema<InstanceType<C>>, true, false>;
346
350
  <P extends RawPrimitiveType>(child: P): FieldBuilder<MapSchema<InferValueType<P>>, true, false>;
351
+ <T>(child: CodecFor<T>): FieldBuilder<MapSchema<T>, true, false>;
347
352
  }
348
353
  interface SetFactory {
349
354
  <C extends Constructor<Schema>>(child: C): FieldBuilder<SetSchema<InstanceType<C>>, true, false>;
350
355
  <P extends RawPrimitiveType>(child: P): FieldBuilder<SetSchema<InferValueType<P>>, true, false>;
356
+ <T>(child: CodecFor<T>): FieldBuilder<SetSchema<T>, true, false>;
351
357
  }
352
358
  interface CollectionFactory {
353
359
  <C extends Constructor<Schema>>(child: C): FieldBuilder<CollectionSchema<InstanceType<C>>, true, false>;
354
360
  <P extends RawPrimitiveType>(child: P): FieldBuilder<CollectionSchema<InferValueType<P>>, true, false>;
361
+ <T>(child: CodecFor<T>): FieldBuilder<CollectionSchema<T>, true, false>;
355
362
  }
356
363
  // t.stream(Entity) — priority-batched collection of Schema instances.
357
364
  // Element type is restricted to Schema subclasses (no primitives) because