@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/build/Schema.d.ts
CHANGED
|
@@ -20,6 +20,13 @@ export declare class Schema<C = any> implements IRef {
|
|
|
20
20
|
*/
|
|
21
21
|
static initialize(instance: any): void;
|
|
22
22
|
static is(type: DefinitionType): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Check if a value is an instance of Schema.
|
|
25
|
+
* This method uses duck-typing to avoid issues with multiple @colyseus/schema versions.
|
|
26
|
+
* @param obj Value to check
|
|
27
|
+
* @returns true if the value is a Schema instance
|
|
28
|
+
*/
|
|
29
|
+
static isSchema(obj: any): obj is Schema;
|
|
23
30
|
/**
|
|
24
31
|
* Track property changes
|
|
25
32
|
*/
|
|
@@ -10,6 +10,7 @@ import { ArraySchema } from "../../types/custom/ArraySchema.js";
|
|
|
10
10
|
import { type SchemaCallbackProxy } from "./getDecoderStateCallbacks.js";
|
|
11
11
|
type PropertyChangeCallback<K> = (currentValue: K, previousValue: K) => void;
|
|
12
12
|
type KeyValueCallback<K, V> = (key: K, value: V) => void;
|
|
13
|
+
type ValueKeyCallback<V, K> = (value: V, key: K) => void;
|
|
13
14
|
type InstanceChangeCallback = () => void;
|
|
14
15
|
type PublicPropNames<T> = Exclude<NonFunctionPropNames<T>, typeof $refId> & string;
|
|
15
16
|
type CollectionPropNames<T> = Exclude<{
|
|
@@ -17,32 +18,6 @@ type CollectionPropNames<T> = Exclude<{
|
|
|
17
18
|
}[keyof T] & string, typeof $refId>;
|
|
18
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 Collection<any, infer V, any> ? V : never;
|
|
19
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 Collection<infer Key, any, any> ? Key : never;
|
|
20
|
-
/**
|
|
21
|
-
* State Callbacks handler
|
|
22
|
-
*
|
|
23
|
-
* Usage:
|
|
24
|
-
* ```ts
|
|
25
|
-
* const $ = Callbacks.get(decoder);
|
|
26
|
-
*
|
|
27
|
-
* // Listen to property changes
|
|
28
|
-
* $.listen("currentTurn", (currentValue, previousValue) => { ... });
|
|
29
|
-
*
|
|
30
|
-
* // Listen to collection additions
|
|
31
|
-
* $.onAdd("entities", (sessionId, entity) => {
|
|
32
|
-
* // Nested property listening
|
|
33
|
-
* $.listen(entity, "hp", (currentHp, previousHp) => { ... });
|
|
34
|
-
* });
|
|
35
|
-
*
|
|
36
|
-
* // Listen to collection removals
|
|
37
|
-
* $.onRemove("entities", (sessionId, entity) => { ... });
|
|
38
|
-
*
|
|
39
|
-
* // Listen to any property change on an instance
|
|
40
|
-
* $.onChange(entity, () => { ... });
|
|
41
|
-
*
|
|
42
|
-
* // Bind properties to another object
|
|
43
|
-
* $.bindTo(player, playerVisual);
|
|
44
|
-
* ```
|
|
45
|
-
*/
|
|
46
21
|
export declare class StateCallbackStrategy<TState extends Schema> {
|
|
47
22
|
protected decoder: Decoder<TState>;
|
|
48
23
|
protected uniqueRefIds: Set<number>;
|
|
@@ -78,19 +53,19 @@ export declare class StateCallbackStrategy<TState extends Schema> {
|
|
|
78
53
|
/**
|
|
79
54
|
* Listen to items added to a collection on root state.
|
|
80
55
|
*/
|
|
81
|
-
onAdd<K extends CollectionPropNames<TState>>(property: K, handler:
|
|
56
|
+
onAdd<K extends CollectionPropNames<TState>>(property: K, handler: ValueKeyCallback<CollectionValueType<TState, K>, CollectionKeyType<TState, K>>, immediate?: boolean): () => void;
|
|
82
57
|
/**
|
|
83
58
|
* Listen to items added to a nested collection.
|
|
84
59
|
*/
|
|
85
|
-
onAdd<TInstance extends Schema, K extends CollectionPropNames<TInstance>>(instance: TInstance, property: K, handler:
|
|
60
|
+
onAdd<TInstance extends Schema, K extends CollectionPropNames<TInstance>>(instance: TInstance, property: K, handler: ValueKeyCallback<CollectionValueType<TInstance, K>, CollectionKeyType<TInstance, K>>, immediate?: boolean): () => void;
|
|
86
61
|
/**
|
|
87
62
|
* Listen to items removed from a collection on root state.
|
|
88
63
|
*/
|
|
89
|
-
onRemove<K extends CollectionPropNames<TState>>(property: K, handler:
|
|
64
|
+
onRemove<K extends CollectionPropNames<TState>>(property: K, handler: ValueKeyCallback<CollectionValueType<TState, K>, CollectionKeyType<TState, K>>): () => void;
|
|
90
65
|
/**
|
|
91
66
|
* Listen to items removed from a nested collection.
|
|
92
67
|
*/
|
|
93
|
-
onRemove<TInstance extends Schema, K extends CollectionPropNames<TInstance>>(instance: TInstance, property: K, handler:
|
|
68
|
+
onRemove<TInstance extends Schema, K extends CollectionPropNames<TInstance>>(instance: TInstance, property: K, handler: ValueKeyCallback<CollectionValueType<TInstance, K>, CollectionKeyType<TInstance, K>>): () => void;
|
|
94
69
|
/**
|
|
95
70
|
* Bind properties from a Schema instance to a target object.
|
|
96
71
|
* Changes will be automatically reflected on the target object.
|
|
@@ -113,13 +88,13 @@ export declare const Callbacks: {
|
|
|
113
88
|
* callbacks.listen("currentTurn", (currentValue, previousValue) => { ... });
|
|
114
89
|
*
|
|
115
90
|
* // Listen to collection additions
|
|
116
|
-
* callbacks.onAdd("entities", (
|
|
91
|
+
* callbacks.onAdd("entities", (entity, sessionId) => {
|
|
117
92
|
* // Nested property listening
|
|
118
93
|
* callbacks.listen(entity, "hp", (currentHp, previousHp) => { ... });
|
|
119
94
|
* });
|
|
120
95
|
*
|
|
121
96
|
* // Listen to collection removals
|
|
122
|
-
* callbacks.onRemove("entities", (
|
|
97
|
+
* callbacks.onRemove("entities", (entity, sessionId) => { ... });
|
|
123
98
|
*
|
|
124
99
|
* // Listen to any property change on an instance
|
|
125
100
|
* callbacks.onChange(entity, () => { ... });
|
package/build/index.cjs
CHANGED
|
@@ -3668,6 +3668,15 @@ class Schema {
|
|
|
3668
3668
|
static is(type) {
|
|
3669
3669
|
return typeof (type[Symbol.metadata]) === "object";
|
|
3670
3670
|
}
|
|
3671
|
+
/**
|
|
3672
|
+
* Check if a value is an instance of Schema.
|
|
3673
|
+
* This method uses duck-typing to avoid issues with multiple @colyseus/schema versions.
|
|
3674
|
+
* @param obj Value to check
|
|
3675
|
+
* @returns true if the value is a Schema instance
|
|
3676
|
+
*/
|
|
3677
|
+
static isSchema(obj) {
|
|
3678
|
+
return typeof obj?.assign === "function";
|
|
3679
|
+
}
|
|
3671
3680
|
/**
|
|
3672
3681
|
* Track property changes
|
|
3673
3682
|
*/
|
|
@@ -4872,13 +4881,13 @@ function getDecoderStateCallbacks(decoder) {
|
|
|
4872
4881
|
// trigger onRemove on child structure.
|
|
4873
4882
|
//
|
|
4874
4883
|
if ((change.op & exports.OPERATION.DELETE) === exports.OPERATION.DELETE &&
|
|
4875
|
-
change.previousValue
|
|
4884
|
+
Schema.isSchema(change.previousValue)) {
|
|
4876
4885
|
const deleteCallbacks = callbacks[change.previousValue[$refId]]?.[exports.OPERATION.DELETE];
|
|
4877
4886
|
for (let i = deleteCallbacks?.length - 1; i >= 0; i--) {
|
|
4878
4887
|
deleteCallbacks[i]();
|
|
4879
4888
|
}
|
|
4880
4889
|
}
|
|
4881
|
-
if (ref
|
|
4890
|
+
if (Schema.isSchema(ref)) {
|
|
4882
4891
|
//
|
|
4883
4892
|
// Handle schema instance
|
|
4884
4893
|
//
|
|
@@ -5122,32 +5131,6 @@ function getRawChangesCallback(decoder, callback) {
|
|
|
5122
5131
|
decoder.triggerChanges = callback;
|
|
5123
5132
|
}
|
|
5124
5133
|
|
|
5125
|
-
/**
|
|
5126
|
-
* State Callbacks handler
|
|
5127
|
-
*
|
|
5128
|
-
* Usage:
|
|
5129
|
-
* ```ts
|
|
5130
|
-
* const $ = Callbacks.get(decoder);
|
|
5131
|
-
*
|
|
5132
|
-
* // Listen to property changes
|
|
5133
|
-
* $.listen("currentTurn", (currentValue, previousValue) => { ... });
|
|
5134
|
-
*
|
|
5135
|
-
* // Listen to collection additions
|
|
5136
|
-
* $.onAdd("entities", (sessionId, entity) => {
|
|
5137
|
-
* // Nested property listening
|
|
5138
|
-
* $.listen(entity, "hp", (currentHp, previousHp) => { ... });
|
|
5139
|
-
* });
|
|
5140
|
-
*
|
|
5141
|
-
* // Listen to collection removals
|
|
5142
|
-
* $.onRemove("entities", (sessionId, entity) => { ... });
|
|
5143
|
-
*
|
|
5144
|
-
* // Listen to any property change on an instance
|
|
5145
|
-
* $.onChange(entity, () => { ... });
|
|
5146
|
-
*
|
|
5147
|
-
* // Bind properties to another object
|
|
5148
|
-
* $.bindTo(player, playerVisual);
|
|
5149
|
-
* ```
|
|
5150
|
-
*/
|
|
5151
5134
|
class StateCallbackStrategy {
|
|
5152
5135
|
decoder;
|
|
5153
5136
|
uniqueRefIds = new Set();
|
|
@@ -5186,7 +5169,7 @@ class StateCallbackStrategy {
|
|
|
5186
5169
|
immediate = immediate && this.isTriggering === false;
|
|
5187
5170
|
if (operation === exports.OPERATION.ADD && immediate) {
|
|
5188
5171
|
collection.forEach((value, key) => {
|
|
5189
|
-
handler(
|
|
5172
|
+
handler(value, key);
|
|
5190
5173
|
});
|
|
5191
5174
|
}
|
|
5192
5175
|
return this.addCallback(collection[$refId], operation, handler);
|
|
@@ -5288,7 +5271,7 @@ class StateCallbackStrategy {
|
|
|
5288
5271
|
// trigger onRemove on child structure.
|
|
5289
5272
|
//
|
|
5290
5273
|
if ((change.op & exports.OPERATION.DELETE) === exports.OPERATION.DELETE &&
|
|
5291
|
-
change.previousValue
|
|
5274
|
+
Schema.isSchema(change.previousValue)) {
|
|
5292
5275
|
const childRefId = change.previousValue[$refId];
|
|
5293
5276
|
const deleteCallbacks = this.callbacks[childRefId]?.[exports.OPERATION.DELETE];
|
|
5294
5277
|
if (deleteCallbacks) {
|
|
@@ -5297,7 +5280,7 @@ class StateCallbackStrategy {
|
|
|
5297
5280
|
}
|
|
5298
5281
|
}
|
|
5299
5282
|
}
|
|
5300
|
-
if (ref
|
|
5283
|
+
if (Schema.isSchema(ref)) {
|
|
5301
5284
|
//
|
|
5302
5285
|
// Handle Schema instance
|
|
5303
5286
|
//
|
|
@@ -5342,11 +5325,11 @@ class StateCallbackStrategy {
|
|
|
5342
5325
|
// FIXME: `previousValue` should always be available.
|
|
5343
5326
|
//
|
|
5344
5327
|
if (change.previousValue !== undefined) {
|
|
5345
|
-
// trigger onRemove (
|
|
5328
|
+
// trigger onRemove (value, key)
|
|
5346
5329
|
const deleteCallbacks = $callbacks[exports.OPERATION.DELETE];
|
|
5347
5330
|
if (deleteCallbacks) {
|
|
5348
5331
|
for (let j = deleteCallbacks.length - 1; j >= 0; j--) {
|
|
5349
|
-
deleteCallbacks[j](
|
|
5332
|
+
deleteCallbacks[j](change.previousValue, dynamicIndex);
|
|
5350
5333
|
}
|
|
5351
5334
|
}
|
|
5352
5335
|
}
|
|
@@ -5356,7 +5339,7 @@ class StateCallbackStrategy {
|
|
|
5356
5339
|
if (addCallbacks) {
|
|
5357
5340
|
this.isTriggering = true;
|
|
5358
5341
|
for (let j = addCallbacks.length - 1; j >= 0; j--) {
|
|
5359
|
-
addCallbacks[j](
|
|
5342
|
+
addCallbacks[j](change.value, dynamicIndex);
|
|
5360
5343
|
}
|
|
5361
5344
|
this.isTriggering = false;
|
|
5362
5345
|
}
|
|
@@ -5364,12 +5347,12 @@ class StateCallbackStrategy {
|
|
|
5364
5347
|
}
|
|
5365
5348
|
else if ((change.op & exports.OPERATION.ADD) === exports.OPERATION.ADD &&
|
|
5366
5349
|
change.previousValue !== change.value) {
|
|
5367
|
-
// trigger onAdd (
|
|
5350
|
+
// trigger onAdd (value, key)
|
|
5368
5351
|
const addCallbacks = $callbacks[exports.OPERATION.ADD];
|
|
5369
5352
|
if (addCallbacks) {
|
|
5370
5353
|
this.isTriggering = true;
|
|
5371
5354
|
for (let j = addCallbacks.length - 1; j >= 0; j--) {
|
|
5372
|
-
addCallbacks[j](
|
|
5355
|
+
addCallbacks[j](change.value, dynamicIndex);
|
|
5373
5356
|
}
|
|
5374
5357
|
this.isTriggering = false;
|
|
5375
5358
|
}
|
|
@@ -5403,13 +5386,13 @@ const Callbacks = {
|
|
|
5403
5386
|
* callbacks.listen("currentTurn", (currentValue, previousValue) => { ... });
|
|
5404
5387
|
*
|
|
5405
5388
|
* // Listen to collection additions
|
|
5406
|
-
* callbacks.onAdd("entities", (
|
|
5389
|
+
* callbacks.onAdd("entities", (entity, sessionId) => {
|
|
5407
5390
|
* // Nested property listening
|
|
5408
5391
|
* callbacks.listen(entity, "hp", (currentHp, previousHp) => { ... });
|
|
5409
5392
|
* });
|
|
5410
5393
|
*
|
|
5411
5394
|
* // Listen to collection removals
|
|
5412
|
-
* callbacks.onRemove("entities", (
|
|
5395
|
+
* callbacks.onRemove("entities", (entity, sessionId) => { ... });
|
|
5413
5396
|
*
|
|
5414
5397
|
* // Listen to any property change on an instance
|
|
5415
5398
|
* callbacks.onChange(entity, () => { ... });
|