@colyseus/schema 2.0.31 → 3.0.0-alpha.0

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.
Files changed (159) hide show
  1. package/build/cjs/index.js +3614 -2634
  2. package/build/cjs/index.js.map +1 -1
  3. package/build/esm/index.mjs +3324 -2445
  4. package/build/esm/index.mjs.map +1 -1
  5. package/build/umd/index.js +3614 -2634
  6. package/lib/Decoder.d.ts +16 -0
  7. package/lib/Decoder.js +182 -0
  8. package/lib/Decoder.js.map +1 -0
  9. package/lib/Encoder.d.ts +13 -0
  10. package/lib/Encoder.js +79 -0
  11. package/lib/Encoder.js.map +1 -0
  12. package/lib/Metadata.d.ts +36 -0
  13. package/lib/Metadata.js +91 -0
  14. package/lib/Metadata.js.map +1 -0
  15. package/lib/Reflection.d.ts +7 -5
  16. package/lib/Reflection.js +62 -58
  17. package/lib/Reflection.js.map +1 -1
  18. package/lib/Schema.d.ts +39 -51
  19. package/lib/Schema.js +189 -731
  20. package/lib/Schema.js.map +1 -1
  21. package/lib/annotations.d.ts +26 -45
  22. package/lib/annotations.js +363 -194
  23. package/lib/annotations.js.map +1 -1
  24. package/lib/changes/ChangeSet.d.ts +12 -0
  25. package/lib/changes/ChangeSet.js +35 -0
  26. package/lib/changes/ChangeSet.js.map +1 -0
  27. package/lib/changes/DecodeOperation.d.ts +15 -0
  28. package/lib/changes/DecodeOperation.js +186 -0
  29. package/lib/changes/DecodeOperation.js.map +1 -0
  30. package/lib/changes/EncodeOperation.d.ts +18 -0
  31. package/lib/changes/EncodeOperation.js +130 -0
  32. package/lib/changes/EncodeOperation.js.map +1 -0
  33. package/lib/changes/consts.d.ts +14 -0
  34. package/lib/changes/consts.js +18 -0
  35. package/lib/changes/consts.js.map +1 -0
  36. package/lib/decoder/DecodeOperation.d.ts +24 -0
  37. package/lib/decoder/DecodeOperation.js +256 -0
  38. package/lib/decoder/DecodeOperation.js.map +1 -0
  39. package/lib/decoder/Decoder.d.ts +21 -0
  40. package/lib/decoder/Decoder.js +114 -0
  41. package/lib/decoder/Decoder.js.map +1 -0
  42. package/lib/decoder/ReferenceTracker.d.ts +26 -0
  43. package/lib/decoder/ReferenceTracker.js +131 -0
  44. package/lib/decoder/ReferenceTracker.js.map +1 -0
  45. package/lib/decoder/strategy/RawChanges.d.ts +3 -0
  46. package/lib/decoder/strategy/RawChanges.js +8 -0
  47. package/lib/decoder/strategy/RawChanges.js.map +1 -0
  48. package/lib/decoder/strategy/StateCallbacks.d.ts +20 -0
  49. package/lib/decoder/strategy/StateCallbacks.js +240 -0
  50. package/lib/decoder/strategy/StateCallbacks.js.map +1 -0
  51. package/lib/decoding/decode.d.ts +48 -0
  52. package/lib/decoding/decode.js +267 -0
  53. package/lib/decoding/decode.js.map +1 -0
  54. package/lib/ecs.d.ts +11 -0
  55. package/lib/ecs.js +160 -0
  56. package/lib/ecs.js.map +1 -0
  57. package/lib/encoder/ChangeTree.d.ts +72 -0
  58. package/lib/encoder/ChangeTree.js +384 -0
  59. package/lib/encoder/ChangeTree.js.map +1 -0
  60. package/lib/encoder/EncodeOperation.d.ts +25 -0
  61. package/lib/encoder/EncodeOperation.js +156 -0
  62. package/lib/encoder/EncodeOperation.js.map +1 -0
  63. package/lib/encoder/Encoder.d.ts +23 -0
  64. package/lib/encoder/Encoder.js +192 -0
  65. package/lib/encoder/Encoder.js.map +1 -0
  66. package/lib/encoder/StateView.d.ts +21 -0
  67. package/lib/encoder/StateView.js +196 -0
  68. package/lib/encoder/StateView.js.map +1 -0
  69. package/lib/encoding/assert.d.ts +9 -0
  70. package/lib/encoding/assert.js +47 -0
  71. package/lib/encoding/assert.js.map +1 -0
  72. package/lib/encoding/decode.js +1 -1
  73. package/lib/encoding/decode.js.map +1 -1
  74. package/lib/encoding/encode.d.ts +17 -16
  75. package/lib/encoding/encode.js +88 -81
  76. package/lib/encoding/encode.js.map +1 -1
  77. package/lib/encoding/spec.d.ts +25 -0
  78. package/lib/encoding/spec.js +30 -0
  79. package/lib/encoding/spec.js.map +1 -0
  80. package/lib/index.d.ts +18 -10
  81. package/lib/index.js +39 -17
  82. package/lib/index.js.map +1 -1
  83. package/lib/symbol.shim.d.ts +6 -0
  84. package/lib/symbol.shim.js +4 -0
  85. package/lib/symbol.shim.js.map +1 -0
  86. package/lib/types/ArraySchema.js +0 -7
  87. package/lib/types/ArraySchema.js.map +1 -1
  88. package/lib/types/HelperTypes.d.ts +10 -2
  89. package/lib/types/HelperTypes.js.map +1 -1
  90. package/lib/types/custom/ArraySchema.d.ts +245 -0
  91. package/lib/types/custom/ArraySchema.js +659 -0
  92. package/lib/types/custom/ArraySchema.js.map +1 -0
  93. package/lib/types/custom/CollectionSchema.d.ts +42 -0
  94. package/lib/types/custom/CollectionSchema.js +165 -0
  95. package/lib/types/custom/CollectionSchema.js.map +1 -0
  96. package/lib/types/custom/MapSchema.d.ts +43 -0
  97. package/lib/types/custom/MapSchema.js +200 -0
  98. package/lib/types/custom/MapSchema.js.map +1 -0
  99. package/lib/types/custom/SetSchema.d.ts +39 -0
  100. package/lib/types/custom/SetSchema.js +177 -0
  101. package/lib/types/custom/SetSchema.js.map +1 -0
  102. package/lib/types/registry.d.ts +6 -0
  103. package/lib/types/registry.js +19 -0
  104. package/lib/types/registry.js.map +1 -0
  105. package/lib/types/symbols.d.ts +29 -0
  106. package/lib/types/symbols.js +33 -0
  107. package/lib/types/symbols.js.map +1 -0
  108. package/lib/types/utils.d.ts +0 -8
  109. package/lib/types/utils.js +1 -33
  110. package/lib/types/utils.js.map +1 -1
  111. package/lib/usage.d.ts +1 -0
  112. package/lib/usage.js +22 -0
  113. package/lib/usage.js.map +1 -0
  114. package/lib/utils.d.ts +13 -2
  115. package/lib/utils.js +36 -15
  116. package/lib/utils.js.map +1 -1
  117. package/lib/v3.d.ts +1 -0
  118. package/lib/v3.js +427 -0
  119. package/lib/v3.js.map +1 -0
  120. package/lib/v3_bench.d.ts +1 -0
  121. package/lib/v3_bench.js +130 -0
  122. package/lib/v3_bench.js.map +1 -0
  123. package/lib/v3_experiment.d.ts +1 -0
  124. package/lib/v3_experiment.js +407 -0
  125. package/lib/v3_experiment.js.map +1 -0
  126. package/package.json +5 -5
  127. package/src/Metadata.ts +135 -0
  128. package/src/Reflection.ts +75 -66
  129. package/src/Schema.ts +213 -931
  130. package/src/annotations.ts +430 -243
  131. package/src/decoder/DecodeOperation.ts +372 -0
  132. package/src/decoder/Decoder.ts +155 -0
  133. package/src/decoder/ReferenceTracker.ts +151 -0
  134. package/src/decoder/strategy/RawChanges.ts +9 -0
  135. package/src/decoder/strategy/StateCallbacks.ts +326 -0
  136. package/src/encoder/ChangeTree.ts +492 -0
  137. package/src/encoder/EncodeOperation.ts +237 -0
  138. package/src/encoder/Encoder.ts +246 -0
  139. package/src/encoder/StateView.ts +229 -0
  140. package/src/encoding/assert.ts +58 -0
  141. package/src/encoding/decode.ts +1 -1
  142. package/src/encoding/encode.ts +88 -82
  143. package/src/encoding/spec.ts +29 -0
  144. package/src/index.ts +22 -19
  145. package/src/symbol.shim.ts +12 -0
  146. package/src/types/HelperTypes.ts +16 -2
  147. package/src/types/{ArraySchema.ts → custom/ArraySchema.ts} +345 -251
  148. package/src/types/{CollectionSchema.ts → custom/CollectionSchema.ts} +56 -46
  149. package/src/types/{MapSchema.ts → custom/MapSchema.ts} +88 -115
  150. package/src/types/{SetSchema.ts → custom/SetSchema.ts} +58 -47
  151. package/src/types/{typeRegistry.ts → registry.ts} +6 -6
  152. package/src/types/symbols.ts +36 -0
  153. package/src/types/utils.ts +0 -46
  154. package/src/utils.ts +50 -21
  155. package/src/v3_bench.ts +107 -0
  156. package/src/changes/ChangeTree.ts +0 -295
  157. package/src/changes/ReferenceTracker.ts +0 -91
  158. package/src/filters/index.ts +0 -23
  159. package/src/spec.ts +0 -49
