@colyseus/schema 4.0.2 → 4.0.3

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 (326) hide show
  1. package/{lib → build}/Metadata.d.ts +2 -2
  2. package/{lib → build}/Reflection.d.ts +13 -13
  3. package/{lib → build}/Schema.d.ts +10 -10
  4. package/{lib/src → build}/annotations.d.ts +10 -10
  5. package/build/codegen/languages/cpp.d.ts +3 -0
  6. package/build/codegen/languages/csharp.d.ts +4 -0
  7. package/build/codegen/languages/haxe.d.ts +3 -0
  8. package/{lib → build}/codegen/languages/java.d.ts +2 -2
  9. package/build/codegen/languages/js.d.ts +3 -0
  10. package/build/codegen/languages/lua.d.ts +3 -0
  11. package/build/codegen/languages/ts.d.ts +3 -0
  12. package/{lib → build}/codegen/parser.d.ts +1 -1
  13. package/{lib → build}/decoder/DecodeOperation.d.ts +5 -5
  14. package/{lib/src → build}/decoder/Decoder.d.ts +7 -7
  15. package/{lib → build}/decoder/ReferenceTracker.d.ts +1 -1
  16. package/{lib → build}/decoder/strategy/Callbacks.d.ts +11 -11
  17. package/{lib → build}/decoder/strategy/RawChanges.d.ts +2 -2
  18. package/{lib → build}/decoder/strategy/getDecoderStateCallbacks.d.ts +3 -3
  19. package/{lib → build}/encoder/ChangeTree.d.ts +11 -11
  20. package/{lib → build}/encoder/EncodeOperation.d.ts +5 -5
  21. package/{lib → build}/encoder/Encoder.d.ts +6 -6
  22. package/{lib/src → build}/encoder/Root.d.ts +2 -2
  23. package/{lib/src → build}/encoder/StateView.d.ts +1 -1
  24. package/{lib/src → build}/encoding/assert.d.ts +6 -6
  25. package/{lib/src → build}/encoding/decode.d.ts +1 -1
  26. package/{lib/src → build}/encoding/encode.d.ts +1 -1
  27. package/build/index.cjs.map +1 -0
  28. package/build/index.d.ts +32 -0
  29. package/build/index.mjs.map +1 -0
  30. package/{lib → build}/types/HelperTypes.d.ts +6 -6
  31. package/{lib → build}/types/TypeContext.d.ts +1 -1
  32. package/{lib/src → build}/types/custom/ArraySchema.d.ts +8 -8
  33. package/{lib/src → build}/types/custom/CollectionSchema.d.ts +7 -7
  34. package/{lib → build}/types/custom/MapSchema.d.ts +7 -7
  35. package/{lib/src → build}/types/custom/SetSchema.d.ts +7 -7
  36. package/{lib/src → build}/types/registry.d.ts +2 -2
  37. package/{lib → build}/utils.d.ts +1 -1
  38. package/package.json +9 -10
  39. package/src/Metadata.ts +5 -5
  40. package/src/Reflection.ts +7 -7
  41. package/src/Schema.ts +11 -11
  42. package/src/annotations.ts +13 -13
  43. package/src/codegen/api.ts +3 -3
  44. package/src/codegen/cli.ts +2 -2
  45. package/src/codegen/languages/cpp.ts +2 -2
  46. package/src/codegen/languages/csharp.ts +3 -3
  47. package/src/codegen/languages/haxe.ts +2 -2
  48. package/src/codegen/languages/java.ts +2 -2
  49. package/src/codegen/languages/js.ts +2 -2
  50. package/src/codegen/languages/lua.ts +2 -2
  51. package/src/codegen/languages/ts.ts +2 -2
  52. package/src/codegen/parser.ts +6 -1
  53. package/src/decoder/DecodeOperation.ts +14 -14
  54. package/src/decoder/Decoder.ts +11 -11
  55. package/src/decoder/ReferenceTracker.ts +8 -8
  56. package/src/decoder/strategy/Callbacks.ts +12 -12
  57. package/src/decoder/strategy/RawChanges.ts +2 -2
  58. package/src/decoder/strategy/getDecoderStateCallbacks.ts +10 -10
  59. package/src/encoder/ChangeTree.ts +13 -13
  60. package/src/encoder/EncodeOperation.ts +9 -9
  61. package/src/encoder/Encoder.ts +10 -10
  62. package/src/encoder/Root.ts +4 -4
  63. package/src/encoder/StateView.ts +7 -7
  64. package/src/encoding/assert.ts +6 -6
  65. package/src/encoding/decode.ts +1 -1
  66. package/src/encoding/encode.ts +1 -1
  67. package/src/index.ts +27 -27
  68. package/src/types/HelperTypes.ts +6 -6
  69. package/src/types/TypeContext.ts +3 -3
  70. package/src/types/custom/ArraySchema.ts +11 -11
  71. package/src/types/custom/CollectionSchema.ts +9 -9
  72. package/src/types/custom/MapSchema.ts +10 -10
  73. package/src/types/custom/SetSchema.ts +9 -9
  74. package/src/types/registry.ts +3 -3
  75. package/src/utils.ts +3 -3
  76. package/src/v3_bench.ts +1 -1
  77. package/build/cjs/index.cjs.map +0 -1
  78. package/build/esm/index.mjs.map +0 -1
  79. package/lib/Metadata.js +0 -256
  80. package/lib/Metadata.js.map +0 -1
  81. package/lib/Reflection.js +0 -179
  82. package/lib/Reflection.js.map +0 -1
  83. package/lib/Schema.js +0 -352
  84. package/lib/Schema.js.map +0 -1
  85. package/lib/annotations.d.ts +0 -109
  86. package/lib/annotations.js +0 -473
  87. package/lib/annotations.js.map +0 -1
  88. package/lib/bench_encode.d.ts +0 -1
  89. package/lib/bench_encode.js +0 -91
  90. package/lib/bench_encode.js.map +0 -1
  91. package/lib/benchmark.d.ts +0 -1
  92. package/lib/benchmark.js +0 -218
  93. package/lib/benchmark.js.map +0 -1
  94. package/lib/codegen/api.js +0 -56
  95. package/lib/codegen/api.js.map +0 -1
  96. package/lib/codegen/argv.js +0 -39
  97. package/lib/codegen/argv.js.map +0 -1
  98. package/lib/codegen/cli.js +0 -58
  99. package/lib/codegen/cli.js.map +0 -1
  100. package/lib/codegen/languages/cpp.d.ts +0 -3
  101. package/lib/codegen/languages/cpp.js +0 -258
  102. package/lib/codegen/languages/cpp.js.map +0 -1
  103. package/lib/codegen/languages/csharp.d.ts +0 -4
  104. package/lib/codegen/languages/csharp.js +0 -154
  105. package/lib/codegen/languages/csharp.js.map +0 -1
  106. package/lib/codegen/languages/haxe.d.ts +0 -3
  107. package/lib/codegen/languages/haxe.js +0 -100
  108. package/lib/codegen/languages/haxe.js.map +0 -1
  109. package/lib/codegen/languages/java.js +0 -100
  110. package/lib/codegen/languages/java.js.map +0 -1
  111. package/lib/codegen/languages/js.d.ts +0 -3
  112. package/lib/codegen/languages/js.js +0 -101
  113. package/lib/codegen/languages/js.js.map +0 -1
  114. package/lib/codegen/languages/lua.d.ts +0 -3
  115. package/lib/codegen/languages/lua.js +0 -103
  116. package/lib/codegen/languages/lua.js.map +0 -1
  117. package/lib/codegen/languages/ts.d.ts +0 -3
  118. package/lib/codegen/languages/ts.js +0 -116
  119. package/lib/codegen/languages/ts.js.map +0 -1
  120. package/lib/codegen/parser.js +0 -327
  121. package/lib/codegen/parser.js.map +0 -1
  122. package/lib/codegen/types.js +0 -142
  123. package/lib/codegen/types.js.map +0 -1
  124. package/lib/decoder/DecodeOperation.js +0 -248
  125. package/lib/decoder/DecodeOperation.js.map +0 -1
  126. package/lib/decoder/Decoder.d.ts +0 -21
  127. package/lib/decoder/Decoder.js +0 -114
  128. package/lib/decoder/Decoder.js.map +0 -1
  129. package/lib/decoder/ReferenceTracker.js +0 -135
  130. package/lib/decoder/ReferenceTracker.js.map +0 -1
  131. package/lib/decoder/strategy/Callbacks.js +0 -336
  132. package/lib/decoder/strategy/Callbacks.js.map +0 -1
  133. package/lib/decoder/strategy/RawChanges.js +0 -4
  134. package/lib/decoder/strategy/RawChanges.js.map +0 -1
  135. package/lib/decoder/strategy/getDecoderStateCallbacks.js +0 -274
  136. package/lib/decoder/strategy/getDecoderStateCallbacks.js.map +0 -1
  137. package/lib/encoder/ChangeTree.js +0 -534
  138. package/lib/encoder/ChangeTree.js.map +0 -1
  139. package/lib/encoder/EncodeOperation.js +0 -132
  140. package/lib/encoder/EncodeOperation.js.map +0 -1
  141. package/lib/encoder/Encoder.js +0 -204
  142. package/lib/encoder/Encoder.js.map +0 -1
  143. package/lib/encoder/Root.d.ts +0 -28
  144. package/lib/encoder/Root.js +0 -229
  145. package/lib/encoder/Root.js.map +0 -1
  146. package/lib/encoder/StateView.d.ts +0 -34
  147. package/lib/encoder/StateView.js +0 -279
  148. package/lib/encoder/StateView.js.map +0 -1
  149. package/lib/encoding/assert.d.ts +0 -10
  150. package/lib/encoding/assert.js +0 -49
  151. package/lib/encoding/assert.js.map +0 -1
  152. package/lib/encoding/decode.d.ts +0 -67
  153. package/lib/encoding/decode.js +0 -217
  154. package/lib/encoding/decode.js.map +0 -1
  155. package/lib/encoding/encode.d.ts +0 -40
  156. package/lib/encoding/encode.js +0 -279
  157. package/lib/encoding/encode.js.map +0 -1
  158. package/lib/encoding/spec.js +0 -26
  159. package/lib/encoding/spec.js.map +0 -1
  160. package/lib/index.d.ts +0 -32
  161. package/lib/index.js +0 -39
  162. package/lib/index.js.map +0 -1
  163. package/lib/src/Metadata.d.ts +0 -49
  164. package/lib/src/Metadata.js +0 -256
  165. package/lib/src/Metadata.js.map +0 -1
  166. package/lib/src/Reflection.d.ts +0 -71
  167. package/lib/src/Reflection.js +0 -179
  168. package/lib/src/Reflection.js.map +0 -1
  169. package/lib/src/Schema.d.ts +0 -86
  170. package/lib/src/Schema.js +0 -352
  171. package/lib/src/Schema.js.map +0 -1
  172. package/lib/src/annotations.js +0 -473
  173. package/lib/src/annotations.js.map +0 -1
  174. package/lib/src/bench_encode.d.ts +0 -1
  175. package/lib/src/bench_encode.js +0 -91
  176. package/lib/src/bench_encode.js.map +0 -1
  177. package/lib/src/codegen/api.d.ts +0 -7
  178. package/lib/src/codegen/api.js +0 -56
  179. package/lib/src/codegen/api.js.map +0 -1
  180. package/lib/src/codegen/argv.d.ts +0 -6
  181. package/lib/src/codegen/argv.js +0 -39
  182. package/lib/src/codegen/argv.js.map +0 -1
  183. package/lib/src/codegen/cli.d.ts +0 -1
  184. package/lib/src/codegen/cli.js +0 -58
  185. package/lib/src/codegen/cli.js.map +0 -1
  186. package/lib/src/codegen/languages/cpp.d.ts +0 -3
  187. package/lib/src/codegen/languages/cpp.js +0 -258
  188. package/lib/src/codegen/languages/cpp.js.map +0 -1
  189. package/lib/src/codegen/languages/csharp.d.ts +0 -4
  190. package/lib/src/codegen/languages/csharp.js +0 -154
  191. package/lib/src/codegen/languages/csharp.js.map +0 -1
  192. package/lib/src/codegen/languages/haxe.d.ts +0 -3
  193. package/lib/src/codegen/languages/haxe.js +0 -100
  194. package/lib/src/codegen/languages/haxe.js.map +0 -1
  195. package/lib/src/codegen/languages/java.d.ts +0 -6
  196. package/lib/src/codegen/languages/java.js +0 -100
  197. package/lib/src/codegen/languages/java.js.map +0 -1
  198. package/lib/src/codegen/languages/js.d.ts +0 -3
  199. package/lib/src/codegen/languages/js.js +0 -101
  200. package/lib/src/codegen/languages/js.js.map +0 -1
  201. package/lib/src/codegen/languages/lua.d.ts +0 -3
  202. package/lib/src/codegen/languages/lua.js +0 -103
  203. package/lib/src/codegen/languages/lua.js.map +0 -1
  204. package/lib/src/codegen/languages/ts.d.ts +0 -3
  205. package/lib/src/codegen/languages/ts.js +0 -116
  206. package/lib/src/codegen/languages/ts.js.map +0 -1
  207. package/lib/src/codegen/parser.d.ts +0 -13
  208. package/lib/src/codegen/parser.js +0 -327
  209. package/lib/src/codegen/parser.js.map +0 -1
  210. package/lib/src/codegen/types.d.ts +0 -52
  211. package/lib/src/codegen/types.js +0 -142
  212. package/lib/src/codegen/types.js.map +0 -1
  213. package/lib/src/decoder/DecodeOperation.d.ts +0 -23
  214. package/lib/src/decoder/DecodeOperation.js +0 -248
  215. package/lib/src/decoder/DecodeOperation.js.map +0 -1
  216. package/lib/src/decoder/Decoder.js +0 -114
  217. package/lib/src/decoder/Decoder.js.map +0 -1
  218. package/lib/src/decoder/ReferenceTracker.d.ts +0 -25
  219. package/lib/src/decoder/ReferenceTracker.js +0 -135
  220. package/lib/src/decoder/ReferenceTracker.js.map +0 -1
  221. package/lib/src/decoder/strategy/Callbacks.d.ts +0 -154
  222. package/lib/src/decoder/strategy/Callbacks.js +0 -336
  223. package/lib/src/decoder/strategy/Callbacks.js.map +0 -1
  224. package/lib/src/decoder/strategy/RawChanges.d.ts +0 -3
  225. package/lib/src/decoder/strategy/RawChanges.js +0 -4
  226. package/lib/src/decoder/strategy/RawChanges.js.map +0 -1
  227. package/lib/src/decoder/strategy/getDecoderStateCallbacks.d.ts +0 -76
  228. package/lib/src/decoder/strategy/getDecoderStateCallbacks.js +0 -274
  229. package/lib/src/decoder/strategy/getDecoderStateCallbacks.js.map +0 -1
  230. package/lib/src/encoder/ChangeTree.d.ts +0 -135
  231. package/lib/src/encoder/ChangeTree.js +0 -534
  232. package/lib/src/encoder/ChangeTree.js.map +0 -1
  233. package/lib/src/encoder/EncodeOperation.d.ts +0 -22
  234. package/lib/src/encoder/EncodeOperation.js +0 -132
  235. package/lib/src/encoder/EncodeOperation.js.map +0 -1
  236. package/lib/src/encoder/Encoder.d.ts +0 -22
  237. package/lib/src/encoder/Encoder.js +0 -204
  238. package/lib/src/encoder/Encoder.js.map +0 -1
  239. package/lib/src/encoder/Root.js +0 -229
  240. package/lib/src/encoder/Root.js.map +0 -1
  241. package/lib/src/encoder/StateView.js +0 -279
  242. package/lib/src/encoder/StateView.js.map +0 -1
  243. package/lib/src/encoding/assert.js +0 -49
  244. package/lib/src/encoding/assert.js.map +0 -1
  245. package/lib/src/encoding/decode.js +0 -217
  246. package/lib/src/encoding/decode.js.map +0 -1
  247. package/lib/src/encoding/encode.js +0 -279
  248. package/lib/src/encoding/encode.js.map +0 -1
  249. package/lib/src/encoding/spec.d.ts +0 -24
  250. package/lib/src/encoding/spec.js +0 -26
  251. package/lib/src/encoding/spec.js.map +0 -1
  252. package/lib/src/index.d.ts +0 -32
  253. package/lib/src/index.js +0 -39
  254. package/lib/src/index.js.map +0 -1
  255. package/lib/src/symbol.shim.js +0 -3
  256. package/lib/src/symbol.shim.js.map +0 -1
  257. package/lib/src/types/HelperTypes.d.ts +0 -77
  258. package/lib/src/types/HelperTypes.js +0 -2
  259. package/lib/src/types/HelperTypes.js.map +0 -1
  260. package/lib/src/types/TypeContext.d.ts +0 -31
  261. package/lib/src/types/TypeContext.js +0 -143
  262. package/lib/src/types/TypeContext.js.map +0 -1
  263. package/lib/src/types/custom/ArraySchema.js +0 -733
  264. package/lib/src/types/custom/ArraySchema.js.map +0 -1
  265. package/lib/src/types/custom/CollectionSchema.js +0 -170
  266. package/lib/src/types/custom/CollectionSchema.js.map +0 -1
  267. package/lib/src/types/custom/MapSchema.d.ts +0 -51
  268. package/lib/src/types/custom/MapSchema.js +0 -222
  269. package/lib/src/types/custom/MapSchema.js.map +0 -1
  270. package/lib/src/types/custom/SetSchema.js +0 -178
  271. package/lib/src/types/custom/SetSchema.js.map +0 -1
  272. package/lib/src/types/registry.js +0 -30
  273. package/lib/src/types/registry.js.map +0 -1
  274. package/lib/src/types/symbols.js +0 -34
  275. package/lib/src/types/symbols.js.map +0 -1
  276. package/lib/src/types/utils.js +0 -13
  277. package/lib/src/types/utils.js.map +0 -1
  278. package/lib/src/utils.d.ts +0 -13
  279. package/lib/src/utils.js +0 -49
  280. package/lib/src/utils.js.map +0 -1
  281. package/lib/src/v3_bench.js +0 -128
  282. package/lib/src/v3_bench.js.map +0 -1
  283. package/lib/symbol.shim.d.ts +0 -6
  284. package/lib/symbol.shim.js +0 -3
  285. package/lib/symbol.shim.js.map +0 -1
  286. package/lib/types/HelperTypes.js +0 -2
  287. package/lib/types/HelperTypes.js.map +0 -1
  288. package/lib/types/TypeContext.js +0 -143
  289. package/lib/types/TypeContext.js.map +0 -1
  290. package/lib/types/custom/ArraySchema.d.ts +0 -270
  291. package/lib/types/custom/ArraySchema.js +0 -733
  292. package/lib/types/custom/ArraySchema.js.map +0 -1
  293. package/lib/types/custom/CollectionSchema.d.ts +0 -51
  294. package/lib/types/custom/CollectionSchema.js +0 -170
  295. package/lib/types/custom/CollectionSchema.js.map +0 -1
  296. package/lib/types/custom/MapSchema.js +0 -222
  297. package/lib/types/custom/MapSchema.js.map +0 -1
  298. package/lib/types/custom/SetSchema.d.ts +0 -48
  299. package/lib/types/custom/SetSchema.js +0 -178
  300. package/lib/types/custom/SetSchema.js.map +0 -1
  301. package/lib/types/registry.d.ts +0 -16
  302. package/lib/types/registry.js +0 -30
  303. package/lib/types/registry.js.map +0 -1
  304. package/lib/types/symbols.d.ts +0 -33
  305. package/lib/types/symbols.js +0 -34
  306. package/lib/types/symbols.js.map +0 -1
  307. package/lib/types/utils.d.ts +0 -1
  308. package/lib/types/utils.js +0 -13
  309. package/lib/types/utils.js.map +0 -1
  310. package/lib/utils.js +0 -49
  311. package/lib/utils.js.map +0 -1
  312. package/lib/v3_bench.d.ts +0 -1
  313. package/lib/v3_bench.js +0 -128
  314. package/lib/v3_bench.js.map +0 -1
  315. /package/{lib → build}/codegen/api.d.ts +0 -0
  316. /package/{lib → build}/codegen/argv.d.ts +0 -0
  317. /package/{lib → build}/codegen/cli.d.ts +0 -0
  318. /package/{lib → build}/codegen/types.d.ts +0 -0
  319. /package/{lib → build}/encoding/spec.d.ts +0 -0
  320. /package/build/{cjs/index.cjs → index.cjs} +0 -0
  321. /package/build/{umd/index.js → index.js} +0 -0
  322. /package/build/{esm/index.mjs → index.mjs} +0 -0
  323. /package/{lib/src → build}/symbol.shim.d.ts +0 -0
  324. /package/{lib/src → build}/types/symbols.d.ts +0 -0
  325. /package/{lib/src → build}/types/utils.d.ts +0 -0
  326. /package/{lib/src → build}/v3_bench.d.ts +0 -0
