@colyseus/schema 4.0.2 → 4.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +18 -43
  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/{cjs/index.cjs → index.cjs} +8 -34
  28. package/build/index.cjs.map +1 -0
  29. package/build/index.d.ts +32 -0
  30. package/build/{umd/index.js → index.js} +8 -34
  31. package/build/{esm/index.mjs → index.mjs} +8 -34
  32. package/build/index.mjs.map +1 -0
  33. package/{lib → build}/types/HelperTypes.d.ts +6 -6
  34. package/{lib → build}/types/TypeContext.d.ts +1 -1
  35. package/{lib/src → build}/types/custom/ArraySchema.d.ts +8 -8
  36. package/{lib/src → build}/types/custom/CollectionSchema.d.ts +7 -7
  37. package/{lib → build}/types/custom/MapSchema.d.ts +7 -7
  38. package/{lib/src → build}/types/custom/SetSchema.d.ts +7 -7
  39. package/{lib/src → build}/types/registry.d.ts +2 -2
  40. package/{lib → build}/utils.d.ts +1 -1
  41. package/package.json +9 -10
  42. package/src/Metadata.ts +5 -5
  43. package/src/Reflection.ts +7 -7
  44. package/src/Schema.ts +11 -11
  45. package/src/annotations.ts +13 -13
  46. package/src/codegen/api.ts +3 -3
  47. package/src/codegen/cli.ts +2 -2
  48. package/src/codegen/languages/cpp.ts +2 -2
  49. package/src/codegen/languages/csharp.ts +3 -3
  50. package/src/codegen/languages/haxe.ts +2 -2
  51. package/src/codegen/languages/java.ts +2 -2
  52. package/src/codegen/languages/js.ts +2 -2
  53. package/src/codegen/languages/lua.ts +2 -2
  54. package/src/codegen/languages/ts.ts +2 -2
  55. package/src/codegen/parser.ts +6 -1
  56. package/src/decoder/DecodeOperation.ts +14 -14
  57. package/src/decoder/Decoder.ts +11 -11
  58. package/src/decoder/ReferenceTracker.ts +8 -8
  59. package/src/decoder/strategy/Callbacks.ts +27 -53
  60. package/src/decoder/strategy/RawChanges.ts +2 -2
  61. package/src/decoder/strategy/getDecoderStateCallbacks.ts +10 -10
  62. package/src/encoder/ChangeTree.ts +13 -13
  63. package/src/encoder/EncodeOperation.ts +9 -9
  64. package/src/encoder/Encoder.ts +10 -10
  65. package/src/encoder/Root.ts +4 -4
  66. package/src/encoder/StateView.ts +7 -7
  67. package/src/encoding/assert.ts +6 -6
  68. package/src/encoding/decode.ts +1 -1
  69. package/src/encoding/encode.ts +1 -1
  70. package/src/index.ts +27 -27
  71. package/src/types/HelperTypes.ts +6 -6
  72. package/src/types/TypeContext.ts +3 -3
  73. package/src/types/custom/ArraySchema.ts +11 -11
  74. package/src/types/custom/CollectionSchema.ts +9 -9
  75. package/src/types/custom/MapSchema.ts +10 -10
  76. package/src/types/custom/SetSchema.ts +9 -9
  77. package/src/types/registry.ts +3 -3
  78. package/src/utils.ts +3 -3
  79. package/src/v3_bench.ts +1 -1
  80. package/build/cjs/index.cjs.map +0 -1
  81. package/build/esm/index.mjs.map +0 -1
  82. package/lib/Metadata.js +0 -256
  83. package/lib/Metadata.js.map +0 -1
  84. package/lib/Reflection.js +0 -179
  85. package/lib/Reflection.js.map +0 -1
  86. package/lib/Schema.js +0 -352
  87. package/lib/Schema.js.map +0 -1
  88. package/lib/annotations.d.ts +0 -109
  89. package/lib/annotations.js +0 -473
  90. package/lib/annotations.js.map +0 -1
  91. package/lib/bench_encode.d.ts +0 -1
  92. package/lib/bench_encode.js +0 -91
  93. package/lib/bench_encode.js.map +0 -1
  94. package/lib/benchmark.d.ts +0 -1
  95. package/lib/benchmark.js +0 -218
  96. package/lib/benchmark.js.map +0 -1
  97. package/lib/codegen/api.js +0 -56
  98. package/lib/codegen/api.js.map +0 -1
  99. package/lib/codegen/argv.js +0 -39
  100. package/lib/codegen/argv.js.map +0 -1
  101. package/lib/codegen/cli.js +0 -58
  102. package/lib/codegen/cli.js.map +0 -1
  103. package/lib/codegen/languages/cpp.d.ts +0 -3
  104. package/lib/codegen/languages/cpp.js +0 -258
  105. package/lib/codegen/languages/cpp.js.map +0 -1
  106. package/lib/codegen/languages/csharp.d.ts +0 -4
  107. package/lib/codegen/languages/csharp.js +0 -154
  108. package/lib/codegen/languages/csharp.js.map +0 -1
  109. package/lib/codegen/languages/haxe.d.ts +0 -3
  110. package/lib/codegen/languages/haxe.js +0 -100
  111. package/lib/codegen/languages/haxe.js.map +0 -1
  112. package/lib/codegen/languages/java.js +0 -100
  113. package/lib/codegen/languages/java.js.map +0 -1
  114. package/lib/codegen/languages/js.d.ts +0 -3
  115. package/lib/codegen/languages/js.js +0 -101
  116. package/lib/codegen/languages/js.js.map +0 -1
  117. package/lib/codegen/languages/lua.d.ts +0 -3
  118. package/lib/codegen/languages/lua.js +0 -103
  119. package/lib/codegen/languages/lua.js.map +0 -1
  120. package/lib/codegen/languages/ts.d.ts +0 -3
  121. package/lib/codegen/languages/ts.js +0 -116
  122. package/lib/codegen/languages/ts.js.map +0 -1
  123. package/lib/codegen/parser.js +0 -327
  124. package/lib/codegen/parser.js.map +0 -1
  125. package/lib/codegen/types.js +0 -142
  126. package/lib/codegen/types.js.map +0 -1
  127. package/lib/decoder/DecodeOperation.js +0 -248
  128. package/lib/decoder/DecodeOperation.js.map +0 -1
  129. package/lib/decoder/Decoder.d.ts +0 -21
  130. package/lib/decoder/Decoder.js +0 -114
  131. package/lib/decoder/Decoder.js.map +0 -1
  132. package/lib/decoder/ReferenceTracker.js +0 -135
  133. package/lib/decoder/ReferenceTracker.js.map +0 -1
  134. package/lib/decoder/strategy/Callbacks.js +0 -336
  135. package/lib/decoder/strategy/Callbacks.js.map +0 -1
  136. package/lib/decoder/strategy/RawChanges.js +0 -4
  137. package/lib/decoder/strategy/RawChanges.js.map +0 -1
  138. package/lib/decoder/strategy/getDecoderStateCallbacks.js +0 -274
  139. package/lib/decoder/strategy/getDecoderStateCallbacks.js.map +0 -1
  140. package/lib/encoder/ChangeTree.js +0 -534
  141. package/lib/encoder/ChangeTree.js.map +0 -1
  142. package/lib/encoder/EncodeOperation.js +0 -132
  143. package/lib/encoder/EncodeOperation.js.map +0 -1
  144. package/lib/encoder/Encoder.js +0 -204
  145. package/lib/encoder/Encoder.js.map +0 -1
  146. package/lib/encoder/Root.d.ts +0 -28
  147. package/lib/encoder/Root.js +0 -229
  148. package/lib/encoder/Root.js.map +0 -1
  149. package/lib/encoder/StateView.d.ts +0 -34
  150. package/lib/encoder/StateView.js +0 -279
  151. package/lib/encoder/StateView.js.map +0 -1
  152. package/lib/encoding/assert.d.ts +0 -10
  153. package/lib/encoding/assert.js +0 -49
  154. package/lib/encoding/assert.js.map +0 -1
  155. package/lib/encoding/decode.d.ts +0 -67
  156. package/lib/encoding/decode.js +0 -217
  157. package/lib/encoding/decode.js.map +0 -1
  158. package/lib/encoding/encode.d.ts +0 -40
  159. package/lib/encoding/encode.js +0 -279
  160. package/lib/encoding/encode.js.map +0 -1
  161. package/lib/encoding/spec.js +0 -26
  162. package/lib/encoding/spec.js.map +0 -1
  163. package/lib/index.d.ts +0 -32
  164. package/lib/index.js +0 -39
  165. package/lib/index.js.map +0 -1
  166. package/lib/src/Metadata.d.ts +0 -49
  167. package/lib/src/Metadata.js +0 -256
  168. package/lib/src/Metadata.js.map +0 -1
  169. package/lib/src/Reflection.d.ts +0 -71
  170. package/lib/src/Reflection.js +0 -179
  171. package/lib/src/Reflection.js.map +0 -1
  172. package/lib/src/Schema.d.ts +0 -86
  173. package/lib/src/Schema.js +0 -352
  174. package/lib/src/Schema.js.map +0 -1
  175. package/lib/src/annotations.js +0 -473
  176. package/lib/src/annotations.js.map +0 -1
  177. package/lib/src/bench_encode.d.ts +0 -1
  178. package/lib/src/bench_encode.js +0 -91
  179. package/lib/src/bench_encode.js.map +0 -1
  180. package/lib/src/codegen/api.d.ts +0 -7
  181. package/lib/src/codegen/api.js +0 -56
  182. package/lib/src/codegen/api.js.map +0 -1
  183. package/lib/src/codegen/argv.d.ts +0 -6
  184. package/lib/src/codegen/argv.js +0 -39
  185. package/lib/src/codegen/argv.js.map +0 -1
  186. package/lib/src/codegen/cli.d.ts +0 -1
  187. package/lib/src/codegen/cli.js +0 -58
  188. package/lib/src/codegen/cli.js.map +0 -1
  189. package/lib/src/codegen/languages/cpp.d.ts +0 -3
  190. package/lib/src/codegen/languages/cpp.js +0 -258
  191. package/lib/src/codegen/languages/cpp.js.map +0 -1
  192. package/lib/src/codegen/languages/csharp.d.ts +0 -4
  193. package/lib/src/codegen/languages/csharp.js +0 -154
  194. package/lib/src/codegen/languages/csharp.js.map +0 -1
  195. package/lib/src/codegen/languages/haxe.d.ts +0 -3
  196. package/lib/src/codegen/languages/haxe.js +0 -100
  197. package/lib/src/codegen/languages/haxe.js.map +0 -1
  198. package/lib/src/codegen/languages/java.d.ts +0 -6
  199. package/lib/src/codegen/languages/java.js +0 -100
  200. package/lib/src/codegen/languages/java.js.map +0 -1
  201. package/lib/src/codegen/languages/js.d.ts +0 -3
  202. package/lib/src/codegen/languages/js.js +0 -101
  203. package/lib/src/codegen/languages/js.js.map +0 -1
  204. package/lib/src/codegen/languages/lua.d.ts +0 -3
  205. package/lib/src/codegen/languages/lua.js +0 -103
  206. package/lib/src/codegen/languages/lua.js.map +0 -1
  207. package/lib/src/codegen/languages/ts.d.ts +0 -3
  208. package/lib/src/codegen/languages/ts.js +0 -116
  209. package/lib/src/codegen/languages/ts.js.map +0 -1
  210. package/lib/src/codegen/parser.d.ts +0 -13
  211. package/lib/src/codegen/parser.js +0 -327
  212. package/lib/src/codegen/parser.js.map +0 -1
  213. package/lib/src/codegen/types.d.ts +0 -52
  214. package/lib/src/codegen/types.js +0 -142
  215. package/lib/src/codegen/types.js.map +0 -1
  216. package/lib/src/decoder/DecodeOperation.d.ts +0 -23
  217. package/lib/src/decoder/DecodeOperation.js +0 -248
  218. package/lib/src/decoder/DecodeOperation.js.map +0 -1
  219. package/lib/src/decoder/Decoder.js +0 -114
  220. package/lib/src/decoder/Decoder.js.map +0 -1
  221. package/lib/src/decoder/ReferenceTracker.d.ts +0 -25
  222. package/lib/src/decoder/ReferenceTracker.js +0 -135
  223. package/lib/src/decoder/ReferenceTracker.js.map +0 -1
  224. package/lib/src/decoder/strategy/Callbacks.d.ts +0 -154
  225. package/lib/src/decoder/strategy/Callbacks.js +0 -336
  226. package/lib/src/decoder/strategy/Callbacks.js.map +0 -1
  227. package/lib/src/decoder/strategy/RawChanges.d.ts +0 -3
  228. package/lib/src/decoder/strategy/RawChanges.js +0 -4
  229. package/lib/src/decoder/strategy/RawChanges.js.map +0 -1
  230. package/lib/src/decoder/strategy/getDecoderStateCallbacks.d.ts +0 -76
  231. package/lib/src/decoder/strategy/getDecoderStateCallbacks.js +0 -274
  232. package/lib/src/decoder/strategy/getDecoderStateCallbacks.js.map +0 -1
  233. package/lib/src/encoder/ChangeTree.d.ts +0 -135
  234. package/lib/src/encoder/ChangeTree.js +0 -534
  235. package/lib/src/encoder/ChangeTree.js.map +0 -1
  236. package/lib/src/encoder/EncodeOperation.d.ts +0 -22
  237. package/lib/src/encoder/EncodeOperation.js +0 -132
  238. package/lib/src/encoder/EncodeOperation.js.map +0 -1
  239. package/lib/src/encoder/Encoder.d.ts +0 -22
  240. package/lib/src/encoder/Encoder.js +0 -204
  241. package/lib/src/encoder/Encoder.js.map +0 -1
  242. package/lib/src/encoder/Root.js +0 -229
  243. package/lib/src/encoder/Root.js.map +0 -1
  244. package/lib/src/encoder/StateView.js +0 -279
  245. package/lib/src/encoder/StateView.js.map +0 -1
  246. package/lib/src/encoding/assert.js +0 -49
  247. package/lib/src/encoding/assert.js.map +0 -1
  248. package/lib/src/encoding/decode.js +0 -217
  249. package/lib/src/encoding/decode.js.map +0 -1
  250. package/lib/src/encoding/encode.js +0 -279
  251. package/lib/src/encoding/encode.js.map +0 -1
  252. package/lib/src/encoding/spec.d.ts +0 -24
  253. package/lib/src/encoding/spec.js +0 -26
  254. package/lib/src/encoding/spec.js.map +0 -1
  255. package/lib/src/index.d.ts +0 -32
  256. package/lib/src/index.js +0 -39
  257. package/lib/src/index.js.map +0 -1
  258. package/lib/src/symbol.shim.js +0 -3
  259. package/lib/src/symbol.shim.js.map +0 -1
  260. package/lib/src/types/HelperTypes.d.ts +0 -77
  261. package/lib/src/types/HelperTypes.js +0 -2
  262. package/lib/src/types/HelperTypes.js.map +0 -1
  263. package/lib/src/types/TypeContext.d.ts +0 -31
  264. package/lib/src/types/TypeContext.js +0 -143
  265. package/lib/src/types/TypeContext.js.map +0 -1
  266. package/lib/src/types/custom/ArraySchema.js +0 -733
  267. package/lib/src/types/custom/ArraySchema.js.map +0 -1
  268. package/lib/src/types/custom/CollectionSchema.js +0 -170
  269. package/lib/src/types/custom/CollectionSchema.js.map +0 -1
  270. package/lib/src/types/custom/MapSchema.d.ts +0 -51
  271. package/lib/src/types/custom/MapSchema.js +0 -222
  272. package/lib/src/types/custom/MapSchema.js.map +0 -1
  273. package/lib/src/types/custom/SetSchema.js +0 -178
  274. package/lib/src/types/custom/SetSchema.js.map +0 -1
  275. package/lib/src/types/registry.js +0 -30
  276. package/lib/src/types/registry.js.map +0 -1
  277. package/lib/src/types/symbols.js +0 -34
  278. package/lib/src/types/symbols.js.map +0 -1
  279. package/lib/src/types/utils.js +0 -13
  280. package/lib/src/types/utils.js.map +0 -1
  281. package/lib/src/utils.d.ts +0 -13
  282. package/lib/src/utils.js +0 -49
  283. package/lib/src/utils.js.map +0 -1
  284. package/lib/src/v3_bench.js +0 -128
  285. package/lib/src/v3_bench.js.map +0 -1
  286. package/lib/symbol.shim.d.ts +0 -6
  287. package/lib/symbol.shim.js +0 -3
  288. package/lib/symbol.shim.js.map +0 -1
  289. package/lib/types/HelperTypes.js +0 -2
  290. package/lib/types/HelperTypes.js.map +0 -1
  291. package/lib/types/TypeContext.js +0 -143
  292. package/lib/types/TypeContext.js.map +0 -1
  293. package/lib/types/custom/ArraySchema.d.ts +0 -270
  294. package/lib/types/custom/ArraySchema.js +0 -733
  295. package/lib/types/custom/ArraySchema.js.map +0 -1
  296. package/lib/types/custom/CollectionSchema.d.ts +0 -51
  297. package/lib/types/custom/CollectionSchema.js +0 -170
  298. package/lib/types/custom/CollectionSchema.js.map +0 -1
  299. package/lib/types/custom/MapSchema.js +0 -222
  300. package/lib/types/custom/MapSchema.js.map +0 -1
  301. package/lib/types/custom/SetSchema.d.ts +0 -48
  302. package/lib/types/custom/SetSchema.js +0 -178
  303. package/lib/types/custom/SetSchema.js.map +0 -1
  304. package/lib/types/registry.d.ts +0 -16
  305. package/lib/types/registry.js +0 -30
  306. package/lib/types/registry.js.map +0 -1
  307. package/lib/types/symbols.d.ts +0 -33
  308. package/lib/types/symbols.js +0 -34
  309. package/lib/types/symbols.js.map +0 -1
  310. package/lib/types/utils.d.ts +0 -1
  311. package/lib/types/utils.js +0 -13
  312. package/lib/types/utils.js.map +0 -1
  313. package/lib/utils.js +0 -49
  314. package/lib/utils.js.map +0 -1
  315. package/lib/v3_bench.d.ts +0 -1
  316. package/lib/v3_bench.js +0 -128
  317. package/lib/v3_bench.js.map +0 -1
  318. /package/{lib → build}/codegen/api.d.ts +0 -0
  319. /package/{lib → build}/codegen/argv.d.ts +0 -0
  320. /package/{lib → build}/codegen/cli.d.ts +0 -0
  321. /package/{lib → build}/codegen/types.d.ts +0 -0
  322. /package/{lib → build}/encoding/spec.d.ts +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,132 +0,0 @@
