@colyseus/schema 4.0.3 → 4.0.5
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/Schema.d.ts +7 -0
- package/build/decoder/strategy/Callbacks.d.ts +7 -32
- package/build/index.cjs +21 -38
- package/build/index.cjs.map +1 -1
- package/build/index.js +21 -38
- package/build/index.mjs +21 -38
- package/build/index.mjs.map +1 -1
- package/package.json +20 -21
- package/src/Schema.ts +10 -0
- package/src/decoder/strategy/Callbacks.ts +17 -43
- package/src/decoder/strategy/getDecoderStateCallbacks.ts +2 -2
package/package.json
CHANGED
|
@@ -1,31 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@colyseus/schema",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.5",
|
|
4
4
|
"description": "Binary state serializer with delta encoding for games",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"schema-codegen": "bin/schema-codegen",
|
|
8
8
|
"schema-debug": "bin/schema-debug"
|
|
9
9
|
},
|
|
10
|
-
"scripts": {
|
|
11
|
-
"build": "tsc -p tsconfig.build.json && rollup -c rollup.config.mjs",
|
|
12
|
-
"watch": "tsc -p tsconfig.build.json -w",
|
|
13
|
-
"test": "tsx --tsconfig tsconfig.test.json ./node_modules/.bin/mocha test/*.test.ts test/**/*.test.ts",
|
|
14
|
-
"coverage": "c8 npm run test",
|
|
15
|
-
"generate-test-1": "bin/schema-codegen test-external/PrimitiveTypes.ts --namespace SchemaTest.PrimitiveTypes --output ../colyseus-unity-sdk/Assets/Colyseus/Tests/Editor/ColyseusTests/Schema/PrimitiveTypes",
|
|
16
|
-
"generate-test-2": "bin/schema-codegen test-external/ChildSchemaTypes.ts --namespace SchemaTest.ChildSchemaTypes --output ../colyseus-unity-sdk/Assets/Colyseus/Tests/Editor/ColyseusTests/Schema/ChildSchemaTypes",
|
|
17
|
-
"generate-test-3": "bin/schema-codegen test-external/ArraySchemaTypes.ts --namespace SchemaTest.ArraySchemaTypes --output ../colyseus-unity-sdk/Assets/Colyseus/Tests/Editor/ColyseusTests/Schema/ArraySchemaTypes",
|
|
18
|
-
"generate-test-4": "bin/schema-codegen test-external/MapSchemaTypes.ts --namespace SchemaTest.MapSchemaTypes --output ../colyseus-unity-sdk/Assets/Colyseus/Tests/Editor/ColyseusTests/Schema/MapSchemaTypes",
|
|
19
|
-
"generate-test-5": "bin/schema-codegen test-external/InheritedTypes.ts --namespace SchemaTest.InheritedTypes --output ../colyseus-unity-sdk/Assets/Colyseus/Tests/Editor/ColyseusTests/Schema/InheritedTypes",
|
|
20
|
-
"generate-test-6": "bin/schema-codegen test-external/MapSchemaInt8.ts --namespace SchemaTest.MapSchemaInt8 --output ../colyseus-unity-sdk/Assets/Colyseus/Tests/Editor/ColyseusTests/Schema/MapSchemaInt8",
|
|
21
|
-
"generate-test-7": "bin/schema-codegen test-external/BackwardsForwards.ts --namespace SchemaTest.BackwardsForwards --output ../colyseus-unity-sdk/Assets/Colyseus/Tests/Editor/ColyseusTests/Schema/BackwardsForwards",
|
|
22
|
-
"generate-test-8": "bin/schema-codegen test-external/FilteredTypes.ts --namespace SchemaTest.FilteredTypes --output ../colyseus-unity-sdk/Assets/Colyseus/Tests/Editor/ColyseusTests/Schema/FilteredTypes",
|
|
23
|
-
"generate-test-9": "bin/schema-codegen test-external/InstanceSharingTypes.ts --namespace SchemaTest.InstanceSharingTypes --output ../colyseus-unity-sdk/Assets/Colyseus/Tests/Editor/ColyseusTests/Schema/InstanceSharingTypes",
|
|
24
|
-
"generate-test-10": "bin/schema-codegen test-external/Callbacks.ts --namespace SchemaTest.Callbacks --output ../colyseus-unity-sdk/Assets/Colyseus/Tests/Editor/ColyseusTests/Schema/Callbacks",
|
|
25
|
-
"generate-test-11": "bin/schema-codegen test-external/MapSchemaMoveNullifyType.ts --namespace SchemaTest.MapSchemaMoveNullifyType --output ../colyseus-unity-sdk/Assets/Colyseus/Tests/Editor/ColyseusTests/Schema/MapSchemaMoveNullifyType",
|
|
26
|
-
"generate-test-12": "bin/schema-codegen test-external/ArraySchemaClear --namespace SchemaTest.ArraySchemaClear --output ../colyseus-unity-sdk/Assets/Colyseus/Tests/Editor/ColyseusTests/Schema/ArraySchemaClear",
|
|
27
|
-
"prepublishOnly": "npm run build"
|
|
28
|
-
},
|
|
29
10
|
"files": [
|
|
30
11
|
"src",
|
|
31
12
|
"build",
|
|
@@ -93,5 +74,23 @@
|
|
|
93
74
|
"text"
|
|
94
75
|
],
|
|
95
76
|
"all": true
|
|
77
|
+
},
|
|
78
|
+
"scripts": {
|
|
79
|
+
"build": "tsc -p tsconfig.build.json && rollup -c rollup.config.mjs",
|
|
80
|
+
"watch": "tsc -p tsconfig.build.json -w",
|
|
81
|
+
"test": "tsx --tsconfig tsconfig.test.json ./node_modules/.bin/mocha test/*.test.ts test/**/*.test.ts",
|
|
82
|
+
"coverage": "c8 npm run test",
|
|
83
|
+
"generate-test-1": "bin/schema-codegen test-external/PrimitiveTypes.ts --namespace SchemaTest.PrimitiveTypes --output ../colyseus-unity-sdk/Assets/Colyseus/Tests/Editor/ColyseusTests/Schema/PrimitiveTypes",
|
|
84
|
+
"generate-test-2": "bin/schema-codegen test-external/ChildSchemaTypes.ts --namespace SchemaTest.ChildSchemaTypes --output ../colyseus-unity-sdk/Assets/Colyseus/Tests/Editor/ColyseusTests/Schema/ChildSchemaTypes",
|
|
85
|
+
"generate-test-3": "bin/schema-codegen test-external/ArraySchemaTypes.ts --namespace SchemaTest.ArraySchemaTypes --output ../colyseus-unity-sdk/Assets/Colyseus/Tests/Editor/ColyseusTests/Schema/ArraySchemaTypes",
|
|
86
|
+
"generate-test-4": "bin/schema-codegen test-external/MapSchemaTypes.ts --namespace SchemaTest.MapSchemaTypes --output ../colyseus-unity-sdk/Assets/Colyseus/Tests/Editor/ColyseusTests/Schema/MapSchemaTypes",
|
|
87
|
+
"generate-test-5": "bin/schema-codegen test-external/InheritedTypes.ts --namespace SchemaTest.InheritedTypes --output ../colyseus-unity-sdk/Assets/Colyseus/Tests/Editor/ColyseusTests/Schema/InheritedTypes",
|
|
88
|
+
"generate-test-6": "bin/schema-codegen test-external/MapSchemaInt8.ts --namespace SchemaTest.MapSchemaInt8 --output ../colyseus-unity-sdk/Assets/Colyseus/Tests/Editor/ColyseusTests/Schema/MapSchemaInt8",
|
|
89
|
+
"generate-test-7": "bin/schema-codegen test-external/BackwardsForwards.ts --namespace SchemaTest.BackwardsForwards --output ../colyseus-unity-sdk/Assets/Colyseus/Tests/Editor/ColyseusTests/Schema/BackwardsForwards",
|
|
90
|
+
"generate-test-8": "bin/schema-codegen test-external/FilteredTypes.ts --namespace SchemaTest.FilteredTypes --output ../colyseus-unity-sdk/Assets/Colyseus/Tests/Editor/ColyseusTests/Schema/FilteredTypes",
|
|
91
|
+
"generate-test-9": "bin/schema-codegen test-external/InstanceSharingTypes.ts --namespace SchemaTest.InstanceSharingTypes --output ../colyseus-unity-sdk/Assets/Colyseus/Tests/Editor/ColyseusTests/Schema/InstanceSharingTypes",
|
|
92
|
+
"generate-test-10": "bin/schema-codegen test-external/Callbacks.ts --namespace SchemaTest.Callbacks --output ../colyseus-unity-sdk/Assets/Colyseus/Tests/Editor/ColyseusTests/Schema/Callbacks",
|
|
93
|
+
"generate-test-11": "bin/schema-codegen test-external/MapSchemaMoveNullifyType.ts --namespace SchemaTest.MapSchemaMoveNullifyType --output ../colyseus-unity-sdk/Assets/Colyseus/Tests/Editor/ColyseusTests/Schema/MapSchemaMoveNullifyType",
|
|
94
|
+
"generate-test-12": "bin/schema-codegen test-external/ArraySchemaClear --namespace SchemaTest.ArraySchemaClear --output ../colyseus-unity-sdk/Assets/Colyseus/Tests/Editor/ColyseusTests/Schema/ArraySchemaClear"
|
|
96
95
|
}
|
|
97
|
-
}
|
|
96
|
+
}
|
package/src/Schema.ts
CHANGED
|
@@ -42,6 +42,16 @@ export class Schema<C = any> implements IRef {
|
|
|
42
42
|
return typeof((type as typeof Schema)[Symbol.metadata]) === "object";
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Check if a value is an instance of Schema.
|
|
47
|
+
* This method uses duck-typing to avoid issues with multiple @colyseus/schema versions.
|
|
48
|
+
* @param obj Value to check
|
|
49
|
+
* @returns true if the value is a Schema instance
|
|
50
|
+
*/
|
|
51
|
+
static isSchema(obj: any): obj is Schema {
|
|
52
|
+
return typeof obj?.assign === "function";
|
|
53
|
+
}
|
|
54
|
+
|
|
45
55
|
/**
|
|
46
56
|
* Track property changes
|
|
47
57
|
*/
|
|
@@ -12,17 +12,17 @@ import { getDecoderStateCallbacks, type SchemaCallbackProxy } from "./getDecoder
|
|
|
12
12
|
import { getRawChangesCallback } from "./RawChanges.js";
|
|
13
13
|
|
|
14
14
|
//
|
|
15
|
-
// C#-style Callbacks API
|
|
16
|
-
// Matches the API from: https://docs.colyseus.io/state/callbacks
|
|
15
|
+
// C#-style Callbacks API (https://docs.colyseus.io/state/callbacks)
|
|
17
16
|
//
|
|
18
17
|
// Key features:
|
|
19
18
|
// - Uses string property names with TypeScript auto-completion
|
|
20
|
-
// -
|
|
19
|
+
// - Parameter order (value, key) for onAdd/onRemove callbacks
|
|
21
20
|
// - Overloaded methods for nested instance callbacks
|
|
22
21
|
//
|
|
23
22
|
|
|
24
23
|
type PropertyChangeCallback<K> = (currentValue: K, previousValue: K) => void;
|
|
25
24
|
type KeyValueCallback<K, V> = (key: K, value: V) => void;
|
|
25
|
+
type ValueKeyCallback<V, K> = (value: V, key: K) => void;
|
|
26
26
|
type InstanceChangeCallback = () => void;
|
|
27
27
|
|
|
28
28
|
// Exclude internal properties from valid property names
|
|
@@ -45,32 +45,6 @@ type CollectionKeyType<T, K extends keyof T> =
|
|
|
45
45
|
T[K] extends ArraySchema<any> ? number :
|
|
46
46
|
T[K] extends Collection<infer Key, any, any> ? Key : never;
|
|
47
47
|
|
|
48
|
-
/**
|
|
49
|
-
* State Callbacks handler
|
|
50
|
-
*
|
|
51
|
-
* Usage:
|
|
52
|
-
* ```ts
|
|
53
|
-
* const $ = Callbacks.get(decoder);
|
|
54
|
-
*
|
|
55
|
-
* // Listen to property changes
|
|
56
|
-
* $.listen("currentTurn", (currentValue, previousValue) => { ... });
|
|
57
|
-
*
|
|
58
|
-
* // Listen to collection additions
|
|
59
|
-
* $.onAdd("entities", (sessionId, entity) => {
|
|
60
|
-
* // Nested property listening
|
|
61
|
-
* $.listen(entity, "hp", (currentHp, previousHp) => { ... });
|
|
62
|
-
* });
|
|
63
|
-
*
|
|
64
|
-
* // Listen to collection removals
|
|
65
|
-
* $.onRemove("entities", (sessionId, entity) => { ... });
|
|
66
|
-
*
|
|
67
|
-
* // Listen to any property change on an instance
|
|
68
|
-
* $.onChange(entity, () => { ... });
|
|
69
|
-
*
|
|
70
|
-
* // Bind properties to another object
|
|
71
|
-
* $.bindTo(player, playerVisual);
|
|
72
|
-
* ```
|
|
73
|
-
*/
|
|
74
48
|
export class StateCallbackStrategy<TState extends Schema> {
|
|
75
49
|
protected decoder: Decoder<TState>;
|
|
76
50
|
protected uniqueRefIds: Set<number> = new Set();
|
|
@@ -131,7 +105,7 @@ export class StateCallbackStrategy<TState extends Schema> {
|
|
|
131
105
|
|
|
132
106
|
if (operation === OPERATION.ADD && immediate) {
|
|
133
107
|
(collection as Collection<any, any>).forEach((value: any, key: any) => {
|
|
134
|
-
handler(
|
|
108
|
+
handler(value, key);
|
|
135
109
|
});
|
|
136
110
|
}
|
|
137
111
|
|
|
@@ -244,7 +218,7 @@ export class StateCallbackStrategy<TState extends Schema> {
|
|
|
244
218
|
*/
|
|
245
219
|
onAdd<K extends CollectionPropNames<TState>>(
|
|
246
220
|
property: K,
|
|
247
|
-
handler:
|
|
221
|
+
handler: ValueKeyCallback<CollectionValueType<TState, K>, CollectionKeyType<TState, K>>,
|
|
248
222
|
immediate?: boolean
|
|
249
223
|
): () => void;
|
|
250
224
|
|
|
@@ -254,7 +228,7 @@ export class StateCallbackStrategy<TState extends Schema> {
|
|
|
254
228
|
onAdd<TInstance extends Schema, K extends CollectionPropNames<TInstance>>(
|
|
255
229
|
instance: TInstance,
|
|
256
230
|
property: K,
|
|
257
|
-
handler:
|
|
231
|
+
handler: ValueKeyCallback<CollectionValueType<TInstance, K>, CollectionKeyType<TInstance, K>>,
|
|
258
232
|
immediate?: boolean
|
|
259
233
|
): () => void;
|
|
260
234
|
|
|
@@ -285,7 +259,7 @@ export class StateCallbackStrategy<TState extends Schema> {
|
|
|
285
259
|
*/
|
|
286
260
|
onRemove<K extends CollectionPropNames<TState>>(
|
|
287
261
|
property: K,
|
|
288
|
-
handler:
|
|
262
|
+
handler: ValueKeyCallback<CollectionValueType<TState, K>, CollectionKeyType<TState, K>>
|
|
289
263
|
): () => void;
|
|
290
264
|
|
|
291
265
|
/**
|
|
@@ -294,7 +268,7 @@ export class StateCallbackStrategy<TState extends Schema> {
|
|
|
294
268
|
onRemove<TInstance extends Schema, K extends CollectionPropNames<TInstance>>(
|
|
295
269
|
instance: TInstance,
|
|
296
270
|
property: K,
|
|
297
|
-
handler:
|
|
271
|
+
handler: ValueKeyCallback<CollectionValueType<TInstance, K>, CollectionKeyType<TInstance, K>>
|
|
298
272
|
): () => void;
|
|
299
273
|
|
|
300
274
|
onRemove(...args: any[]): () => void {
|
|
@@ -370,7 +344,7 @@ export class StateCallbackStrategy<TState extends Schema> {
|
|
|
370
344
|
//
|
|
371
345
|
if (
|
|
372
346
|
(change.op & OPERATION.DELETE) === OPERATION.DELETE &&
|
|
373
|
-
change.previousValue
|
|
347
|
+
Schema.isSchema(change.previousValue)
|
|
374
348
|
) {
|
|
375
349
|
const childRefId = (change.previousValue as Ref)[$refId];
|
|
376
350
|
const deleteCallbacks = this.callbacks[childRefId]?.[OPERATION.DELETE];
|
|
@@ -381,7 +355,7 @@ export class StateCallbackStrategy<TState extends Schema> {
|
|
|
381
355
|
}
|
|
382
356
|
}
|
|
383
357
|
|
|
384
|
-
if (ref
|
|
358
|
+
if (Schema.isSchema(ref)) {
|
|
385
359
|
//
|
|
386
360
|
// Handle Schema instance
|
|
387
361
|
//
|
|
@@ -426,11 +400,11 @@ export class StateCallbackStrategy<TState extends Schema> {
|
|
|
426
400
|
// FIXME: `previousValue` should always be available.
|
|
427
401
|
//
|
|
428
402
|
if (change.previousValue !== undefined) {
|
|
429
|
-
// trigger onRemove (
|
|
403
|
+
// trigger onRemove (value, key)
|
|
430
404
|
const deleteCallbacks = $callbacks[OPERATION.DELETE];
|
|
431
405
|
if (deleteCallbacks) {
|
|
432
406
|
for (let j = deleteCallbacks.length - 1; j >= 0; j--) {
|
|
433
|
-
deleteCallbacks[j](
|
|
407
|
+
deleteCallbacks[j](change.previousValue, dynamicIndex);
|
|
434
408
|
}
|
|
435
409
|
}
|
|
436
410
|
}
|
|
@@ -441,7 +415,7 @@ export class StateCallbackStrategy<TState extends Schema> {
|
|
|
441
415
|
if (addCallbacks) {
|
|
442
416
|
this.isTriggering = true;
|
|
443
417
|
for (let j = addCallbacks.length - 1; j >= 0; j--) {
|
|
444
|
-
addCallbacks[j](
|
|
418
|
+
addCallbacks[j](change.value, dynamicIndex);
|
|
445
419
|
}
|
|
446
420
|
this.isTriggering = false;
|
|
447
421
|
}
|
|
@@ -451,12 +425,12 @@ export class StateCallbackStrategy<TState extends Schema> {
|
|
|
451
425
|
(change.op & OPERATION.ADD) === OPERATION.ADD &&
|
|
452
426
|
change.previousValue !== change.value
|
|
453
427
|
) {
|
|
454
|
-
// trigger onAdd (
|
|
428
|
+
// trigger onAdd (value, key)
|
|
455
429
|
const addCallbacks = $callbacks[OPERATION.ADD];
|
|
456
430
|
if (addCallbacks) {
|
|
457
431
|
this.isTriggering = true;
|
|
458
432
|
for (let j = addCallbacks.length - 1; j >= 0; j--) {
|
|
459
|
-
addCallbacks[j](
|
|
433
|
+
addCallbacks[j](change.value, dynamicIndex);
|
|
460
434
|
}
|
|
461
435
|
this.isTriggering = false;
|
|
462
436
|
}
|
|
@@ -493,13 +467,13 @@ export const Callbacks = {
|
|
|
493
467
|
* callbacks.listen("currentTurn", (currentValue, previousValue) => { ... });
|
|
494
468
|
*
|
|
495
469
|
* // Listen to collection additions
|
|
496
|
-
* callbacks.onAdd("entities", (
|
|
470
|
+
* callbacks.onAdd("entities", (entity, sessionId) => {
|
|
497
471
|
* // Nested property listening
|
|
498
472
|
* callbacks.listen(entity, "hp", (currentHp, previousHp) => { ... });
|
|
499
473
|
* });
|
|
500
474
|
*
|
|
501
475
|
* // Listen to collection removals
|
|
502
|
-
* callbacks.onRemove("entities", (
|
|
476
|
+
* callbacks.onRemove("entities", (entity, sessionId) => { ... });
|
|
503
477
|
*
|
|
504
478
|
* // Listen to any property change on an instance
|
|
505
479
|
* callbacks.onChange(entity, () => { ... });
|
|
@@ -137,7 +137,7 @@ export function getDecoderStateCallbacks<T extends Schema>(decoder: Decoder<T>):
|
|
|
137
137
|
//
|
|
138
138
|
if (
|
|
139
139
|
(change.op & OPERATION.DELETE) === OPERATION.DELETE &&
|
|
140
|
-
change.previousValue
|
|
140
|
+
Schema.isSchema(change.previousValue)
|
|
141
141
|
) {
|
|
142
142
|
const deleteCallbacks = callbacks[(change.previousValue as Ref)[$refId]]?.[OPERATION.DELETE];
|
|
143
143
|
for (let i = deleteCallbacks?.length - 1; i >= 0; i--) {
|
|
@@ -145,7 +145,7 @@ export function getDecoderStateCallbacks<T extends Schema>(decoder: Decoder<T>):
|
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
if (ref
|
|
148
|
+
if (Schema.isSchema(ref)) {
|
|
149
149
|
//
|
|
150
150
|
// Handle schema instance
|
|
151
151
|
//
|