@@ -1,135 +0,0 @@
1
- import { $childType, $refId } from "../types/symbols";
2
- import { spliceOne } from "../types/utils";
3
- import { OPERATION } from "../encoding/spec";
4
- class DecodingWarning extends Error {
5
- constructor(message) {
6
- super(message);
7
- this.name = "DecodingWarning";
8
- }
9
- }
10
- export class ReferenceTracker {
11
- constructor() {
12
- //
13
- // Relation of refId => Schema structure
14
- // For direct access of structures during decoding time.
15
- //
16
- this.refs = new Map();
17
- this.refCount = {};
18
- this.deletedRefs = new Set();
19
- this.callbacks = {};
20
- this.nextUniqueId = 0;
21
- }
22
- getNextUniqueId() {
23
- return this.nextUniqueId++;
24
- }
25
- // for decoding
26
- addRef(refId, ref, incrementCount = true) {
27
- this.refs.set(refId, ref);
28
- ref[$refId] = refId;
29
- if (incrementCount) {
30
- this.refCount[refId] = (this.refCount[refId] || 0) + 1;
31
- }
32
- if (this.deletedRefs.has(refId)) {
33
- this.deletedRefs.delete(refId);
34
- }
35
- }
36
- // for decoding
37
- removeRef(refId) {
38
- const refCount = this.refCount[refId];
39
- if (refCount === undefined) {
40
- try {
41
- throw new DecodingWarning("trying to remove refId that doesn't exist: " + refId);
42
- }
43
- catch (e) {
44
- console.warn(e);
45
- }
46
- return;
47
- }
48
- if (refCount === 0) {
49
- try {
50
- const ref = this.refs.get(refId);
51
- throw new DecodingWarning(`trying to remove refId '${refId}' with 0 refCount (${ref.constructor.name}: ${JSON.stringify(ref)})`);
52
- }
53
- catch (e) {
54
- console.warn(e);
55
- }
56
- return;
57
- }
58
- if ((this.refCount[refId] = refCount - 1) <= 0) {
59
- this.deletedRefs.add(refId);
60
- }
61
- }
62
- clearRefs() {
63
- this.refs.clear();
64
- this.deletedRefs.clear();
65
- this.callbacks = {};
66
- this.refCount = {};
67
- }
68
- // for decoding
69
- garbageCollectDeletedRefs() {
70
- this.deletedRefs.forEach((refId) => {
71
- //
72
- // Skip active references.
73
- //
74
- if (this.refCount[refId] > 0) {
75
- return;
76
- }
77
- const ref = this.refs.get(refId);
78
- //
79
- // Ensure child schema instances have their references removed as well.
80
- //
81
- if (ref.constructor[Symbol.metadata] !== undefined) {
82
- const metadata = ref.constructor[Symbol.metadata];
83
- for (const index in metadata) {
84
- const field = metadata[index].name;
85
- const child = ref[field];
86
- if (typeof (child) === "object" && child) {
87
- const childRefId = child[$refId];
88
- if (childRefId !== undefined && !this.deletedRefs.has(childRefId)) {
89
- this.removeRef(childRefId);
90
- }
91
- }
92
- }
93
- }
94
- else {
95
- if (typeof (ref[$childType]) === "function") {
96
- Array.from(ref.values())
97
- .forEach((child) => {
98
- const childRefId = child[$refId];
99
- if (childRefId !== undefined && !this.deletedRefs.has(childRefId)) {
100
- this.removeRef(childRefId);
101
- }
102
- });
103
- }
104
- }
105
- this.refs.delete(refId); // remove ref
106
- delete this.refCount[refId]; // remove ref count
107
- delete this.callbacks[refId]; // remove callbacks
108
- });
109
- // clear deleted refs.
110
- this.deletedRefs.clear();
111
- }
112
- addCallback(refId, fieldOrOperation, callback) {
113
- if (refId === undefined) {
114
- const name = (typeof (fieldOrOperation) === "number")
115
- ? OPERATION[fieldOrOperation]
116
- : fieldOrOperation;
117
- throw new Error(`Can't addCallback on '${name}' (refId is undefined)`);
118
- }
119
- if (!this.callbacks[refId]) {
120
- this.callbacks[refId] = {};
121
- }
122
- if (!this.callbacks[refId][fieldOrOperation]) {
123
- this.callbacks[refId][fieldOrOperation] = [];
124
- }
125
- this.callbacks[refId][fieldOrOperation].push(callback);
126
- return () => this.removeCallback(refId, fieldOrOperation, callback);
127
- }
128
- removeCallback(refId, field, callback) {
129
- const index = this.callbacks?.[refId]?.[field]?.indexOf(callback);
130
- if (index !== undefined && index !== -1) {
131
- spliceOne(this.callbacks[refId][field], index);
132
- }
133
- }
134
- }
135
- //# sourceMappingURL=ReferenceTracker.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ReferenceTracker.js","sourceRoot":"","sources":["../../../src/decoder/ReferenceTracker.ts"],"names":[],"mappings":"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","sourcesContent":["import { Metadata } from \"../Metadata\";\nimport { $childType, $refId } from \"../types/symbols\";\nimport { Ref } from \"../encoder/ChangeTree\";\nimport { spliceOne } from \"../types/utils\";\nimport { OPERATION } from \"../encoding/spec\";\n\nimport type { MapSchema } from \"../types/custom/MapSchema\";\nimport type { Schema } from \"../Schema\";\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\n public refCount: { [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 ref[$refId] = refId;\n\n if (incrementCount) {\n this.refCount[refId] = (this.refCount[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.refCount[refId];\n\n if (refCount === undefined) {\n try {\n throw new DecodingWarning(\"trying to remove refId that doesn't exist: \" + refId);\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.refCount[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.refCount = {};\n }\n\n // for decoding\n garbageCollectDeletedRefs() {\n this.deletedRefs.forEach((refId) => {\n //\n // Skip active references.\n //\n if (this.refCount[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 ((ref.constructor as typeof Schema)[Symbol.metadata] !== undefined) {\n const metadata: Metadata = (ref.constructor as typeof Schema)[Symbol.metadata];\n for (const index in metadata) {\n const field = metadata[index as any as number].name;\n const child = ref[field as keyof Ref];\n if (typeof(child) === \"object\" && child) {\n const childRefId = (child as any)[$refId];\n if (childRefId !== undefined && !this.deletedRefs.has(childRefId)) {\n this.removeRef(childRefId);\n }\n }\n }\n\n } else {\n if (typeof ((ref as any)[$childType]) === \"function\") {\n Array.from((ref as MapSchema).values())\n .forEach((child) => {\n const childRefId = child[$refId];\n if (childRefId !== undefined && !this.deletedRefs.has(childRefId)) {\n this.removeRef(childRefId);\n }\n });\n }\n }\n\n this.refs.delete(refId); // remove ref\n delete this.refCount[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: number | undefined = this.callbacks?.[refId]?.[field]?.indexOf(callback);\n if (index !== undefined && index !== -1) {\n spliceOne(this.callbacks[refId][field], index);\n }\n }\n\n}\n"]}
@@ -1,154 +0,0 @@
1
- import { Collection, NonFunctionPropNames } from "../../types/HelperTypes";
2
- import { Ref } from "../../encoder/ChangeTree";
3
- import { Decoder } from "../Decoder";
4
- import { DataChange } from "../DecodeOperation";
5
- import { OPERATION } from "../../encoding/spec";
6
- import { Schema } from "../../Schema";
7
- import { $refId } from "../../types/symbols";
8
- import { MapSchema } from "../../types/custom/MapSchema";
9
- import { ArraySchema } from "../../types/custom/ArraySchema";
10
- import { type SchemaCallbackProxy } from "./getDecoderStateCallbacks";
11
- type PropertyChangeCallback<K> = (currentValue: K, previousValue: K) => void;
12
- type KeyValueCallback<K, V> = (key: K, value: V) => void;
13
- type InstanceChangeCallback = () => void;
14
- type PublicPropNames<T> = Exclude<NonFunctionPropNames<T>, typeof $refId> & string;
15
- type CollectionPropNames<T> = Exclude<{
16
- [K in keyof T]: T[K] extends Collection<any, any> ? K : never;
17
- }[keyof T] & string, typeof $refId>;
18
- type CollectionValueType<T, K extends keyof T> = T[K] extends MapSchema<infer V, any> ? V : T[K] extends ArraySchema<infer V> ? V : T[K] extends Collection<any, infer V, any> ? V : never;
19
- type CollectionKeyType<T, K extends keyof T> = T[K] extends MapSchema<any, infer Key> ? Key : T[K] extends ArraySchema<any> ? number : T[K] extends Collection<infer Key, any, any> ? Key : never;
20
- /**
21
- * State Callbacks handler
22
- *
23
- * Usage:
24
- * ```ts
25
- * const $ = Callbacks.get(decoder);
26
- *
27
- * // Listen to property changes
28
- * $.listen("currentTurn", (currentValue, previousValue) => { ... });
29
- *
30
- * // Listen to collection additions
31
- * $.onAdd("entities", (sessionId, entity) => {
32
- * // Nested property listening
33
- * $.listen(entity, "hp", (currentHp, previousHp) => { ... });
34
- * });
35
- *
36
- * // Listen to collection removals
37
- * $.onRemove("entities", (sessionId, entity) => { ... });
38
- *
39
- * // Listen to any property change on an instance
40
- * $.onChange(entity, () => { ... });
41
- *
42
- * // Bind properties to another object
43
- * $.bindTo(player, playerVisual);
44
- * ```
45
- */
46
- export declare class StateCallbackStrategy<TState extends Schema> {
47
- protected decoder: Decoder<TState>;
48
- protected uniqueRefIds: Set<number>;
49
- protected isTriggering: boolean;
50
- constructor(decoder: Decoder<TState>);
51
- protected get callbacks(): {
52
- [refId: number]: import("../ReferenceTracker").SchemaCallbacks;
53
- };
54
- protected get state(): TState;
55
- protected addCallback(refId: number, operationOrProperty: OPERATION | string, handler: Function): () => void;
56
- protected addCallbackOrWaitCollectionAvailable<TInstance extends Schema, TReturn extends Ref>(instance: TInstance, propertyName: string, operation: OPERATION, handler: Function, immediate?: boolean): () => void;
57
- /**
58
- * Listen to property changes on the root state.
59
- */
60
- listen<K extends PublicPropNames<TState>>(property: K, handler: PropertyChangeCallback<TState[K]>, immediate?: boolean): () => void;
61
- /**
62
- * Listen to property changes on a nested instance.
63
- */
64
- listen<TInstance extends Schema, K extends PublicPropNames<TInstance>>(instance: TInstance, property: K, handler: PropertyChangeCallback<TInstance[K]>, immediate?: boolean): () => void;
65
- protected listenInstance<TInstance extends Schema>(instance: TInstance, propertyName: string, handler: PropertyChangeCallback<any>, immediate?: boolean): () => void;
66
- /**
67
- * Listen to any property change on an instance.
68
- */
69
- onChange<TInstance extends Schema>(instance: TInstance, handler: InstanceChangeCallback): () => void;
70
- /**
71
- * Listen to item changes in a collection on root state.
72
- */
73
- onChange<K extends CollectionPropNames<TState>>(property: K, handler: KeyValueCallback<CollectionKeyType<TState, K>, CollectionValueType<TState, K>>): () => void;
74
- /**
75
- * Listen to item changes in a nested collection.
76
- */
77
- onChange<TInstance extends Schema, K extends CollectionPropNames<TInstance>>(instance: TInstance, property: K, handler: KeyValueCallback<CollectionKeyType<TInstance, K>, CollectionValueType<TInstance, K>>): () => void;
78
- /**
79
- * Listen to items added to a collection on root state.
80
- */
81
- onAdd<K extends CollectionPropNames<TState>>(property: K, handler: KeyValueCallback<CollectionKeyType<TState, K>, CollectionValueType<TState, K>>, immediate?: boolean): () => void;
82
- /**
83
- * Listen to items added to a nested collection.
84
- */
85
- onAdd<TInstance extends Schema, K extends CollectionPropNames<TInstance>>(instance: TInstance, property: K, handler: KeyValueCallback<CollectionKeyType<TInstance, K>, CollectionValueType<TInstance, K>>, immediate?: boolean): () => void;
86
- /**
87
- * Listen to items removed from a collection on root state.
88
- */
89
- onRemove<K extends CollectionPropNames<TState>>(property: K, handler: KeyValueCallback<CollectionKeyType<TState, K>, CollectionValueType<TState, K>>): () => void;
90
- /**
91
- * Listen to items removed from a nested collection.
92
- */
93
- onRemove<TInstance extends Schema, K extends CollectionPropNames<TInstance>>(instance: TInstance, property: K, handler: KeyValueCallback<CollectionKeyType<TInstance, K>, CollectionValueType<TInstance, K>>): () => void;
94
- /**
95
- * Bind properties from a Schema instance to a target object.
96
- * Changes will be automatically reflected on the target object.
97
- */
98
- bindTo<TInstance extends Schema, TTarget>(from: TInstance, to: TTarget, properties?: string[], immediate?: boolean): () => void;
99
- protected triggerChanges(allChanges: DataChange[]): void;
100
- }
101
- /**
102
- * Factory class for retrieving the callbacks API.
103
- */
104
- export declare const Callbacks: {
105
- /**
106
- * Get the new callbacks standard API.
107
- *
108
- * Usage:
109
- * ```ts
110
- * const callbacks = Callbacks.get(roomOrDecoder);
111
- *
112
- * // Listen to property changes
113
- * callbacks.listen("currentTurn", (currentValue, previousValue) => { ... });
114
- *
115
- * // Listen to collection additions
116
- * callbacks.onAdd("entities", (sessionId, entity) => {
117
- * // Nested property listening
118
- * callbacks.listen(entity, "hp", (currentHp, previousHp) => { ... });
119
- * });
120
- *
121
- * // Listen to collection removals
122
- * callbacks.onRemove("entities", (sessionId, entity) => { ... });
123
- *
124
- * // Listen to any property change on an instance
125
- * callbacks.onChange(entity, () => { ... });
126
- *
127
- * // Bind properties to another object
128
- * callbacks.bindTo(player, playerVisual);
129
- * ```
130
- *
131
- * @param roomOrDecoder - Room or Decoder instance to get the callbacks for.
132
- * @returns the new callbacks standard API.
133
- */
134
- get<T extends Schema>(roomOrDecoder: Decoder<T> | {
135
- serializer: {
136
- decoder: Decoder<T>;
137
- };
138
- }): StateCallbackStrategy<T>;
139
- /**
140
- * Get the legacy callbacks API.
141
- *
142
- * We aim to deprecate this API on 1.0, and iterate on improving Callbacks.get() API.
143
- *
144
- * @param roomOrDecoder - Room or Decoder instance to get the legacy callbacks for.
145
- * @returns the legacy callbacks API.
146
- */
147
- getLegacy<T extends Schema>(roomOrDecoder: Decoder<T> | {
148
- serializer: {
149
- decoder: Decoder<T>;
150
- };
151
- }): SchemaCallbackProxy<T>;
152
- getRawChanges(decoder: Decoder, callback: (changes: DataChange[]) => void): void;
153
- };
154
- export {};
@@ -1,336 +0,0 @@
1
- import { Decoder } from "../Decoder";
2
- import { OPERATION } from "../../encoding/spec";
3
- import { Schema } from "../../Schema";
4
- import { $refId } from "../../types/symbols";
5
- import { getDecoderStateCallbacks } from "./getDecoderStateCallbacks";
6
- import { getRawChangesCallback } from "./RawChanges";
7
- /**
8
- * State Callbacks handler
9
- *
10
- * Usage:
11
- * ```ts
12
- * const $ = Callbacks.get(decoder);
13
- *
14
- * // Listen to property changes
15
- * $.listen("currentTurn", (currentValue, previousValue) => { ... });
16
- *
17
- * // Listen to collection additions
18
- * $.onAdd("entities", (sessionId, entity) => {
19
- * // Nested property listening
20
- * $.listen(entity, "hp", (currentHp, previousHp) => { ... });
21
- * });
22
- *
23
- * // Listen to collection removals
24
- * $.onRemove("entities", (sessionId, entity) => { ... });
25
- *
26
- * // Listen to any property change on an instance
27
- * $.onChange(entity, () => { ... });
28
- *
29
- * // Bind properties to another object
30
- * $.bindTo(player, playerVisual);
31
- * ```
32
- */
33
- export class StateCallbackStrategy {
34
- constructor(decoder) {
35
- this.uniqueRefIds = new Set();
36
- this.isTriggering = false;
37
- this.decoder = decoder;
38
- this.decoder.triggerChanges = this.triggerChanges.bind(this);
39
- }
40
- get callbacks() {
41
- return this.decoder.root.callbacks;
42
- }
43
- get state() {
44
- return this.decoder.state;
45
- }
46
- addCallback(refId, operationOrProperty, handler) {
47
- const $root = this.decoder.root;
48
- return $root.addCallback(refId, operationOrProperty, handler);
49
- }
50
- addCallbackOrWaitCollectionAvailable(instance, propertyName, operation, handler, immediate = true) {
51
- let removeHandler = () => { };
52
- const removeOnAdd = () => removeHandler();
53
- const collection = instance[propertyName];
54
- // Collection not available yet. Listen for its availability before attaching the handler.
55
- if (collection === null || collection === undefined) {
56
- removeHandler = this.addCallback(instance[$refId], propertyName, (value, _) => {
57
- if (value !== null && value !== undefined) {
58
- removeHandler = this.addCallback(value[$refId], operation, handler);
59
- }
60
- });
61
- return removeOnAdd;
62
- }
63
- else {
64
- //
65
- // Call immediately if collection is already available, if it's an ADD operation.
66
- //
67
- immediate = immediate && this.isTriggering === false;
68
- if (operation === OPERATION.ADD && immediate) {
69
- collection.forEach((value, key) => {
70
- handler(key, value);
71
- });
72
- }
73
- return this.addCallback(collection[$refId], operation, handler);
74
- }
75
- }
76
- listen(...args) {
77
- if (typeof args[0] === 'string') {
78
- // listen(property, handler, immediate?)
79
- return this.listenInstance(this.state, args[0], args[1], args[2]);
80
- }
81
- else {
82
- // listen(instance, property, handler, immediate?)
83
- return this.listenInstance(args[0], args[1], args[2], args[3]);
84
- }
85
- }
86
- listenInstance(instance, propertyName, handler, immediate = true) {
87
- immediate = immediate && this.isTriggering === false;
88
- //
89
- // Call handler immediately if property is already available.
90
- //
91
- const currentValue = instance[propertyName];
92
- if (immediate && currentValue !== null && currentValue !== undefined) {
93
- handler(currentValue, undefined);
94
- }
95
- return this.addCallback(instance[$refId], propertyName, handler);
96
- }
97
- onChange(...args) {
98
- if (args.length === 2 && typeof args[0] !== 'string') {
99
- // onChange(instance, handler) - instance change
100
- const instance = args[0];
101
- const handler = args[1];
102
- return this.addCallback(instance[$refId], OPERATION.REPLACE, handler);
103
- }
104
- if (typeof args[0] === 'string') {
105
- // onChange(property, handler) - collection on root state
106
- return this.addCallbackOrWaitCollectionAvailable(this.state, args[0], OPERATION.REPLACE, args[1]);
107
- }
108
- else {
109
- // onChange(instance, property, handler) - nested collection
110
- return this.addCallbackOrWaitCollectionAvailable(args[0], args[1], OPERATION.REPLACE, args[2]);
111
- }
112
- }
113
- onAdd(...args) {
114
- if (typeof args[0] === 'string') {
115
- // onAdd(property, handler, immediate?) - collection on root state
116
- return this.addCallbackOrWaitCollectionAvailable(this.state, args[0], OPERATION.ADD, args[1], args[2] !== false);
117
- }
118
- else {
119
- // onAdd(instance, property, handler, immediate?) - nested collection
120
- return this.addCallbackOrWaitCollectionAvailable(args[0], args[1], OPERATION.ADD, args[2], args[3] !== false);
121
- }
122
- }
123
- onRemove(...args) {
124
- if (typeof args[0] === 'string') {
125
- // onRemove(property, handler) - collection on root state
126
- return this.addCallbackOrWaitCollectionAvailable(this.state, args[0], OPERATION.DELETE, args[1]);
127
- }
128
- else {
129
- // onRemove(instance, property, handler) - nested collection
130
- return this.addCallbackOrWaitCollectionAvailable(args[0], args[1], OPERATION.DELETE, args[2]);
131
- }
132
- }
133
- /**
134
- * Bind properties from a Schema instance to a target object.
135
- * Changes will be automatically reflected on the target object.
136
- */
137
- bindTo(from, to, properties, immediate = true) {
138
- const metadata = from.constructor[Symbol.metadata];
139
- // If no properties specified, bind all properties
140
- if (!properties) {
141
- properties = Object.keys(metadata)
142
- .filter(key => !isNaN(Number(key)))
143
- .map((index) => metadata[index].name);
144
- }
145
- const action = () => {
146
- for (const prop of properties) {
147
- const fromValue = from[prop];
148
- if (fromValue !== undefined) {
149
- to[prop] = fromValue;
150
- }
151
- }
152
- };
153
- if (immediate) {
154
- action();
155
- }
156
- return this.addCallback(from[$refId], OPERATION.REPLACE, action);
157
- }
158
- triggerChanges(allChanges) {
159
- this.uniqueRefIds.clear();
160
- for (let i = 0, l = allChanges.length; i < l; i++) {
161
- const change = allChanges[i];
162
- const refId = change.refId;
163
- const ref = change.ref;
164
- const $callbacks = this.callbacks[refId];
165
- if (!$callbacks) {
166
- continue;
167
- }
168
- //
169
- // trigger onRemove on child structure.
170
- //
171
- if ((change.op & OPERATION.DELETE) === OPERATION.DELETE &&
172
- change.previousValue instanceof Schema) {
173
- const childRefId = change.previousValue[$refId];
174
- const deleteCallbacks = this.callbacks[childRefId]?.[OPERATION.DELETE];
175
- if (deleteCallbacks) {
176
- for (let j = deleteCallbacks.length - 1; j >= 0; j--) {
177
- deleteCallbacks[j]();
178
- }
179
- }
180
- }
181
- if (ref instanceof Schema) {
182
- //
183
- // Handle Schema instance
184
- //
185
- if (!this.uniqueRefIds.has(refId)) {
186
- // trigger onChange
187
- const replaceCallbacks = $callbacks[OPERATION.REPLACE];
188
- if (replaceCallbacks) {
189
- for (let j = replaceCallbacks.length - 1; j >= 0; j--) {
190
- try {
191
- replaceCallbacks[j]();
192
- }
193
- catch (e) {
194
- console.error(e);
195
- }
196
- }
197
- }
198
- }
199
- // trigger field callbacks
200
- const fieldCallbacks = $callbacks[change.field];
201
- if (fieldCallbacks) {
202
- for (let j = fieldCallbacks.length - 1; j >= 0; j--) {
203
- try {
204
- this.isTriggering = true;
205
- fieldCallbacks[j](change.value, change.previousValue);
206
- }
207
- catch (e) {
208
- console.error(e);
209
- }
210
- finally {
211
- this.isTriggering = false;
212
- }
213
- }
214
- }
215
- }
216
- else {
217
- //
218
- // Handle collection of items
219
- //
220
- const dynamicIndex = change.dynamicIndex ?? change.field;
221
- if ((change.op & OPERATION.DELETE) === OPERATION.DELETE) {
222
- //
223
- // FIXME: `previousValue` should always be available.
224
- //
225
- if (change.previousValue !== undefined) {
226
- // trigger onRemove (key, value)
227
- const deleteCallbacks = $callbacks[OPERATION.DELETE];
228
- if (deleteCallbacks) {
229
- for (let j = deleteCallbacks.length - 1; j >= 0; j--) {
230
- deleteCallbacks[j](dynamicIndex, change.previousValue);
231
- }
232
- }
233
- }
234
- // Handle DELETE_AND_ADD operation
235
- if ((change.op & OPERATION.ADD) === OPERATION.ADD) {
236
- const addCallbacks = $callbacks[OPERATION.ADD];
237
- if (addCallbacks) {
238
- this.isTriggering = true;
239
- for (let j = addCallbacks.length - 1; j >= 0; j--) {
240
- addCallbacks[j](dynamicIndex, change.value);
241
- }
242
- this.isTriggering = false;
243
- }
244
- }
245
- }
246
- else if ((change.op & OPERATION.ADD) === OPERATION.ADD &&
247
- change.previousValue !== change.value) {
248
- // trigger onAdd (key, value)
249
- const addCallbacks = $callbacks[OPERATION.ADD];
250
- if (addCallbacks) {
251
- this.isTriggering = true;
252
- for (let j = addCallbacks.length - 1; j >= 0; j--) {
253
- addCallbacks[j](dynamicIndex, change.value);
254
- }
255
- this.isTriggering = false;
256
- }
257
- }
258
- // trigger onChange (key, value)
259
- if (change.value !== change.previousValue) {
260
- const replaceCallbacks = $callbacks[OPERATION.REPLACE];
261
- if (replaceCallbacks) {
262
- for (let j = replaceCallbacks.length - 1; j >= 0; j--) {
263
- replaceCallbacks[j](dynamicIndex, change.value);
264
- }
265
- }
266
- }
267
- }
268
- this.uniqueRefIds.add(refId);
269
- }
270
- }
271
- }
272
- /**
273
- * Factory class for retrieving the callbacks API.
274
- */
275
- export const Callbacks = {
276
- /**
277
- * Get the new callbacks standard API.
278
- *
279
- * Usage:
280
- * ```ts
281
- * const callbacks = Callbacks.get(roomOrDecoder);
282
- *
283
- * // Listen to property changes
284
- * callbacks.listen("currentTurn", (currentValue, previousValue) => { ... });
285
- *
286
- * // Listen to collection additions
287
- * callbacks.onAdd("entities", (sessionId, entity) => {
288
- * // Nested property listening
289
- * callbacks.listen(entity, "hp", (currentHp, previousHp) => { ... });
290
- * });
291
- *
292
- * // Listen to collection removals
293
- * callbacks.onRemove("entities", (sessionId, entity) => { ... });
294
- *
295
- * // Listen to any property change on an instance
296
- * callbacks.onChange(entity, () => { ... });
297
- *
298
- * // Bind properties to another object
299
- * callbacks.bindTo(player, playerVisual);
300
- * ```
301
- *
302
- * @param roomOrDecoder - Room or Decoder instance to get the callbacks for.
303
- * @returns the new callbacks standard API.
304
- */
305
- get(roomOrDecoder) {
306
- if (roomOrDecoder instanceof Decoder) {
307
- return new StateCallbackStrategy(roomOrDecoder);
308
- }
309
- else if (roomOrDecoder.serializer.decoder) {
310
- return new StateCallbackStrategy(roomOrDecoder.serializer.decoder);
311
- }
312
- else {
313
- throw new Error('Invalid room or decoder');
314
- }
315
- },
316
- /**
317
- * Get the legacy callbacks API.
318
- *
319
- * We aim to deprecate this API on 1.0, and iterate on improving Callbacks.get() API.
320
- *
321
- * @param roomOrDecoder - Room or Decoder instance to get the legacy callbacks for.
322
- * @returns the legacy callbacks API.
323
- */
324
- getLegacy(roomOrDecoder) {
325
- if (roomOrDecoder instanceof Decoder) {
326
- return getDecoderStateCallbacks(roomOrDecoder);
327
- }
328
- else if (roomOrDecoder.serializer.decoder) {
329
- return getDecoderStateCallbacks(roomOrDecoder.serializer.decoder);
330
- }
331
- },
332
- getRawChanges(decoder, callback) {
333
- return getRawChangesCallback(decoder, callback);
334
- }
335
- };
336
- //# sourceMappingURL=Callbacks.js.map