1
- import { OPERATION } from "../encoding/spec";
2
- import { $childType, $getByIndex, $refId } from "../types/symbols";
3
- import { encode } from "../encoding/encode";
4
- export function encodeValue(encoder, bytes, type, value, operation, it) {
5
- if (typeof (type) === "string") {
6
- encode[type]?.(bytes, value, it);
7
- }
8
- else if (type[Symbol.metadata] !== undefined) {
9
- //
10
- // Encode refId for this instance.
11
- // The actual instance is going to be encoded on next `changeTree` iteration.
12
- //
13
- encode.number(bytes, value[$refId], it);
14
- // Try to encode inherited TYPE_ID if it's an ADD operation.
15
- if ((operation & OPERATION.ADD) === OPERATION.ADD) {
16
- encoder.tryEncodeTypeId(bytes, type, value.constructor, it);
17
- }
18
- }
19
- else {
20
- //
21
- // Encode refId for this instance.
22
- // The actual instance is going to be encoded on next `changeTree` iteration.
23
- //
24
- encode.number(bytes, value[$refId], it);
25
- }
26
- }
27
- /**
28
- * Used for Schema instances.
29
- * @private
30
- */
31
- export const encodeSchemaOperation = function (encoder, bytes, changeTree, index, operation, it, _, __, metadata) {
32
- // "compress" field index + operation
33
- bytes[it.offset++] = (index | operation) & 255;
34
- // Do not encode value for DELETE operations
35
- if (operation === OPERATION.DELETE) {
36
- return;
37
- }
38
- const ref = changeTree.ref;
39
- const field = metadata[index];
40
- // TODO: inline this function call small performance gain
41
- encodeValue(encoder, bytes, metadata[index].type, ref[field.name], operation, it);
42
- };
43
- /**
44
- * Used for collections (MapSchema, CollectionSchema, SetSchema)
45
- * @private
46
- */
47
- export const encodeKeyValueOperation = function (encoder, bytes, changeTree, index, operation, it) {
48
- // encode operation
49
- bytes[it.offset++] = operation & 255;
50
- // encode index
51
- encode.number(bytes, index, it);
52
- // Do not encode value for DELETE operations
53
- if (operation === OPERATION.DELETE) {
54
- return;
55
- }
56
- const ref = changeTree.ref;
57
- //
58
- // encode "alias" for dynamic fields (maps)
59
- //
60
- if ((operation & OPERATION.ADD) === OPERATION.ADD) { // ADD or DELETE_AND_ADD
61
- if (typeof (ref['set']) === "function") {
62
- //
63
- // MapSchema dynamic key
64
- //
65
- const dynamicIndex = changeTree.ref['$indexes'].get(index);
66
- encode.string(bytes, dynamicIndex, it);
67
- }
68
- }
69
- const type = ref[$childType];
70
- const value = ref[$getByIndex](index);
71
- // try { throw new Error(); } catch (e) {
72
- // // only print if not coming from Reflection.ts
73
- // if (!e.stack.includes("src/Reflection.ts")) {
74
- // console.log("encodeKeyValueOperation -> ", {
75
- // ref: changeTree.ref.constructor.name,
76
- // field,
77
- // operation: OPERATION[operation],
78
- // value: value?.toJSON(),
79
- // items: ref.toJSON(),
80
- // });
81
- // }
82
- // }
83
- // TODO: inline this function call small performance gain
84
- encodeValue(encoder, bytes, type, value, operation, it);
85
- };
86
- /**
87
- * Used for collections (MapSchema, ArraySchema, etc.)
88
- * @private
89
- */
90
- export const encodeArray = function (encoder, bytes, changeTree, field, operation, it, isEncodeAll, hasView) {
91
- const ref = changeTree.ref;
92
- const useOperationByRefId = hasView && changeTree.isFiltered && (typeof (changeTree.getType(field)) !== "string");
93
- let refOrIndex;
94
- if (useOperationByRefId) {
95
- const item = ref['tmpItems'][field];
96
- // Skip encoding if item is undefined (e.g. when clear() is called)
97
- if (!item) {
98
- return;
99
- }
100
- refOrIndex = item[$refId];
101
- if (operation === OPERATION.DELETE) {
102
- operation = OPERATION.DELETE_BY_REFID;
103
- }
104
- else if (operation === OPERATION.ADD) {
105
- operation = OPERATION.ADD_BY_REFID;
106
- }
107
- }
108
- else {
109
- refOrIndex = field;
110
- }
111
- // encode operation
112
- bytes[it.offset++] = operation & 255;
113
- // encode index
114
- encode.number(bytes, refOrIndex, it);
115
- // Do not encode value for DELETE operations
116
- if (operation === OPERATION.DELETE || operation === OPERATION.DELETE_BY_REFID) {
117
- return;
118
- }
119
- const type = changeTree.getType(field);
120
- const value = changeTree.getValue(field, isEncodeAll);
121
- // console.log({ type, field, value });
122
- // console.log("encodeArray -> ", {
123
- // ref: changeTree.ref.constructor.name,
124
- // field,
125
- // operation: OPERATION[operation],
126
- // value: value?.toJSON(),
127
- // items: ref.toJSON(),
128
- // });
129
- // TODO: inline this function call small performance gain
130
- encodeValue(encoder, bytes, type, value, operation, it);
131
- };
132
- //# sourceMappingURL=EncodeOperation.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"EncodeOperation.js","sourceRoot":"","sources":["../../../src/encoder/EncodeOperation.ts"],"names":[],"mappings":"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","sourcesContent":["import { OPERATION } from \"../encoding/spec\";\nimport { $changes, $childType, $getByIndex, $refId } from \"../types/symbols\";\n\nimport { encode } from \"../encoding/encode\";\n\nimport type { ChangeTree, Ref } from \"./ChangeTree\";\nimport type { Encoder } from \"./Encoder\";\nimport type { Schema } from \"../Schema\";\n\nimport type { Iterator } from \"../encoding/decode\";\nimport type { ArraySchema } from \"../types/custom/ArraySchema\";\nimport type { Metadata } from \"../Metadata\";\n\nexport type EncodeOperation<T extends Ref = any> = (\n encoder: Encoder,\n bytes: Uint8Array,\n changeTree: ChangeTree<T>,\n index: number,\n operation: OPERATION,\n it: Iterator,\n isEncodeAll: boolean,\n hasView: boolean,\n metadata?: Metadata,\n) => void;\n\nexport function encodeValue(\n encoder: Encoder,\n bytes: Uint8Array,\n type: any,\n value: any,\n operation: OPERATION,\n it: Iterator,\n) {\n if (typeof (type) === \"string\") {\n (encode as any)[type]?.(bytes, value, it);\n\n } else if (type[Symbol.metadata] !== undefined) {\n //\n // Encode refId for this instance.\n // The actual instance is going to be encoded on next `changeTree` iteration.\n //\n encode.number(bytes, value[$refId], it);\n\n // Try to encode inherited TYPE_ID if it's an ADD operation.\n if ((operation & OPERATION.ADD) === OPERATION.ADD) {\n encoder.tryEncodeTypeId(bytes, type as typeof Schema, value.constructor as typeof Schema, it);\n }\n\n } else {\n //\n // Encode refId for this instance.\n // The actual instance is going to be encoded on next `changeTree` iteration.\n //\n encode.number(bytes, value[$refId], it);\n }\n}\n\n/**\n * Used for Schema instances.\n * @private\n */\nexport const encodeSchemaOperation: EncodeOperation = function <T extends Schema> (\n encoder: Encoder,\n bytes: Uint8Array,\n changeTree: ChangeTree<T>,\n index: number,\n operation: OPERATION,\n it: Iterator,\n _: any,\n __: any,\n metadata: Metadata,\n) {\n // \"compress\" field index + operation\n bytes[it.offset++] = (index | operation) & 255;\n\n // Do not encode value for DELETE operations\n if (operation === OPERATION.DELETE) {\n return;\n }\n\n const ref = changeTree.ref;\n const field = metadata[index];\n\n // TODO: inline this function call small performance gain\n encodeValue(\n encoder,\n bytes,\n metadata[index].type,\n ref[field.name as keyof T],\n operation,\n it\n );\n}\n\n/**\n * Used for collections (MapSchema, CollectionSchema, SetSchema)\n * @private\n */\nexport const encodeKeyValueOperation: EncodeOperation = function (\n encoder: Encoder,\n bytes: Uint8Array,\n changeTree: ChangeTree,\n index: number,\n operation: OPERATION,\n it: Iterator,\n) {\n // encode operation\n bytes[it.offset++] = operation & 255;\n\n // encode index\n encode.number(bytes, index, it);\n\n // Do not encode value for DELETE operations\n if (operation === OPERATION.DELETE) {\n return;\n }\n\n const ref = changeTree.ref;\n\n //\n // encode \"alias\" for dynamic fields (maps)\n //\n if ((operation & OPERATION.ADD) === OPERATION.ADD) { // ADD or DELETE_AND_ADD\n if (typeof(ref['set']) === \"function\") {\n //\n // MapSchema dynamic key\n //\n const dynamicIndex = changeTree.ref['$indexes'].get(index);\n encode.string(bytes, dynamicIndex, it);\n }\n }\n\n const type = ref[$childType];\n const value = ref[$getByIndex](index);\n\n // try { throw new Error(); } catch (e) {\n // // only print if not coming from Reflection.ts\n // if (!e.stack.includes(\"src/Reflection.ts\")) {\n // console.log(\"encodeKeyValueOperation -> \", {\n // ref: changeTree.ref.constructor.name,\n // field,\n // operation: OPERATION[operation],\n // value: value?.toJSON(),\n // items: ref.toJSON(),\n // });\n // }\n // }\n\n // TODO: inline this function call small performance gain\n encodeValue(\n encoder,\n bytes,\n type,\n value,\n operation,\n it\n );\n}\n\n/**\n * Used for collections (MapSchema, ArraySchema, etc.)\n * @private\n */\nexport const encodeArray: EncodeOperation = function (\n encoder: Encoder,\n bytes: Uint8Array,\n changeTree: ChangeTree<ArraySchema>,\n field: number,\n operation: OPERATION,\n it: Iterator,\n isEncodeAll: boolean,\n hasView: boolean,\n) {\n const ref = changeTree.ref;\n const useOperationByRefId = hasView && changeTree.isFiltered && (typeof (changeTree.getType(field)) !== \"string\");\n\n let refOrIndex: number;\n\n if (useOperationByRefId) {\n const item = ref['tmpItems'][field];\n\n // Skip encoding if item is undefined (e.g. when clear() is called)\n if (!item) { return; }\n\n refOrIndex = item[$refId];\n\n if (operation === OPERATION.DELETE) {\n operation = OPERATION.DELETE_BY_REFID;\n\n } else if (operation === OPERATION.ADD) {\n operation = OPERATION.ADD_BY_REFID;\n }\n\n } else {\n refOrIndex = field;\n }\n\n // encode operation\n bytes[it.offset++] = operation & 255;\n\n // encode index\n encode.number(bytes, refOrIndex, it);\n\n // Do not encode value for DELETE operations\n if (operation === OPERATION.DELETE || operation === OPERATION.DELETE_BY_REFID) {\n return;\n }\n\n const type = changeTree.getType(field);\n const value = changeTree.getValue(field, isEncodeAll);\n\n // console.log({ type, field, value });\n\n // console.log(\"encodeArray -> \", {\n // ref: changeTree.ref.constructor.name,\n // field,\n // operation: OPERATION[operation],\n // value: value?.toJSON(),\n // items: ref.toJSON(),\n // });\n\n // TODO: inline this function call small performance gain\n encodeValue(\n encoder,\n bytes,\n type,\n value,\n operation,\n it\n );\n}"]}
@@ -1,22 +0,0 @@
1
- import type { Schema } from "../Schema";
2
- import { TypeContext } from "../types/TypeContext";
3
- import type { Iterator } from "../encoding/decode";
4
- import { Root } from "./Root";
5
- import type { StateView } from "./StateView";
6
- import type { ChangeSetName } from "./ChangeTree";
7
- export declare class Encoder<T extends Schema = any> {
8
- static BUFFER_SIZE: number;
9
- sharedBuffer: Uint8Array;
10
- context: TypeContext;
11
- state: T;
12
- root: Root;
13
- constructor(state: T);
14
- protected setState(state: T): void;
15
- encode(it?: Iterator, view?: StateView, buffer?: Uint8Array, changeSetName?: ChangeSetName, isEncodeAll?: boolean, initialOffset?: number): Uint8Array;
16
- encodeAll(it?: Iterator, buffer?: Uint8Array): Uint8Array<ArrayBufferLike>;
17
- encodeAllView(view: StateView, sharedOffset: number, it: Iterator, bytes?: Uint8Array): Uint8Array<ArrayBufferLike>;
18
- encodeView(view: StateView, sharedOffset: number, it: Iterator, bytes?: Uint8Array): Uint8Array<ArrayBufferLike>;
19
- discardChanges(): void;
20
- tryEncodeTypeId(bytes: Uint8Array, baseType: typeof Schema, targetType: typeof Schema, it: Iterator): void;
21
- get hasChanges(): boolean;
22
- }
@@ -1,204 +0,0 @@
1
- import { TypeContext } from "../types/TypeContext";
2
- import { $changes, $encoder, $filter, $getByIndex, $refId } from "../types/symbols";
3
- import { encode } from "../encoding/encode";
4
- import { OPERATION, SWITCH_TO_STRUCTURE, TYPE_ID } from '../encoding/spec';
5
- import { Root } from "./Root";
6
- import { createChangeTreeList } from "./ChangeTree";
7
- function concatBytes(a, b) {
8
- const result = new Uint8Array(a.length + b.length);
9
- result.set(a, 0);
10
- result.set(b, a.length);
11
- return result;
12
- }
13
- export class Encoder {
14
- static { this.BUFFER_SIZE = 8 * 1024; } // 8KB
15
- constructor(state) {
16
- this.sharedBuffer = new Uint8Array(Encoder.BUFFER_SIZE);
17
- //
18
- // Use .cache() here to avoid re-creating a new context for every new room instance.
19
- //
20
- // We may need to make this optional in case of dynamically created
21
- // schemas - which would lead to memory leaks
22
- //
23
- this.context = TypeContext.cache(state.constructor);
24
- this.root = new Root(this.context);
25
- this.setState(state);
26
- // console.log(">>>>>>>>>>>>>>>> Encoder types");
27
- // this.context.schemas.forEach((id, schema) => {
28
- // console.log("type:", id, schema.name, Object.keys(schema[Symbol.metadata]));
29
- // });
30
- }
31
- setState(state) {
32
- this.state = state;
33
- this.state[$changes].setRoot(this.root);
34
- }
35
- encode(it = { offset: 0 }, view, buffer = this.sharedBuffer, changeSetName = "changes", isEncodeAll = changeSetName === "allChanges", initialOffset = it.offset // cache current offset in case we need to resize the buffer
36
- ) {
37
- const hasView = (view !== undefined);
38
- const rootChangeTree = this.state[$changes];
39
- let current = this.root[changeSetName];
40
- while (current = current.next) {
41
- const changeTree = current.changeTree;
42
- if (hasView) {
43
- if (!view.isChangeTreeVisible(changeTree)) {
44
- // console.log("MARK AS INVISIBLE:", { ref: changeTree.ref.constructor.name, refId: changeTree.ref[$refId], raw: changeTree.ref.toJSON() });
45
- view.invisible.add(changeTree);
46
- continue; // skip this change tree
47
- }
48
- view.invisible.delete(changeTree); // remove from invisible list
49
- }
50
- const changeSet = changeTree[changeSetName];
51
- const ref = changeTree.ref;
52
- // TODO: avoid iterating over change tree if no changes were made
53
- const numChanges = changeSet.operations.length;
54
- if (numChanges === 0) {
55
- continue;
56
- }
57
- const ctor = ref.constructor;
58
- const encoder = ctor[$encoder];
59
- const filter = ctor[$filter];
60
- const metadata = ctor[Symbol.metadata];
61
- // skip root `refId` if it's the first change tree
62
- // (unless it "hasView", which will need to revisit the root)
63
- if (hasView || it.offset > initialOffset || changeTree !== rootChangeTree) {
64
- buffer[it.offset++] = SWITCH_TO_STRUCTURE & 255;
65
- encode.number(buffer, ref[$refId], it);
66
- }
67
- for (let j = 0; j < numChanges; j++) {
68
- const fieldIndex = changeSet.operations[j];
69
- if (fieldIndex < 0) {
70
- // "pure" operation without fieldIndex (e.g. CLEAR, REVERSE, etc.)
71
- // encode and continue early - no need to reach $filter check
72
- buffer[it.offset++] = Math.abs(fieldIndex) & 255;
73
- continue;
74
- }
75
- const operation = (isEncodeAll)
76
- ? OPERATION.ADD
77
- : changeTree.indexedOperations[fieldIndex];
78
- //
79
- // first pass (encodeAll), identify "filtered" operations without encoding them
80
- // they will be encoded per client, based on their view.
81
- //
82
- // TODO: how can we optimize filtering out "encode all" operations?
83
- // TODO: avoid checking if no view tags were defined
84
- //
85
- if (fieldIndex === undefined || operation === undefined || (filter && !filter(ref, fieldIndex, view))) {
86
- // console.log("ADD AS INVISIBLE:", fieldIndex, changeTree.ref.constructor.name)
87
- // view?.invisible.add(changeTree);
88
- continue;
89
- }
90
- encoder(this, buffer, changeTree, fieldIndex, operation, it, isEncodeAll, hasView, metadata);
91
- }
92
- }
93
- if (it.offset > buffer.byteLength) {
94
- // we can assume that n + 1 BUFFER_SIZE will suffice given that we are likely done with encoding at this point
95
- // multiples of BUFFER_SIZE are faster to allocate than arbitrary sizes
96
- const newSize = Math.ceil(it.offset / Encoder.BUFFER_SIZE) * Encoder.BUFFER_SIZE;
97
- console.warn(`@colyseus/schema buffer overflow. Encoded state is higher than default BUFFER_SIZE. Use the following to increase default BUFFER_SIZE:
98
-
99
- import { Encoder } from "@colyseus/schema";
100
- Encoder.BUFFER_SIZE = ${Math.round(newSize / 1024)} * 1024; // ${Math.round(newSize / 1024)} KB
101
- `);
102
- //
103
- // resize buffer and re-encode (TODO: can we avoid re-encoding here?)
104
- // -> No we probably can't unless we catch the need for resize before encoding which is likely more computationally expensive than resizing on demand
105
- //
106
- const newBuffer = new Uint8Array(newSize);
107
- newBuffer.set(buffer); // copy previous encoding steps beyond the initialOffset
108
- buffer = newBuffer;
109
- // assign resized buffer to local sharedBuffer
110
- if (buffer === this.sharedBuffer) {
111
- this.sharedBuffer = buffer;
112
- }
113
- return this.encode({ offset: initialOffset }, view, buffer, changeSetName, isEncodeAll);
114
- }
115
- else {
116
- return buffer.subarray(0, it.offset);
117
- }
118
- }
119
- encodeAll(it = { offset: 0 }, buffer = this.sharedBuffer) {
120
- return this.encode(it, undefined, buffer, "allChanges", true);
121
- }
122
- encodeAllView(view, sharedOffset, it, bytes = this.sharedBuffer) {
123
- const viewOffset = it.offset;
124
- // try to encode "filtered" changes
125
- this.encode(it, view, bytes, "allFilteredChanges", true, viewOffset);
126
- return concatBytes(bytes.subarray(0, sharedOffset), bytes.subarray(viewOffset, it.offset));
127
- }
128
- encodeView(view, sharedOffset, it, bytes = this.sharedBuffer) {
129
- const viewOffset = it.offset;
130
- // encode visibility changes (add/remove for this view)
131
- for (const [refId, changes] of view.changes) {
132
- const changeTree = this.root.changeTrees[refId];
133
- if (changeTree === undefined) {
134
- // detached instance, remove from view and skip.
135
- // console.log("detached instance, remove from view and skip.", refId);
136
- view.changes.delete(refId);
137
- continue;
138
- }
139
- const keys = Object.keys(changes);
140
- if (keys.length === 0) {
141
- // FIXME: avoid having empty changes if no changes were made
142
- // console.log("changes.size === 0, skip", refId, changeTree.ref.constructor.name);
143
- continue;
144
- }
145
- const ref = changeTree.ref;
146
- const ctor = ref.constructor;
147
- const encoder = ctor[$encoder];
148
- const metadata = ctor[Symbol.metadata];
149
- bytes[it.offset++] = SWITCH_TO_STRUCTURE & 255;
150
- encode.number(bytes, ref[$refId], it);
151
- for (let i = 0, numChanges = keys.length; i < numChanges; i++) {
152
- const index = Number(keys[i]);
153
- // workaround when using view.add() on item that has been deleted from state (see test "adding to view item that has been removed from state")
154
- const value = changeTree.ref[$getByIndex](index);
155
- const operation = (value !== undefined && changes[index]) || OPERATION.DELETE;
156
- // isEncodeAll = false
157
- // hasView = true
158
- encoder(this, bytes, changeTree, index, operation, it, false, true, metadata);
159
- }
160
- }
161
- //
162
- // TODO: only clear view changes after all views are encoded
163
- // (to allow re-using StateView's for multiple clients)
164
- //
165
- // clear "view" changes after encoding
166
- view.changes.clear();
167
- // try to encode "filtered" changes
168
- this.encode(it, view, bytes, "filteredChanges", false, viewOffset);
169
- return concatBytes(bytes.subarray(0, sharedOffset), bytes.subarray(viewOffset, it.offset));
170
- }
171
- discardChanges() {
172
- // discard shared changes
173
- let current = this.root.changes.next;
174
- while (current) {
175
- current.changeTree.endEncode('changes');
176
- current = current.next;
177
- }
178
- this.root.changes = createChangeTreeList();
179
- // discard filtered changes
180
- current = this.root.filteredChanges.next;
181
- while (current) {
182
- current.changeTree.endEncode('filteredChanges');
183
- current = current.next;
184
- }
185
- this.root.filteredChanges = createChangeTreeList();
186
- }
187
- tryEncodeTypeId(bytes, baseType, targetType, it) {
188
- const baseTypeId = this.context.getTypeId(baseType);
189
- const targetTypeId = this.context.getTypeId(targetType);
190
- if (targetTypeId === undefined) {
191
- console.warn(`@colyseus/schema WARNING: Class "${targetType.name}" is not registered on TypeRegistry - Please either tag the class with @entity or define a @type() field.`);
192
- return;
193
- }
194
- if (baseTypeId !== targetTypeId) {
195
- bytes[it.offset++] = TYPE_ID & 255;
196
- encode.number(bytes, targetTypeId, it);
197
- }
198
- }
199
- get hasChanges() {
200
- return (this.root.changes.next !== undefined ||
201
- this.root.filteredChanges.next !== undefined);
202
- }
203
- }
204
- //# sourceMappingURL=Encoder.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Encoder.js","sourceRoot":"","sources":["../../../src/encoder/Encoder.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Schema } from \"../Schema\";\nimport { TypeContext } from \"../types/TypeContext\";\nimport { $changes, $encoder, $filter, $getByIndex, $refId } from \"../types/symbols\";\n\nimport { encode } from \"../encoding/encode\";\nimport type { Iterator } from \"../encoding/decode\";\n\nimport { OPERATION, SWITCH_TO_STRUCTURE, TYPE_ID } from '../encoding/spec';\nimport { Root } from \"./Root\";\n\nimport type { StateView } from \"./StateView\";\nimport type { ChangeSetName, ChangeTree, ChangeTreeList, ChangeTreeNode } from \"./ChangeTree\";\nimport { createChangeTreeList } from \"./ChangeTree\";\n\nfunction concatBytes(a: Uint8Array, b: Uint8Array): Uint8Array {\n const result = new Uint8Array(a.length + b.length);\n result.set(a, 0);\n result.set(b, a.length);\n return result;\n}\n\nexport class Encoder<T extends Schema = any> {\n static BUFFER_SIZE = 8 * 1024; // 8KB\n sharedBuffer: Uint8Array = new Uint8Array(Encoder.BUFFER_SIZE);\n\n context: TypeContext;\n state: T;\n\n root: Root;\n\n constructor(state: T) {\n //\n // Use .cache() here to avoid re-creating a new context for every new room instance.\n //\n // We may need to make this optional in case of dynamically created\n // schemas - which would lead to memory leaks\n //\n this.context = TypeContext.cache(state.constructor as typeof Schema);\n this.root = new Root(this.context);\n\n this.setState(state);\n\n // console.log(\">>>>>>>>>>>>>>>> Encoder 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(state: T) {\n this.state = state;\n this.state[$changes].setRoot(this.root);\n }\n\n encode(\n it: Iterator = { offset: 0 },\n view?: StateView,\n buffer: Uint8Array = this.sharedBuffer,\n changeSetName: ChangeSetName = \"changes\",\n isEncodeAll = changeSetName === \"allChanges\",\n initialOffset = it.offset // cache current offset in case we need to resize the buffer\n ): Uint8Array {\n const hasView = (view !== undefined);\n const rootChangeTree = this.state[$changes];\n\n let current: ChangeTreeList | ChangeTreeNode = this.root[changeSetName];\n\n while (current = current.next) {\n const changeTree = (current as ChangeTreeNode).changeTree;\n\n if (hasView) {\n if (!view.isChangeTreeVisible(changeTree)) {\n // console.log(\"MARK AS INVISIBLE:\", { ref: changeTree.ref.constructor.name, refId: changeTree.ref[$refId], raw: changeTree.ref.toJSON() });\n view.invisible.add(changeTree);\n continue; // skip this change tree\n }\n view.invisible.delete(changeTree); // remove from invisible list\n }\n\n const changeSet = changeTree[changeSetName];\n const ref = changeTree.ref;\n\n // TODO: avoid iterating over change tree if no changes were made\n const numChanges = changeSet.operations.length;\n if (numChanges === 0) { continue; }\n\n const ctor = ref.constructor;\n const encoder = ctor[$encoder];\n const filter = ctor[$filter];\n const metadata = ctor[Symbol.metadata];\n\n // skip root `refId` if it's the first change tree\n // (unless it \"hasView\", which will need to revisit the root)\n if (hasView || it.offset > initialOffset || changeTree !== rootChangeTree) {\n buffer[it.offset++] = SWITCH_TO_STRUCTURE & 255;\n encode.number(buffer, ref[$refId], it);\n }\n\n for (let j = 0; j < numChanges; j++) {\n const fieldIndex = changeSet.operations[j];\n\n if (fieldIndex < 0) {\n // \"pure\" operation without fieldIndex (e.g. CLEAR, REVERSE, etc.)\n // encode and continue early - no need to reach $filter check\n buffer[it.offset++] = Math.abs(fieldIndex) & 255;\n continue;\n }\n\n const operation = (isEncodeAll)\n ? OPERATION.ADD\n : changeTree.indexedOperations[fieldIndex];\n\n //\n // first pass (encodeAll), identify \"filtered\" operations without encoding them\n // they will be encoded per client, based on their view.\n //\n // TODO: how can we optimize filtering out \"encode all\" operations?\n // TODO: avoid checking if no view tags were defined\n //\n if (fieldIndex === undefined || operation === undefined || (filter && !filter(ref, fieldIndex, view))) {\n // console.log(\"ADD AS INVISIBLE:\", fieldIndex, changeTree.ref.constructor.name)\n // view?.invisible.add(changeTree);\n continue;\n }\n\n encoder(this, buffer, changeTree, fieldIndex, operation, it, isEncodeAll, hasView, metadata);\n }\n }\n\n if (it.offset > buffer.byteLength) {\n // we can assume that n + 1 BUFFER_SIZE will suffice given that we are likely done with encoding at this point\n // multiples of BUFFER_SIZE are faster to allocate than arbitrary sizes\n const newSize = Math.ceil(it.offset / Encoder.BUFFER_SIZE) * Encoder.BUFFER_SIZE;\n\n console.warn(`@colyseus/schema buffer overflow. Encoded state is higher than default BUFFER_SIZE. Use the following to increase default BUFFER_SIZE:\n\n import { Encoder } from \"@colyseus/schema\";\n Encoder.BUFFER_SIZE = ${Math.round(newSize / 1024)} * 1024; // ${Math.round(newSize / 1024)} KB\n`);\n\n //\n // resize buffer and re-encode (TODO: can we avoid re-encoding here?)\n // -> No we probably can't unless we catch the need for resize before encoding which is likely more computationally expensive than resizing on demand\n //\n const newBuffer = new Uint8Array(newSize);\n newBuffer.set(buffer); // copy previous encoding steps beyond the initialOffset\n buffer = newBuffer;\n\n // assign resized buffer to local sharedBuffer\n if (buffer === this.sharedBuffer) {\n this.sharedBuffer = buffer;\n }\n\n return this.encode({ offset: initialOffset }, view, buffer, changeSetName, isEncodeAll);\n\n } else {\n\n return buffer.subarray(0, it.offset);\n }\n }\n\n encodeAll(\n it: Iterator = { offset: 0 },\n buffer: Uint8Array = this.sharedBuffer\n ) {\n return this.encode(it, undefined, buffer, \"allChanges\", true);\n }\n\n encodeAllView(\n view: StateView,\n sharedOffset: number,\n it: Iterator,\n bytes: Uint8Array = this.sharedBuffer\n ) {\n const viewOffset = it.offset;\n\n // try to encode \"filtered\" changes\n this.encode(it, view, bytes, \"allFilteredChanges\", true, viewOffset);\n\n return concatBytes(\n bytes.subarray(0, sharedOffset),\n bytes.subarray(viewOffset, it.offset)\n );\n }\n\n encodeView(\n view: StateView,\n sharedOffset: number,\n it: Iterator,\n bytes: Uint8Array = this.sharedBuffer\n ) {\n const viewOffset = it.offset;\n\n // encode visibility changes (add/remove for this view)\n for (const [refId, changes] of view.changes) {\n const changeTree: ChangeTree = this.root.changeTrees[refId];\n\n if (changeTree === undefined) {\n // detached instance, remove from view and skip.\n // console.log(\"detached instance, remove from view and skip.\", refId);\n view.changes.delete(refId);\n continue;\n }\n\n const keys = Object.keys(changes);\n if (keys.length === 0) {\n // FIXME: avoid having empty changes if no changes were made\n // console.log(\"changes.size === 0, skip\", refId, changeTree.ref.constructor.name);\n continue;\n }\n\n const ref = changeTree.ref;\n\n const ctor = ref.constructor;\n const encoder = ctor[$encoder];\n const metadata = ctor[Symbol.metadata];\n\n bytes[it.offset++] = SWITCH_TO_STRUCTURE & 255;\n encode.number(bytes, ref[$refId], it);\n\n for (let i = 0, numChanges = keys.length; i < numChanges; i++) {\n const index = Number(keys[i]);\n // workaround when using view.add() on item that has been deleted from state (see test \"adding to view item that has been removed from state\")\n const value = changeTree.ref[$getByIndex](index);\n const operation = (value !== undefined && changes[index]) || OPERATION.DELETE;\n\n // isEncodeAll = false\n // hasView = true\n encoder(this, bytes, changeTree, index, operation, it, false, true, metadata);\n }\n }\n\n //\n // TODO: only clear view changes after all views are encoded\n // (to allow re-using StateView's for multiple clients)\n //\n // clear \"view\" changes after encoding\n view.changes.clear();\n\n // try to encode \"filtered\" changes\n this.encode(it, view, bytes, \"filteredChanges\", false, viewOffset);\n\n return concatBytes(\n bytes.subarray(0, sharedOffset),\n bytes.subarray(viewOffset, it.offset)\n );\n }\n\n discardChanges() {\n // discard shared changes\n let current = this.root.changes.next;\n while (current) {\n current.changeTree.endEncode('changes');\n current = current.next;\n }\n this.root.changes = createChangeTreeList();\n\n // discard filtered changes\n current = this.root.filteredChanges.next;\n while (current) {\n current.changeTree.endEncode('filteredChanges');\n current = current.next;\n }\n this.root.filteredChanges = createChangeTreeList();\n }\n\n tryEncodeTypeId(\n bytes: Uint8Array,\n baseType: typeof Schema,\n targetType: typeof Schema,\n it: Iterator\n ) {\n const baseTypeId = this.context.getTypeId(baseType);\n const targetTypeId = this.context.getTypeId(targetType);\n\n if (targetTypeId === undefined) {\n console.warn(`@colyseus/schema WARNING: Class \"${targetType.name}\" is not registered on TypeRegistry - Please either tag the class with @entity or define a @type() field.`);\n return;\n }\n\n if (baseTypeId !== targetTypeId) {\n bytes[it.offset++] = TYPE_ID & 255;\n encode.number(bytes, targetTypeId, it);\n }\n }\n\n get hasChanges() {\n return (\n this.root.changes.next !== undefined ||\n this.root.filteredChanges.next !== undefined\n );\n }\n}\n"]}
@@ -1,229 +0,0 @@
1
- import { OPERATION } from "../encoding/spec";
2
- import { setOperationAtIndex, createChangeTreeList } from "./ChangeTree";
3
- import { $changes, $refId } from "../types/symbols";
4
- export class Root {
5
- constructor(types) {
6
- this.types = types;
7
- this.nextUniqueId = 0;
8
- this.refCount = {};
9
- this.changeTrees = {};
10
- // all changes
11
- this.allChanges = createChangeTreeList();
12
- this.allFilteredChanges = createChangeTreeList(); // TODO: do not initialize it if filters are not used
13
- // pending changes to be encoded
14
- this.changes = createChangeTreeList();
15
- this.filteredChanges = createChangeTreeList(); // TODO: do not initialize it if filters are not used
16
- }
17
- getNextUniqueId() {
18
- return this.nextUniqueId++;
19
- }
20
- add(changeTree) {
21
- const ref = changeTree.ref;
22
- // Assign unique `refId` to ref if it doesn't have one yet.
23
- if (ref[$refId] === undefined) {
24
- ref[$refId] = this.getNextUniqueId();
25
- }
26
- const refId = ref[$refId];
27
- const isNewChangeTree = (this.changeTrees[refId] === undefined);
28
- if (isNewChangeTree) {
29
- this.changeTrees[refId] = changeTree;
30
- }
31
- const previousRefCount = this.refCount[refId];
32
- if (previousRefCount === 0) {
33
- //
34
- // When a ChangeTree is re-added, it means that it was previously removed.
35
- // We need to re-add all changes to the `changes` map.
36
- //
37
- const ops = changeTree.allChanges.operations;
38
- let len = ops.length;
39
- while (len--) {
40
- changeTree.indexedOperations[ops[len]] = OPERATION.ADD;
41
- setOperationAtIndex(changeTree.changes, len);
42
- }
43
- }
44
- this.refCount[refId] = (previousRefCount || 0) + 1;
45
- // console.log("ADD", { refId, ref: ref.constructor.name, refCount: this.refCount[refId], isNewChangeTree });
46
- return isNewChangeTree;
47
- }
48
- remove(changeTree) {
49
- const refId = changeTree.ref[$refId];
50
- const refCount = (this.refCount[refId]) - 1;
51
- // console.log("REMOVE", { refId, ref: changeTree.ref.constructor.name, refCount, needRemove: refCount <= 0 });
52
- if (refCount <= 0) {
53
- //
54
- // Only remove "root" reference if it's the last reference
55
- //
56
- changeTree.root = undefined;
57
- delete this.changeTrees[refId];
58
- this.removeChangeFromChangeSet("allChanges", changeTree);
59
- this.removeChangeFromChangeSet("changes", changeTree);
60
- if (changeTree.filteredChanges) {
61
- this.removeChangeFromChangeSet("allFilteredChanges", changeTree);
62
- this.removeChangeFromChangeSet("filteredChanges", changeTree);
63
- }
64
- this.refCount[refId] = 0;
65
- changeTree.forEachChild((child, _) => {
66
- if (child.removeParent(changeTree.ref)) {
67
- if ((child.parentChain === undefined || // no parent, remove it
68
- (child.parentChain && this.refCount[child.ref[$refId]] > 0) // parent is still in use, but has more than one reference, remove it
69
- )) {
70
- this.remove(child);
71
- }
72
- else if (child.parentChain) {
73
- // re-assigning a child of the same root, move it next to parent
74
- this.moveNextToParent(child);
75
- }
76
- }
77
- });
78
- }
79
- else {
80
- this.refCount[refId] = refCount;
81
- //
82
- // When losing a reference to an instance, it is best to move the
83
- // ChangeTree next to its parent in the encoding queue.
84
- //
85
- // This way, at decoding time, the instance that contains the
86
- // ChangeTree will be available before the ChangeTree itself. If the
87
- // containing instance is not available, the Decoder will throw
88
- // "refId not found" error.
89
- //
90
- this.recursivelyMoveNextToParent(changeTree);
91
- }
92
- return refCount;
93
- }
94
- recursivelyMoveNextToParent(changeTree) {
95
- this.moveNextToParent(changeTree);
96
- changeTree.forEachChild((child, _) => this.recursivelyMoveNextToParent(child));
97
- }
98
- moveNextToParent(changeTree) {
99
- if (changeTree.filteredChanges) {
100
- this.moveNextToParentInChangeTreeList("filteredChanges", changeTree);
101
- this.moveNextToParentInChangeTreeList("allFilteredChanges", changeTree);
102
- }
103
- else {
104
- this.moveNextToParentInChangeTreeList("changes", changeTree);
105
- this.moveNextToParentInChangeTreeList("allChanges", changeTree);
106
- }
107
- }
108
- moveNextToParentInChangeTreeList(changeSetName, changeTree) {
109
- const changeSet = this[changeSetName];
110
- const node = changeTree[changeSetName].queueRootNode;
111
- if (!node)
112
- return;
113
- // Find the parent in the linked list
114
- const parent = changeTree.parent;
115
- if (!parent || !parent[$changes])
116
- return;
117
- const parentNode = parent[$changes][changeSetName]?.queueRootNode;
118
- if (!parentNode || parentNode === node)
119
- return;
120
- // Use cached positions - no iteration needed!
121
- const parentPosition = parentNode.position;
122
- const childPosition = node.position;
123
- // If child is already after parent, no need to move
124
- if (childPosition > parentPosition)
125
- return;
126
- // Child is before parent, so we need to move it after parent
127
- // This maintains decoding order (parent before child)
128
- // Remove node from current position
129
- if (node.prev) {
130
- node.prev.next = node.next;
131
- }
132
- else {
133
- changeSet.next = node.next;
134
- }
135
- if (node.next) {
136
- node.next.prev = node.prev;
137
- }
138
- else {
139
- changeSet.tail = node.prev;
140
- }
141
- // Insert node right after parent
142
- node.prev = parentNode;
143
- node.next = parentNode.next;
144
- if (parentNode.next) {
145
- parentNode.next.prev = node;
146
- }
147
- else {
148
- changeSet.tail = node;
149
- }
150
- parentNode.next = node;
151
- // Update positions after the move
152
- this.updatePositionsAfterMove(changeSet, node, parentPosition + 1);
153
- }
154
- enqueueChangeTree(changeTree, changeSet, queueRootNode = changeTree[changeSet].queueRootNode) {
155
- // skip
156
- if (queueRootNode) {
157
- return;
158
- }
159
- // Add to linked list if not already present
160
- changeTree[changeSet].queueRootNode = this.addToChangeTreeList(this[changeSet], changeTree);
161
- }
162
- addToChangeTreeList(list, changeTree) {
163
- const node = {
164
- changeTree,
165
- next: undefined,
166
- prev: undefined,
167
- position: list.tail ? list.tail.position + 1 : 0
168
- };
169
- if (!list.next) {
170
- list.next = node;
171
- list.tail = node;
172
- }
173
- else {
174
- node.prev = list.tail;
175
- list.tail.next = node;
176
- list.tail = node;
177
- }
178
- return node;
179
- }
180
- updatePositionsAfterRemoval(list, removedPosition) {
181
- // Update positions for all nodes after the removed position
182
- let current = list.next;
183
- let position = 0;
184
- while (current) {
185
- if (position >= removedPosition) {
186
- current.position = position;
187
- }
188
- current = current.next;
189
- position++;
190
- }
191
- }
192
- updatePositionsAfterMove(list, node, newPosition) {
193
- // Recalculate all positions - this is more reliable than trying to be clever
194
- let current = list.next;
195
- let position = 0;
196
- while (current) {
197
- current.position = position;
198
- current = current.next;
199
- position++;
200
- }
201
- }
202
- removeChangeFromChangeSet(changeSetName, changeTree) {
203
- const changeSet = this[changeSetName];
204
- const node = changeTree[changeSetName].queueRootNode;
205
- if (node && node.changeTree === changeTree) {
206
- const removedPosition = node.position;
207
- // Remove the node from the linked list
208
- if (node.prev) {
209
- node.prev.next = node.next;
210
- }
211
- else {
212
- changeSet.next = node.next;
213
- }
214
- if (node.next) {
215
- node.next.prev = node.prev;
216
- }
217
- else {
218
- changeSet.tail = node.prev;
219
- }
220
- // Update positions for nodes that came after the removed node
221
- this.updatePositionsAfterRemoval(changeSet, removedPosition);
222
- // Clear ChangeTree reference
223
- changeTree[changeSetName].queueRootNode = undefined;
224
- return true;
225
- }
226
- return false;
227
- }
228
- }
229
- //# sourceMappingURL=Root.js.map