@colyseus/schema 3.0.2 → 3.0.4
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 +8 -7
- package/build/cjs/index.js +29 -4
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +29 -4
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +29 -4
- package/lib/decoder/DecodeOperation.js +1 -1
- package/lib/decoder/DecodeOperation.js.map +1 -1
- package/lib/decoder/strategy/StateCallbacks.d.ts +9 -0
- package/lib/decoder/strategy/StateCallbacks.js +20 -1
- package/lib/decoder/strategy/StateCallbacks.js.map +1 -1
- package/lib/types/custom/ArraySchema.d.ts +2 -8
- package/lib/types/custom/ArraySchema.js +8 -2
- package/lib/types/custom/ArraySchema.js.map +1 -1
- package/package.json +1 -1
- package/src/decoder/DecodeOperation.ts +1 -1
- package/src/decoder/strategy/StateCallbacks.ts +35 -8
- package/src/types/custom/ArraySchema.ts +17 -10
package/build/umd/index.js
CHANGED
|
@@ -1551,7 +1551,7 @@
|
|
|
1551
1551
|
// previousValue,
|
|
1552
1552
|
// });
|
|
1553
1553
|
}
|
|
1554
|
-
value =
|
|
1554
|
+
value = undefined;
|
|
1555
1555
|
}
|
|
1556
1556
|
if (operation === exports.OPERATION.DELETE) ;
|
|
1557
1557
|
else if (Schema.is(type)) {
|
|
@@ -1865,6 +1865,9 @@
|
|
|
1865
1865
|
// type format: { array: "string" }
|
|
1866
1866
|
(type['array'] !== undefined));
|
|
1867
1867
|
}
|
|
1868
|
+
static from(iterable) {
|
|
1869
|
+
return new ArraySchema(...Array.from(iterable));
|
|
1870
|
+
}
|
|
1868
1871
|
constructor(...items) {
|
|
1869
1872
|
this.items = [];
|
|
1870
1873
|
this.tmpItems = [];
|
|
@@ -2231,8 +2234,8 @@
|
|
|
2231
2234
|
lastIndexOf(searchElement, fromIndex = this.length - 1) {
|
|
2232
2235
|
return this.items.lastIndexOf(searchElement, fromIndex);
|
|
2233
2236
|
}
|
|
2234
|
-
every(
|
|
2235
|
-
return this.items.every(
|
|
2237
|
+
every(predicate, thisArg) {
|
|
2238
|
+
return this.items.every(predicate, thisArg);
|
|
2236
2239
|
}
|
|
2237
2240
|
/**
|
|
2238
2241
|
* Determines whether the specified callback function returns true for any element of an array.
|
|
@@ -2414,6 +2417,9 @@
|
|
|
2414
2417
|
//
|
|
2415
2418
|
with(index, value) {
|
|
2416
2419
|
const copy = this.items.slice();
|
|
2420
|
+
// Allow negative indexing from the end
|
|
2421
|
+
if (index < 0)
|
|
2422
|
+
index += this.length;
|
|
2417
2423
|
copy[index] = value;
|
|
2418
2424
|
return new ArraySchema(...copy);
|
|
2419
2425
|
}
|
|
@@ -4489,7 +4495,10 @@
|
|
|
4489
4495
|
}
|
|
4490
4496
|
}
|
|
4491
4497
|
// trigger onChange
|
|
4492
|
-
if (change.value !== change.previousValue
|
|
4498
|
+
if (change.value !== change.previousValue &&
|
|
4499
|
+
// FIXME: see "should not encode item if added and removed at the same patch" test case.
|
|
4500
|
+
// some "ADD" + "DELETE" operations on same patch are being encoded as "DELETE"
|
|
4501
|
+
(change.value !== undefined || change.previousValue !== undefined)) {
|
|
4493
4502
|
const replaceCallbacks = $callbacks[exports.OPERATION.REPLACE];
|
|
4494
4503
|
for (let i = replaceCallbacks?.length - 1; i >= 0; i--) {
|
|
4495
4504
|
replaceCallbacks[i](change.value, change.dynamicIndex ?? change.field);
|
|
@@ -4602,6 +4611,9 @@
|
|
|
4602
4611
|
const onRemove = function (ref, callback) {
|
|
4603
4612
|
return $root.addCallback($root.refIds.get(ref), exports.OPERATION.DELETE, callback);
|
|
4604
4613
|
};
|
|
4614
|
+
const onChange = function (ref, callback) {
|
|
4615
|
+
return $root.addCallback($root.refIds.get(ref), exports.OPERATION.REPLACE, callback);
|
|
4616
|
+
};
|
|
4605
4617
|
return new Proxy({
|
|
4606
4618
|
onAdd: function (callback, immediate = true) {
|
|
4607
4619
|
//
|
|
@@ -4633,6 +4645,19 @@
|
|
|
4633
4645
|
return onRemove(context.instance, callback);
|
|
4634
4646
|
}
|
|
4635
4647
|
},
|
|
4648
|
+
onChange: function (callback) {
|
|
4649
|
+
if (context.onInstanceAvailable) {
|
|
4650
|
+
// collection instance not received yet
|
|
4651
|
+
let detachCallback = () => { };
|
|
4652
|
+
context.onInstanceAvailable((ref) => {
|
|
4653
|
+
detachCallback = onChange(ref, callback);
|
|
4654
|
+
});
|
|
4655
|
+
return () => detachCallback();
|
|
4656
|
+
}
|
|
4657
|
+
else if (context.instance) {
|
|
4658
|
+
return onChange(context.instance, callback);
|
|
4659
|
+
}
|
|
4660
|
+
},
|
|
4636
4661
|
}, {
|
|
4637
4662
|
get(target, prop) {
|
|
4638
4663
|
if (!target[prop]) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DecodeOperation.js","sourceRoot":"","sources":["../../src/decoder/DecodeOperation.ts"],"names":[],"mappings":"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","sourcesContent":["import { OPERATION } from \"../encoding/spec\";\nimport { Metadata } from \"../Metadata\";\nimport { Schema } from \"../Schema\";\nimport type { Ref } from \"../encoder/ChangeTree\";\nimport type { Decoder } from \"./Decoder\";\nimport { Iterator, decode } from \"../encoding/decode\";\nimport { $childType, $deleteByIndex, $getByIndex } from \"../types/symbols\";\n\nimport type { MapSchema } from \"../types/custom/MapSchema\";\nimport type { ArraySchema } from \"../types/custom/ArraySchema\";\nimport type { CollectionSchema } from \"../types/custom/CollectionSchema\";\n\nimport { getType } from \"../types/registry\";\nimport { Collection } from \"../types/HelperTypes\";\n\nexport interface DataChange<T = any, F = string> {\n ref: Ref,\n refId: number,\n op: OPERATION,\n field: F;\n dynamicIndex?: number | string;\n value: T;\n previousValue: T;\n}\n\nexport const DEFINITION_MISMATCH = -1;\n\nexport type DecodeOperation<T extends Schema = any> = (\n decoder: Decoder<T>,\n bytes: Buffer,\n it: Iterator,\n ref: Ref,\n allChanges: DataChange[],\n) => number | void;\n\nexport function decodeValue(\n decoder: Decoder,\n operation: OPERATION,\n ref: Ref,\n index: number,\n type: any,\n bytes: Buffer,\n it: Iterator,\n allChanges: DataChange[],\n) {\n const $root = decoder.root;\n const previousValue = ref[$getByIndex](index);\n\n let value: any;\n\n if ((operation & OPERATION.DELETE) === OPERATION.DELETE)\n {\n // Flag `refId` for garbage collection.\n const previousRefId = $root.refIds.get(previousValue);\n if (previousRefId !== undefined) { $root.removeRef(previousRefId); }\n\n //\n // Delete operations\n //\n if (operation !== OPERATION.DELETE_AND_ADD) {\n ref[$deleteByIndex](index);\n\n // //\n // // FIXME: is this in the correct place?\n // // (This is sounding like a workaround just for ArraySchema, see\n // // \"should splice and move\" test on ArraySchema.test.ts)\n // //\n // allChanges.push({\n // ref,\n // refId: decoder.currentRefId,\n // op: OPERATION.DELETE,\n // field: index as unknown as string,\n // value: undefined,\n // previousValue,\n // });\n }\n\n value = null;\n }\n\n if (operation === OPERATION.DELETE) {\n //\n // Don't do anything\n //\n\n } else if (Schema.is(type)) {\n const refId = decode.number(bytes, it);\n value = $root.refs.get(refId);\n\n if (previousValue) {\n const previousRefId = $root.refIds.get(previousValue);\n if (\n previousRefId &&\n refId !== previousRefId &&\n // FIXME: we may need to check for REPLACE operation as well\n ((operation & OPERATION.DELETE) === OPERATION.DELETE)\n ) {\n $root.removeRef(previousRefId);\n }\n }\n\n if ((operation & OPERATION.ADD) === OPERATION.ADD) {\n const childType = decoder.getInstanceType(bytes, it, type);\n if (!value) {\n value = decoder.createInstanceOfType(childType);\n }\n\n $root.addRef(\n refId,\n value,\n (\n value !== previousValue || // increment ref count if value has changed\n (operation === OPERATION.DELETE_AND_ADD && value === previousValue) // increment ref count if the same instance is being added again\n )\n );\n }\n\n\n } else if (typeof(type) === \"string\") {\n //\n // primitive value (number, string, boolean, etc)\n //\n value = decode[type as string](bytes, it);\n\n } else {\n const typeDef = getType(Object.keys(type)[0]);\n const refId = decode.number(bytes, it);\n\n const valueRef: Ref = ($root.refs.has(refId))\n ? previousValue || $root.refs.get(refId)\n : new typeDef.constructor();\n\n value = valueRef.clone(true);\n value[$childType] = Object.values(type)[0]; // cache childType for ArraySchema and MapSchema\n\n if (previousValue) {\n let previousRefId = $root.refIds.get(previousValue);\n\n if (previousRefId !== undefined && refId !== previousRefId) {\n $root.removeRef(previousRefId);\n\n //\n // enqueue onRemove if structure has been replaced.\n //\n const entries: IterableIterator<[any, any]> = previousValue.entries();\n let iter: IteratorResult<[any, any]>;\n while ((iter = entries.next()) && !iter.done) {\n const [key, value] = iter.value;\n\n // if value is a schema, remove its reference\n // FIXME: not sure if this is necessary, add more tests to confirm\n if (typeof(value) === \"object\") {\n previousRefId = $root.refIds.get(value);\n $root.removeRef(previousRefId);\n }\n\n allChanges.push({\n ref: previousValue,\n refId: previousRefId,\n op: OPERATION.DELETE,\n field: key,\n value: undefined,\n previousValue: value,\n });\n }\n\n }\n }\n\n $root.addRef(refId, value, (valueRef !== previousValue));\n }\n\n return { value, previousValue };\n}\n\nexport const decodeSchemaOperation: DecodeOperation = function (\n decoder: Decoder<any>,\n bytes: Buffer,\n it: Iterator,\n ref: Ref,\n allChanges: DataChange[],\n) {\n const first_byte = bytes[it.offset++];\n const metadata: Metadata = ref.constructor[Symbol.metadata];\n\n // \"compressed\" index + operation\n const operation = (first_byte >> 6) << 6\n const index = first_byte % (operation || 255);\n\n // skip early if field is not defined\n const field = metadata[index];\n if (field === undefined) {\n console.warn(\"@colyseus/schema: field not defined at\", { index, ref: ref.constructor.name, metadata });\n return DEFINITION_MISMATCH;\n }\n\n const { value, previousValue } = decodeValue(\n decoder,\n operation,\n ref,\n index,\n field.type,\n bytes,\n it,\n allChanges,\n );\n\n if (value !== null && value !== undefined) {\n ref[field.name] = value;\n }\n\n // add change\n if (previousValue !== value) {\n allChanges.push({\n ref,\n refId: decoder.currentRefId,\n op: operation,\n field: field.name,\n value,\n previousValue,\n });\n }\n}\n\nexport const decodeKeyValueOperation: DecodeOperation = function (\n decoder: Decoder<any>,\n bytes: Buffer,\n it: Iterator,\n ref: Ref,\n allChanges: DataChange[]\n) {\n // \"uncompressed\" index + operation (array/map items)\n const operation = bytes[it.offset++];\n\n if (operation === OPERATION.CLEAR) {\n //\n // When decoding:\n // - enqueue items for DELETE callback.\n // - flag child items for garbage collection.\n //\n decoder.removeChildRefs(ref as unknown as Collection, allChanges);\n\n (ref as any).clear();\n return;\n }\n\n const index = decode.number(bytes, it);\n const type = ref[$childType];\n\n let dynamicIndex: number | string;\n\n if ((operation & OPERATION.ADD) === OPERATION.ADD) { // ADD or DELETE_AND_ADD\n if (typeof(ref['set']) === \"function\") {\n dynamicIndex = decode.string(bytes, it); // MapSchema\n ref['setIndex'](index, dynamicIndex);\n } else {\n dynamicIndex = index; // ArraySchema\n }\n } else {\n // get dynamic index from \"ref\"\n dynamicIndex = ref['getIndex'](index);\n }\n\n\n const { value, previousValue } = decodeValue(\n decoder,\n operation,\n ref,\n index,\n type,\n bytes,\n it,\n allChanges,\n );\n\n if (value !== null && value !== undefined) {\n if (typeof(ref['set']) === \"function\") {\n // MapSchema\n (ref as MapSchema)['$items'].set(dynamicIndex as string, value);\n\n } else if (typeof(ref['$setAt']) === \"function\") {\n // ArraySchema\n (ref as ArraySchema)['$setAt'](index, value, operation);\n\n } else if (typeof(ref['add']) === \"function\") {\n // CollectionSchema && SetSchema\n const index = (ref as CollectionSchema).add(value);\n\n if (typeof(index) === \"number\") {\n ref['setIndex'](index, index);\n }\n }\n }\n\n // add change\n if (previousValue !== value) {\n allChanges.push({\n ref,\n refId: decoder.currentRefId,\n op: operation,\n field: \"\", // FIXME: remove this\n dynamicIndex,\n value,\n previousValue,\n });\n }\n}\n\nexport const decodeArray: DecodeOperation = function (\n decoder: Decoder<any>,\n bytes: Buffer,\n it: Iterator,\n ref: ArraySchema,\n allChanges: DataChange[]\n) {\n // \"uncompressed\" index + operation (array/map items)\n let operation = bytes[it.offset++];\n let index: number;\n\n if (operation === OPERATION.CLEAR) {\n //\n // When decoding:\n // - enqueue items for DELETE callback.\n // - flag child items for garbage collection.\n //\n decoder.removeChildRefs(ref as unknown as Collection, allChanges);\n (ref as ArraySchema).clear();\n return;\n\n } else if (operation === OPERATION.REVERSE) {\n (ref as ArraySchema).reverse();\n return;\n\n } else if (operation === OPERATION.DELETE_BY_REFID) {\n // TODO: refactor here, try to follow same flow as below\n const refId = decode.number(bytes, it);\n const previousValue = decoder.root.refs.get(refId);\n index = ref.findIndex((value) => value === previousValue);\n ref[$deleteByIndex](index);\n allChanges.push({\n ref,\n refId: decoder.currentRefId,\n op: OPERATION.DELETE,\n field: \"\", // FIXME: remove this\n dynamicIndex: index,\n value: undefined,\n previousValue,\n });\n\n return;\n\n } else if (operation === OPERATION.ADD_BY_REFID) {\n const refId = decode.number(bytes, it);\n const itemByRefId = decoder.root.refs.get(refId);\n\n // use existing index, or push new value\n index = (itemByRefId)\n ? ref.findIndex((value) => value === itemByRefId)\n : ref.length;\n\n } else {\n index = decode.number(bytes, it);\n }\n\n const type = ref[$childType];\n\n let dynamicIndex: number | string = index;\n\n const { value, previousValue } = decodeValue(\n decoder,\n operation,\n ref,\n index,\n type,\n bytes,\n it,\n allChanges,\n );\n\n if (\n value !== null && value !== undefined &&\n value !== previousValue // avoid setting same value twice (if index === 0 it will result in a \"unshift\" for ArraySchema)\n ) {\n // ArraySchema\n (ref as ArraySchema)['$setAt'](index, value, operation);\n }\n\n // add change\n if (previousValue !== value) {\n allChanges.push({\n ref,\n refId: decoder.currentRefId,\n op: operation,\n field: \"\", // FIXME: remove this\n dynamicIndex,\n value,\n previousValue,\n });\n }\n}"]}
|
|
1
|
+
{"version":3,"file":"DecodeOperation.js","sourceRoot":"","sources":["../../src/decoder/DecodeOperation.ts"],"names":[],"mappings":"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","sourcesContent":["import { OPERATION } from \"../encoding/spec\";\nimport { Metadata } from \"../Metadata\";\nimport { Schema } from \"../Schema\";\nimport type { Ref } from \"../encoder/ChangeTree\";\nimport type { Decoder } from \"./Decoder\";\nimport { Iterator, decode } from \"../encoding/decode\";\nimport { $childType, $deleteByIndex, $getByIndex } from \"../types/symbols\";\n\nimport type { MapSchema } from \"../types/custom/MapSchema\";\nimport type { ArraySchema } from \"../types/custom/ArraySchema\";\nimport type { CollectionSchema } from \"../types/custom/CollectionSchema\";\n\nimport { getType } from \"../types/registry\";\nimport { Collection } from \"../types/HelperTypes\";\n\nexport interface DataChange<T = any, F = string> {\n ref: Ref,\n refId: number,\n op: OPERATION,\n field: F;\n dynamicIndex?: number | string;\n value: T;\n previousValue: T;\n}\n\nexport const DEFINITION_MISMATCH = -1;\n\nexport type DecodeOperation<T extends Schema = any> = (\n decoder: Decoder<T>,\n bytes: Buffer,\n it: Iterator,\n ref: Ref,\n allChanges: DataChange[],\n) => number | void;\n\nexport function decodeValue(\n decoder: Decoder,\n operation: OPERATION,\n ref: Ref,\n index: number,\n type: any,\n bytes: Buffer,\n it: Iterator,\n allChanges: DataChange[],\n) {\n const $root = decoder.root;\n const previousValue = ref[$getByIndex](index);\n\n let value: any;\n\n if ((operation & OPERATION.DELETE) === OPERATION.DELETE)\n {\n // Flag `refId` for garbage collection.\n const previousRefId = $root.refIds.get(previousValue);\n if (previousRefId !== undefined) { $root.removeRef(previousRefId); }\n\n //\n // Delete operations\n //\n if (operation !== OPERATION.DELETE_AND_ADD) {\n ref[$deleteByIndex](index);\n\n // //\n // // FIXME: is this in the correct place?\n // // (This is sounding like a workaround just for ArraySchema, see\n // // \"should splice and move\" test on ArraySchema.test.ts)\n // //\n // allChanges.push({\n // ref,\n // refId: decoder.currentRefId,\n // op: OPERATION.DELETE,\n // field: index as unknown as string,\n // value: undefined,\n // previousValue,\n // });\n }\n\n value = undefined;\n }\n\n if (operation === OPERATION.DELETE) {\n //\n // Don't do anything\n //\n\n } else if (Schema.is(type)) {\n const refId = decode.number(bytes, it);\n value = $root.refs.get(refId);\n\n if (previousValue) {\n const previousRefId = $root.refIds.get(previousValue);\n if (\n previousRefId &&\n refId !== previousRefId &&\n // FIXME: we may need to check for REPLACE operation as well\n ((operation & OPERATION.DELETE) === OPERATION.DELETE)\n ) {\n $root.removeRef(previousRefId);\n }\n }\n\n if ((operation & OPERATION.ADD) === OPERATION.ADD) {\n const childType = decoder.getInstanceType(bytes, it, type);\n if (!value) {\n value = decoder.createInstanceOfType(childType);\n }\n\n $root.addRef(\n refId,\n value,\n (\n value !== previousValue || // increment ref count if value has changed\n (operation === OPERATION.DELETE_AND_ADD && value === previousValue) // increment ref count if the same instance is being added again\n )\n );\n }\n\n\n } else if (typeof(type) === \"string\") {\n //\n // primitive value (number, string, boolean, etc)\n //\n value = decode[type as string](bytes, it);\n\n } else {\n const typeDef = getType(Object.keys(type)[0]);\n const refId = decode.number(bytes, it);\n\n const valueRef: Ref = ($root.refs.has(refId))\n ? previousValue || $root.refs.get(refId)\n : new typeDef.constructor();\n\n value = valueRef.clone(true);\n value[$childType] = Object.values(type)[0]; // cache childType for ArraySchema and MapSchema\n\n if (previousValue) {\n let previousRefId = $root.refIds.get(previousValue);\n\n if (previousRefId !== undefined && refId !== previousRefId) {\n $root.removeRef(previousRefId);\n\n //\n // enqueue onRemove if structure has been replaced.\n //\n const entries: IterableIterator<[any, any]> = previousValue.entries();\n let iter: IteratorResult<[any, any]>;\n while ((iter = entries.next()) && !iter.done) {\n const [key, value] = iter.value;\n\n // if value is a schema, remove its reference\n // FIXME: not sure if this is necessary, add more tests to confirm\n if (typeof(value) === \"object\") {\n previousRefId = $root.refIds.get(value);\n $root.removeRef(previousRefId);\n }\n\n allChanges.push({\n ref: previousValue,\n refId: previousRefId,\n op: OPERATION.DELETE,\n field: key,\n value: undefined,\n previousValue: value,\n });\n }\n\n }\n }\n\n $root.addRef(refId, value, (valueRef !== previousValue));\n }\n\n return { value, previousValue };\n}\n\nexport const decodeSchemaOperation: DecodeOperation = function (\n decoder: Decoder<any>,\n bytes: Buffer,\n it: Iterator,\n ref: Ref,\n allChanges: DataChange[],\n) {\n const first_byte = bytes[it.offset++];\n const metadata: Metadata = ref.constructor[Symbol.metadata];\n\n // \"compressed\" index + operation\n const operation = (first_byte >> 6) << 6\n const index = first_byte % (operation || 255);\n\n // skip early if field is not defined\n const field = metadata[index];\n if (field === undefined) {\n console.warn(\"@colyseus/schema: field not defined at\", { index, ref: ref.constructor.name, metadata });\n return DEFINITION_MISMATCH;\n }\n\n const { value, previousValue } = decodeValue(\n decoder,\n operation,\n ref,\n index,\n field.type,\n bytes,\n it,\n allChanges,\n );\n\n if (value !== null && value !== undefined) {\n ref[field.name] = value;\n }\n\n // add change\n if (previousValue !== value) {\n allChanges.push({\n ref,\n refId: decoder.currentRefId,\n op: operation,\n field: field.name,\n value,\n previousValue,\n });\n }\n}\n\nexport const decodeKeyValueOperation: DecodeOperation = function (\n decoder: Decoder<any>,\n bytes: Buffer,\n it: Iterator,\n ref: Ref,\n allChanges: DataChange[]\n) {\n // \"uncompressed\" index + operation (array/map items)\n const operation = bytes[it.offset++];\n\n if (operation === OPERATION.CLEAR) {\n //\n // When decoding:\n // - enqueue items for DELETE callback.\n // - flag child items for garbage collection.\n //\n decoder.removeChildRefs(ref as unknown as Collection, allChanges);\n\n (ref as any).clear();\n return;\n }\n\n const index = decode.number(bytes, it);\n const type = ref[$childType];\n\n let dynamicIndex: number | string;\n\n if ((operation & OPERATION.ADD) === OPERATION.ADD) { // ADD or DELETE_AND_ADD\n if (typeof(ref['set']) === \"function\") {\n dynamicIndex = decode.string(bytes, it); // MapSchema\n ref['setIndex'](index, dynamicIndex);\n } else {\n dynamicIndex = index; // ArraySchema\n }\n } else {\n // get dynamic index from \"ref\"\n dynamicIndex = ref['getIndex'](index);\n }\n\n\n const { value, previousValue } = decodeValue(\n decoder,\n operation,\n ref,\n index,\n type,\n bytes,\n it,\n allChanges,\n );\n\n if (value !== null && value !== undefined) {\n if (typeof(ref['set']) === \"function\") {\n // MapSchema\n (ref as MapSchema)['$items'].set(dynamicIndex as string, value);\n\n } else if (typeof(ref['$setAt']) === \"function\") {\n // ArraySchema\n (ref as ArraySchema)['$setAt'](index, value, operation);\n\n } else if (typeof(ref['add']) === \"function\") {\n // CollectionSchema && SetSchema\n const index = (ref as CollectionSchema).add(value);\n\n if (typeof(index) === \"number\") {\n ref['setIndex'](index, index);\n }\n }\n }\n\n // add change\n if (previousValue !== value) {\n allChanges.push({\n ref,\n refId: decoder.currentRefId,\n op: operation,\n field: \"\", // FIXME: remove this\n dynamicIndex,\n value,\n previousValue,\n });\n }\n}\n\nexport const decodeArray: DecodeOperation = function (\n decoder: Decoder<any>,\n bytes: Buffer,\n it: Iterator,\n ref: ArraySchema,\n allChanges: DataChange[]\n) {\n // \"uncompressed\" index + operation (array/map items)\n let operation = bytes[it.offset++];\n let index: number;\n\n if (operation === OPERATION.CLEAR) {\n //\n // When decoding:\n // - enqueue items for DELETE callback.\n // - flag child items for garbage collection.\n //\n decoder.removeChildRefs(ref as unknown as Collection, allChanges);\n (ref as ArraySchema).clear();\n return;\n\n } else if (operation === OPERATION.REVERSE) {\n (ref as ArraySchema).reverse();\n return;\n\n } else if (operation === OPERATION.DELETE_BY_REFID) {\n // TODO: refactor here, try to follow same flow as below\n const refId = decode.number(bytes, it);\n const previousValue = decoder.root.refs.get(refId);\n index = ref.findIndex((value) => value === previousValue);\n ref[$deleteByIndex](index);\n allChanges.push({\n ref,\n refId: decoder.currentRefId,\n op: OPERATION.DELETE,\n field: \"\", // FIXME: remove this\n dynamicIndex: index,\n value: undefined,\n previousValue,\n });\n\n return;\n\n } else if (operation === OPERATION.ADD_BY_REFID) {\n const refId = decode.number(bytes, it);\n const itemByRefId = decoder.root.refs.get(refId);\n\n // use existing index, or push new value\n index = (itemByRefId)\n ? ref.findIndex((value) => value === itemByRefId)\n : ref.length;\n\n } else {\n index = decode.number(bytes, it);\n }\n\n const type = ref[$childType];\n\n let dynamicIndex: number | string = index;\n\n const { value, previousValue } = decodeValue(\n decoder,\n operation,\n ref,\n index,\n type,\n bytes,\n it,\n allChanges,\n );\n\n if (\n value !== null && value !== undefined &&\n value !== previousValue // avoid setting same value twice (if index === 0 it will result in a \"unshift\" for ArraySchema)\n ) {\n // ArraySchema\n (ref as ArraySchema)['$setAt'](index, value, operation);\n }\n\n // add change\n if (previousValue !== value) {\n allChanges.push({\n ref,\n refId: decoder.currentRefId,\n op: operation,\n field: \"\", // FIXME: remove this\n dynamicIndex,\n value,\n previousValue,\n });\n }\n}"]}
|
|
@@ -48,6 +48,15 @@ type CollectionCallback<K, V> = {
|
|
|
48
48
|
* @return callback to detach the onRemove listener
|
|
49
49
|
*/
|
|
50
50
|
onRemove(callback: (item: V, index: K) => void): () => void;
|
|
51
|
+
/**
|
|
52
|
+
* Trigger callback when the value on a key has changed.
|
|
53
|
+
*
|
|
54
|
+
* THIS METHOD IS NOT RECURSIVE!
|
|
55
|
+
* If you want to listen to changes on individual items, you need to attach callbacks to the them directly inside the `onAdd` callback.
|
|
56
|
+
*
|
|
57
|
+
* @param callback
|
|
58
|
+
*/
|
|
59
|
+
onChange(callback: (item: V, index: K) => void): void;
|
|
51
60
|
};
|
|
52
61
|
export declare function getDecoderStateCallbacks<T extends Schema>(decoder: Decoder<T>): GetCallbackProxy;
|
|
53
62
|
export {};
|
|
@@ -85,7 +85,10 @@ function getDecoderStateCallbacks(decoder) {
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
// trigger onChange
|
|
88
|
-
if (change.value !== change.previousValue
|
|
88
|
+
if (change.value !== change.previousValue &&
|
|
89
|
+
// FIXME: see "should not encode item if added and removed at the same patch" test case.
|
|
90
|
+
// some "ADD" + "DELETE" operations on same patch are being encoded as "DELETE"
|
|
91
|
+
(change.value !== undefined || change.previousValue !== undefined)) {
|
|
89
92
|
const replaceCallbacks = $callbacks[spec_1.OPERATION.REPLACE];
|
|
90
93
|
for (let i = replaceCallbacks?.length - 1; i >= 0; i--) {
|
|
91
94
|
replaceCallbacks[i](change.value, change.dynamicIndex ?? change.field);
|
|
@@ -198,6 +201,9 @@ function getDecoderStateCallbacks(decoder) {
|
|
|
198
201
|
const onRemove = function (ref, callback) {
|
|
199
202
|
return $root.addCallback($root.refIds.get(ref), spec_1.OPERATION.DELETE, callback);
|
|
200
203
|
};
|
|
204
|
+
const onChange = function (ref, callback) {
|
|
205
|
+
return $root.addCallback($root.refIds.get(ref), spec_1.OPERATION.REPLACE, callback);
|
|
206
|
+
};
|
|
201
207
|
return new Proxy({
|
|
202
208
|
onAdd: function (callback, immediate = true) {
|
|
203
209
|
//
|
|
@@ -229,6 +235,19 @@ function getDecoderStateCallbacks(decoder) {
|
|
|
229
235
|
return onRemove(context.instance, callback);
|
|
230
236
|
}
|
|
231
237
|
},
|
|
238
|
+
onChange: function (callback) {
|
|
239
|
+
if (context.onInstanceAvailable) {
|
|
240
|
+
// collection instance not received yet
|
|
241
|
+
let detachCallback = () => { };
|
|
242
|
+
context.onInstanceAvailable((ref) => {
|
|
243
|
+
detachCallback = onChange(ref, callback);
|
|
244
|
+
});
|
|
245
|
+
return () => detachCallback();
|
|
246
|
+
}
|
|
247
|
+
else if (context.instance) {
|
|
248
|
+
return onChange(context.instance, callback);
|
|
249
|
+
}
|
|
250
|
+
},
|
|
232
251
|
}, {
|
|
233
252
|
get(target, prop) {
|
|
234
253
|
if (!target[prop]) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StateCallbacks.js","sourceRoot":"","sources":["../../../src/decoder/strategy/StateCallbacks.ts"],"names":[],"mappings":"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","sourcesContent":["import { Metadata } from \"../../Metadata\";\nimport { Collection, NonFunctionNonPrimitivePropNames, NonFunctionPropNames } from \"../../types/HelperTypes\";\nimport { Ref } from \"../../encoder/ChangeTree\";\nimport { Decoder } from \"../Decoder\";\nimport { DataChange } from \"../DecodeOperation\";\nimport { OPERATION } from \"../../encoding/spec\";\nimport { Schema } from \"../../Schema\";\nimport type { DefinitionType } from \"../../annotations\";\nimport type { CollectionSchema } from \"../../types/custom/CollectionSchema\";\n\n//\n// Discussion: https://github.com/colyseus/schema/issues/155\n//\n// Main points:\n// - Decouple structures from their callbacks.\n// - Registering deep callbacks can be confusing.\n// - Avoid closures by allowing to pass a context. (https://github.com/colyseus/schema/issues/155#issuecomment-1804694081)\n//\n\nexport type GetCallbackProxy = (<T extends Schema>(instance: T) => CallbackProxy<T>);\n\nexport type CallbackProxy<T> = unknown extends T // is \"any\"?\n ? InstanceCallback<T> & CollectionCallback<any, any>\n : T extends Collection<infer K, infer V, infer _>\n ? CollectionCallback<K, V>\n : InstanceCallback<T>;\n\ntype InstanceCallback<T> = {\n /**\n * Trigger callback when value of a property changes.\n *\n * @param prop name of the property\n * @param callback callback to be triggered on property change\n * @param immediate trigger immediatelly if property has been already set.\n * @return callback to detach the listener\n */\n listen<K extends NonFunctionPropNames<T>>(\n prop: K,\n callback: (value: T[K], previousValue: T[K]) => void,\n immediate?: boolean,\n ): () => void;\n\n /**\n * Trigger callback whenever any property changed within this instance.\n *\n * @param prop name of the property\n * @param callback callback to be triggered on property change\n * @param immediate trigger immediatelly if property has been already set.\n * @return callback to detach the listener\n */\n onChange(callback: () => void): () => void;\n\n /**\n * Bind properties to another object. Changes on the properties will be reflected on the target object.\n *\n * @param targetObject object to bind properties to\n * @param properties list of properties to bind. If not provided, all properties will be bound.\n */\n bindTo(targetObject: any, properties?: Array<NonFunctionPropNames<T>>): void;\n} & {\n [K in NonFunctionNonPrimitivePropNames<T>]: CallbackProxy<T[K]>;\n}\n\ntype CollectionCallback<K, V> = {\n /**\n * Trigger callback when an item has been added to the collection.\n *\n * @param callback\n * @param immediate\n * @return callback to detach the onAdd listener\n */\n onAdd(callback: (item: V, index: K) => void, immediate?: boolean): () => void;\n\n /**\n * Trigger callback when an item has been removed to the collection.\n *\n * @param callback\n * @return callback to detach the onRemove listener\n */\n onRemove(callback: (item: V, index: K) => void): () => void;\n\n // /**\n // * Trigger callback when an item has been removed to the collection.\n // *\n // * @param callback\n // */\n // onChange(callback: (item: V, index: K) => void): void;\n};\n\ntype OnInstanceAvailableCallback = (callback: (ref: Ref, existing: boolean) => void) => void;\n\ntype CallContext = {\n instance?: any,\n parentInstance?: any,\n onInstanceAvailable?: OnInstanceAvailableCallback,\n}\n\n\nexport function getDecoderStateCallbacks<T extends Schema>(decoder: Decoder<T>): GetCallbackProxy {\n const $root = decoder.root;\n const callbacks = $root.callbacks;\n\n const onAddCalls: WeakMap<Function, boolean> = new WeakMap();\n let currentOnAddCallback: Function | undefined;\n\n decoder.triggerChanges = function (allChanges: DataChange[]) {\n const uniqueRefIds = new Set<number>();\n\n for (let i = 0, l = allChanges.length; i < l; i++) {\n const change = allChanges[i];\n const refId = change.refId;\n const ref = change.ref;\n const $callbacks = callbacks[refId];\n\n if (!$callbacks) { continue; }\n\n //\n // trigger onRemove on child structure.\n //\n if (\n (change.op & OPERATION.DELETE) === OPERATION.DELETE &&\n change.previousValue instanceof Schema\n ) {\n const deleteCallbacks = callbacks[$root.refIds.get(change.previousValue)]?.[OPERATION.DELETE];\n for (let i = deleteCallbacks?.length - 1; i >= 0; i--) {\n deleteCallbacks[i]();\n }\n }\n\n if (ref instanceof Schema) {\n //\n // Handle schema instance\n //\n\n if (!uniqueRefIds.has(refId)) {\n // trigger onChange\n const replaceCallbacks = $callbacks?.[OPERATION.REPLACE];\n for (let i = replaceCallbacks?.length - 1; i >= 0; i--) {\n replaceCallbacks[i]();\n // try {\n // } catch (e) {\n // console.error(e);\n // }\n }\n }\n\n if ($callbacks.hasOwnProperty(change.field)) {\n const fieldCallbacks = $callbacks[change.field];\n for (let i = fieldCallbacks?.length - 1; i >= 0; i--) {\n fieldCallbacks[i](change.value, change.previousValue);\n // try {\n // } catch (e) {\n // console.error(e);\n // }\n }\n }\n\n\n } else {\n //\n // Handle collection of items\n //\n\n if ((change.op & OPERATION.DELETE) === OPERATION.DELETE) {\n //\n // FIXME: `previousValue` should always be available.\n //\n if (change.previousValue !== undefined) {\n // triger onRemove\n const deleteCallbacks = $callbacks[OPERATION.DELETE];\n for (let i = deleteCallbacks?.length - 1; i >= 0; i--) {\n deleteCallbacks[i](change.previousValue, change.dynamicIndex ?? change.field);\n }\n }\n\n // Handle DELETE_AND_ADD operations\n if ((change.op & OPERATION.ADD) === OPERATION.ADD) {\n const addCallbacks = $callbacks[OPERATION.ADD];\n for (let i = addCallbacks?.length - 1; i >= 0; i--) {\n addCallbacks[i](change.value, change.dynamicIndex ?? change.field);\n }\n }\n\n } else if ((change.op & OPERATION.ADD) === OPERATION.ADD && change.previousValue === undefined) {\n // triger onAdd\n const addCallbacks = $callbacks[OPERATION.ADD];\n for (let i = addCallbacks?.length - 1; i >= 0; i--) {\n addCallbacks[i](change.value, change.dynamicIndex ?? change.field);\n }\n }\n\n // trigger onChange\n if (change.value !== change.previousValue) {\n const replaceCallbacks = $callbacks[OPERATION.REPLACE];\n for (let i = replaceCallbacks?.length - 1; i >= 0; i--) {\n replaceCallbacks[i](change.value, change.dynamicIndex ?? change.field);\n }\n }\n }\n\n uniqueRefIds.add(refId);\n }\n };\n\n function getProxy(\n metadataOrType: Metadata | DefinitionType,\n context: CallContext\n ) {\n let metadata: Metadata = context.instance?.constructor[Symbol.metadata] || metadataOrType;\n let isCollection = (\n (context.instance && typeof (context.instance['forEach']) === \"function\") ||\n (metadataOrType && typeof (metadataOrType[Symbol.metadata]) === \"undefined\")\n );\n\n if (metadata && !isCollection) {\n\n const onAddListen = function (\n ref: Ref,\n prop: string,\n callback: (value: any, previousValue: any) => void, immediate: boolean\n ) {\n // immediate trigger\n if (\n immediate &&\n context.instance[prop] !== undefined &&\n !onAddCalls.has(currentOnAddCallback) // Workaround for https://github.com/colyseus/schema/issues/147\n ) {\n callback(context.instance[prop], undefined);\n }\n return $root.addCallback($root.refIds.get(ref), prop, callback);\n }\n\n /**\n * Schema instances\n */\n return new Proxy({\n listen: function listen(prop: string, callback: (value: any, previousValue: any) => void, immediate: boolean = true) {\n if (context.instance) {\n return onAddListen(context.instance, prop, callback, immediate);\n\n } else {\n // collection instance not received yet\n let detachCallback = () => {};\n\n context.onInstanceAvailable((ref: Ref, existing: boolean) => {\n detachCallback = onAddListen(ref, prop, callback, immediate && existing && !onAddCalls.has(currentOnAddCallback))\n });\n\n return () => detachCallback();\n }\n },\n\n onChange: function onChange(callback: () => void) {\n return $root.addCallback(\n $root.refIds.get(context.instance),\n OPERATION.REPLACE,\n callback\n );\n },\n\n //\n // TODO: refactor `bindTo()` implementation.\n // There is room for improvement.\n //\n bindTo: function bindTo(targetObject: any, properties?: string[]) {\n if (!properties) {\n properties = Object.keys(metadata).map((index) => metadata[index as any as number].name);\n }\n return $root.addCallback(\n $root.refIds.get(context.instance),\n OPERATION.REPLACE,\n () => {\n properties.forEach((prop) =>\n targetObject[prop] = context.instance[prop])\n }\n );\n }\n }, {\n get(target, prop: string) {\n const metadataField = metadata[metadata[prop]];\n if (metadataField) {\n const instance = context.instance?.[prop];\n const onInstanceAvailable: OnInstanceAvailableCallback = (\n (callback: (ref: Ref, existing: boolean) => void) => {\n const unbind = $(context.instance).listen(prop, (value, _) => {\n callback(value, false);\n\n // FIXME: by \"unbinding\" the callback here,\n // it will not support when the server\n // re-instantiates the instance.\n //\n unbind?.();\n }, false);\n\n // has existing value\n if ($root.refIds.get(instance) !== undefined) {\n callback(instance, true);\n }\n }\n );\n return getProxy(metadataField.type, {\n // make sure refId is available, otherwise need to wait for the instance to be available.\n instance: ($root.refIds.get(instance) && instance),\n parentInstance: context.instance,\n onInstanceAvailable,\n });\n\n } else {\n // accessing the function\n return target[prop];\n }\n },\n has(target, prop: string) { return metadata[prop] !== undefined; },\n set(_, _1, _2) { throw new Error(\"not allowed\"); },\n deleteProperty(_, _1) { throw new Error(\"not allowed\"); },\n });\n\n } else {\n /**\n * Collection instances\n */\n\n const onAdd = function (ref: Ref, callback: (value: any, key: any) => void, immediate: boolean) {\n // Trigger callback on existing items\n if (immediate) {\n (ref as CollectionSchema).forEach((v, k) => callback(v, k));\n }\n\n return $root.addCallback($root.refIds.get(ref), OPERATION.ADD, (value, key) => {\n onAddCalls.set(callback, true);\n currentOnAddCallback = callback;\n callback(value, key);\n onAddCalls.delete(callback)\n currentOnAddCallback = undefined;\n });\n };\n\n const onRemove = function (ref: Ref, callback: (value: any, key: any) => void) {\n return $root.addCallback($root.refIds.get(ref), OPERATION.DELETE, callback);\n };\n\n return new Proxy({\n onAdd: function(callback: (value, key) => void, immediate: boolean = true) {\n //\n // https://github.com/colyseus/schema/issues/147\n // If parent instance has \"onAdd\" registered, avoid triggering immediate callback.\n //\n\n if (context.instance) {\n return onAdd(context.instance, callback, immediate && !onAddCalls.has(currentOnAddCallback));\n\n } else if (context.onInstanceAvailable) {\n // collection instance not received yet\n let detachCallback = () => {};\n\n context.onInstanceAvailable((ref: Ref, existing: boolean) => {\n detachCallback = onAdd(ref, callback, immediate && existing && !onAddCalls.has(currentOnAddCallback));\n });\n\n return () => detachCallback();\n }\n },\n onRemove: function(callback: (value, key) => void) {\n if (context.onInstanceAvailable) {\n // collection instance not received yet\n let detachCallback = () => {};\n\n context.onInstanceAvailable((ref: Ref) => {\n detachCallback = onRemove(ref, callback)\n });\n\n return () => detachCallback();\n\n } else if (context.instance) {\n return onRemove(context.instance, callback);\n }\n },\n }, {\n get(target, prop: string) {\n if (!target[prop]) {\n throw new Error(`Can't access '${prop}' through callback proxy. access the instance directly.`);\n }\n return target[prop];\n },\n has(target, prop) { return target[prop] !== undefined; },\n set(_, _1, _2) { throw new Error(\"not allowed\"); },\n deleteProperty(_, _1) { throw new Error(\"not allowed\"); },\n });\n }\n }\n\n function $<T>(instance: T): CallbackProxy<T> {\n return getProxy(undefined, { instance }) as CallbackProxy<T>;\n }\n\n return $;\n}"]}
|
|
1
|
+
{"version":3,"file":"StateCallbacks.js","sourceRoot":"","sources":["../../../src/decoder/strategy/StateCallbacks.ts"],"names":[],"mappings":";;AAqGA,4DAkUC;AAlaD,8CAAgD;AAChD,yCAAsC;AA+FtC,SAAgB,wBAAwB,CAAmB,OAAmB;IAC1E,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAC3B,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;IAElC,MAAM,UAAU,GAA+B,IAAI,OAAO,EAAE,CAAC;IAC7D,IAAI,oBAA0C,CAAC;IAE/C,OAAO,CAAC,cAAc,GAAG,UAAU,UAAwB;QACvD,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;QAEvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAChD,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;YAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;YAC3B,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;YACvB,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;YAEpC,IAAI,CAAC,UAAU,EAAE,CAAC;gBAAC,SAAS;YAAC,CAAC;YAE9B,EAAE;YACF,uCAAuC;YACvC,EAAE;YACF,IACI,CAAC,MAAM,CAAC,EAAE,GAAG,gBAAS,CAAC,MAAM,CAAC,KAAK,gBAAS,CAAC,MAAM;gBACnD,MAAM,CAAC,aAAa,YAAY,eAAM,EACxC,CAAC;gBACC,MAAM,eAAe,GAAG,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,gBAAS,CAAC,MAAM,CAAC,CAAC;gBAC9F,KAAK,IAAI,CAAC,GAAG,eAAe,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;oBACpD,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzB,CAAC;YACL,CAAC;YAED,IAAI,GAAG,YAAY,eAAM,EAAE,CAAC;gBACxB,EAAE;gBACF,yBAAyB;gBACzB,EAAE;gBAEF,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC3B,mBAAmB;oBACnB,MAAM,gBAAgB,GAAG,UAAU,EAAE,CAAC,gBAAS,CAAC,OAAO,CAAC,CAAC;oBACzD,KAAK,IAAI,CAAC,GAAG,gBAAgB,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;wBACrD,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;wBACtB,QAAQ;wBACR,gBAAgB;wBAChB,wBAAwB;wBACxB,IAAI;oBACR,CAAC;gBACL,CAAC;gBAED,IAAI,UAAU,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC1C,MAAM,cAAc,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oBAChD,KAAK,IAAI,CAAC,GAAG,cAAc,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;wBACnD,cAAc,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;wBACtD,QAAQ;wBACR,gBAAgB;wBAChB,wBAAwB;wBACxB,IAAI;oBACR,CAAC;gBACL,CAAC;YAGL,CAAC;iBAAM,CAAC;gBACJ,EAAE;gBACF,6BAA6B;gBAC7B,EAAE;gBAEF,IAAI,CAAC,MAAM,CAAC,EAAE,GAAG,gBAAS,CAAC,MAAM,CAAC,KAAK,gBAAS,CAAC,MAAM,EAAE,CAAC;oBACtD,EAAE;oBACF,qDAAqD;oBACrD,EAAE;oBACF,IAAI,MAAM,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;wBACrC,kBAAkB;wBAClB,MAAM,eAAe,GAAG,UAAU,CAAC,gBAAS,CAAC,MAAM,CAAC,CAAC;wBACrD,KAAK,IAAI,CAAC,GAAG,eAAe,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;4BACpD,eAAe,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC;wBAClF,CAAC;oBACL,CAAC;oBAED,mCAAmC;oBACnC,IAAI,CAAC,MAAM,CAAC,EAAE,GAAG,gBAAS,CAAC,GAAG,CAAC,KAAK,gBAAS,CAAC,GAAG,EAAE,CAAC;wBAChD,MAAM,YAAY,GAAG,UAAU,CAAC,gBAAS,CAAC,GAAG,CAAC,CAAC;wBAC/C,KAAK,IAAI,CAAC,GAAG,YAAY,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;4BACjD,YAAY,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC;wBACvE,CAAC;oBACL,CAAC;gBAEL,CAAC;qBAAM,IAAI,CAAC,MAAM,CAAC,EAAE,GAAG,gBAAS,CAAC,GAAG,CAAC,KAAK,gBAAS,CAAC,GAAG,IAAI,MAAM,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;oBAC7F,eAAe;oBACf,MAAM,YAAY,GAAG,UAAU,CAAC,gBAAS,CAAC,GAAG,CAAC,CAAC;oBAC/C,KAAK,IAAI,CAAC,GAAG,YAAY,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;wBACjD,YAAY,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC;oBACvE,CAAC;gBACL,CAAC;gBAED,mBAAmB;gBACnB,IACI,MAAM,CAAC,KAAK,KAAK,MAAM,CAAC,aAAa;oBACrC,wFAAwF;oBACxF,+EAA+E;oBAC/E,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,IAAI,MAAM,CAAC,aAAa,KAAK,SAAS,CAAC,EACpE,CAAC;oBACC,MAAM,gBAAgB,GAAG,UAAU,CAAC,gBAAS,CAAC,OAAO,CAAC,CAAC;oBACvD,KAAK,IAAI,CAAC,GAAG,gBAAgB,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;wBACrD,gBAAgB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC;oBAC3E,CAAC;gBACL,CAAC;YACL,CAAC;YAED,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;IACL,CAAC,CAAC;IAEF,SAAS,QAAQ,CACb,cAAyC,EACzC,OAAoB;QAEpB,IAAI,QAAQ,GAAa,OAAO,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,cAAc,CAAC;QAC1F,IAAI,YAAY,GAAG,CACf,CAAC,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,KAAK,UAAU,CAAC;YACzE,CAAC,cAAc,IAAI,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,WAAW,CAAC,CAC/E,CAAC;QAEF,IAAI,QAAQ,IAAI,CAAC,YAAY,EAAE,CAAC;YAE5B,MAAM,WAAW,GAAG,UAChB,GAAQ,EACR,IAAY,EACZ,QAAkD,EAAE,SAAkB;gBAEtE,oBAAoB;gBACpB,IACI,SAAS;oBACT,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,SAAS;oBACpC,CAAC,UAAU,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC,+DAA+D;kBACvG,CAAC;oBACC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC;gBAChD,CAAC;gBACD,OAAO,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;YACpE,CAAC,CAAA;YAED;;eAEG;YACH,OAAO,IAAI,KAAK,CAAC;gBACb,MAAM,EAAE,SAAS,MAAM,CAAC,IAAY,EAAE,QAAkD,EAAE,YAAqB,IAAI;oBAC/G,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;wBACnB,OAAO,WAAW,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;oBAEpE,CAAC;yBAAM,CAAC;wBACJ,uCAAuC;wBACvC,IAAI,cAAc,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;wBAE9B,OAAO,CAAC,mBAAmB,CAAC,CAAC,GAAQ,EAAE,QAAiB,EAAE,EAAE;4BACxD,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,IAAI,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC,CAAA;wBACrH,CAAC,CAAC,CAAC;wBAEH,OAAO,GAAG,EAAE,CAAC,cAAc,EAAE,CAAC;oBAClC,CAAC;gBACL,CAAC;gBAED,QAAQ,EAAE,SAAS,QAAQ,CAAC,QAAoB;oBAC5C,OAAO,KAAK,CAAC,WAAW,CACpB,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,EAClC,gBAAS,CAAC,OAAO,EACjB,QAAQ,CACX,CAAC;gBACN,CAAC;gBAED,EAAE;gBACF,4CAA4C;gBAC5C,iCAAiC;gBACjC,EAAE;gBACF,MAAM,EAAE,SAAS,MAAM,CAAC,YAAiB,EAAE,UAAqB;oBAC5D,IAAI,CAAC,UAAU,EAAE,CAAC;wBACd,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAsB,CAAC,CAAC,IAAI,CAAC,CAAC;oBAC7F,CAAC;oBACD,OAAO,KAAK,CAAC,WAAW,CACpB,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,EAClC,gBAAS,CAAC,OAAO,EACjB,GAAG,EAAE;wBACD,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CACxB,YAAY,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAA;oBACpD,CAAC,CACJ,CAAC;gBACN,CAAC;aACJ,EAAE;gBACC,GAAG,CAAC,MAAM,EAAE,IAAY;oBACpB,MAAM,aAAa,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;oBAC/C,IAAI,aAAa,EAAE,CAAC;wBAChB,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC;wBAC1C,MAAM,mBAAmB,GAAgC,CACrD,CAAC,QAA+C,EAAE,EAAE;4BAChD,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;gCACzD,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;gCAEvB,2CAA2C;gCAC3C,sCAAsC;gCACtC,gCAAgC;gCAChC,EAAE;gCACF,MAAM,EAAE,EAAE,CAAC;4BACf,CAAC,EAAE,KAAK,CAAC,CAAC;4BAEV,qBAAqB;4BACrB,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,SAAS,EAAE,CAAC;gCAC3C,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;4BAC7B,CAAC;wBACL,CAAC,CACJ,CAAC;wBACF,OAAO,QAAQ,CAAC,aAAa,CAAC,IAAI,EAAE;4BAChC,yFAAyF;4BACzF,QAAQ,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC;4BAClD,cAAc,EAAE,OAAO,CAAC,QAAQ;4BAChC,mBAAmB;yBACtB,CAAC,CAAC;oBAEP,CAAC;yBAAM,CAAC;wBACJ,yBAAyB;wBACzB,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC;oBACxB,CAAC;gBACL,CAAC;gBACD,GAAG,CAAC,MAAM,EAAE,IAAY,IAAI,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC;gBAClE,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;gBAClD,cAAc,CAAC,CAAC,EAAE,EAAE,IAAI,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;aAC5D,CAAC,CAAC;QAEP,CAAC;aAAM,CAAC;YACJ;;eAEG;YAEH,MAAM,KAAK,GAAG,UAAU,GAAQ,EAAE,QAAwC,EAAE,SAAkB;gBAC1F,qCAAqC;gBACrC,IAAI,SAAS,EAAE,CAAC;oBACX,GAAwB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBAChE,CAAC;gBAED,OAAO,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,gBAAS,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;oBAC1E,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;oBAC/B,oBAAoB,GAAG,QAAQ,CAAC;oBAChC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;oBACrB,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;oBAC3B,oBAAoB,GAAG,SAAS,CAAC;gBACrC,CAAC,CAAC,CAAC;YACP,CAAC,CAAC;YAEF,MAAM,QAAQ,GAAG,UAAU,GAAQ,EAAE,QAAwC;gBACzE,OAAO,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,gBAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YAChF,CAAC,CAAC;YAEF,MAAM,QAAQ,GAAG,UAAU,GAAQ,EAAE,QAAwC;gBACzE,OAAO,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,gBAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YACjF,CAAC,CAAC;YAEF,OAAO,IAAI,KAAK,CAAC;gBACb,KAAK,EAAE,UAAS,QAA8B,EAAE,YAAqB,IAAI;oBACrE,EAAE;oBACF,gDAAgD;oBAChD,kFAAkF;oBAClF,EAAE;oBAEF,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;wBACnB,OAAO,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC,CAAC;oBAEjG,CAAC;yBAAM,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;wBACrC,uCAAuC;wBACvC,IAAI,cAAc,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;wBAE9B,OAAO,CAAC,mBAAmB,CAAC,CAAC,GAAQ,EAAE,QAAiB,EAAE,EAAE;4BACxD,cAAc,GAAG,KAAK,CAAC,GAAG,EAAE,QAAQ,EAAE,SAAS,IAAI,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC,CAAC;wBAC1G,CAAC,CAAC,CAAC;wBAEH,OAAO,GAAG,EAAE,CAAC,cAAc,EAAE,CAAC;oBAClC,CAAC;gBACL,CAAC;gBACD,QAAQ,EAAE,UAAS,QAA8B;oBAC7C,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;wBAC9B,uCAAuC;wBACvC,IAAI,cAAc,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;wBAE9B,OAAO,CAAC,mBAAmB,CAAC,CAAC,GAAQ,EAAE,EAAE;4BACrC,cAAc,GAAG,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;wBAC5C,CAAC,CAAC,CAAC;wBAEH,OAAO,GAAG,EAAE,CAAC,cAAc,EAAE,CAAC;oBAElC,CAAC;yBAAM,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;wBAC1B,OAAO,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;oBAChD,CAAC;gBACL,CAAC;gBACD,QAAQ,EAAE,UAAS,QAA8B;oBAC7C,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;wBAC9B,uCAAuC;wBACvC,IAAI,cAAc,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;wBAE9B,OAAO,CAAC,mBAAmB,CAAC,CAAC,GAAQ,EAAE,EAAE;4BACrC,cAAc,GAAG,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;wBAC5C,CAAC,CAAC,CAAC;wBAEH,OAAO,GAAG,EAAE,CAAC,cAAc,EAAE,CAAC;oBAElC,CAAC;yBAAM,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;wBAC1B,OAAO,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;oBAChD,CAAC;gBACL,CAAC;aACJ,EAAE;gBACC,GAAG,CAAC,MAAM,EAAE,IAAY;oBACpB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;wBAChB,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,yDAAyD,CAAC,CAAC;oBACpG,CAAC;oBACD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC;gBACxB,CAAC;gBACD,GAAG,CAAC,MAAM,EAAE,IAAI,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC;gBACxD,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;gBAClD,cAAc,CAAC,CAAC,EAAE,EAAE,IAAI,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;aAC5D,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IAED,SAAS,CAAC,CAAI,QAAW;QACrB,OAAO,QAAQ,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,CAAgC,CAAC;IAC5E,CAAC;IAED,OAAO,CAAC,CAAC;AACb,CAAC","sourcesContent":["import { Metadata } from \"../../Metadata\";\nimport { Collection, NonFunctionNonPrimitivePropNames, NonFunctionPropNames } from \"../../types/HelperTypes\";\nimport { Ref } from \"../../encoder/ChangeTree\";\nimport { Decoder } from \"../Decoder\";\nimport { DataChange } from \"../DecodeOperation\";\nimport { OPERATION } from \"../../encoding/spec\";\nimport { Schema } from \"../../Schema\";\nimport type { DefinitionType } from \"../../annotations\";\nimport type { CollectionSchema } from \"../../types/custom/CollectionSchema\";\n\n//\n// Discussion: https://github.com/colyseus/schema/issues/155\n//\n// Main points:\n// - Decouple structures from their callbacks.\n// - Registering deep callbacks can be confusing.\n// - Avoid closures by allowing to pass a context. (https://github.com/colyseus/schema/issues/155#issuecomment-1804694081)\n//\n\nexport type GetCallbackProxy = (<T extends Schema>(instance: T) => CallbackProxy<T>);\n\nexport type CallbackProxy<T> = unknown extends T // is \"any\"?\n ? InstanceCallback<T> & CollectionCallback<any, any>\n : T extends Collection<infer K, infer V, infer _>\n ? CollectionCallback<K, V>\n : InstanceCallback<T>;\n\ntype InstanceCallback<T> = {\n /**\n * Trigger callback when value of a property changes.\n *\n * @param prop name of the property\n * @param callback callback to be triggered on property change\n * @param immediate trigger immediatelly if property has been already set.\n * @return callback to detach the listener\n */\n listen<K extends NonFunctionPropNames<T>>(\n prop: K,\n callback: (value: T[K], previousValue: T[K]) => void,\n immediate?: boolean,\n ): () => void;\n\n /**\n * Trigger callback whenever any property changed within this instance.\n *\n * @param prop name of the property\n * @param callback callback to be triggered on property change\n * @param immediate trigger immediatelly if property has been already set.\n * @return callback to detach the listener\n */\n onChange(callback: () => void): () => void;\n\n /**\n * Bind properties to another object. Changes on the properties will be reflected on the target object.\n *\n * @param targetObject object to bind properties to\n * @param properties list of properties to bind. If not provided, all properties will be bound.\n */\n bindTo(targetObject: any, properties?: Array<NonFunctionPropNames<T>>): void;\n} & {\n [K in NonFunctionNonPrimitivePropNames<T>]: CallbackProxy<T[K]>;\n}\n\ntype CollectionCallback<K, V> = {\n /**\n * Trigger callback when an item has been added to the collection.\n *\n * @param callback\n * @param immediate\n * @return callback to detach the onAdd listener\n */\n onAdd(callback: (item: V, index: K) => void, immediate?: boolean): () => void;\n\n /**\n * Trigger callback when an item has been removed to the collection.\n *\n * @param callback\n * @return callback to detach the onRemove listener\n */\n onRemove(callback: (item: V, index: K) => void): () => void;\n\n /**\n * Trigger callback when the value on a key has changed.\n *\n * THIS METHOD IS NOT RECURSIVE!\n * If you want to listen to changes on individual items, you need to attach callbacks to the them directly inside the `onAdd` callback.\n *\n * @param callback\n */\n onChange(callback: (item: V, index: K) => void): void;\n};\n\ntype OnInstanceAvailableCallback = (callback: (ref: Ref, existing: boolean) => void) => void;\n\ntype CallContext = {\n instance?: any,\n parentInstance?: any,\n onInstanceAvailable?: OnInstanceAvailableCallback,\n}\n\n\nexport function getDecoderStateCallbacks<T extends Schema>(decoder: Decoder<T>): GetCallbackProxy {\n const $root = decoder.root;\n const callbacks = $root.callbacks;\n\n const onAddCalls: WeakMap<Function, boolean> = new WeakMap();\n let currentOnAddCallback: Function | undefined;\n\n decoder.triggerChanges = function (allChanges: DataChange[]) {\n const uniqueRefIds = new Set<number>();\n\n for (let i = 0, l = allChanges.length; i < l; i++) {\n const change = allChanges[i];\n const refId = change.refId;\n const ref = change.ref;\n const $callbacks = callbacks[refId];\n\n if (!$callbacks) { continue; }\n\n //\n // trigger onRemove on child structure.\n //\n if (\n (change.op & OPERATION.DELETE) === OPERATION.DELETE &&\n change.previousValue instanceof Schema\n ) {\n const deleteCallbacks = callbacks[$root.refIds.get(change.previousValue)]?.[OPERATION.DELETE];\n for (let i = deleteCallbacks?.length - 1; i >= 0; i--) {\n deleteCallbacks[i]();\n }\n }\n\n if (ref instanceof Schema) {\n //\n // Handle schema instance\n //\n\n if (!uniqueRefIds.has(refId)) {\n // trigger onChange\n const replaceCallbacks = $callbacks?.[OPERATION.REPLACE];\n for (let i = replaceCallbacks?.length - 1; i >= 0; i--) {\n replaceCallbacks[i]();\n // try {\n // } catch (e) {\n // console.error(e);\n // }\n }\n }\n\n if ($callbacks.hasOwnProperty(change.field)) {\n const fieldCallbacks = $callbacks[change.field];\n for (let i = fieldCallbacks?.length - 1; i >= 0; i--) {\n fieldCallbacks[i](change.value, change.previousValue);\n // try {\n // } catch (e) {\n // console.error(e);\n // }\n }\n }\n\n\n } else {\n //\n // Handle collection of items\n //\n\n if ((change.op & OPERATION.DELETE) === OPERATION.DELETE) {\n //\n // FIXME: `previousValue` should always be available.\n //\n if (change.previousValue !== undefined) {\n // triger onRemove\n const deleteCallbacks = $callbacks[OPERATION.DELETE];\n for (let i = deleteCallbacks?.length - 1; i >= 0; i--) {\n deleteCallbacks[i](change.previousValue, change.dynamicIndex ?? change.field);\n }\n }\n\n // Handle DELETE_AND_ADD operations\n if ((change.op & OPERATION.ADD) === OPERATION.ADD) {\n const addCallbacks = $callbacks[OPERATION.ADD];\n for (let i = addCallbacks?.length - 1; i >= 0; i--) {\n addCallbacks[i](change.value, change.dynamicIndex ?? change.field);\n }\n }\n\n } else if ((change.op & OPERATION.ADD) === OPERATION.ADD && change.previousValue === undefined) {\n // triger onAdd\n const addCallbacks = $callbacks[OPERATION.ADD];\n for (let i = addCallbacks?.length - 1; i >= 0; i--) {\n addCallbacks[i](change.value, change.dynamicIndex ?? change.field);\n }\n }\n\n // trigger onChange\n if (\n change.value !== change.previousValue &&\n // FIXME: see \"should not encode item if added and removed at the same patch\" test case.\n // some \"ADD\" + \"DELETE\" operations on same patch are being encoded as \"DELETE\"\n (change.value !== undefined || change.previousValue !== undefined)\n ) {\n const replaceCallbacks = $callbacks[OPERATION.REPLACE];\n for (let i = replaceCallbacks?.length - 1; i >= 0; i--) {\n replaceCallbacks[i](change.value, change.dynamicIndex ?? change.field);\n }\n }\n }\n\n uniqueRefIds.add(refId);\n }\n };\n\n function getProxy(\n metadataOrType: Metadata | DefinitionType,\n context: CallContext\n ) {\n let metadata: Metadata = context.instance?.constructor[Symbol.metadata] || metadataOrType;\n let isCollection = (\n (context.instance && typeof (context.instance['forEach']) === \"function\") ||\n (metadataOrType && typeof (metadataOrType[Symbol.metadata]) === \"undefined\")\n );\n\n if (metadata && !isCollection) {\n\n const onAddListen = function (\n ref: Ref,\n prop: string,\n callback: (value: any, previousValue: any) => void, immediate: boolean\n ) {\n // immediate trigger\n if (\n immediate &&\n context.instance[prop] !== undefined &&\n !onAddCalls.has(currentOnAddCallback) // Workaround for https://github.com/colyseus/schema/issues/147\n ) {\n callback(context.instance[prop], undefined);\n }\n return $root.addCallback($root.refIds.get(ref), prop, callback);\n }\n\n /**\n * Schema instances\n */\n return new Proxy({\n listen: function listen(prop: string, callback: (value: any, previousValue: any) => void, immediate: boolean = true) {\n if (context.instance) {\n return onAddListen(context.instance, prop, callback, immediate);\n\n } else {\n // collection instance not received yet\n let detachCallback = () => {};\n\n context.onInstanceAvailable((ref: Ref, existing: boolean) => {\n detachCallback = onAddListen(ref, prop, callback, immediate && existing && !onAddCalls.has(currentOnAddCallback))\n });\n\n return () => detachCallback();\n }\n },\n\n onChange: function onChange(callback: () => void) {\n return $root.addCallback(\n $root.refIds.get(context.instance),\n OPERATION.REPLACE,\n callback\n );\n },\n\n //\n // TODO: refactor `bindTo()` implementation.\n // There is room for improvement.\n //\n bindTo: function bindTo(targetObject: any, properties?: string[]) {\n if (!properties) {\n properties = Object.keys(metadata).map((index) => metadata[index as any as number].name);\n }\n return $root.addCallback(\n $root.refIds.get(context.instance),\n OPERATION.REPLACE,\n () => {\n properties.forEach((prop) =>\n targetObject[prop] = context.instance[prop])\n }\n );\n }\n }, {\n get(target, prop: string) {\n const metadataField = metadata[metadata[prop]];\n if (metadataField) {\n const instance = context.instance?.[prop];\n const onInstanceAvailable: OnInstanceAvailableCallback = (\n (callback: (ref: Ref, existing: boolean) => void) => {\n const unbind = $(context.instance).listen(prop, (value, _) => {\n callback(value, false);\n\n // FIXME: by \"unbinding\" the callback here,\n // it will not support when the server\n // re-instantiates the instance.\n //\n unbind?.();\n }, false);\n\n // has existing value\n if ($root.refIds.get(instance) !== undefined) {\n callback(instance, true);\n }\n }\n );\n return getProxy(metadataField.type, {\n // make sure refId is available, otherwise need to wait for the instance to be available.\n instance: ($root.refIds.get(instance) && instance),\n parentInstance: context.instance,\n onInstanceAvailable,\n });\n\n } else {\n // accessing the function\n return target[prop];\n }\n },\n has(target, prop: string) { return metadata[prop] !== undefined; },\n set(_, _1, _2) { throw new Error(\"not allowed\"); },\n deleteProperty(_, _1) { throw new Error(\"not allowed\"); },\n });\n\n } else {\n /**\n * Collection instances\n */\n\n const onAdd = function (ref: Ref, callback: (value: any, key: any) => void, immediate: boolean) {\n // Trigger callback on existing items\n if (immediate) {\n (ref as CollectionSchema).forEach((v, k) => callback(v, k));\n }\n\n return $root.addCallback($root.refIds.get(ref), OPERATION.ADD, (value, key) => {\n onAddCalls.set(callback, true);\n currentOnAddCallback = callback;\n callback(value, key);\n onAddCalls.delete(callback)\n currentOnAddCallback = undefined;\n });\n };\n\n const onRemove = function (ref: Ref, callback: (value: any, key: any) => void) {\n return $root.addCallback($root.refIds.get(ref), OPERATION.DELETE, callback);\n };\n\n const onChange = function (ref: Ref, callback: (value: any, key: any) => void) {\n return $root.addCallback($root.refIds.get(ref), OPERATION.REPLACE, callback);\n };\n\n return new Proxy({\n onAdd: function(callback: (value, key) => void, immediate: boolean = true) {\n //\n // https://github.com/colyseus/schema/issues/147\n // If parent instance has \"onAdd\" registered, avoid triggering immediate callback.\n //\n\n if (context.instance) {\n return onAdd(context.instance, callback, immediate && !onAddCalls.has(currentOnAddCallback));\n\n } else if (context.onInstanceAvailable) {\n // collection instance not received yet\n let detachCallback = () => {};\n\n context.onInstanceAvailable((ref: Ref, existing: boolean) => {\n detachCallback = onAdd(ref, callback, immediate && existing && !onAddCalls.has(currentOnAddCallback));\n });\n\n return () => detachCallback();\n }\n },\n onRemove: function(callback: (value, key) => void) {\n if (context.onInstanceAvailable) {\n // collection instance not received yet\n let detachCallback = () => {};\n\n context.onInstanceAvailable((ref: Ref) => {\n detachCallback = onRemove(ref, callback)\n });\n\n return () => detachCallback();\n\n } else if (context.instance) {\n return onRemove(context.instance, callback);\n }\n },\n onChange: function(callback: (value, key) => void) {\n if (context.onInstanceAvailable) {\n // collection instance not received yet\n let detachCallback = () => {};\n\n context.onInstanceAvailable((ref: Ref) => {\n detachCallback = onChange(ref, callback)\n });\n\n return () => detachCallback();\n\n } else if (context.instance) {\n return onChange(context.instance, callback);\n }\n },\n }, {\n get(target, prop: string) {\n if (!target[prop]) {\n throw new Error(`Can't access '${prop}' through callback proxy. access the instance directly.`);\n }\n return target[prop];\n },\n has(target, prop) { return target[prop] !== undefined; },\n set(_, _1, _2) { throw new Error(\"not allowed\"); },\n deleteProperty(_, _1) { throw new Error(\"not allowed\"); },\n });\n }\n }\n\n function $<T>(instance: T): CallbackProxy<T> {\n return getProxy(undefined, { instance }) as unknown as CallbackProxy<T>;\n }\n\n return $;\n}"]}
|
|
@@ -22,6 +22,7 @@ export declare class ArraySchema<V = any> implements Array<V>, Collection<number
|
|
|
22
22
|
*/
|
|
23
23
|
static [$filter](ref: ArraySchema, index: number, view: StateView): boolean;
|
|
24
24
|
static is(type: any): boolean;
|
|
25
|
+
static from<T>(iterable: Iterable<T> | ArrayLike<T>): ArraySchema<T>;
|
|
25
26
|
constructor(...items: V[]);
|
|
26
27
|
set length(newLength: number);
|
|
27
28
|
get length(): number;
|
|
@@ -93,15 +94,8 @@ export declare class ArraySchema<V = any> implements Array<V>, Collection<number
|
|
|
93
94
|
* @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at the last index in the array.
|
|
94
95
|
*/
|
|
95
96
|
lastIndexOf(searchElement: V, fromIndex?: number): number;
|
|
96
|
-
/**
|
|
97
|
-
* Determines whether all the members of an array satisfy the specified test.
|
|
98
|
-
* @param callbackfn A function that accepts up to three arguments. The every method calls
|
|
99
|
-
* the callbackfn function for each element in the array until the callbackfn returns a value
|
|
100
|
-
* which is coercible to the Boolean value false, or until the end of the array.
|
|
101
|
-
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
|
102
|
-
* If thisArg is omitted, undefined is used as the this value.
|
|
103
|
-
*/
|
|
104
97
|
every<S extends V>(predicate: (value: V, index: number, array: V[]) => value is S, thisArg?: any): this is S[];
|
|
98
|
+
every(callbackfn: (value: V, index: number, array: V[]) => unknown, thisArg?: any): boolean;
|
|
105
99
|
/**
|
|
106
100
|
* Determines whether the specified callback function returns true for any element of an array.
|
|
107
101
|
* @param callbackfn A function that accepts up to three arguments. The some method calls
|
|
@@ -45,6 +45,9 @@ class ArraySchema {
|
|
|
45
45
|
// type format: { array: "string" }
|
|
46
46
|
(type['array'] !== undefined));
|
|
47
47
|
}
|
|
48
|
+
static from(iterable) {
|
|
49
|
+
return new ArraySchema(...Array.from(iterable));
|
|
50
|
+
}
|
|
48
51
|
constructor(...items) {
|
|
49
52
|
this.items = [];
|
|
50
53
|
this.tmpItems = [];
|
|
@@ -411,8 +414,8 @@ class ArraySchema {
|
|
|
411
414
|
lastIndexOf(searchElement, fromIndex = this.length - 1) {
|
|
412
415
|
return this.items.lastIndexOf(searchElement, fromIndex);
|
|
413
416
|
}
|
|
414
|
-
every(
|
|
415
|
-
return this.items.every(
|
|
417
|
+
every(predicate, thisArg) {
|
|
418
|
+
return this.items.every(predicate, thisArg);
|
|
416
419
|
}
|
|
417
420
|
/**
|
|
418
421
|
* Determines whether the specified callback function returns true for any element of an array.
|
|
@@ -597,6 +600,9 @@ class ArraySchema {
|
|
|
597
600
|
//
|
|
598
601
|
with(index, value) {
|
|
599
602
|
const copy = this.items.slice();
|
|
603
|
+
// Allow negative indexing from the end
|
|
604
|
+
if (index < 0)
|
|
605
|
+
index += this.length;
|
|
600
606
|
copy[index] = value;
|
|
601
607
|
return new ArraySchema(...copy);
|
|
602
608
|
}
|