@colyseus/schema 5.0.8 → 5.0.10
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 +87 -51
- package/build/annotations.d.ts +8 -0
- package/build/codegen/cli.cjs +42 -5
- package/build/codegen/cli.cjs.map +1 -1
- package/build/encoder/ChangeTree.d.ts +10 -2
- package/build/index.cjs +182 -47
- package/build/index.cjs.map +1 -1
- package/build/index.d.ts +1 -1
- package/build/index.js +182 -47
- package/build/index.mjs +182 -48
- package/build/index.mjs.map +1 -1
- package/build/types/custom/ArraySchema.d.ts +9 -1
- package/build/types/custom/MapSchema.d.ts +18 -1
- package/package.json +9 -3
- package/src/annotations.ts +24 -0
- package/src/codegen/cli.ts +4 -4
- package/src/codegen/parser.ts +50 -1
- package/src/decoder/DecodeOperation.ts +23 -7
- package/src/encoder/ChangeTree.ts +18 -10
- package/src/encoder/EncodeOperation.ts +14 -1
- package/src/index.ts +1 -0
- package/src/types/custom/ArraySchema.ts +77 -30
- package/src/types/custom/MapSchema.ts +34 -1
package/build/index.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ export { encode } from "./encoding/encode.js";
|
|
|
19
19
|
export { decode, type Iterator } from "./encoding/decode.js";
|
|
20
20
|
export { Reflection, ReflectionType, ReflectionField, } from "./Reflection.js";
|
|
21
21
|
export { Metadata } from "./Metadata.js";
|
|
22
|
-
export { type, deprecated, owned, unreliable, transient, view, schema, entity, type DefinitionType, type PrimitiveType, type Definition, type FieldsAndMethods, type SchemaWithExtendsConstructor, type SchemaWithExtends, type SchemaType, } from "./annotations.js";
|
|
22
|
+
export { type, deprecated, defineTypes, owned, unreliable, transient, view, schema, entity, type DefinitionType, type PrimitiveType, type Definition, type FieldsAndMethods, type SchemaWithExtendsConstructor, type SchemaWithExtends, type SchemaType, } from "./annotations.js";
|
|
23
23
|
export { t, FieldBuilder, isBuilder, type BuilderDefinition, type ChildType } from "./types/builder.js";
|
|
24
24
|
export { TypeContext } from "./types/TypeContext.js";
|
|
25
25
|
export type { InferValueType, InferSchemaInstanceType, AssignableProps, BuilderInitProps, Data } from "./types/HelperTypes.js";
|
package/build/index.js
CHANGED
|
@@ -2954,14 +2954,31 @@
|
|
|
2954
2954
|
this.tagViews = undefined;
|
|
2955
2955
|
this.subscribedViews = undefined;
|
|
2956
2956
|
}
|
|
2957
|
-
|
|
2957
|
+
/**
|
|
2958
|
+
* ArraySchema#unshift(): re-key pending ops on both channels by
|
|
2959
|
+
* `+count`, then record ADDs for the new items at indexes 0..count-1.
|
|
2960
|
+
*
|
|
2961
|
+
* The rebuilt map's insertion order IS the wire order: new ADDs first
|
|
2962
|
+
* (ascending — the decoder splice-inserts each one, which only works
|
|
2963
|
+
* lowest-index-first), then prior ops in their original relative order
|
|
2964
|
+
* at their shifted positions. See ArraySchema#$setAt.
|
|
2965
|
+
*/
|
|
2966
|
+
unshift(count) {
|
|
2958
2967
|
if (this._isSchema)
|
|
2959
|
-
throw new Error("ChangeTree (Schema):
|
|
2968
|
+
throw new Error("ChangeTree (Schema): unshift is not supported");
|
|
2960
2969
|
const src = this.collDirty;
|
|
2961
2970
|
const dst = new Map();
|
|
2971
|
+
const track = !this.paused && !this.isStatic;
|
|
2972
|
+
if (track) {
|
|
2973
|
+
for (let i = 0; i < count; i++)
|
|
2974
|
+
dst.set(i, exports.OPERATION.ADD);
|
|
2975
|
+
}
|
|
2962
2976
|
for (const [idx, val] of src)
|
|
2963
|
-
dst.set(idx +
|
|
2977
|
+
dst.set(idx + count, val);
|
|
2964
2978
|
this.collDirty = dst;
|
|
2979
|
+
this.unreliableRecorder?.shift(count);
|
|
2980
|
+
if (track)
|
|
2981
|
+
this.root?.enqueueChangeTree(this);
|
|
2965
2982
|
}
|
|
2966
2983
|
// Tree attachment + child iteration — see ./changeTree/treeAttachment.ts.
|
|
2967
2984
|
setRoot(root) { setRoot(this, root); }
|
|
@@ -3030,12 +3047,6 @@
|
|
|
3030
3047
|
indexedOperation(index, operation) {
|
|
3031
3048
|
this._routeAndRecord(index, operation, true);
|
|
3032
3049
|
}
|
|
3033
|
-
// ArraySchema#unshift(): apply shift to both channels.
|
|
3034
|
-
// Unreliable recorder on an array is always a CollectionChangeRecorder.
|
|
3035
|
-
shiftChangeIndexes(shiftIndex) {
|
|
3036
|
-
this.shift(shiftIndex);
|
|
3037
|
-
this.unreliableRecorder?.shift(shiftIndex);
|
|
3038
|
-
}
|
|
3039
3050
|
getChange(index) {
|
|
3040
3051
|
return this.operationAt(index);
|
|
3041
3052
|
}
|
|
@@ -3376,7 +3387,8 @@
|
|
|
3376
3387
|
// ArraySchema stores its per-instance child type at `$childType`.
|
|
3377
3388
|
// This encoder is array-only — there's no Schema fallback to consider.
|
|
3378
3389
|
const type = ref[$childType];
|
|
3379
|
-
const
|
|
3390
|
+
const isSchemaChild = typeof type !== "string";
|
|
3391
|
+
const useOperationByRefId = hasView && changeTree.isFiltered && isSchemaChild;
|
|
3380
3392
|
let refOrIndex;
|
|
3381
3393
|
if (useOperationByRefId) {
|
|
3382
3394
|
const item = ref.tmpItems[field];
|
|
@@ -3392,6 +3404,20 @@
|
|
|
3392
3404
|
operation = exports.OPERATION.ADD_BY_REFID;
|
|
3393
3405
|
}
|
|
3394
3406
|
}
|
|
3407
|
+
else if (operation === exports.OPERATION.DELETE && isSchemaChild) {
|
|
3408
|
+
//
|
|
3409
|
+
// DELETE by identity: idempotent, so a stale positional DELETE
|
|
3410
|
+
// (pending in the shared queue when a client bootstraps via
|
|
3411
|
+
// encodeAll) can't corrupt that client — its snapshot no longer
|
|
3412
|
+
// holds the item, the refId is unknown, and the decoder skips.
|
|
3413
|
+
//
|
|
3414
|
+
const item = ref.tmpItems[field];
|
|
3415
|
+
if (!item) {
|
|
3416
|
+
return;
|
|
3417
|
+
}
|
|
3418
|
+
refOrIndex = item[$refId];
|
|
3419
|
+
operation = exports.OPERATION.DELETE_BY_REFID;
|
|
3420
|
+
}
|
|
3395
3421
|
else {
|
|
3396
3422
|
refOrIndex = field;
|
|
3397
3423
|
}
|
|
@@ -3783,7 +3809,10 @@
|
|
|
3783
3809
|
tgt.$items.set(dynamicIndex, value);
|
|
3784
3810
|
break;
|
|
3785
3811
|
case CollectionKind.Array:
|
|
3786
|
-
|
|
3812
|
+
// resync snapshot ADDs are positional overwrites, not inserts
|
|
3813
|
+
tgt.$setAt(index, value, (decoder.resyncVisited !== null && operation === exports.OPERATION.ADD)
|
|
3814
|
+
? exports.OPERATION.REPLACE
|
|
3815
|
+
: operation);
|
|
3787
3816
|
break;
|
|
3788
3817
|
// SetSchema / CollectionSchema / StreamSchema — use the wire-
|
|
3789
3818
|
// index we decoded above so server/client `$items` stay in sync
|
|
@@ -3850,9 +3879,13 @@
|
|
|
3850
3879
|
return;
|
|
3851
3880
|
}
|
|
3852
3881
|
else if (operation === exports.OPERATION.DELETE_BY_REFID) {
|
|
3853
|
-
// TODO: refactor here, try to follow same flow as below
|
|
3854
3882
|
const refId = decode.number(bytes, it);
|
|
3855
3883
|
const previousValue = decoder.root.refs.get(refId);
|
|
3884
|
+
// Stale DELETE — refId unknown to this decoder (e.g. it
|
|
3885
|
+
// bootstrapped via encodeAll after the item was already removed).
|
|
3886
|
+
if (previousValue === undefined) {
|
|
3887
|
+
return;
|
|
3888
|
+
}
|
|
3856
3889
|
// Decrement the removed child's ref-count so it can be garbage
|
|
3857
3890
|
// collected — this refId-based branch returns early and never reaches
|
|
3858
3891
|
// decodeValue(), so it must do the same DELETE bookkeeping itself.
|
|
@@ -3860,10 +3893,13 @@
|
|
|
3860
3893
|
// different type → "field not defined" / "definition mismatch"
|
|
3861
3894
|
// (surfaces under StateView when a filtered ArraySchema element is
|
|
3862
3895
|
// spliced while its parent moves through view membership churn).
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
}
|
|
3896
|
+
// Must run even when the item is absent from THIS array (view churn).
|
|
3897
|
+
decoder.root.removeRef(refId);
|
|
3866
3898
|
index = tgt.findIndex((value) => value === previousValue);
|
|
3899
|
+
// Item not present in this decoder's array — nothing to remove locally.
|
|
3900
|
+
if (index === -1) {
|
|
3901
|
+
return;
|
|
3902
|
+
}
|
|
3867
3903
|
tgt[$deleteByIndex](index);
|
|
3868
3904
|
allChanges?.push({
|
|
3869
3905
|
ref,
|
|
@@ -3904,9 +3940,12 @@
|
|
|
3904
3940
|
resyncTouchEntry(decoder, ref, operation, index, previousValue, value, allChanges);
|
|
3905
3941
|
}
|
|
3906
3942
|
if (value !== null && value !== undefined &&
|
|
3907
|
-
value !== previousValue // avoid setting same value twice (
|
|
3943
|
+
value !== previousValue // avoid setting same value twice (an ADD at an occupied index would splice-insert)
|
|
3908
3944
|
) {
|
|
3909
|
-
|
|
3945
|
+
// resync snapshot ADDs are positional overwrites, not inserts
|
|
3946
|
+
tgt.$setAt(index, value, (decoder.resyncVisited !== null && operation === exports.OPERATION.ADD)
|
|
3947
|
+
? exports.OPERATION.REPLACE
|
|
3948
|
+
: operation);
|
|
3910
3949
|
}
|
|
3911
3950
|
// add change
|
|
3912
3951
|
if (previousValue !== value) {
|
|
@@ -3963,30 +4002,35 @@
|
|
|
3963
4002
|
obj.$deleteAt(key);
|
|
3964
4003
|
}
|
|
3965
4004
|
else {
|
|
4005
|
+
// wire slot the write was recorded at; undefined = nothing
|
|
4006
|
+
// recorded (same value / skipped) — must NOT touch tmpItems
|
|
4007
|
+
// then, or a same-tick shifted layout gets clobbered.
|
|
4008
|
+
let wireIndex;
|
|
3966
4009
|
if (setValue[$changes]) {
|
|
3967
4010
|
assertInstanceType(setValue, obj[$childType], obj, key);
|
|
3968
4011
|
const previousValue = obj.items[key];
|
|
3969
4012
|
if (!obj.isMovingItems) {
|
|
3970
|
-
obj.$changeAt(Number(key), setValue);
|
|
4013
|
+
wireIndex = obj.$changeAt(Number(key), setValue);
|
|
3971
4014
|
}
|
|
3972
4015
|
else {
|
|
4016
|
+
wireIndex = obj.$wireIndex(Number(key));
|
|
3973
4017
|
if (previousValue !== undefined) {
|
|
3974
4018
|
if (setValue[$changes].isNew) {
|
|
3975
|
-
obj[$changes].indexedOperation(
|
|
4019
|
+
obj[$changes].indexedOperation(wireIndex, exports.OPERATION.MOVE_AND_ADD);
|
|
3976
4020
|
}
|
|
3977
4021
|
else {
|
|
3978
|
-
if ((obj[$changes].getChange(
|
|
3979
|
-
obj[$changes].indexedOperation(
|
|
4022
|
+
if ((obj[$changes].getChange(wireIndex) & exports.OPERATION.DELETE) === exports.OPERATION.DELETE) {
|
|
4023
|
+
obj[$changes].indexedOperation(wireIndex, exports.OPERATION.DELETE_AND_MOVE);
|
|
3980
4024
|
}
|
|
3981
4025
|
else {
|
|
3982
|
-
obj[$changes].indexedOperation(
|
|
4026
|
+
obj[$changes].indexedOperation(wireIndex, exports.OPERATION.MOVE);
|
|
3983
4027
|
}
|
|
3984
4028
|
}
|
|
3985
4029
|
}
|
|
3986
4030
|
else if (setValue[$changes].isNew) {
|
|
3987
|
-
obj[$changes].indexedOperation(
|
|
4031
|
+
obj[$changes].indexedOperation(wireIndex, exports.OPERATION.ADD);
|
|
3988
4032
|
}
|
|
3989
|
-
setValue[$changes].setParent(obj, obj[$changes].root,
|
|
4033
|
+
setValue[$changes].setParent(obj, obj[$changes].root, wireIndex);
|
|
3990
4034
|
}
|
|
3991
4035
|
if (previousValue !== undefined) {
|
|
3992
4036
|
// remove root reference from previous value
|
|
@@ -3994,10 +4038,12 @@
|
|
|
3994
4038
|
}
|
|
3995
4039
|
}
|
|
3996
4040
|
else {
|
|
3997
|
-
obj.$changeAt(Number(key), setValue);
|
|
4041
|
+
wireIndex = obj.$changeAt(Number(key), setValue);
|
|
3998
4042
|
}
|
|
3999
4043
|
obj.items[key] = setValue;
|
|
4000
|
-
|
|
4044
|
+
if (wireIndex !== undefined) {
|
|
4045
|
+
obj.tmpItems[wireIndex] = setValue;
|
|
4046
|
+
}
|
|
4001
4047
|
}
|
|
4002
4048
|
return true;
|
|
4003
4049
|
}
|
|
@@ -4180,40 +4226,68 @@
|
|
|
4180
4226
|
index += this.length;
|
|
4181
4227
|
return this.items[index];
|
|
4182
4228
|
}
|
|
4183
|
-
|
|
4229
|
+
/**
|
|
4230
|
+
* items-index → wire (tmpItems) index. Identity while no deletions are
|
|
4231
|
+
* staged this tick; otherwise maps to the index-th live (non-deleted)
|
|
4232
|
+
* tmpItems slot — the same live-index walk `splice()` uses. Without the
|
|
4233
|
+
* translation, index writes recorded after a same-tick `shift()`/`splice()`
|
|
4234
|
+
* land on the wrong wire slots.
|
|
4235
|
+
*/
|
|
4236
|
+
$wireIndex(index) {
|
|
4237
|
+
const deletedIndexes = this.deletedIndexes;
|
|
4238
|
+
if (deletedIndexes.length === 0) {
|
|
4239
|
+
return index;
|
|
4240
|
+
}
|
|
4241
|
+
const tmpItems = this.tmpItems;
|
|
4242
|
+
let live = 0;
|
|
4243
|
+
for (let i = 0; i < tmpItems.length; i++) {
|
|
4244
|
+
if (deletedIndexes[i] !== true) {
|
|
4245
|
+
if (live === index) {
|
|
4246
|
+
return i;
|
|
4247
|
+
}
|
|
4248
|
+
live++;
|
|
4249
|
+
}
|
|
4250
|
+
}
|
|
4251
|
+
// beyond the live range: appends land after the staged tmpItems tail
|
|
4252
|
+
return tmpItems.length + (index - live);
|
|
4253
|
+
}
|
|
4254
|
+
// encoding only. Returns the wire index the change was recorded at
|
|
4255
|
+
// (undefined when nothing was recorded).
|
|
4184
4256
|
$changeAt(index, value) {
|
|
4185
4257
|
if (value === undefined || value === null) {
|
|
4186
|
-
console.error("ArraySchema items cannot be null nor undefined; Use `
|
|
4187
|
-
return;
|
|
4258
|
+
console.error("ArraySchema items cannot be null nor undefined; Use `splice(index, 1)` instead.");
|
|
4259
|
+
return undefined;
|
|
4188
4260
|
}
|
|
4189
4261
|
// skip if the value is the same as cached.
|
|
4190
4262
|
if (this.items[index] === value) {
|
|
4191
|
-
return;
|
|
4263
|
+
return undefined;
|
|
4192
4264
|
}
|
|
4193
4265
|
const operation = (this.items[index] !== undefined)
|
|
4194
4266
|
? typeof (value) === "object"
|
|
4195
4267
|
? exports.OPERATION.DELETE_AND_ADD // schema child
|
|
4196
4268
|
: exports.OPERATION.REPLACE // primitive
|
|
4197
4269
|
: exports.OPERATION.ADD;
|
|
4270
|
+
const wireIndex = this.$wireIndex(index);
|
|
4198
4271
|
const changeTree = this[$changes];
|
|
4199
|
-
changeTree.change(
|
|
4272
|
+
changeTree.change(wireIndex, operation);
|
|
4200
4273
|
//
|
|
4201
4274
|
// set value's parent after the value is set
|
|
4202
4275
|
// (to avoid encoding "refId" operations before parent's "ADD" operation)
|
|
4203
4276
|
//
|
|
4204
|
-
value[$changes]?.setParent(this, changeTree.root,
|
|
4277
|
+
value[$changes]?.setParent(this, changeTree.root, wireIndex);
|
|
4278
|
+
return wireIndex;
|
|
4205
4279
|
}
|
|
4206
4280
|
// encoding only
|
|
4207
4281
|
$deleteAt(index, operation) {
|
|
4208
|
-
this[$changes].delete(index, operation);
|
|
4282
|
+
this[$changes].delete(this.$wireIndex(index), operation);
|
|
4209
4283
|
}
|
|
4210
4284
|
// decoding only
|
|
4211
4285
|
$setAt(index, value, operation) {
|
|
4212
|
-
if (
|
|
4213
|
-
operation === exports.OPERATION.ADD &&
|
|
4286
|
+
if (operation === exports.OPERATION.ADD &&
|
|
4214
4287
|
this.items[index] !== undefined) {
|
|
4215
|
-
//
|
|
4216
|
-
|
|
4288
|
+
// ADD at an occupied index = insert (unshift / splice-insert):
|
|
4289
|
+
// shift existing items up instead of overwriting.
|
|
4290
|
+
this.items.splice(index, 0, value);
|
|
4217
4291
|
}
|
|
4218
4292
|
else if (operation === exports.OPERATION.DELETE_AND_MOVE) {
|
|
4219
4293
|
this.items.splice(index, 1);
|
|
@@ -4300,10 +4374,16 @@
|
|
|
4300
4374
|
return undefined;
|
|
4301
4375
|
}
|
|
4302
4376
|
const changeTree = self[$changes];
|
|
4303
|
-
|
|
4304
|
-
|
|
4377
|
+
// items[0] ≡ first live (non-deleted) tmpItems slot. Value-based
|
|
4378
|
+
// findIndex is unsafe here: same-tick index writes can duplicate a
|
|
4379
|
+
// value across tmp slots and resolve the wrong one.
|
|
4380
|
+
const deletedIndexes = self.deletedIndexes;
|
|
4381
|
+
let index = 0;
|
|
4382
|
+
while (deletedIndexes[index] === true) {
|
|
4383
|
+
index++;
|
|
4384
|
+
}
|
|
4305
4385
|
changeTree.delete(index, exports.OPERATION.DELETE);
|
|
4306
|
-
|
|
4386
|
+
deletedIndexes[index] = true;
|
|
4307
4387
|
return items.shift();
|
|
4308
4388
|
}
|
|
4309
4389
|
/**
|
|
@@ -4401,13 +4481,18 @@
|
|
|
4401
4481
|
unshift(...items) {
|
|
4402
4482
|
const self = this[$proxyTarget];
|
|
4403
4483
|
const changeTree = self[$changes];
|
|
4404
|
-
//
|
|
4405
|
-
//
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
items.
|
|
4409
|
-
changeTree.
|
|
4410
|
-
}
|
|
4484
|
+
// single recorder op: shifts pending indexes up and records the new
|
|
4485
|
+
// ADDs lowest-first (the decoder splice-inserts in ascending order).
|
|
4486
|
+
changeTree.unshift(items.length);
|
|
4487
|
+
// attach ref-type items — parent set AFTER recording, as in $changeAt
|
|
4488
|
+
for (let i = 0; i < items.length; i++) {
|
|
4489
|
+
items[i]?.[$changes]?.setParent(this, changeTree.root, i);
|
|
4490
|
+
}
|
|
4491
|
+
// keep staged-delete flags aligned with the prepended tmp slots
|
|
4492
|
+
const deletedIndexes = self.deletedIndexes;
|
|
4493
|
+
if (deletedIndexes.length > 0) {
|
|
4494
|
+
deletedIndexes.unshift(...new Array(items.length).fill(false));
|
|
4495
|
+
}
|
|
4411
4496
|
self.tmpItems.unshift(...items);
|
|
4412
4497
|
return self.items.unshift(...items);
|
|
4413
4498
|
}
|
|
@@ -5026,6 +5111,37 @@
|
|
|
5026
5111
|
get(key) {
|
|
5027
5112
|
return this.$items.get(key);
|
|
5028
5113
|
}
|
|
5114
|
+
/**
|
|
5115
|
+
* Returns the value for `key` if present. Otherwise inserts `defaultValue`
|
|
5116
|
+
* (tracked as an ADD change, like `set()`) and returns it.
|
|
5117
|
+
*
|
|
5118
|
+
* Mirrors `Map.prototype.getOrInsert` (TC39 "upsert" proposal, typed in
|
|
5119
|
+
* TypeScript 6's standard library).
|
|
5120
|
+
*/
|
|
5121
|
+
getOrInsert(key, defaultValue) {
|
|
5122
|
+
if (this.$items.has(key)) {
|
|
5123
|
+
return this.$items.get(key);
|
|
5124
|
+
}
|
|
5125
|
+
this.set(key, defaultValue);
|
|
5126
|
+
return defaultValue;
|
|
5127
|
+
}
|
|
5128
|
+
/**
|
|
5129
|
+
* Returns the value for `key` if present. Otherwise computes a value via
|
|
5130
|
+
* `callbackfn(key)`, inserts it (tracked as an ADD change, like `set()`)
|
|
5131
|
+
* and returns it. The callback is only invoked when the key is missing.
|
|
5132
|
+
*
|
|
5133
|
+
* Mirrors `Map.prototype.getOrInsertComputed` (TC39 "upsert" proposal,
|
|
5134
|
+
* typed in TypeScript 6's standard library).
|
|
5135
|
+
*/
|
|
5136
|
+
getOrInsertComputed(key, callbackfn) {
|
|
5137
|
+
if (this.$items.has(key)) {
|
|
5138
|
+
return this.$items.get(key);
|
|
5139
|
+
}
|
|
5140
|
+
const value = callbackfn(key);
|
|
5141
|
+
// per spec: overwrites even if callbackfn itself inserted `key`
|
|
5142
|
+
this.set(key, value);
|
|
5143
|
+
return value;
|
|
5144
|
+
}
|
|
5029
5145
|
delete(key) {
|
|
5030
5146
|
if (!this.$items.has(key)) {
|
|
5031
5147
|
return false;
|
|
@@ -6751,6 +6867,24 @@
|
|
|
6751
6867
|
});
|
|
6752
6868
|
};
|
|
6753
6869
|
}
|
|
6870
|
+
let defineTypesWarned = false;
|
|
6871
|
+
/**
|
|
6872
|
+
* Adds synchronizable fields to an existing `Schema` subclass — the pre-5.0
|
|
6873
|
+
* helper for plain JavaScript users.
|
|
6874
|
+
*
|
|
6875
|
+
* @deprecated Use `schema()` with `t.*` field builders instead:
|
|
6876
|
+
* https://docs.colyseus.io/state/schema
|
|
6877
|
+
*/
|
|
6878
|
+
function defineTypes(target, fields, options) {
|
|
6879
|
+
if (!defineTypesWarned) {
|
|
6880
|
+
defineTypesWarned = true;
|
|
6881
|
+
console.warn("@colyseus/schema: defineTypes() is deprecated and will be removed in a future release. Use schema() with t.* field builders instead → https://docs.colyseus.io/state/schema");
|
|
6882
|
+
}
|
|
6883
|
+
for (let field in fields) {
|
|
6884
|
+
type(fields[field], options)(target.prototype, field);
|
|
6885
|
+
}
|
|
6886
|
+
return target;
|
|
6887
|
+
}
|
|
6754
6888
|
/**
|
|
6755
6889
|
* Build a per-construction factory for a builder type's auto-instantiated
|
|
6756
6890
|
* default (empty collection or zero-arg Schema ref), or `undefined` when the
|
|
@@ -10613,6 +10747,7 @@
|
|
|
10613
10747
|
exports.decodeKeyValueOperation = decodeKeyValueOperation;
|
|
10614
10748
|
exports.decodeSchemaOperation = decodeSchemaOperation;
|
|
10615
10749
|
exports.defineCustomTypes = defineCustomTypes;
|
|
10750
|
+
exports.defineTypes = defineTypes;
|
|
10616
10751
|
exports.deprecated = deprecated;
|
|
10617
10752
|
exports.dumpChanges = dumpChanges;
|
|
10618
10753
|
exports.encode = encode;
|