@@ -0,0 +1,3 @@
1
+ import { DataChange } from "../DecodeOperation";
2
+ import { Decoder } from "../Decoder";
3
+ export declare function getRawChangesCallback(decoder: Decoder, callback: (changes: DataChange[]) => void): void;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getRawChangesCallback = void 0;
4
+ function getRawChangesCallback(decoder, callback) {
5
+ decoder.triggerChanges = callback;
6
+ }
7
+ exports.getRawChangesCallback = getRawChangesCallback;
8
+ //# sourceMappingURL=RawChanges.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RawChanges.js","sourceRoot":"","sources":["../../../src/decoder/strategy/RawChanges.ts"],"names":[],"mappings":";;;AAGA,SAAgB,qBAAqB,CACjC,OAAgB,EAChB,QAAyC;IAEzC,OAAO,CAAC,cAAc,GAAG,QAAQ,CAAC;AACtC,CAAC;AALD,sDAKC","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}"]}
@@ -0,0 +1,20 @@
1
+ import { Collection, NonFunctionNonPrimitivePropNames, NonFunctionPropNames } from "../../types/HelperTypes";
2
+ import { Decoder } from "../Decoder";
3
+ import { DataChange } from "../DecodeOperation";
4
+ type GetProxyType<T> = unknown extends T ? InstanceCallback<T> & CollectionCallback<any, any> : T extends Collection<infer K, infer V, infer _> ? CollectionCallback<K, V> : InstanceCallback<T>;
5
+ type InstanceCallback<T> = {
6
+ listen<K extends NonFunctionPropNames<T>>(prop: K, callback: (value: T[K], previousValue: T[K]) => void, immediate?: boolean): any;
7
+ onChange(callback: () => void): void;
8
+ bindTo(targetObject: any, properties?: Array<NonFunctionPropNames<T>>): void;
9
+ } & {
10
+ [K in NonFunctionNonPrimitivePropNames<T>]: GetProxyType<T[K]>;
11
+ };
12
+ type CollectionCallback<K, V> = {
13
+ onAdd(callback: (item: V, index: K) => void, immediate?: boolean): void;
14
+ onRemove(callback: (item: V, index: K) => void): void;
15
+ };
16
+ export declare function getStateCallbacks(decoder: Decoder): {
17
+ $: <T>(instance: T) => GetProxyType<T>;
18
+ trigger: (changes: DataChange[]) => void;
19
+ };
20
+ export {};
@@ -0,0 +1,240 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getStateCallbacks = void 0;
4
+ const spec_1 = require("../../encoding/spec");
5
+ const Schema_1 = require("../../Schema");
6
+ function getStateCallbacks(decoder) {
7
+ const $root = decoder.$root;
8
+ const callbacks = $root.callbacks;
9
+ let isTriggeringOnAdd = false;
10
+ decoder.triggerChanges = function (allChanges) {
11
+ const uniqueRefIds = new Set();
12
+ for (let i = 0, l = allChanges.length; i < l; i++) {
13
+ const change = allChanges[i];
14
+ const refId = change.refId;
15
+ const ref = change.ref;
16
+ const $callbacks = callbacks[refId];
17
+ if (!$callbacks) {
18
+ continue;
19
+ }
20
+ //
21
+ // trigger onRemove on child structure.
22
+ //
23
+ if ((change.op & spec_1.OPERATION.DELETE) === spec_1.OPERATION.DELETE &&
24
+ change.previousValue instanceof Schema_1.Schema) {
25
+ const deleteCallbacks = callbacks[$root.refIds.get(change.previousValue)]?.[spec_1.OPERATION.DELETE];
26
+ for (let i = deleteCallbacks?.length - 1; i >= 0; i--) {
27
+ deleteCallbacks[i]();
28
+ }
29
+ // callbacks[$root.refIds.get(change.previousValue)]?.[OPERATION.DELETE]?.forEach(callback =>
30
+ // callback());
31
+ }
32
+ if (ref instanceof Schema_1.Schema) {
33
+ //
34
+ // Handle schema instance
35
+ //
36
+ if (!uniqueRefIds.has(refId)) {
37
+ try {
38
+ // trigger onChange
39
+ const replaceCallbacks = $callbacks?.[spec_1.OPERATION.REPLACE];
40
+ for (let i = replaceCallbacks?.length - 1; i >= 0; i--) {
41
+ replaceCallbacks[i]();
42
+ }
43
+ }
44
+ catch (e) {
45
+ console.error(e);
46
+ }
47
+ }
48
+ try {
49
+ if ($callbacks.hasOwnProperty(change.field)) {
50
+ const fieldCallbacks = $callbacks[change.field];
51
+ for (let i = fieldCallbacks?.length - 1; i >= 0; i--) {
52
+ fieldCallbacks[i](change.value, change.previousValue);
53
+ }
54
+ }
55
+ }
56
+ catch (e) {
57
+ //
58
+ console.error(e);
59
+ }
60
+ }
61
+ else {
62
+ //
63
+ // Handle collection of items
64
+ //
65
+ if (change.op === spec_1.OPERATION.ADD && change.previousValue === undefined) {
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) {
75
+ //
76
+ // FIXME: `previousValue` should always be available.
77
+ //
78
+ if (change.previousValue !== undefined) {
79
+ // triger onRemove
80
+ const deleteCallbacks = $callbacks[spec_1.OPERATION.DELETE];
81
+ for (let i = deleteCallbacks?.length - 1; i >= 0; i--) {
82
+ deleteCallbacks[i](change.previousValue, change.dynamicIndex ?? change.field);
83
+ }
84
+ }
85
+ // Handle DELETE_AND_ADD operations
86
+ // FIXME: should we set "isTriggeringOnAdd" here?
87
+ if ((change.op & spec_1.OPERATION.ADD) === spec_1.OPERATION.ADD) {
88
+ const addCallbacks = $callbacks[spec_1.OPERATION.ADD];
89
+ for (let i = addCallbacks?.length - 1; i >= 0; i--) {
90
+ addCallbacks[i](change.value, change.dynamicIndex ?? change.field);
91
+ }
92
+ }
93
+ }
94
+ // trigger onChange
95
+ if (change.value !== change.previousValue) {
96
+ const replaceCallbacks = $callbacks[spec_1.OPERATION.REPLACE];
97
+ for (let i = replaceCallbacks?.length - 1; i >= 0; i--) {
98
+ replaceCallbacks[i](change.value, change.dynamicIndex ?? change.field);
99
+ }
100
+ }
101
+ }
102
+ uniqueRefIds.add(refId);
103
+ }
104
+ };
105
+ function getProxy(metadataOrType, context) {
106
+ let metadata = context.instance?.constructor[Symbol.metadata] || metadataOrType;
107
+ let isCollection = ((context.instance && typeof (context.instance['forEach']) === "function") ||
108
+ (metadataOrType && typeof (metadataOrType[Symbol.metadata]) === "undefined"));
109
+ if (metadata && !isCollection) {
110
+ const onAdd = function (ref, prop, callback, immediate) {
111
+ // immediate trigger
112
+ if (immediate &&
113
+ context.instance[prop] !== undefined &&
114
+ !isTriggeringOnAdd // FIXME: This is a workaround (https://github.com/colyseus/schema/issues/147)
115
+ ) {
116
+ callback(context.instance[prop], undefined);
117
+ }
118
+ return $root.addCallback($root.refIds.get(ref), prop, callback);
119
+ };
120
+ /**
121
+ * Schema instances
122
+ */
123
+ return new Proxy({
124
+ listen: function listen(prop, callback, immediate = true) {
125
+ if (context.instance) {
126
+ return onAdd(context.instance, prop, callback, immediate);
127
+ }
128
+ else {
129
+ // collection instance not received yet
130
+ context.onInstanceAvailable((ref, existing) => onAdd(ref, prop, callback, immediate && existing));
131
+ }
132
+ },
133
+ onChange: function onChange(callback) {
134
+ return $root.addCallback($root.refIds.get(context.instance), spec_1.OPERATION.REPLACE, callback);
135
+ },
136
+ bindTo: function bindTo(targetObject, properties) {
137
+ console.log("bindTo", targetObject, properties);
138
+ }
139
+ }, {
140
+ get(target, prop) {
141
+ if (metadata[prop]) {
142
+ const instance = context.instance?.[prop];
143
+ const onInstanceAvailable = ((callback) => {
144
+ const unbind = $(context.instance).listen(prop, (value, _) => {
145
+ callback(value, false);
146
+ // FIXME: by "unbinding" the callback here,
147
+ // it will not support when the server
148
+ // re-instantiates the instance.
149
+ //
150
+ unbind?.();
151
+ }, false);
152
+ // has existing value
153
+ if ($root.refIds.get(instance) !== undefined) {
154
+ callback(instance, true);
155
+ }
156
+ });
157
+ return getProxy(metadata[prop].type, {
158
+ instance,
159
+ parentInstance: context.instance,
160
+ onInstanceAvailable,
161
+ });
162
+ }
163
+ else {
164
+ // accessing the function
165
+ return target[prop];
166
+ }
167
+ },
168
+ has(target, prop) { return metadata[prop] !== undefined; },
169
+ set(_, _1, _2) { throw new Error("not allowed"); },
170
+ deleteProperty(_, _1) { throw new Error("not allowed"); },
171
+ });
172
+ }
173
+ else {
174
+ /**
175
+ * Collection instances
176
+ */
177
+ const onAdd = function (ref, callback, immediate) {
178
+ // Trigger callback on existing items
179
+ if (immediate) {
180
+ ref.forEach((v, k) => callback(v, k));
181
+ }
182
+ return $root.addCallback($root.refIds.get(ref), spec_1.OPERATION.ADD, callback);
183
+ };
184
+ const onRemove = function (ref, callback) {
185
+ return $root.addCallback($root.refIds.get(ref), spec_1.OPERATION.DELETE, callback);
186
+ };
187
+ return new Proxy({
188
+ onAdd: function (callback, immediate = true) {
189
+ //
190
+ // https://github.com/colyseus/schema/issues/147
191
+ // If parent instance has "onAdd" registered, avoid triggering immediate callback.
192
+ //
193
+ // FIXME: "isTriggeringOnAdd" is a workaround. We should find a better way to handle this.
194
+ //
195
+ if (context.onInstanceAvailable) {
196
+ // collection instance not received yet
197
+ context.onInstanceAvailable((ref, existing) => onAdd(ref, callback, immediate && existing && !isTriggeringOnAdd));
198
+ }
199
+ else if (context.instance) {
200
+ onAdd(context.instance, callback, immediate && !isTriggeringOnAdd);
201
+ }
202
+ },
203
+ onRemove: function (callback) {
204
+ if (context.onInstanceAvailable) {
205
+ // collection instance not received yet
206
+ context.onInstanceAvailable((ref) => onRemove(ref, callback));
207
+ }
208
+ else if (context.instance) {
209
+ onRemove(context.instance, callback);
210
+ }
211
+ },
212
+ }, {
213
+ get(target, prop) {
214
+ if (!target[prop]) {
215
+ throw new Error(`Can't access '${prop}' through callback proxy. access the instance directly.`);
216
+ }
217
+ return target[prop];
218
+ },
219
+ has(target, prop) { return target[prop] !== undefined; },
220
+ set(_, _1, _2) { throw new Error("not allowed"); },
221
+ deleteProperty(_, _1) { throw new Error("not allowed"); },
222
+ });
223
+ }
224
+ }
225
+ function $(instance) {
226
+ return getProxy(undefined, { instance });
227
+ }
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
+ };
238
+ }
239
+ exports.getStateCallbacks = getStateCallbacks;
240
+ //# sourceMappingURL=StateCallbacks.js.map
@@ -0,0 +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 { DefinitionType } from \"../../annotations\";\nimport { Schema } from \"../../Schema\";\nimport type { ArraySchema } from \"../../types/custom/ArraySchema\";\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\ntype GetProxyType<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 listen<K extends NonFunctionPropNames<T>>(\n prop: K,\n callback: (value: T[K], previousValue: T[K]) => void,\n immediate?: boolean,\n )\n onChange(callback: () => void): void;\n bindTo(targetObject: any, properties?: Array<NonFunctionPropNames<T>>): void;\n} & {\n [K in NonFunctionNonPrimitivePropNames<T>]: GetProxyType<T[K]>;\n}\n\ntype CollectionCallback<K, V> = {\n onAdd(callback: (item: V, index: K) => void, immediate?: boolean): void;\n onRemove(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\nexport function getStateCallbacks(decoder: Decoder) {\n const $root = decoder.$root;\n const callbacks = $root.callbacks;\n\n let isTriggeringOnAdd = false;\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 // callbacks[$root.refIds.get(change.previousValue)]?.[OPERATION.DELETE]?.forEach(callback =>\n // callback());\n }\n\n if (ref instanceof Schema) {\n //\n // Handle schema instance\n //\n\n if (!uniqueRefIds.has(refId)) {\n try {\n // trigger onChange\n const replaceCallbacks = $callbacks?.[OPERATION.REPLACE];\n for (let i = replaceCallbacks?.length - 1; i >= 0; i--) {\n replaceCallbacks[i]();\n }\n\n } catch (e) {\n console.error(e);\n }\n }\n\n try {\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 }\n }\n\n } catch (e) {\n //\n console.error(e);\n }\n\n } else {\n //\n // Handle collection of items\n //\n\n if (change.op === OPERATION.ADD && change.previousValue === undefined) {\n // triger onAdd\n\n isTriggeringOnAdd = true;\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 isTriggeringOnAdd = false;\n\n } else 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 // FIXME: should we set \"isTriggeringOnAdd\" here?\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\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(metadataOrType: Metadata | DefinitionType, context: CallContext) {\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 onAdd = 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 !isTriggeringOnAdd // FIXME: This is a workaround (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 onAdd(context.instance, prop, callback, immediate);\n\n } else {\n // collection instance not received yet\n context.onInstanceAvailable((ref: Ref, existing: boolean) =>\n onAdd(ref, prop, callback, immediate && existing));\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 bindTo: function bindTo(targetObject: any, properties?: string[]) {\n console.log(\"bindTo\", targetObject, properties);\n }\n }, {\n get(target, prop: string) {\n if (metadata[prop]) {\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(metadata[prop].type, {\n 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 ArraySchema).forEach((v, k) => callback(v, k));\n }\n return $root.addCallback($root.refIds.get(ref), OPERATION.ADD, callback);\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 // FIXME: \"isTriggeringOnAdd\" is a workaround. We should find a better way to handle this.\n //\n if (context.onInstanceAvailable) {\n // collection instance not received yet\n context.onInstanceAvailable((ref: Ref, existing: boolean) =>\n onAdd(ref, callback, immediate && existing && !isTriggeringOnAdd));\n\n } else if (context.instance) {\n onAdd(context.instance, callback, immediate && !isTriggeringOnAdd);\n }\n },\n onRemove: function(callback: (value, key) => void) {\n if (context.onInstanceAvailable) {\n // collection instance not received yet\n context.onInstanceAvailable((ref: Ref) =>\n onRemove(ref, callback));\n\n } else if (context.instance) {\n 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): GetProxyType<T> {\n return getProxy(undefined, { instance }) as GetProxyType<T>;\n }\n\n return {\n $,\n trigger: function trigger(changes: DataChange[]) {\n for (let i = 0, l = changes.length; i < l; i++) {\n const change = changes[i];\n\n change.op\n change.ref\n }\n }\n }\n\n}"]}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Copyright (c) 2018 Endel Dreyer
3
+ * Copyright (c) 2014 Ion Drive Software Ltd.
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ * of this software and associated documentation files (the "Software"), to deal
7
+ * in the Software without restriction, including without limitation the rights
8
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ * copies of the Software, and to permit persons to whom the Software is
10
+ * furnished to do so, subject to the following conditions:
11
+ *
12
+ * The above copyright notice and this permission notice shall be included in all
13
+ * copies or substantial portions of the Software.
14
+ *
15
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ * SOFTWARE
22
+ */
23
+ /**
24
+ * msgpack implementation highly based on notepack.io
25
+ * https://github.com/darrachequesne/notepack
26
+ */
27
+ export interface Iterator {
28
+ offset: number;
29
+ }
30
+ export declare function int8(bytes: number[], it: Iterator): number;
31
+ export declare function uint8(bytes: number[], it: Iterator): number;
32
+ export declare function int16(bytes: number[], it: Iterator): number;
33
+ export declare function uint16(bytes: number[], it: Iterator): number;
34
+ export declare function int32(bytes: number[], it: Iterator): number;
35
+ export declare function uint32(bytes: number[], it: Iterator): number;
36
+ export declare function float32(bytes: number[], it: Iterator): number;
37
+ export declare function float64(bytes: number[], it: Iterator): number;
38
+ export declare function int64(bytes: number[], it: Iterator): number;
39
+ export declare function uint64(bytes: number[], it: Iterator): number;
40
+ export declare function readFloat32(bytes: number[], it: Iterator): number;
41
+ export declare function readFloat64(bytes: number[], it: Iterator): number;
42
+ export declare function boolean(bytes: number[], it: Iterator): boolean;
43
+ export declare function string(bytes: any, it: Iterator): string;
44
+ export declare function stringCheck(bytes: any, it: Iterator): boolean;
45
+ export declare function number(bytes: any, it: Iterator): any;
46
+ export declare function numberCheck(bytes: any, it: Iterator): boolean;
47
+ export declare function arrayCheck(bytes: any, it: Iterator): boolean;
48
+ export declare function switchStructureCheck(bytes: any, it: Iterator): boolean;
@@ -0,0 +1,267 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2018 Endel Dreyer
4
+ * Copyright (c) 2014 Ion Drive Software Ltd.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in all
14
+ * copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ * SOFTWARE
23
+ */
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.switchStructureCheck = exports.arrayCheck = exports.numberCheck = exports.number = exports.stringCheck = exports.string = exports.boolean = exports.readFloat64 = exports.readFloat32 = exports.uint64 = exports.int64 = exports.float64 = exports.float32 = exports.uint32 = exports.int32 = exports.uint16 = exports.int16 = exports.uint8 = exports.int8 = void 0;
26
+ const spec_1 = require("../spec");
27
+ function utf8Read(bytes, offset, length) {
28
+ var string = '', chr = 0;
29
+ for (var i = offset, end = offset + length; i < end; i++) {
30
+ var byte = bytes[i];
31
+ if ((byte & 0x80) === 0x00) {
32
+ string += String.fromCharCode(byte);
33
+ continue;
34
+ }
35
+ if ((byte & 0xe0) === 0xc0) {
36
+ string += String.fromCharCode(((byte & 0x1f) << 6) |
37
+ (bytes[++i] & 0x3f));
38
+ continue;
39
+ }
40
+ if ((byte & 0xf0) === 0xe0) {
41
+ string += String.fromCharCode(((byte & 0x0f) << 12) |
42
+ ((bytes[++i] & 0x3f) << 6) |
43
+ ((bytes[++i] & 0x3f) << 0));
44
+ continue;
45
+ }
46
+ if ((byte & 0xf8) === 0xf0) {
47
+ chr = ((byte & 0x07) << 18) |
48
+ ((bytes[++i] & 0x3f) << 12) |
49
+ ((bytes[++i] & 0x3f) << 6) |
50
+ ((bytes[++i] & 0x3f) << 0);
51
+ if (chr >= 0x010000) { // surrogate pair
52
+ chr -= 0x010000;
53
+ string += String.fromCharCode((chr >>> 10) + 0xD800, (chr & 0x3FF) + 0xDC00);
54
+ }
55
+ else {
56
+ string += String.fromCharCode(chr);
57
+ }
58
+ continue;
59
+ }
60
+ console.error('Invalid byte ' + byte.toString(16));
61
+ // (do not throw error to avoid server/client from crashing due to hack attemps)
62
+ // throw new Error('Invalid byte ' + byte.toString(16));
63
+ }
64
+ return string;
65
+ }
66
+ function int8(bytes, it) {
67
+ return uint8(bytes, it) << 24 >> 24;
68
+ }
69
+ exports.int8 = int8;
70
+ ;
71
+ function uint8(bytes, it) {
72
+ return bytes[it.offset++];
73
+ }
74
+ exports.uint8 = uint8;
75
+ ;
76
+ function int16(bytes, it) {
77
+ return uint16(bytes, it) << 16 >> 16;
78
+ }
79
+ exports.int16 = int16;
80
+ ;
81
+ function uint16(bytes, it) {
82
+ return bytes[it.offset++] | bytes[it.offset++] << 8;
83
+ }
84
+ exports.uint16 = uint16;
85
+ ;
86
+ function int32(bytes, it) {
87
+ return bytes[it.offset++] | bytes[it.offset++] << 8 | bytes[it.offset++] << 16 | bytes[it.offset++] << 24;
88
+ }
89
+ exports.int32 = int32;
90
+ ;
91
+ function uint32(bytes, it) {
92
+ return int32(bytes, it) >>> 0;
93
+ }
94
+ exports.uint32 = uint32;
95
+ ;
96
+ function float32(bytes, it) {
97
+ return readFloat32(bytes, it);
98
+ }
99
+ exports.float32 = float32;
100
+ function float64(bytes, it) {
101
+ return readFloat64(bytes, it);
102
+ }
103
+ exports.float64 = float64;
104
+ function int64(bytes, it) {
105
+ const low = uint32(bytes, it);
106
+ const high = int32(bytes, it) * Math.pow(2, 32);
107
+ return high + low;
108
+ }
109
+ exports.int64 = int64;
110
+ ;
111
+ function uint64(bytes, it) {
112
+ const low = uint32(bytes, it);
113
+ const high = uint32(bytes, it) * Math.pow(2, 32);
114
+ return high + low;
115
+ }
116
+ exports.uint64 = uint64;
117
+ ;
118
+ // force little endian to facilitate decoding on multiple implementations
119
+ const _isLittleEndian = true; // new Uint16Array(new Uint8Array([1, 0]).buffer)[0] === 1;
120
+ const _int32 = new Int32Array(2);
121
+ const _float32 = new Float32Array(_int32.buffer);
122
+ const _float64 = new Float64Array(_int32.buffer);
123
+ function readFloat32(bytes, it) {
124
+ _int32[0] = int32(bytes, it);
125
+ return _float32[0];
126
+ }
127
+ exports.readFloat32 = readFloat32;
128
+ ;
129
+ function readFloat64(bytes, it) {
130
+ _int32[_isLittleEndian ? 0 : 1] = int32(bytes, it);
131
+ _int32[_isLittleEndian ? 1 : 0] = int32(bytes, it);
132
+ return _float64[0];
133
+ }
134
+ exports.readFloat64 = readFloat64;
135
+ ;
136
+ function boolean(bytes, it) {
137
+ return uint8(bytes, it) > 0;
138
+ }
139
+ exports.boolean = boolean;
140
+ ;
141
+ function string(bytes, it) {
142
+ const prefix = bytes[it.offset++];
143
+ let length;
144
+ if (prefix < 0xc0) {
145
+ // fixstr
146
+ length = prefix & 0x1f;
147
+ }
148
+ else if (prefix === 0xd9) {
149
+ length = uint8(bytes, it);
150
+ }
151
+ else if (prefix === 0xda) {
152
+ length = uint16(bytes, it);
153
+ }
154
+ else if (prefix === 0xdb) {
155
+ length = uint32(bytes, it);
156
+ }
157
+ const value = utf8Read(bytes, it.offset, length);
158
+ it.offset += length;
159
+ return value;
160
+ }
161
+ exports.string = string;
162
+ function stringCheck(bytes, it) {
163
+ const prefix = bytes[it.offset];
164
+ return (
165
+ // fixstr
166
+ (prefix < 0xc0 && prefix > 0xa0) ||
167
+ // str 8
168
+ prefix === 0xd9 ||
169
+ // str 16
170
+ prefix === 0xda ||
171
+ // str 32
172
+ prefix === 0xdb);
173
+ }
174
+ exports.stringCheck = stringCheck;
175
+ function number(bytes, it) {
176
+ const prefix = bytes[it.offset++];
177
+ if (prefix < 0x80) {
178
+ // positive fixint
179
+ return prefix;
180
+ }
181
+ else if (prefix === 0xca) {
182
+ // float 32
183
+ return readFloat32(bytes, it);
184
+ }
185
+ else if (prefix === 0xcb) {
186
+ // float 64
187
+ return readFloat64(bytes, it);
188
+ }
189
+ else if (prefix === 0xcc) {
190
+ // uint 8
191
+ return uint8(bytes, it);
192
+ }
193
+ else if (prefix === 0xcd) {
194
+ // uint 16
195
+ return uint16(bytes, it);
196
+ }
197
+ else if (prefix === 0xce) {
198
+ // uint 32
199
+ return uint32(bytes, it);
200
+ }
201
+ else if (prefix === 0xcf) {
202
+ // uint 64
203
+ return uint64(bytes, it);
204
+ }
205
+ else if (prefix === 0xd0) {
206
+ // int 8
207
+ return int8(bytes, it);
208
+ }
209
+ else if (prefix === 0xd1) {
210
+ // int 16
211
+ return int16(bytes, it);
212
+ }
213
+ else if (prefix === 0xd2) {
214
+ // int 32
215
+ return int32(bytes, it);
216
+ }
217
+ else if (prefix === 0xd3) {
218
+ // int 64
219
+ return int64(bytes, it);
220
+ }
221
+ else if (prefix > 0xdf) {
222
+ // negative fixint
223
+ return (0xff - prefix + 1) * -1;
224
+ }
225
+ }
226
+ exports.number = number;
227
+ ;
228
+ function numberCheck(bytes, it) {
229
+ const prefix = bytes[it.offset];
230
+ // positive fixint - 0x00 - 0x7f
231
+ // float 32 - 0xca
232
+ // float 64 - 0xcb
233
+ // uint 8 - 0xcc
234
+ // uint 16 - 0xcd
235
+ // uint 32 - 0xce
236
+ // uint 64 - 0xcf
237
+ // int 8 - 0xd0
238
+ // int 16 - 0xd1
239
+ // int 32 - 0xd2
240
+ // int 64 - 0xd3
241
+ return (prefix < 0x80 ||
242
+ (prefix >= 0xca && prefix <= 0xd3));
243
+ }
244
+ exports.numberCheck = numberCheck;
245
+ function arrayCheck(bytes, it) {
246
+ return bytes[it.offset] < 0xa0;
247
+ // const prefix = bytes[it.offset] ;
248
+ // if (prefix < 0xa0) {
249
+ // return prefix;
250
+ // // array
251
+ // } else if (prefix === 0xdc) {
252
+ // it.offset += 2;
253
+ // } else if (0xdd) {
254
+ // it.offset += 4;
255
+ // }
256
+ // return prefix;
257
+ }
258
+ exports.arrayCheck = arrayCheck;
259
+ function switchStructureCheck(bytes, it) {
260
+ return (
261
+ // previous byte should be `SWITCH_TO_STRUCTURE`
262
+ bytes[it.offset - 1] === spec_1.SWITCH_TO_STRUCTURE &&
263
+ // next byte should be a number
264
+ (bytes[it.offset] < 0x80 || (bytes[it.offset] >= 0xca && bytes[it.offset] <= 0xd3)));
265
+ }
266
+ exports.switchStructureCheck = switchStructureCheck;
267
+ //# sourceMappingURL=decode.js.map