@colyseus/schema 5.0.19 → 5.0.21
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/README.md +4 -3
- package/build/Reflection.d.ts +2 -2
- package/build/annotations.d.ts +9 -7
- package/build/decoder/strategy/Callbacks.d.ts +7 -8
- package/build/decoder/strategy/getDecoderStateCallbacks.d.ts +2 -2
- package/build/index.cjs +23 -9
- package/build/index.cjs.map +1 -1
- package/build/index.js +23 -9
- package/build/index.mjs +23 -9
- package/build/index.mjs.map +1 -1
- package/build/types/HelperTypes.d.ts +24 -14
- package/package.json +9 -8
- package/src/Metadata.ts +4 -0
- package/src/annotations.ts +33 -21
- package/src/decoder/strategy/Callbacks.ts +7 -8
- package/src/decoder/strategy/getDecoderStateCallbacks.ts +2 -2
- package/src/types/HelperTypes.ts +43 -34
package/README.md
CHANGED
|
@@ -2,17 +2,18 @@
|
|
|
2
2
|
<img src="logo.png?raw=true" width="50%" />
|
|
3
3
|
<br>
|
|
4
4
|
<p>
|
|
5
|
-
|
|
5
|
+
<b>Automatic state replication for multiplayer games.</b><br>
|
|
6
6
|
Made for <a href="https://github.com/colyseus/colyseus">Colyseus</a>, yet can be used standalone.
|
|
7
7
|
</p>
|
|
8
8
|
</div>
|
|
9
9
|
|
|
10
10
|
# Features
|
|
11
11
|
|
|
12
|
-
- **
|
|
12
|
+
- **Plain Objects, Synced**: Assign a property, `push` to an array, or `set` on a map. Change tracking, encoding and decoding happen for you.
|
|
13
|
+
- **Delta Encoding**: Only the properties that changed are sent, in a compact binary format.
|
|
13
14
|
- **Trigger Callbacks at Decoding**: [Bring your own](https://docs.colyseus.io/state/callbacks/custom) callback system at decoding, or use the built-in one.
|
|
14
15
|
- **Instance Reference Tracking**: Share references of the same instance across the state.
|
|
15
|
-
- **State Views**:
|
|
16
|
+
- **State Views**: Per-client visibility. Decide which properties and instances each client receives.
|
|
16
17
|
- **Reflection**: Encode/Decode schema definitions.
|
|
17
18
|
- **Schema Generation**: Generate client-side schema files for strictly typed languages.
|
|
18
19
|
- **Type Safety**: Strictly typed schema definitions.
|
package/build/Reflection.d.ts
CHANGED
|
@@ -76,7 +76,7 @@ export declare const ReflectionField: import("./annotations.js").SchemaWithExten
|
|
|
76
76
|
max: number;
|
|
77
77
|
bits: number;
|
|
78
78
|
mode: number;
|
|
79
|
-
} & {} & Schema<any> & Schema<unknown>,
|
|
79
|
+
} & {} & Schema<any> & Schema<unknown>, true, true>;
|
|
80
80
|
}, import("./index.js").BuilderInitProps<{
|
|
81
81
|
name: FieldBuilder<string, false, false>;
|
|
82
82
|
type: FieldBuilder<string, false, false>;
|
|
@@ -91,7 +91,7 @@ export declare const ReflectionField: import("./annotations.js").SchemaWithExten
|
|
|
91
91
|
max: number;
|
|
92
92
|
bits: number;
|
|
93
93
|
mode: number;
|
|
94
|
-
} & {} & Schema<any> & Schema<unknown>,
|
|
94
|
+
} & {} & Schema<any> & Schema<unknown>, true, true>;
|
|
95
95
|
}>, typeof Schema>;
|
|
96
96
|
export type ReflectionField = SchemaType<typeof ReflectionField>;
|
|
97
97
|
export declare const ReflectionType: import("./annotations.js").SchemaWithExtendsConstructor<{
|
package/build/annotations.d.ts
CHANGED
|
@@ -139,8 +139,9 @@ type HasExplicitInit<T> = T extends {
|
|
|
139
139
|
* (shorthand for `t.ref(Class)`), or a method (attached to the prototype).
|
|
140
140
|
*/
|
|
141
141
|
export type FieldsAndMethods = Record<string, FieldBuilder<any, boolean, boolean> | (new (...args: any[]) => Schema) | Function>;
|
|
142
|
+
type SchemaInstance<T, P extends typeof Schema> = InferSchemaInstanceType<T> & InstanceType<P>;
|
|
142
143
|
export interface SchemaWithExtends<T, P extends typeof Schema> {
|
|
143
|
-
extend: <T2 extends FieldsAndMethods = FieldsAndMethods>(fields: T2 & ThisType<
|
|
144
|
+
extend: <T2 extends FieldsAndMethods = FieldsAndMethods>(fields: T2 & ThisType<SchemaInstance<T & T2, P>>, name?: string) => SchemaWithExtendsConstructor<T & T2, ExtractInitProps<T & T2>, P>;
|
|
144
145
|
}
|
|
145
146
|
/**
|
|
146
147
|
* Get the type of the schema defined via `schema('Name', {...})` method.
|
|
@@ -156,17 +157,18 @@ export type SchemaType<T extends {
|
|
|
156
157
|
'~type': any;
|
|
157
158
|
}> = T['~type'];
|
|
158
159
|
export interface SchemaWithExtendsConstructor<T, InitProps, P extends typeof Schema> extends SchemaWithExtends<T, P> {
|
|
159
|
-
'~type':
|
|
160
|
+
'~type': SchemaInstance<T, P>;
|
|
160
161
|
new (...args: [
|
|
161
162
|
InitProps
|
|
162
|
-
] extends [never] ? [] : InitProps extends readonly any[] ? InitProps : HasExplicitInit<T> extends true ? [InitProps] : IsInitPropsRequired<T> extends true ? ([] | [InitProps]) : [InitProps?]):
|
|
163
|
-
prototype:
|
|
164
|
-
initialize(...args: [InitProps] extends [never] ? [] : InitProps extends readonly any[] ? InitProps : [InitProps]): void;
|
|
165
|
-
};
|
|
163
|
+
] extends [never] ? [] : InitProps extends readonly any[] ? InitProps : HasExplicitInit<T> extends true ? [InitProps] : IsInitPropsRequired<T> extends true ? ([] | [InitProps]) : [InitProps?]): SchemaInstance<T, P>;
|
|
164
|
+
prototype: SchemaInstance<T, P>;
|
|
166
165
|
}
|
|
167
166
|
/**
|
|
168
167
|
* Define a Schema class declaratively.
|
|
169
168
|
*
|
|
169
|
+
* `initialize()` acts as the constructor: a class created with `.extend()`
|
|
170
|
+
* inherits the parent's unless it defines its own.
|
|
171
|
+
*
|
|
170
172
|
* @example
|
|
171
173
|
* import { schema, t } from '@colyseus/schema';
|
|
172
174
|
*
|
|
@@ -180,5 +182,5 @@ export interface SchemaWithExtendsConstructor<T, InitProps, P extends typeof Sch
|
|
|
180
182
|
* weapon: t.string(),
|
|
181
183
|
* }, 'Warrior');
|
|
182
184
|
*/
|
|
183
|
-
export declare function schema<T extends FieldsAndMethods, P extends typeof Schema = typeof Schema>(fieldsAndMethods: T & ThisType<
|
|
185
|
+
export declare function schema<T extends FieldsAndMethods, P extends typeof Schema = typeof Schema>(fieldsAndMethods: T & ThisType<SchemaInstance<T, P>>, name?: string, inherits?: P): SchemaWithExtendsConstructor<T, ExtractInitProps<T>, P>;
|
|
184
186
|
export {};
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NonFunctionPropNames, CollectionLike } from "../../types/HelperTypes.js";
|
|
2
2
|
import type { IRef, Ref } from "../../encoder/ChangeTree.js";
|
|
3
3
|
import { Decoder } from "../Decoder.js";
|
|
4
4
|
import { DataChange } from "../DecodeOperation.js";
|
|
5
5
|
import { OPERATION } from "../../encoding/spec.js";
|
|
6
6
|
import { Schema } from "../../Schema.js";
|
|
7
|
-
import { $refId } from "../../types/symbols.js";
|
|
8
7
|
import { MapSchema } from "../../types/custom/MapSchema.js";
|
|
9
8
|
import { ArraySchema } from "../../types/custom/ArraySchema.js";
|
|
10
9
|
import { type SchemaCallbackProxy } from "./getDecoderStateCallbacks.js";
|
|
@@ -12,12 +11,12 @@ type PropertyChangeCallback<K> = (currentValue: K, previousValue: K) => void;
|
|
|
12
11
|
type KeyValueCallback<K, V> = (key: K, value: V) => void;
|
|
13
12
|
type ValueKeyCallback<V, K> = (value: V, key: K) => void;
|
|
14
13
|
type InstanceChangeCallback = () => void;
|
|
15
|
-
type PublicPropNames<T> =
|
|
16
|
-
type CollectionPropNames<T> =
|
|
17
|
-
[K in keyof T]: T[K] extends
|
|
18
|
-
}[keyof T] & string
|
|
19
|
-
type CollectionValueType<T, K extends keyof T> = T[K] extends MapSchema<infer V, any> ? V : T[K] extends ArraySchema<infer V> ? V : T[K] extends
|
|
20
|
-
type CollectionKeyType<T, K extends keyof T> = T[K] extends MapSchema<any, infer Key> ? Key : T[K] extends ArraySchema<any> ? number : T[K] extends
|
|
14
|
+
type PublicPropNames<T> = NonFunctionPropNames<T> & string;
|
|
15
|
+
type CollectionPropNames<T> = {
|
|
16
|
+
[K in keyof T]: T[K] extends CollectionLike<any, any> ? K : never;
|
|
17
|
+
}[keyof T] & string;
|
|
18
|
+
type CollectionValueType<T, K extends keyof T> = T[K] extends MapSchema<infer V, any> ? V : T[K] extends ArraySchema<infer V> ? V : T[K] extends CollectionLike<any, infer V, any> ? V : never;
|
|
19
|
+
type CollectionKeyType<T, K extends keyof T> = T[K] extends MapSchema<any, infer Key> ? Key : T[K] extends ArraySchema<any> ? number : T[K] extends CollectionLike<infer Key, any, any> ? Key : never;
|
|
21
20
|
export declare class StateCallbackStrategy<TState extends IRef> {
|
|
22
21
|
protected decoder: Decoder<TState>;
|
|
23
22
|
protected uniqueRefIds: Set<number>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NonFunctionNonPrimitivePropNames, NonFunctionPropNames, CollectionLike } from "../../types/HelperTypes.js";
|
|
2
2
|
import { Decoder } from "../Decoder.js";
|
|
3
3
|
import { Schema } from "../../Schema.js";
|
|
4
4
|
/**
|
|
@@ -10,7 +10,7 @@ import { Schema } from "../../Schema.js";
|
|
|
10
10
|
*/
|
|
11
11
|
export type SchemaCallbackProxy<RoomState> = (<T>(instance: T) => CallbackProxy<T>);
|
|
12
12
|
export type GetCallbackProxy = SchemaCallbackProxy<any>;
|
|
13
|
-
export type CallbackProxy<T> = unknown extends T ? SchemaCallback<T> & CollectionCallback<any, any> : T extends
|
|
13
|
+
export type CallbackProxy<T> = unknown extends T ? SchemaCallback<T> & CollectionCallback<any, any> : T extends CollectionLike<infer K, infer V, infer _> ? CollectionCallback<K, V> : SchemaCallback<T>;
|
|
14
14
|
export type SchemaCallback<T> = {
|
|
15
15
|
/**
|
|
16
16
|
* Trigger callback when value of a property changes.
|
package/build/index.cjs
CHANGED
|
@@ -1411,6 +1411,10 @@ const Metadata = {
|
|
|
1411
1411
|
});
|
|
1412
1412
|
}
|
|
1413
1413
|
for (const field in fields) {
|
|
1414
|
+
// metadata inherits the parent's, so this also catches a redeclared parent field
|
|
1415
|
+
if (metadata[field] !== undefined) {
|
|
1416
|
+
throw new Error(`@colyseus/schema: Duplicate '${field}' definition on '${constructor.name || "(anonymous)"}'.`);
|
|
1417
|
+
}
|
|
1414
1418
|
Metadata.defineField(constructor, metadata, fieldIndex, field, fields[field]);
|
|
1415
1419
|
fieldIndex++;
|
|
1416
1420
|
}
|
|
@@ -7275,6 +7279,9 @@ function makeAutoDefaultFactory(rawType) {
|
|
|
7275
7279
|
/**
|
|
7276
7280
|
* Define a Schema class declaratively.
|
|
7277
7281
|
*
|
|
7282
|
+
* `initialize()` acts as the constructor: a class created with `.extend()`
|
|
7283
|
+
* inherits the parent's unless it defines its own.
|
|
7284
|
+
*
|
|
7278
7285
|
* @example
|
|
7279
7286
|
* import { schema, t } from '@colyseus/schema';
|
|
7280
7287
|
*
|
|
@@ -7435,8 +7442,11 @@ function schema(fieldsAndMethods, name, inherits = Schema) {
|
|
|
7435
7442
|
return parentProps;
|
|
7436
7443
|
};
|
|
7437
7444
|
const hasInitialize = typeof methods.initialize === "function";
|
|
7438
|
-
|
|
7439
|
-
|
|
7445
|
+
// Like a constructor: the most-derived initialize() runs once, own or
|
|
7446
|
+
// inherited from a schema() parent. A custom base's initialize() is not
|
|
7447
|
+
// picked up — the constructor type only sees the fields map.
|
|
7448
|
+
const initialize = methods.initialize ?? inherits._initialize;
|
|
7449
|
+
const klass = class extends inherits {
|
|
7440
7450
|
constructor(...args) {
|
|
7441
7451
|
const props = args[0];
|
|
7442
7452
|
if (props === undefined) {
|
|
@@ -7451,13 +7461,20 @@ function schema(fieldsAndMethods, name, inherits = Schema) {
|
|
|
7451
7461
|
// `initialize()` owns the schema fields, so only parent props flow up.
|
|
7452
7462
|
super(Object.assign(getDefaultValues(), hasInitialize ? getParentProps(props) : props));
|
|
7453
7463
|
}
|
|
7454
|
-
// Only
|
|
7455
|
-
if (
|
|
7456
|
-
|
|
7464
|
+
// Only on the exact target class — parents' constructors skip it.
|
|
7465
|
+
if (initialize && new.target === klass) {
|
|
7466
|
+
initialize.apply(this, args);
|
|
7457
7467
|
}
|
|
7458
7468
|
}
|
|
7459
|
-
}
|
|
7469
|
+
};
|
|
7470
|
+
// named before setFields so a duplicate-field error can say which class
|
|
7471
|
+
if (name) {
|
|
7472
|
+
Object.defineProperty(klass, "name", { value: name });
|
|
7473
|
+
}
|
|
7474
|
+
/** @codegen-ignore */
|
|
7475
|
+
Metadata.setFields(klass, fields);
|
|
7460
7476
|
klass._getDefaultValues = getDefaultValues;
|
|
7477
|
+
klass._initialize = initialize;
|
|
7461
7478
|
Object.assign(klass.prototype, methods);
|
|
7462
7479
|
for (const fieldName in viewTagFields) {
|
|
7463
7480
|
view(viewTagFields[fieldName])(klass.prototype, fieldName);
|
|
@@ -7489,9 +7506,6 @@ function schema(fieldsAndMethods, name, inherits = Schema) {
|
|
|
7489
7506
|
metadata[metadata[fieldName]].optional = true;
|
|
7490
7507
|
}
|
|
7491
7508
|
}
|
|
7492
|
-
if (name) {
|
|
7493
|
-
Object.defineProperty(klass, "name", { value: name });
|
|
7494
|
-
}
|
|
7495
7509
|
klass.extend = (childFields, childName) => schema(childFields, childName, klass);
|
|
7496
7510
|
return klass;
|
|
7497
7511
|
}
|