@colyseus/schema 3.0.0-alpha.9 → 3.0.1
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 +148 -62
- package/bin/schema-debug +94 -0
- package/build/cjs/index.js +2222 -1513
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +2223 -1516
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +2225 -1516
- package/lib/Metadata.d.ts +21 -9
- package/lib/Metadata.js +169 -32
- package/lib/Metadata.js.map +1 -1
- package/lib/Reflection.d.ts +19 -4
- package/lib/Reflection.js +66 -31
- package/lib/Reflection.js.map +1 -1
- package/lib/Schema.d.ts +12 -5
- package/lib/Schema.js +57 -56
- package/lib/Schema.js.map +1 -1
- package/lib/annotations.d.ts +31 -34
- package/lib/annotations.js +110 -160
- package/lib/annotations.js.map +1 -1
- package/lib/codegen/api.js +1 -2
- package/lib/codegen/api.js.map +1 -1
- package/lib/codegen/languages/cpp.js +1 -2
- package/lib/codegen/languages/cpp.js.map +1 -1
- package/lib/codegen/languages/csharp.js +9 -46
- package/lib/codegen/languages/csharp.js.map +1 -1
- package/lib/codegen/languages/haxe.js +4 -2
- package/lib/codegen/languages/haxe.js.map +1 -1
- package/lib/codegen/languages/java.js +1 -2
- package/lib/codegen/languages/java.js.map +1 -1
- package/lib/codegen/languages/js.js +1 -2
- package/lib/codegen/languages/js.js.map +1 -1
- package/lib/codegen/languages/lua.js +23 -25
- package/lib/codegen/languages/lua.js.map +1 -1
- package/lib/codegen/languages/ts.js +1 -2
- package/lib/codegen/languages/ts.js.map +1 -1
- package/lib/codegen/parser.js +85 -3
- package/lib/codegen/parser.js.map +1 -1
- package/lib/codegen/types.js +6 -3
- package/lib/codegen/types.js.map +1 -1
- package/lib/decoder/DecodeOperation.d.ts +3 -4
- package/lib/decoder/DecodeOperation.js +35 -17
- package/lib/decoder/DecodeOperation.js.map +1 -1
- package/lib/decoder/Decoder.d.ts +5 -6
- package/lib/decoder/Decoder.js +10 -10
- package/lib/decoder/Decoder.js.map +1 -1
- package/lib/decoder/ReferenceTracker.js +4 -2
- package/lib/decoder/ReferenceTracker.js.map +1 -1
- package/lib/decoder/strategy/RawChanges.js +1 -2
- package/lib/decoder/strategy/RawChanges.js.map +1 -1
- package/lib/decoder/strategy/StateCallbacks.d.ts +44 -11
- package/lib/decoder/strategy/StateCallbacks.js +74 -64
- package/lib/decoder/strategy/StateCallbacks.js.map +1 -1
- package/lib/encoder/ChangeTree.d.ts +28 -20
- package/lib/encoder/ChangeTree.js +242 -188
- package/lib/encoder/ChangeTree.js.map +1 -1
- package/lib/encoder/EncodeOperation.d.ts +3 -6
- package/lib/encoder/EncodeOperation.js +51 -65
- package/lib/encoder/EncodeOperation.js.map +1 -1
- package/lib/encoder/Encoder.d.ts +8 -7
- package/lib/encoder/Encoder.js +128 -79
- package/lib/encoder/Encoder.js.map +1 -1
- package/lib/encoder/Root.d.ts +22 -0
- package/lib/encoder/Root.js +81 -0
- package/lib/encoder/Root.js.map +1 -0
- package/lib/encoder/StateView.d.ts +7 -7
- package/lib/encoder/StateView.js +72 -74
- package/lib/encoder/StateView.js.map +1 -1
- package/lib/encoding/assert.d.ts +7 -6
- package/lib/encoding/assert.js +13 -5
- package/lib/encoding/assert.js.map +1 -1
- package/lib/encoding/decode.d.ts +36 -19
- package/lib/encoding/decode.js +54 -84
- package/lib/encoding/decode.js.map +1 -1
- package/lib/encoding/encode.d.ts +36 -18
- package/lib/encoding/encode.js +61 -48
- package/lib/encoding/encode.js.map +1 -1
- package/lib/encoding/spec.d.ts +4 -5
- package/lib/encoding/spec.js +1 -2
- package/lib/encoding/spec.js.map +1 -1
- package/lib/index.d.ts +10 -9
- package/lib/index.js +24 -17
- package/lib/index.js.map +1 -1
- package/lib/types/HelperTypes.d.ts +34 -2
- package/lib/types/HelperTypes.js.map +1 -1
- package/lib/types/TypeContext.d.ts +29 -0
- package/lib/types/TypeContext.js +151 -0
- package/lib/types/TypeContext.js.map +1 -0
- package/lib/types/custom/ArraySchema.d.ts +2 -2
- package/lib/types/custom/ArraySchema.js +33 -22
- package/lib/types/custom/ArraySchema.js.map +1 -1
- package/lib/types/custom/CollectionSchema.d.ts +2 -2
- package/lib/types/custom/CollectionSchema.js +1 -0
- package/lib/types/custom/CollectionSchema.js.map +1 -1
- package/lib/types/custom/MapSchema.d.ts +18 -16
- package/lib/types/custom/MapSchema.js +12 -4
- package/lib/types/custom/MapSchema.js.map +1 -1
- package/lib/types/custom/SetSchema.d.ts +2 -2
- package/lib/types/custom/SetSchema.js +1 -0
- package/lib/types/custom/SetSchema.js.map +1 -1
- package/lib/types/registry.d.ts +8 -1
- package/lib/types/registry.js +23 -6
- package/lib/types/registry.js.map +1 -1
- package/lib/types/symbols.d.ts +8 -5
- package/lib/types/symbols.js +9 -6
- package/lib/types/symbols.js.map +1 -1
- package/lib/types/utils.js +1 -2
- package/lib/types/utils.js.map +1 -1
- package/lib/utils.js +9 -7
- package/lib/utils.js.map +1 -1
- package/package.json +19 -18
- package/src/Metadata.ts +190 -42
- package/src/Reflection.ts +76 -38
- package/src/Schema.ts +72 -70
- package/src/annotations.ts +156 -202
- package/src/codegen/languages/csharp.ts +8 -47
- package/src/codegen/languages/haxe.ts +4 -0
- package/src/codegen/languages/lua.ts +19 -27
- package/src/codegen/parser.ts +107 -0
- package/src/codegen/types.ts +1 -0
- package/src/decoder/DecodeOperation.ts +43 -15
- package/src/decoder/Decoder.ts +12 -10
- package/src/decoder/ReferenceTracker.ts +5 -3
- package/src/decoder/strategy/StateCallbacks.ts +152 -81
- package/src/encoder/ChangeTree.ts +282 -209
- package/src/encoder/EncodeOperation.ts +78 -78
- package/src/encoder/Encoder.ts +152 -88
- package/src/encoder/Root.ts +93 -0
- package/src/encoder/StateView.ts +80 -88
- package/src/encoding/assert.ts +17 -8
- package/src/encoding/decode.ts +73 -93
- package/src/encoding/encode.ts +76 -45
- package/src/encoding/spec.ts +3 -5
- package/src/index.ts +12 -20
- package/src/types/HelperTypes.ts +54 -2
- package/src/types/TypeContext.ts +175 -0
- package/src/types/custom/ArraySchema.ts +49 -19
- package/src/types/custom/CollectionSchema.ts +1 -0
- package/src/types/custom/MapSchema.ts +30 -17
- package/src/types/custom/SetSchema.ts +1 -0
- package/src/types/registry.ts +22 -3
- package/src/types/symbols.ts +10 -7
- package/src/utils.ts +7 -3
- package/lib/Decoder.d.ts +0 -16
- package/lib/Decoder.js +0 -182
- package/lib/Decoder.js.map +0 -1
- package/lib/Encoder.d.ts +0 -13
- package/lib/Encoder.js +0 -79
- package/lib/Encoder.js.map +0 -1
- package/lib/changes/ChangeSet.d.ts +0 -12
- package/lib/changes/ChangeSet.js +0 -35
- package/lib/changes/ChangeSet.js.map +0 -1
- package/lib/changes/ChangeTree.d.ts +0 -53
- package/lib/changes/ChangeTree.js +0 -202
- package/lib/changes/ChangeTree.js.map +0 -1
- package/lib/changes/DecodeOperation.d.ts +0 -15
- package/lib/changes/DecodeOperation.js +0 -186
- package/lib/changes/DecodeOperation.js.map +0 -1
- package/lib/changes/EncodeOperation.d.ts +0 -18
- package/lib/changes/EncodeOperation.js +0 -130
- package/lib/changes/EncodeOperation.js.map +0 -1
- package/lib/changes/ReferenceTracker.d.ts +0 -14
- package/lib/changes/ReferenceTracker.js +0 -83
- package/lib/changes/ReferenceTracker.js.map +0 -1
- package/lib/changes/consts.d.ts +0 -14
- package/lib/changes/consts.js +0 -18
- package/lib/changes/consts.js.map +0 -1
- package/lib/decoding/decode.d.ts +0 -48
- package/lib/decoding/decode.js +0 -267
- package/lib/decoding/decode.js.map +0 -1
- package/lib/ecs.d.ts +0 -11
- package/lib/ecs.js +0 -160
- package/lib/ecs.js.map +0 -1
- package/lib/filters/index.d.ts +0 -8
- package/lib/filters/index.js +0 -24
- package/lib/filters/index.js.map +0 -1
- package/lib/spec.d.ts +0 -13
- package/lib/spec.js +0 -42
- package/lib/spec.js.map +0 -1
- package/lib/types/ArraySchema.d.ts +0 -238
- package/lib/types/ArraySchema.js +0 -555
- package/lib/types/ArraySchema.js.map +0 -1
- package/lib/types/CollectionSchema.d.ts +0 -35
- package/lib/types/CollectionSchema.js +0 -150
- package/lib/types/CollectionSchema.js.map +0 -1
- package/lib/types/MapSchema.d.ts +0 -38
- package/lib/types/MapSchema.js +0 -215
- package/lib/types/MapSchema.js.map +0 -1
- package/lib/types/SetSchema.d.ts +0 -32
- package/lib/types/SetSchema.js +0 -162
- package/lib/types/SetSchema.js.map +0 -1
- package/lib/types/typeRegistry.d.ts +0 -5
- package/lib/types/typeRegistry.js +0 -13
- package/lib/types/typeRegistry.js.map +0 -1
- package/lib/usage.d.ts +0 -1
- package/lib/usage.js +0 -22
- package/lib/usage.js.map +0 -1
- package/lib/v3.d.ts +0 -1
- package/lib/v3.js +0 -427
- package/lib/v3.js.map +0 -1
- package/lib/v3_experiment.d.ts +0 -1
- package/lib/v3_experiment.js +0 -407
- package/lib/v3_experiment.js.map +0 -1
package/lib/decoder/Decoder.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Decoder = void 0;
|
|
4
|
-
const
|
|
4
|
+
const TypeContext_1 = require("../types/TypeContext");
|
|
5
5
|
const symbols_1 = require("../types/symbols");
|
|
6
|
-
const
|
|
6
|
+
const decode_1 = require("../encoding/decode");
|
|
7
7
|
const spec_1 = require("../encoding/spec");
|
|
8
8
|
const ReferenceTracker_1 = require("./ReferenceTracker");
|
|
9
9
|
const DecodeOperation_1 = require("./DecodeOperation");
|
|
10
10
|
class Decoder {
|
|
11
11
|
constructor(root, context) {
|
|
12
12
|
this.currentRefId = 0;
|
|
13
|
-
this.
|
|
14
|
-
this.context = context || new
|
|
13
|
+
this.setState(root);
|
|
14
|
+
this.context = context || new TypeContext_1.TypeContext(root.constructor);
|
|
15
15
|
// console.log(">>>>>>>>>>>>>>>> Decoder types");
|
|
16
16
|
// this.context.schemas.forEach((id, schema) => {
|
|
17
17
|
// console.log("type:", id, schema.name, Object.keys(schema[Symbol.metadata]));
|
|
18
18
|
// });
|
|
19
19
|
}
|
|
20
|
-
|
|
20
|
+
setState(root) {
|
|
21
21
|
this.state = root;
|
|
22
22
|
this.root = new ReferenceTracker_1.ReferenceTracker();
|
|
23
23
|
this.root.addRef(0, root);
|
|
@@ -34,7 +34,7 @@ class Decoder {
|
|
|
34
34
|
//
|
|
35
35
|
if (bytes[it.offset] == spec_1.SWITCH_TO_STRUCTURE) {
|
|
36
36
|
it.offset++;
|
|
37
|
-
this.currentRefId = decode.number(bytes, it);
|
|
37
|
+
this.currentRefId = decode_1.decode.number(bytes, it);
|
|
38
38
|
const nextRef = $root.refs.get(this.currentRefId);
|
|
39
39
|
//
|
|
40
40
|
// Trying to access a reference that haven't been decoded yet.
|
|
@@ -44,7 +44,7 @@ class Decoder {
|
|
|
44
44
|
}
|
|
45
45
|
ref[symbols_1.$onDecodeEnd]?.();
|
|
46
46
|
ref = nextRef;
|
|
47
|
-
decoder = ref
|
|
47
|
+
decoder = ref.constructor[symbols_1.$decoder];
|
|
48
48
|
continue;
|
|
49
49
|
}
|
|
50
50
|
const result = decoder(this, bytes, it, ref, allChanges);
|
|
@@ -56,9 +56,9 @@ class Decoder {
|
|
|
56
56
|
//
|
|
57
57
|
const nextIterator = { offset: it.offset };
|
|
58
58
|
while (it.offset < totalBytes) {
|
|
59
|
-
if (
|
|
59
|
+
if (bytes[it.offset] === spec_1.SWITCH_TO_STRUCTURE) {
|
|
60
60
|
nextIterator.offset = it.offset + 1;
|
|
61
|
-
if ($root.refs.has(decode.number(bytes, nextIterator))) {
|
|
61
|
+
if ($root.refs.has(decode_1.decode.number(bytes, nextIterator))) {
|
|
62
62
|
break;
|
|
63
63
|
}
|
|
64
64
|
}
|
|
@@ -79,7 +79,7 @@ class Decoder {
|
|
|
79
79
|
let type;
|
|
80
80
|
if (bytes[it.offset] === spec_1.TYPE_ID) {
|
|
81
81
|
it.offset++;
|
|
82
|
-
const type_id = decode.number(bytes, it);
|
|
82
|
+
const type_id = decode_1.decode.number(bytes, it);
|
|
83
83
|
type = this.context.get(type_id);
|
|
84
84
|
}
|
|
85
85
|
return type || defaultType;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Decoder.js","sourceRoot":"","sources":["../../src/decoder/Decoder.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"Decoder.js","sourceRoot":"","sources":["../../src/decoder/Decoder.ts"],"names":[],"mappings":";;;AAAA,sDAAmD;AACnD,8CAAgF;AAGhF,+CAA4C;AAC5C,2CAA2E;AAG3E,yDAAsD;AACtD,uDAA+F;AAG/F,MAAa,OAAO;IAUhB,YAAY,IAAO,EAAE,OAAqB;QAJ1C,iBAAY,GAAW,CAAC,CAAC;QAKrB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAEpB,IAAI,CAAC,OAAO,GAAG,OAAO,IAAI,IAAI,yBAAW,CAAC,IAAI,CAAC,WAA4B,CAAC,CAAC;QAE7E,iDAAiD;QACjD,iDAAiD;QACjD,mFAAmF;QACnF,MAAM;IACV,CAAC;IAES,QAAQ,CAAC,IAAO;QACtB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,IAAI,GAAG,IAAI,mCAAgB,EAAE,CAAC;QACnC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED,MAAM,CACF,KAAa,EACb,KAAe,EAAE,MAAM,EAAE,CAAC,EAAE,EAC5B,MAAW,IAAI,CAAC,KAAK;QAErB,MAAM,UAAU,GAAiB,EAAE,CAAC;QAEpC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC;QACxB,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;QAEpC,IAAI,OAAO,GAAoB,GAAG,CAAC,aAAa,CAAC,CAAC,kBAAQ,CAAC,CAAC;QAE5D,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QAEtB,OAAO,EAAE,CAAC,MAAM,GAAG,UAAU,EAAE,CAAC;YAC5B,EAAE;YACF,8DAA8D;YAC9D,EAAE;YACF,IAAI,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,0BAAmB,EAAE,CAAC;gBAC1C,EAAE,CAAC,MAAM,EAAE,CAAC;gBAEZ,IAAI,CAAC,YAAY,GAAG,eAAM,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBAC7C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAW,CAAC;gBAE5D,EAAE;gBACF,8DAA8D;gBAC9D,EAAE;gBACF,IAAI,CAAC,OAAO,EAAE,CAAC;oBAAC,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;gBAAC,CAAC;gBAC7E,GAAG,CAAC,sBAAY,CAAC,EAAE,EAAE,CAAA;gBACrB,GAAG,GAAG,OAAO,CAAC;gBAEd,OAAO,GAAG,GAAG,CAAC,WAAW,CAAC,kBAAQ,CAAC,CAAC;gBAEpC,SAAS;YACb,CAAC;YAED,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC;YAEzD,IAAI,MAAM,KAAK,qCAAmB,EAAE,CAAC;gBACjC,OAAO,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;gBAEtD,EAAE;gBACF,2DAA2D;gBAC3D,oBAAoB;gBACpB,EAAE;gBACF,MAAM,YAAY,GAAa,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC;gBACrD,OAAO,EAAE,CAAC,MAAM,GAAG,UAAU,EAAE,CAAC;oBAC5B,IAAI,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,0BAAmB,EAAE,CAAC;wBAC3C,YAAY,CAAC,MAAM,GAAG,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;wBACpC,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,eAAM,CAAC,MAAM,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC;4BACrD,MAAM;wBACV,CAAC;oBACL,CAAC;oBAED,EAAE,CAAC,MAAM,EAAE,CAAC;gBAChB,CAAC;gBACD,SAAS;YACb,CAAC;QACL,CAAC;QAED,6CAA6C;QAC7C,GAAG,CAAC,sBAAY,CAAC,EAAE,EAAE,CAAA;QAErB,kBAAkB;QAClB,IAAI,CAAC,cAAc,EAAE,CAAC,UAAU,CAAC,CAAC;QAElC,oCAAoC;QACpC,KAAK,CAAC,yBAAyB,EAAE,CAAC;QAElC,OAAO,UAAU,CAAC;IACtB,CAAC;IAED,eAAe,CAAC,KAAa,EAAE,EAAY,EAAE,WAA0B;QACnE,IAAI,IAAmB,CAAC;QAExB,IAAI,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,cAAO,EAAE,CAAC;YAC/B,EAAE,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,OAAO,GAAG,eAAM,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACzC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrC,CAAC;QAED,OAAO,IAAI,IAAI,WAAW,CAAC;IAC/B,CAAC;IAED,oBAAoB,CAAE,IAAmB;QACrC,8CAA8C;QAE9C,6BAA6B;QAC7B,sDAAsD;QAEtD,mBAAmB;QACnB,OAAO,IAAK,IAAY,EAAE,CAAC;IAC/B,CAAC;IAED,eAAe,CAAC,GAAe,EAAE,UAAwB;QACrD,MAAM,UAAU,GAAG,GAAG,CAAC,kBAAQ,CAAC,CAAC;QAEjC,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAU,CAAC,CAAC,KAAK,QAAQ,CAAC;QAC5D,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC;QAE/B,GAAG,CAAC,OAAO,CAAC,CAAC,KAAU,EAAE,GAAQ,EAAE,EAAE;YACjC,UAAU,CAAC,IAAI,CAAC;gBACZ,GAAG,EAAE,KAAK;gBACV,KAAK;gBACL,EAAE,EAAE,gBAAS,CAAC,MAAM;gBACpB,KAAK,EAAE,GAAG;gBACV,KAAK,EAAE,SAAS;gBAChB,aAAa,EAAE,KAAK;aACvB,CAAC,CAAC;YAEH,IAAI,aAAa,EAAE,CAAC;gBAChB,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;YACrD,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;CAEJ;AA/ID,0BA+IC","sourcesContent":["import { TypeContext } from \"../types/TypeContext\";\nimport { $changes, $childType, $decoder, $onDecodeEnd } from \"../types/symbols\";\nimport { Schema } from \"../Schema\";\n\nimport { decode } from \"../encoding/decode\";\nimport { OPERATION, SWITCH_TO_STRUCTURE, TYPE_ID } from '../encoding/spec';\nimport type { Ref } from \"../encoder/ChangeTree\";\nimport type { Iterator } from \"../encoding/decode\";\nimport { ReferenceTracker } from \"./ReferenceTracker\";\nimport { DEFINITION_MISMATCH, type DataChange, type DecodeOperation } from \"./DecodeOperation\";\nimport { Collection } from \"../types/HelperTypes\";\n\nexport class Decoder<T extends Schema = any> {\n context: TypeContext;\n\n state: T;\n root: ReferenceTracker;\n\n currentRefId: number = 0;\n\n triggerChanges?: (allChanges: DataChange[]) => void;\n\n constructor(root: T, context?: TypeContext) {\n this.setState(root);\n\n this.context = context || new TypeContext(root.constructor as typeof Schema);\n\n // console.log(\">>>>>>>>>>>>>>>> Decoder types\");\n // this.context.schemas.forEach((id, schema) => {\n // console.log(\"type:\", id, schema.name, Object.keys(schema[Symbol.metadata]));\n // });\n }\n\n protected setState(root: T) {\n this.state = root;\n this.root = new ReferenceTracker();\n this.root.addRef(0, root);\n }\n\n decode(\n bytes: Buffer,\n it: Iterator = { offset: 0 },\n ref: Ref = this.state,\n ) {\n const allChanges: DataChange[] = [];\n\n const $root = this.root;\n const totalBytes = bytes.byteLength;\n\n let decoder: DecodeOperation = ref['constructor'][$decoder];\n\n this.currentRefId = 0;\n\n while (it.offset < totalBytes) {\n //\n // Peek ahead, check if it's a switch to a different structure\n //\n if (bytes[it.offset] == SWITCH_TO_STRUCTURE) {\n it.offset++;\n\n this.currentRefId = decode.number(bytes, it);\n const nextRef = $root.refs.get(this.currentRefId) as Schema;\n\n //\n // Trying to access a reference that haven't been decoded yet.\n //\n if (!nextRef) { throw new Error(`\"refId\" not found: ${this.currentRefId}`); }\n ref[$onDecodeEnd]?.()\n ref = nextRef;\n\n decoder = ref.constructor[$decoder];\n\n continue;\n }\n\n const result = decoder(this, bytes, it, ref, allChanges);\n\n if (result === DEFINITION_MISMATCH) {\n console.warn(\"@colyseus/schema: definition mismatch\");\n\n //\n // keep skipping next bytes until reaches a known structure\n // by local decoder.\n //\n const nextIterator: Iterator = { offset: it.offset };\n while (it.offset < totalBytes) {\n if (bytes[it.offset] === SWITCH_TO_STRUCTURE) {\n nextIterator.offset = it.offset + 1;\n if ($root.refs.has(decode.number(bytes, nextIterator))) {\n break;\n }\n }\n\n it.offset++;\n }\n continue;\n }\n }\n\n // FIXME: DRY with SWITCH_TO_STRUCTURE block.\n ref[$onDecodeEnd]?.()\n\n // trigger changes\n this.triggerChanges?.(allChanges);\n\n // drop references of unused schemas\n $root.garbageCollectDeletedRefs();\n\n return allChanges;\n }\n\n getInstanceType(bytes: Buffer, it: Iterator, defaultType: typeof Schema): typeof Schema {\n let type: typeof Schema;\n\n if (bytes[it.offset] === TYPE_ID) {\n it.offset++;\n const type_id = decode.number(bytes, it);\n type = this.context.get(type_id);\n }\n\n return type || defaultType;\n }\n\n createInstanceOfType (type: typeof Schema): Schema {\n // let instance: Schema = new (type as any)();\n\n // // assign root on $changes\n // instance[$changes].root = this.root[$changes].root;\n\n // return instance;\n return new (type as any)();\n }\n\n removeChildRefs(ref: Collection, allChanges: DataChange[]) {\n const changeTree = ref[$changes];\n\n const needRemoveRef = typeof (ref[$childType]) !== \"string\";\n const refId = changeTree.refId;\n\n ref.forEach((value: any, key: any) => {\n allChanges.push({\n ref: value,\n refId,\n op: OPERATION.DELETE,\n field: key,\n value: undefined,\n previousValue: value\n });\n\n if (needRemoveRef) {\n this.root.removeRef(this.root.refIds.get(value));\n }\n });\n }\n\n}\n\n"]}
|
|
@@ -67,6 +67,7 @@ class ReferenceTracker {
|
|
|
67
67
|
clearRefs() {
|
|
68
68
|
this.refs.clear();
|
|
69
69
|
this.deletedRefs.clear();
|
|
70
|
+
this.callbacks = {};
|
|
70
71
|
this.refCounts = {};
|
|
71
72
|
}
|
|
72
73
|
// for decoding
|
|
@@ -83,8 +84,9 @@ class ReferenceTracker {
|
|
|
83
84
|
// Ensure child schema instances have their references removed as well.
|
|
84
85
|
//
|
|
85
86
|
if (Metadata_1.Metadata.isValidInstance(ref)) {
|
|
86
|
-
const metadata = ref
|
|
87
|
-
for (const
|
|
87
|
+
const metadata = ref.constructor[Symbol.metadata];
|
|
88
|
+
for (const index in metadata) {
|
|
89
|
+
const field = metadata[index].name;
|
|
88
90
|
const childRefId = typeof (ref[field]) === "object" && this.refIds.get(ref[field]);
|
|
89
91
|
if (childRefId) {
|
|
90
92
|
this.removeRef(childRefId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReferenceTracker.js","sourceRoot":"","sources":["../../src/decoder/ReferenceTracker.ts"],"names":[],"mappings":";;;AAAA,0CAAuC;AACvC,8CAA8C;AAE9C,0CAA2C;AAE3C,2CAA6C;AAE7C,MAAM,eAAgB,SAAQ,KAAK;IAC/B,YAAY,OAAe;QACvB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAClC,CAAC;CACJ;AAQD,MAAa,gBAAgB;IAA7B;QACI,EAAE;QACF,wCAAwC;QACxC,wDAAwD;QACxD,EAAE;QACK,SAAI,GAAG,IAAI,GAAG,EAAe,CAAC;QAC9B,WAAM,GAAG,IAAI,OAAO,EAAe,CAAC;QAEpC,cAAS,GAAiC,EAAE,CAAC;QAC7C,gBAAW,GAAG,IAAI,GAAG,EAAU,CAAC;QAEhC,cAAS,GAAyC,EAAE,CAAC;QAClD,iBAAY,GAAW,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"ReferenceTracker.js","sourceRoot":"","sources":["../../src/decoder/ReferenceTracker.ts"],"names":[],"mappings":";;;AAAA,0CAAuC;AACvC,8CAA8C;AAE9C,0CAA2C;AAE3C,2CAA6C;AAE7C,MAAM,eAAgB,SAAQ,KAAK;IAC/B,YAAY,OAAe;QACvB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAClC,CAAC;CACJ;AAQD,MAAa,gBAAgB;IAA7B;QACI,EAAE;QACF,wCAAwC;QACxC,wDAAwD;QACxD,EAAE;QACK,SAAI,GAAG,IAAI,GAAG,EAAe,CAAC;QAC9B,WAAM,GAAG,IAAI,OAAO,EAAe,CAAC;QAEpC,cAAS,GAAiC,EAAE,CAAC;QAC7C,gBAAW,GAAG,IAAI,GAAG,EAAU,CAAC;QAEhC,cAAS,GAAyC,EAAE,CAAC;QAClD,iBAAY,GAAW,CAAC,CAAC;IAwHvC,CAAC;IAtHG,eAAe;QACX,OAAO,IAAI,CAAC,YAAY,EAAE,CAAC;IAC/B,CAAC;IAED,eAAe;IACf,MAAM,CAAC,KAAa,EAAE,GAAQ,EAAE,iBAA0B,IAAI;QAC1D,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC1B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAE5B,IAAI,cAAc,EAAE,CAAC;YACjB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAC7D,CAAC;QAED,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;IACL,CAAC;IAED,eAAe;IACf,SAAS,CAAC,KAAa;QACnB,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAEvC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YACzB,IAAI,CAAC;gBACD,MAAM,IAAI,eAAe,CAAC,2CAA2C,CAAC,CAAC;YAC3E,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACT,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACpB,CAAC;YACD,OAAO;QACX,CAAC;QAED,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;YACjB,IAAI,CAAC;gBACD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBACjC,MAAM,IAAI,eAAe,CAAC,2BAA2B,KAAK,sBAAsB,GAAG,CAAC,WAAW,CAAC,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACrI,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACT,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACpB,CAAC;YACD,OAAO;QACX,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,QAAQ,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9C,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;IACL,CAAC;IAED,SAAS;QACL,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAClB,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;QACpB,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;IACxB,CAAC;IAED,eAAe;IACf,yBAAyB;QACrB,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YAC/B,EAAE;YACF,0BAA0B;YAC1B,EAAE;YACF,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;gBAAC,OAAO;YAAC,CAAC;YAE1C,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAEjC,EAAE;YACF,uEAAuE;YACvE,EAAE;YACF,IAAI,mBAAQ,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;gBAChC,MAAM,QAAQ,GAAa,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAC5D,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;oBAC3B,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAsB,CAAC,CAAC,IAAI,CAAC;oBACpD,MAAM,UAAU,GAAG,OAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;oBAClF,IAAI,UAAU,EAAE,CAAC;wBACb,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;oBAC/B,CAAC;gBACL,CAAC;YAEL,CAAC;iBAAM,CAAC;gBACJ,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,oBAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,UAAU,EAAE,CAAC;oBAC5D,KAAK,CAAC,IAAI,CAAE,GAAiB,CAAC,MAAM,EAAE,CAAC;yBAClC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBACpE,CAAC;YACL,CAAC;YAED,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa;YACtC,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,mBAAmB;YACjD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,mBAAmB;QACrD,CAAC,CAAC,CAAC;QAEH,sBAAsB;QACtB,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;IAED,WAAW,CAAC,KAAa,EAAE,gBAAiC,EAAE,QAAkB;QAC5E,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACtB,MAAM,IAAI,GAAG,CAAC,OAAM,CAAC,gBAAgB,CAAC,KAAK,QAAQ,CAAC;gBAC5C,CAAC,CAAC,gBAAS,CAAC,gBAAgB,CAAC;gBAC7B,CAAC,CAAC,gBAAgB,CAAA;YAC1B,MAAM,IAAI,KAAK,CACX,yBAAyB,IAAI,wBAAwB,CACxD,CAAC;QACN,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QAC/B,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAC3C,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,gBAAgB,CAAC,GAAG,EAAE,CAAC;QACjD,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvD,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,gBAAgB,EAAE,QAAQ,CAAC,CAAC;IACxE,CAAC;IAED,cAAc,CAAC,KAAa,EAAE,KAAsB,EAAE,QAAkB;QACpE,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;QAClE,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YACf,IAAA,iBAAS,EAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;QACnD,CAAC;IACL,CAAC;CAEJ;AApID,4CAoIC","sourcesContent":["import { Metadata } from \"../Metadata\";\nimport { $childType } from \"../types/symbols\";\nimport { Ref } from \"../encoder/ChangeTree\";\nimport { spliceOne } from \"../types/utils\";\nimport type { MapSchema } from \"../types/custom/MapSchema\";\nimport { OPERATION } from \"../encoding/spec\";\n\nclass DecodingWarning extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"DecodingWarning\";\n }\n}\n\n/**\n * Used for decoding only.\n */\n\nexport type SchemaCallbacks = { [field: string | number]: Function[] };\n\nexport class ReferenceTracker {\n //\n // Relation of refId => Schema structure\n // For direct access of structures during decoding time.\n //\n public refs = new Map<number, Ref>();\n public refIds = new WeakMap<Ref, number>();\n\n public refCounts: { [refId: number]: number; } = {};\n public deletedRefs = new Set<number>();\n\n public callbacks: { [refId: number]: SchemaCallbacks } = {};\n protected nextUniqueId: number = 0;\n\n getNextUniqueId() {\n return this.nextUniqueId++;\n }\n\n // for decoding\n addRef(refId: number, ref: Ref, incrementCount: boolean = true) {\n this.refs.set(refId, ref);\n this.refIds.set(ref, refId);\n\n if (incrementCount) {\n this.refCounts[refId] = (this.refCounts[refId] || 0) + 1;\n }\n\n if (this.deletedRefs.has(refId)) {\n this.deletedRefs.delete(refId);\n }\n }\n\n // for decoding\n removeRef(refId: number) {\n const refCount = this.refCounts[refId];\n\n if (refCount === undefined) {\n try {\n throw new DecodingWarning(\"trying to remove refId that doesn't exist\");\n } catch (e) {\n console.warn(e);\n }\n return;\n }\n\n if (refCount === 0) {\n try {\n const ref = this.refs.get(refId);\n throw new DecodingWarning(`trying to remove refId '${refId}' with 0 refCount (${ref.constructor.name}: ${JSON.stringify(ref)})`);\n } catch (e) {\n console.warn(e);\n }\n return;\n }\n\n if ((this.refCounts[refId] = refCount - 1) <= 0) {\n this.deletedRefs.add(refId);\n }\n }\n\n clearRefs() {\n this.refs.clear();\n this.deletedRefs.clear();\n this.callbacks = {};\n this.refCounts = {};\n }\n\n // for decoding\n garbageCollectDeletedRefs() {\n this.deletedRefs.forEach((refId) => {\n //\n // Skip active references.\n //\n if (this.refCounts[refId] > 0) { return; }\n\n const ref = this.refs.get(refId);\n\n //\n // Ensure child schema instances have their references removed as well.\n //\n if (Metadata.isValidInstance(ref)) {\n const metadata: Metadata = ref.constructor[Symbol.metadata];\n for (const index in metadata) {\n const field = metadata[index as any as number].name;\n const childRefId = typeof(ref[field]) === \"object\" && this.refIds.get(ref[field]);\n if (childRefId) {\n this.removeRef(childRefId);\n }\n }\n\n } else {\n if (typeof (Object.values(ref[$childType])[0]) === \"function\") {\n Array.from((ref as MapSchema).values())\n .forEach((child) => this.removeRef(this.refIds.get(child)));\n }\n }\n\n this.refs.delete(refId); // remove ref\n delete this.refCounts[refId]; // remove ref count\n delete this.callbacks[refId]; // remove callbacks\n });\n\n // clear deleted refs.\n this.deletedRefs.clear();\n }\n\n addCallback(refId: number, fieldOrOperation: string | number, callback: Function) {\n if (refId === undefined) {\n const name = (typeof(fieldOrOperation) === \"number\")\n ? OPERATION[fieldOrOperation]\n : fieldOrOperation\n throw new Error(\n `Can't addCallback on '${name}' (refId is undefined)`\n );\n }\n if (!this.callbacks[refId]) {\n this.callbacks[refId] = {};\n }\n if (!this.callbacks[refId][fieldOrOperation]) {\n this.callbacks[refId][fieldOrOperation] = [];\n }\n this.callbacks[refId][fieldOrOperation].push(callback);\n return () => this.removeCallback(refId, fieldOrOperation, callback);\n }\n\n removeCallback(refId: number, field: string | number, callback: Function) {\n const index = this.callbacks?.[refId]?.[field]?.indexOf(callback);\n if (index !== -1) {\n spliceOne(this.callbacks[refId][field], index);\n }\n }\n\n}\n"]}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getRawChangesCallback =
|
|
3
|
+
exports.getRawChangesCallback = getRawChangesCallback;
|
|
4
4
|
function getRawChangesCallback(decoder, callback) {
|
|
5
5
|
decoder.triggerChanges = callback;
|
|
6
6
|
}
|
|
7
|
-
exports.getRawChangesCallback = getRawChangesCallback;
|
|
8
7
|
//# sourceMappingURL=RawChanges.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RawChanges.js","sourceRoot":"","sources":["../../../src/decoder/strategy/RawChanges.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"RawChanges.js","sourceRoot":"","sources":["../../../src/decoder/strategy/RawChanges.ts"],"names":[],"mappings":";;AAGA,sDAKC;AALD,SAAgB,qBAAqB,CACjC,OAAgB,EAChB,QAAyC;IAEzC,OAAO,CAAC,cAAc,GAAG,QAAQ,CAAC;AACtC,CAAC","sourcesContent":["import { DataChange } from \"../DecodeOperation\";\nimport { Decoder } from \"../Decoder\";\n\nexport function getRawChangesCallback(\n decoder: Decoder,\n callback: (changes: DataChange[]) => void\n) {\n decoder.triggerChanges = callback;\n}"]}
|
|
@@ -1,20 +1,53 @@
|
|
|
1
1
|
import { Collection, NonFunctionNonPrimitivePropNames, NonFunctionPropNames } from "../../types/HelperTypes";
|
|
2
2
|
import { Decoder } from "../Decoder";
|
|
3
|
-
import {
|
|
4
|
-
type
|
|
3
|
+
import { Schema } from "../../Schema";
|
|
4
|
+
export type GetCallbackProxy = (<T extends Schema>(instance: T) => CallbackProxy<T>);
|
|
5
|
+
export type CallbackProxy<T> = unknown extends T ? InstanceCallback<T> & CollectionCallback<any, any> : T extends Collection<infer K, infer V, infer _> ? CollectionCallback<K, V> : InstanceCallback<T>;
|
|
5
6
|
type InstanceCallback<T> = {
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Trigger callback when value of a property changes.
|
|
9
|
+
*
|
|
10
|
+
* @param prop name of the property
|
|
11
|
+
* @param callback callback to be triggered on property change
|
|
12
|
+
* @param immediate trigger immediatelly if property has been already set.
|
|
13
|
+
* @return callback to detach the listener
|
|
14
|
+
*/
|
|
15
|
+
listen<K extends NonFunctionPropNames<T>>(prop: K, callback: (value: T[K], previousValue: T[K]) => void, immediate?: boolean): () => void;
|
|
16
|
+
/**
|
|
17
|
+
* Trigger callback whenever any property changed within this instance.
|
|
18
|
+
*
|
|
19
|
+
* @param prop name of the property
|
|
20
|
+
* @param callback callback to be triggered on property change
|
|
21
|
+
* @param immediate trigger immediatelly if property has been already set.
|
|
22
|
+
* @return callback to detach the listener
|
|
23
|
+
*/
|
|
24
|
+
onChange(callback: () => void): () => void;
|
|
25
|
+
/**
|
|
26
|
+
* Bind properties to another object. Changes on the properties will be reflected on the target object.
|
|
27
|
+
*
|
|
28
|
+
* @param targetObject object to bind properties to
|
|
29
|
+
* @param properties list of properties to bind. If not provided, all properties will be bound.
|
|
30
|
+
*/
|
|
8
31
|
bindTo(targetObject: any, properties?: Array<NonFunctionPropNames<T>>): void;
|
|
9
32
|
} & {
|
|
10
|
-
[K in NonFunctionNonPrimitivePropNames<T>]:
|
|
33
|
+
[K in NonFunctionNonPrimitivePropNames<T>]: CallbackProxy<T[K]>;
|
|
11
34
|
};
|
|
12
35
|
type CollectionCallback<K, V> = {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Trigger callback when an item has been added to the collection.
|
|
38
|
+
*
|
|
39
|
+
* @param callback
|
|
40
|
+
* @param immediate
|
|
41
|
+
* @return callback to detach the onAdd listener
|
|
42
|
+
*/
|
|
43
|
+
onAdd(callback: (item: V, index: K) => void, immediate?: boolean): () => void;
|
|
44
|
+
/**
|
|
45
|
+
* Trigger callback when an item has been removed to the collection.
|
|
46
|
+
*
|
|
47
|
+
* @param callback
|
|
48
|
+
* @return callback to detach the onRemove listener
|
|
49
|
+
*/
|
|
50
|
+
onRemove(callback: (item: V, index: K) => void): () => void;
|
|
19
51
|
};
|
|
52
|
+
export declare function getDecoderStateCallbacks<T extends Schema>(decoder: Decoder<T>): GetCallbackProxy;
|
|
20
53
|
export {};
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.getDecoderStateCallbacks = getDecoderStateCallbacks;
|
|
4
4
|
const spec_1 = require("../../encoding/spec");
|
|
5
5
|
const Schema_1 = require("../../Schema");
|
|
6
|
-
function
|
|
6
|
+
function getDecoderStateCallbacks(decoder) {
|
|
7
7
|
const $root = decoder.root;
|
|
8
8
|
const callbacks = $root.callbacks;
|
|
9
|
-
|
|
9
|
+
const onAddCalls = new WeakMap();
|
|
10
|
+
let currentOnAddCallback;
|
|
10
11
|
decoder.triggerChanges = function (allChanges) {
|
|
11
12
|
const uniqueRefIds = new Set();
|
|
12
13
|
for (let i = 0, l = allChanges.length; i < l; i++) {
|
|
@@ -26,52 +27,38 @@ function getStateCallbacks(decoder) {
|
|
|
26
27
|
for (let i = deleteCallbacks?.length - 1; i >= 0; i--) {
|
|
27
28
|
deleteCallbacks[i]();
|
|
28
29
|
}
|
|
29
|
-
// callbacks[$root.refIds.get(change.previousValue)]?.[OPERATION.DELETE]?.forEach(callback =>
|
|
30
|
-
// callback());
|
|
31
30
|
}
|
|
32
31
|
if (ref instanceof Schema_1.Schema) {
|
|
33
32
|
//
|
|
34
33
|
// Handle schema instance
|
|
35
34
|
//
|
|
36
35
|
if (!uniqueRefIds.has(refId)) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
console.error(e);
|
|
36
|
+
// trigger onChange
|
|
37
|
+
const replaceCallbacks = $callbacks?.[spec_1.OPERATION.REPLACE];
|
|
38
|
+
for (let i = replaceCallbacks?.length - 1; i >= 0; i--) {
|
|
39
|
+
replaceCallbacks[i]();
|
|
40
|
+
// try {
|
|
41
|
+
// } catch (e) {
|
|
42
|
+
// console.error(e);
|
|
43
|
+
// }
|
|
46
44
|
}
|
|
47
45
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
46
|
+
if ($callbacks.hasOwnProperty(change.field)) {
|
|
47
|
+
const fieldCallbacks = $callbacks[change.field];
|
|
48
|
+
for (let i = fieldCallbacks?.length - 1; i >= 0; i--) {
|
|
49
|
+
fieldCallbacks[i](change.value, change.previousValue);
|
|
50
|
+
// try {
|
|
51
|
+
// } catch (e) {
|
|
52
|
+
// console.error(e);
|
|
53
|
+
// }
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
|
-
catch (e) {
|
|
57
|
-
//
|
|
58
|
-
console.error(e);
|
|
59
|
-
}
|
|
60
56
|
}
|
|
61
57
|
else {
|
|
62
58
|
//
|
|
63
59
|
// Handle collection of items
|
|
64
60
|
//
|
|
65
|
-
if (change.op
|
|
66
|
-
// triger onAdd
|
|
67
|
-
isTriggeringOnAdd = true;
|
|
68
|
-
const addCallbacks = $callbacks[spec_1.OPERATION.ADD];
|
|
69
|
-
for (let i = addCallbacks?.length - 1; i >= 0; i--) {
|
|
70
|
-
addCallbacks[i](change.value, change.dynamicIndex ?? change.field);
|
|
71
|
-
}
|
|
72
|
-
isTriggeringOnAdd = false;
|
|
73
|
-
}
|
|
74
|
-
else if ((change.op & spec_1.OPERATION.DELETE) === spec_1.OPERATION.DELETE) {
|
|
61
|
+
if ((change.op & spec_1.OPERATION.DELETE) === spec_1.OPERATION.DELETE) {
|
|
75
62
|
//
|
|
76
63
|
// FIXME: `previousValue` should always be available.
|
|
77
64
|
//
|
|
@@ -83,7 +70,6 @@ function getStateCallbacks(decoder) {
|
|
|
83
70
|
}
|
|
84
71
|
}
|
|
85
72
|
// Handle DELETE_AND_ADD operations
|
|
86
|
-
// FIXME: should we set "isTriggeringOnAdd" here?
|
|
87
73
|
if ((change.op & spec_1.OPERATION.ADD) === spec_1.OPERATION.ADD) {
|
|
88
74
|
const addCallbacks = $callbacks[spec_1.OPERATION.ADD];
|
|
89
75
|
for (let i = addCallbacks?.length - 1; i >= 0; i--) {
|
|
@@ -91,6 +77,13 @@ function getStateCallbacks(decoder) {
|
|
|
91
77
|
}
|
|
92
78
|
}
|
|
93
79
|
}
|
|
80
|
+
else if ((change.op & spec_1.OPERATION.ADD) === spec_1.OPERATION.ADD && change.previousValue === undefined) {
|
|
81
|
+
// triger onAdd
|
|
82
|
+
const addCallbacks = $callbacks[spec_1.OPERATION.ADD];
|
|
83
|
+
for (let i = addCallbacks?.length - 1; i >= 0; i--) {
|
|
84
|
+
addCallbacks[i](change.value, change.dynamicIndex ?? change.field);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
94
87
|
// trigger onChange
|
|
95
88
|
if (change.value !== change.previousValue) {
|
|
96
89
|
const replaceCallbacks = $callbacks[spec_1.OPERATION.REPLACE];
|
|
@@ -107,11 +100,11 @@ function getStateCallbacks(decoder) {
|
|
|
107
100
|
let isCollection = ((context.instance && typeof (context.instance['forEach']) === "function") ||
|
|
108
101
|
(metadataOrType && typeof (metadataOrType[Symbol.metadata]) === "undefined"));
|
|
109
102
|
if (metadata && !isCollection) {
|
|
110
|
-
const
|
|
103
|
+
const onAddListen = function (ref, prop, callback, immediate) {
|
|
111
104
|
// immediate trigger
|
|
112
105
|
if (immediate &&
|
|
113
106
|
context.instance[prop] !== undefined &&
|
|
114
|
-
!
|
|
107
|
+
!onAddCalls.has(currentOnAddCallback) // Workaround for https://github.com/colyseus/schema/issues/147
|
|
115
108
|
) {
|
|
116
109
|
callback(context.instance[prop], undefined);
|
|
117
110
|
}
|
|
@@ -123,22 +116,36 @@ function getStateCallbacks(decoder) {
|
|
|
123
116
|
return new Proxy({
|
|
124
117
|
listen: function listen(prop, callback, immediate = true) {
|
|
125
118
|
if (context.instance) {
|
|
126
|
-
return
|
|
119
|
+
return onAddListen(context.instance, prop, callback, immediate);
|
|
127
120
|
}
|
|
128
121
|
else {
|
|
129
122
|
// collection instance not received yet
|
|
130
|
-
|
|
123
|
+
let detachCallback = () => { };
|
|
124
|
+
context.onInstanceAvailable((ref, existing) => {
|
|
125
|
+
detachCallback = onAddListen(ref, prop, callback, immediate && existing && !onAddCalls.has(currentOnAddCallback));
|
|
126
|
+
});
|
|
127
|
+
return () => detachCallback();
|
|
131
128
|
}
|
|
132
129
|
},
|
|
133
130
|
onChange: function onChange(callback) {
|
|
134
131
|
return $root.addCallback($root.refIds.get(context.instance), spec_1.OPERATION.REPLACE, callback);
|
|
135
132
|
},
|
|
133
|
+
//
|
|
134
|
+
// TODO: refactor `bindTo()` implementation.
|
|
135
|
+
// There is room for improvement.
|
|
136
|
+
//
|
|
136
137
|
bindTo: function bindTo(targetObject, properties) {
|
|
137
|
-
|
|
138
|
+
if (!properties) {
|
|
139
|
+
properties = Object.keys(metadata).map((index) => metadata[index].name);
|
|
140
|
+
}
|
|
141
|
+
return $root.addCallback($root.refIds.get(context.instance), spec_1.OPERATION.REPLACE, () => {
|
|
142
|
+
properties.forEach((prop) => targetObject[prop] = context.instance[prop]);
|
|
143
|
+
});
|
|
138
144
|
}
|
|
139
145
|
}, {
|
|
140
146
|
get(target, prop) {
|
|
141
|
-
|
|
147
|
+
const metadataField = metadata[metadata[prop]];
|
|
148
|
+
if (metadataField) {
|
|
142
149
|
const instance = context.instance?.[prop];
|
|
143
150
|
const onInstanceAvailable = ((callback) => {
|
|
144
151
|
const unbind = $(context.instance).listen(prop, (value, _) => {
|
|
@@ -154,8 +161,9 @@ function getStateCallbacks(decoder) {
|
|
|
154
161
|
callback(instance, true);
|
|
155
162
|
}
|
|
156
163
|
});
|
|
157
|
-
return getProxy(
|
|
158
|
-
instance
|
|
164
|
+
return getProxy(metadataField.type, {
|
|
165
|
+
// make sure refId is available, otherwise need to wait for the instance to be available.
|
|
166
|
+
instance: ($root.refIds.get(instance) && instance),
|
|
159
167
|
parentInstance: context.instance,
|
|
160
168
|
onInstanceAvailable,
|
|
161
169
|
});
|
|
@@ -179,7 +187,13 @@ function getStateCallbacks(decoder) {
|
|
|
179
187
|
if (immediate) {
|
|
180
188
|
ref.forEach((v, k) => callback(v, k));
|
|
181
189
|
}
|
|
182
|
-
return $root.addCallback($root.refIds.get(ref), spec_1.OPERATION.ADD,
|
|
190
|
+
return $root.addCallback($root.refIds.get(ref), spec_1.OPERATION.ADD, (value, key) => {
|
|
191
|
+
onAddCalls.set(callback, true);
|
|
192
|
+
currentOnAddCallback = callback;
|
|
193
|
+
callback(value, key);
|
|
194
|
+
onAddCalls.delete(callback);
|
|
195
|
+
currentOnAddCallback = undefined;
|
|
196
|
+
});
|
|
183
197
|
};
|
|
184
198
|
const onRemove = function (ref, callback) {
|
|
185
199
|
return $root.addCallback($root.refIds.get(ref), spec_1.OPERATION.DELETE, callback);
|
|
@@ -190,23 +204,29 @@ function getStateCallbacks(decoder) {
|
|
|
190
204
|
// https://github.com/colyseus/schema/issues/147
|
|
191
205
|
// If parent instance has "onAdd" registered, avoid triggering immediate callback.
|
|
192
206
|
//
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
if (context.onInstanceAvailable) {
|
|
196
|
-
// collection instance not received yet
|
|
197
|
-
context.onInstanceAvailable((ref, existing) => onAdd(ref, callback, immediate && existing && !isTriggeringOnAdd));
|
|
207
|
+
if (context.instance) {
|
|
208
|
+
return onAdd(context.instance, callback, immediate && !onAddCalls.has(currentOnAddCallback));
|
|
198
209
|
}
|
|
199
|
-
else if (context.
|
|
200
|
-
|
|
210
|
+
else if (context.onInstanceAvailable) {
|
|
211
|
+
// collection instance not received yet
|
|
212
|
+
let detachCallback = () => { };
|
|
213
|
+
context.onInstanceAvailable((ref, existing) => {
|
|
214
|
+
detachCallback = onAdd(ref, callback, immediate && existing && !onAddCalls.has(currentOnAddCallback));
|
|
215
|
+
});
|
|
216
|
+
return () => detachCallback();
|
|
201
217
|
}
|
|
202
218
|
},
|
|
203
219
|
onRemove: function (callback) {
|
|
204
220
|
if (context.onInstanceAvailable) {
|
|
205
221
|
// collection instance not received yet
|
|
206
|
-
|
|
222
|
+
let detachCallback = () => { };
|
|
223
|
+
context.onInstanceAvailable((ref) => {
|
|
224
|
+
detachCallback = onRemove(ref, callback);
|
|
225
|
+
});
|
|
226
|
+
return () => detachCallback();
|
|
207
227
|
}
|
|
208
228
|
else if (context.instance) {
|
|
209
|
-
onRemove(context.instance, callback);
|
|
229
|
+
return onRemove(context.instance, callback);
|
|
210
230
|
}
|
|
211
231
|
},
|
|
212
232
|
}, {
|
|
@@ -225,16 +245,6 @@ function getStateCallbacks(decoder) {
|
|
|
225
245
|
function $(instance) {
|
|
226
246
|
return getProxy(undefined, { instance });
|
|
227
247
|
}
|
|
228
|
-
return
|
|
229
|
-
$,
|
|
230
|
-
trigger: function trigger(changes) {
|
|
231
|
-
for (let i = 0, l = changes.length; i < l; i++) {
|
|
232
|
-
const change = changes[i];
|
|
233
|
-
change.op;
|
|
234
|
-
change.ref;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
};
|
|
248
|
+
return $;
|
|
238
249
|
}
|
|
239
|
-
exports.getStateCallbacks = getStateCallbacks;
|
|
240
250
|
//# sourceMappingURL=StateCallbacks.js.map
|