murow 0.0.60 → 0.0.71

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 (425) hide show
  1. package/README.md +52 -37
  2. package/dist/cjs/core/binary-codec/binary-codec.js +1 -0
  3. package/dist/cjs/core/binary-codec/index.js +1 -0
  4. package/dist/cjs/core/driver/driver.js +1 -0
  5. package/dist/cjs/core/driver/drivers/immediate.js +1 -0
  6. package/dist/cjs/core/driver/drivers/index.js +1 -0
  7. package/dist/cjs/core/driver/drivers/raf.js +1 -0
  8. package/dist/cjs/core/driver/drivers/timeout.js +1 -0
  9. package/dist/cjs/core/driver/index.js +1 -0
  10. package/dist/cjs/core/events/event-system.js +1 -0
  11. package/dist/cjs/core/events/index.js +1 -0
  12. package/dist/cjs/core/fixed-ticker/fixed-ticker.js +1 -0
  13. package/dist/cjs/core/fixed-ticker/index.js +1 -0
  14. package/dist/cjs/core/free-list/free-list.js +1 -0
  15. package/dist/cjs/core/free-list/index.js +1 -0
  16. package/dist/cjs/core/generate-id/generate-id.js +1 -0
  17. package/dist/cjs/core/generate-id/index.js +1 -0
  18. package/dist/cjs/core/index.js +1 -0
  19. package/dist/cjs/core/input/index.js +1 -0
  20. package/dist/cjs/core/input/manager.js +1 -0
  21. package/dist/cjs/core/input/sources/browser.js +1 -0
  22. package/dist/cjs/core/input/sources/index.js +1 -0
  23. package/dist/cjs/core/input/types.js +1 -0
  24. package/dist/cjs/core/lerp/index.js +1 -0
  25. package/dist/cjs/core/lerp/lerp.js +1 -0
  26. package/dist/cjs/core/navmesh/index.js +1 -0
  27. package/dist/cjs/core/navmesh/navmesh-worker-pool.js +1 -0
  28. package/dist/cjs/core/navmesh/navmesh.js +1 -0
  29. package/dist/cjs/core/navmesh/navmesh.worker.js +1 -0
  30. package/dist/cjs/core/pooled-codec/index.js +1 -0
  31. package/dist/cjs/core/pooled-codec/pooled-codec.js +1 -0
  32. package/dist/cjs/core/prediction/index.js +1 -0
  33. package/dist/cjs/core/prediction/prediction.js +1 -0
  34. package/dist/cjs/core/ray/index.js +1 -0
  35. package/dist/cjs/core/ray/ray-2d.js +1 -0
  36. package/dist/cjs/core/ray/ray-3d.js +1 -0
  37. package/dist/cjs/core/simple-rng/index.js +1 -0
  38. package/dist/cjs/core/simple-rng/simple-rng.js +1 -0
  39. package/dist/cjs/core/sparse-batcher/index.js +1 -0
  40. package/dist/cjs/core/sparse-batcher/sparse-batcher.js +1 -0
  41. package/dist/cjs/ecs/component-store.js +1 -0
  42. package/dist/cjs/ecs/component.js +1 -0
  43. package/dist/cjs/ecs/entity-handle.js +1 -0
  44. package/dist/cjs/ecs/index.js +1 -0
  45. package/dist/cjs/ecs/system-builder.js +1 -0
  46. package/dist/cjs/ecs/world-systems.js +1 -0
  47. package/dist/cjs/ecs/world.js +1 -0
  48. package/dist/cjs/game/index.js +1 -0
  49. package/dist/cjs/game/loop/index.js +1 -0
  50. package/dist/cjs/game/loop/loop.js +1 -0
  51. package/dist/cjs/index.js +1 -0
  52. package/dist/cjs/net/adapters/browser-websocket.js +1 -0
  53. package/dist/cjs/net/adapters/bun-websocket.js +1 -0
  54. package/dist/cjs/net/buffer-pool.js +1 -0
  55. package/dist/cjs/net/client.js +1 -0
  56. package/dist/cjs/net/index.js +1 -0
  57. package/dist/cjs/net/server.js +1 -0
  58. package/dist/cjs/net/types.js +1 -0
  59. package/dist/cjs/net/validators.js +1 -0
  60. package/dist/cjs/protocol/index.js +1 -0
  61. package/dist/cjs/protocol/intent/define-intent.js +1 -0
  62. package/dist/cjs/protocol/intent/index.js +1 -0
  63. package/dist/cjs/protocol/intent/intent-registry.js +1 -0
  64. package/dist/cjs/protocol/intent/intent.js +1 -0
  65. package/dist/cjs/protocol/rpc/define-rpc.js +1 -0
  66. package/dist/cjs/protocol/rpc/index.js +1 -0
  67. package/dist/cjs/protocol/rpc/rpc-registry.js +1 -0
  68. package/dist/cjs/protocol/rpc/rpc.js +1 -0
  69. package/dist/cjs/protocol/snapshot/index.js +1 -0
  70. package/dist/cjs/protocol/snapshot/snapshot-codec.js +1 -0
  71. package/dist/cjs/protocol/snapshot/snapshot-registry.js +1 -0
  72. package/dist/cjs/protocol/snapshot/snapshot.js +1 -0
  73. package/dist/cjs/renderer/base-2d-renderer.js +1 -0
  74. package/dist/cjs/renderer/base-3d-renderer.js +1 -0
  75. package/dist/cjs/renderer/base-renderer.js +1 -0
  76. package/dist/cjs/renderer/index.js +1 -0
  77. package/dist/cjs/renderer/types.js +1 -0
  78. package/dist/esm/core/binary-codec/binary-codec.js +1 -0
  79. package/dist/esm/core/binary-codec/index.js +1 -0
  80. package/dist/esm/core/driver/driver.js +1 -0
  81. package/dist/esm/core/driver/drivers/immediate.js +1 -0
  82. package/dist/esm/core/driver/drivers/index.js +1 -0
  83. package/dist/esm/core/driver/drivers/raf.js +1 -0
  84. package/dist/esm/core/driver/drivers/timeout.js +1 -0
  85. package/dist/esm/core/driver/index.js +1 -0
  86. package/dist/esm/core/events/event-system.js +1 -0
  87. package/dist/esm/core/events/index.js +1 -0
  88. package/dist/esm/core/fixed-ticker/fixed-ticker.js +1 -0
  89. package/dist/esm/core/fixed-ticker/index.js +1 -0
  90. package/dist/esm/core/free-list/free-list.js +1 -0
  91. package/dist/esm/core/free-list/index.js +1 -0
  92. package/dist/esm/core/generate-id/generate-id.js +1 -0
  93. package/dist/esm/core/generate-id/index.js +1 -0
  94. package/dist/esm/core/index.js +1 -0
  95. package/dist/esm/core/input/index.js +1 -0
  96. package/dist/esm/core/input/manager.js +1 -0
  97. package/dist/esm/core/input/sources/browser.js +1 -0
  98. package/dist/esm/core/input/sources/index.js +1 -0
  99. package/dist/esm/core/input/types.js +0 -0
  100. package/dist/esm/core/lerp/index.js +1 -0
  101. package/dist/esm/core/lerp/lerp.js +1 -0
  102. package/dist/esm/core/navmesh/index.js +1 -0
  103. package/dist/esm/core/navmesh/navmesh-worker-pool.js +1 -0
  104. package/dist/esm/core/navmesh/navmesh.js +1 -0
  105. package/dist/esm/core/navmesh/navmesh.worker.js +1 -0
  106. package/dist/esm/core/pooled-codec/index.js +1 -0
  107. package/dist/esm/core/pooled-codec/pooled-codec.js +1 -0
  108. package/dist/esm/core/prediction/index.js +1 -0
  109. package/dist/esm/core/prediction/prediction.js +1 -0
  110. package/dist/esm/core/ray/index.js +1 -0
  111. package/dist/esm/core/ray/ray-2d.js +1 -0
  112. package/dist/esm/core/ray/ray-3d.js +1 -0
  113. package/dist/esm/core/simple-rng/index.js +1 -0
  114. package/dist/esm/core/simple-rng/simple-rng.js +1 -0
  115. package/dist/esm/core/sparse-batcher/index.js +1 -0
  116. package/dist/esm/core/sparse-batcher/sparse-batcher.js +1 -0
  117. package/dist/esm/ecs/component-store.js +1 -0
  118. package/dist/esm/ecs/component.js +1 -0
  119. package/dist/esm/ecs/entity-handle.js +1 -0
  120. package/dist/esm/ecs/index.js +1 -0
  121. package/dist/esm/ecs/system-builder.js +1 -0
  122. package/dist/esm/ecs/world-systems.js +1 -0
  123. package/dist/esm/ecs/world.js +1 -0
  124. package/dist/esm/game/index.js +1 -0
  125. package/dist/esm/game/loop/index.js +1 -0
  126. package/dist/esm/game/loop/loop.js +1 -0
  127. package/dist/esm/index.js +1 -0
  128. package/dist/esm/net/adapters/browser-websocket.js +1 -0
  129. package/dist/esm/net/adapters/bun-websocket.js +1 -0
  130. package/dist/esm/net/buffer-pool.js +1 -0
  131. package/dist/esm/net/client.js +1 -0
  132. package/dist/esm/net/index.js +1 -0
  133. package/dist/esm/net/server.js +1 -0
  134. package/dist/esm/net/types.js +1 -0
  135. package/dist/esm/net/validators.js +1 -0
  136. package/dist/esm/protocol/index.js +1 -0
  137. package/dist/esm/protocol/intent/define-intent.js +1 -0
  138. package/dist/esm/protocol/intent/index.js +1 -0
  139. package/dist/esm/protocol/intent/intent-registry.js +1 -0
  140. package/dist/esm/protocol/intent/intent.js +0 -0
  141. package/dist/esm/protocol/rpc/define-rpc.js +1 -0
  142. package/dist/esm/protocol/rpc/index.js +1 -0
  143. package/dist/esm/protocol/rpc/rpc-registry.js +1 -0
  144. package/dist/esm/protocol/rpc/rpc.js +0 -0
  145. package/dist/esm/protocol/snapshot/index.js +1 -0
  146. package/dist/esm/protocol/snapshot/snapshot-codec.js +1 -0
  147. package/dist/esm/protocol/snapshot/snapshot-registry.js +1 -0
  148. package/dist/esm/protocol/snapshot/snapshot.js +1 -0
  149. package/dist/esm/renderer/base-2d-renderer.js +1 -0
  150. package/dist/esm/renderer/base-3d-renderer.js +1 -0
  151. package/dist/esm/renderer/base-renderer.js +1 -0
  152. package/dist/esm/renderer/index.js +1 -0
  153. package/dist/esm/renderer/types.js +0 -0
  154. package/dist/{core → types/core}/binary-codec/binary-codec.d.ts +4 -0
  155. package/dist/{core/loop → types/core/driver}/drivers/immediate.d.ts +1 -1
  156. package/dist/{core/loop → types/core/driver}/drivers/raf.d.ts +1 -1
  157. package/dist/{core/loop → types/core/driver}/drivers/timeout.d.ts +1 -1
  158. package/dist/{core/loop → types/core/driver}/index.d.ts +1 -1
  159. package/dist/{core → types/core}/events/event-system.d.ts +14 -33
  160. package/dist/{core → types/core}/fixed-ticker/fixed-ticker.d.ts +1 -1
  161. package/dist/types/core/free-list/free-list.d.ts +31 -0
  162. package/dist/types/core/free-list/index.d.ts +1 -0
  163. package/dist/{core → types/core}/index.d.ts +7 -1
  164. package/dist/types/core/input/index.d.ts +3 -0
  165. package/dist/types/core/input/manager.d.ts +56 -0
  166. package/dist/types/core/input/sources/browser.d.ts +9 -0
  167. package/dist/types/core/input/sources/index.d.ts +1 -0
  168. package/dist/types/core/input/types.d.ts +36 -0
  169. package/dist/{core → types/core}/navmesh/navmesh.d.ts +1 -21
  170. package/dist/types/core/ray/index.d.ts +2 -0
  171. package/dist/types/core/ray/ray-2d.d.ts +37 -0
  172. package/dist/types/core/ray/ray-3d.d.ts +42 -0
  173. package/dist/types/core/simple-rng/index.d.ts +1 -0
  174. package/dist/types/core/simple-rng/simple-rng.d.ts +36 -0
  175. package/dist/types/core/sparse-batcher/index.d.ts +1 -0
  176. package/dist/types/core/sparse-batcher/sparse-batcher.d.ts +55 -0
  177. package/dist/{ecs → types/ecs}/system-builder.d.ts +20 -9
  178. package/dist/{ecs → types/ecs}/world.d.ts +11 -0
  179. package/dist/types/game/index.d.ts +1 -0
  180. package/dist/types/game/loop/index.d.ts +1 -0
  181. package/dist/types/game/loop/loop.d.ts +175 -0
  182. package/dist/{index.d.ts → types/index.d.ts} +2 -0
  183. package/dist/{net → types/net}/index.d.ts +2 -2
  184. package/dist/{net → types/net}/server.d.ts +39 -19
  185. package/dist/{protocol → types/protocol}/intent/define-intent.d.ts +15 -0
  186. package/dist/{protocol → types/protocol}/intent/index.d.ts +1 -1
  187. package/dist/types/renderer/base-2d-renderer.d.ts +13 -0
  188. package/dist/types/renderer/base-3d-renderer.d.ts +10 -0
  189. package/dist/types/renderer/base-renderer.d.ts +21 -0
  190. package/dist/types/renderer/index.d.ts +4 -0
  191. package/dist/types/renderer/types.d.ts +79 -0
  192. package/dist/webgpu/cjs/index.js +6004 -0
  193. package/dist/webgpu/esm/index.js +5972 -0
  194. package/dist/webgpu/types/2d/animation.d.ts +97 -0
  195. package/dist/webgpu/types/2d/renderer.d.ts +55 -0
  196. package/dist/webgpu/types/2d/shader.d.ts +61 -0
  197. package/dist/webgpu/types/2d/sprite-accessor.d.ts +47 -0
  198. package/dist/webgpu/types/2d/sprite-accessor.test.d.ts +1 -0
  199. package/dist/webgpu/types/3d/gltf-skin-parser.d.ts +101 -0
  200. package/dist/webgpu/types/3d/morph-animation.d.ts +69 -0
  201. package/dist/webgpu/types/3d/morph-animation.test.d.ts +1 -0
  202. package/dist/webgpu/types/3d/renderer.d.ts +216 -0
  203. package/dist/webgpu/types/3d/shader.d.ts +136 -0
  204. package/dist/webgpu/types/3d/skeletal-animation-compute/index.d.ts +2 -0
  205. package/dist/webgpu/types/3d/skeletal-animation-compute/kernel.d.ts +8 -0
  206. package/dist/webgpu/types/3d/skeletal-animation-compute/packer.d.ts +32 -0
  207. package/dist/webgpu/types/3d/skeletal-animation.d.ts +90 -0
  208. package/dist/webgpu/types/camera/camera-2d.d.ts +53 -0
  209. package/dist/webgpu/types/camera/camera-2d.test.d.ts +1 -0
  210. package/dist/webgpu/types/camera/camera-3d.d.ts +81 -0
  211. package/dist/webgpu/types/camera/camera-3d.test.d.ts +1 -0
  212. package/dist/webgpu/types/camera/index.d.ts +2 -0
  213. package/dist/webgpu/types/compute/compute-builder.d.ts +123 -0
  214. package/dist/webgpu/types/compute/compute-builder.test.d.ts +1 -0
  215. package/dist/webgpu/types/core/constants.d.ts +59 -0
  216. package/dist/webgpu/types/core/constants.test.d.ts +1 -0
  217. package/dist/webgpu/types/core/index.d.ts +2 -0
  218. package/dist/webgpu/types/core/math.d.ts +37 -0
  219. package/dist/webgpu/types/core/types.d.ts +125 -0
  220. package/dist/webgpu/types/core/types.test.d.ts +1 -0
  221. package/dist/webgpu/types/geometry/built-in.d.ts +58 -0
  222. package/dist/webgpu/types/geometry/built-in.test.d.ts +1 -0
  223. package/dist/webgpu/types/geometry/geometry-builder.d.ts +281 -0
  224. package/dist/webgpu/types/geometry/geometry-builder.test.d.ts +1 -0
  225. package/dist/webgpu/types/geometry/index.d.ts +2 -0
  226. package/dist/webgpu/types/index.d.ts +32 -0
  227. package/dist/webgpu/types/particle/emitter.d.ts +36 -0
  228. package/dist/webgpu/types/shaders/index.d.ts +2 -0
  229. package/dist/webgpu/types/shaders/runtime-transpile.d.ts +18 -0
  230. package/dist/webgpu/types/shaders/sprite-2d.wgsl.d.ts +10 -0
  231. package/dist/webgpu/types/shaders/typegpu.d.ts +9 -0
  232. package/dist/webgpu/types/shaders/utils.d.ts +28 -0
  233. package/dist/webgpu/types/shaders/utils.test.d.ts +1 -0
  234. package/dist/webgpu/types/spritesheet/index.d.ts +1 -0
  235. package/dist/webgpu/types/spritesheet/spritesheet.d.ts +57 -0
  236. package/dist/webgpu/types/spritesheet/spritesheet.test.d.ts +1 -0
  237. package/package.json +96 -26
  238. package/dist/core/binary-codec/binary-codec.js +0 -354
  239. package/dist/core/binary-codec/index.js +0 -1
  240. package/dist/core/events/event-system.js +0 -88
  241. package/dist/core/events/index.js +0 -1
  242. package/dist/core/fixed-ticker/fixed-ticker.js +0 -101
  243. package/dist/core/fixed-ticker/index.js +0 -1
  244. package/dist/core/generate-id/generate-id.js +0 -25
  245. package/dist/core/generate-id/index.js +0 -1
  246. package/dist/core/index.js +0 -9
  247. package/dist/core/lerp/index.js +0 -1
  248. package/dist/core/lerp/lerp.js +0 -42
  249. package/dist/core/loop/drivers/immediate.js +0 -61
  250. package/dist/core/loop/drivers/index.js +0 -3
  251. package/dist/core/loop/drivers/raf.js +0 -62
  252. package/dist/core/loop/drivers/timeout.js +0 -71
  253. package/dist/core/loop/index.js +0 -2
  254. package/dist/core/loop/loop.js +0 -47
  255. package/dist/core/navmesh/index.js +0 -1
  256. package/dist/core/navmesh/navmesh-worker-pool.js +0 -180
  257. package/dist/core/navmesh/navmesh.js +0 -799
  258. package/dist/core/navmesh/navmesh.worker.js +0 -79
  259. package/dist/core/pooled-codec/index.js +0 -1
  260. package/dist/core/pooled-codec/pooled-codec.js +0 -410
  261. package/dist/core/prediction/index.js +0 -1
  262. package/dist/core/prediction/prediction.js +0 -99
  263. package/dist/core.esm.js +0 -1
  264. package/dist/core.js +0 -1
  265. package/dist/ecs/component-store.js +0 -175
  266. package/dist/ecs/component.js +0 -43
  267. package/dist/ecs/entity-handle.js +0 -515
  268. package/dist/ecs/example.js +0 -125
  269. package/dist/ecs/index.js +0 -4
  270. package/dist/ecs/system-builder.js +0 -180
  271. package/dist/ecs/system.d.ts +0 -63
  272. package/dist/ecs/system.js +0 -92
  273. package/dist/ecs/world-systems.js +0 -79
  274. package/dist/ecs/world.js +0 -684
  275. package/dist/index.js +0 -24
  276. package/dist/net/adapters/browser-websocket.js +0 -74
  277. package/dist/net/adapters/bun-websocket.js +0 -245
  278. package/dist/net/buffer-pool.js +0 -89
  279. package/dist/net/client.js +0 -586
  280. package/dist/net/index.js +0 -58
  281. package/dist/net/server.js +0 -938
  282. package/dist/net/types.js +0 -31
  283. package/dist/net/validators.js +0 -88
  284. package/dist/protocol/index.js +0 -92
  285. package/dist/protocol/intent/define-intent.js +0 -125
  286. package/dist/protocol/intent/index.js +0 -91
  287. package/dist/protocol/intent/intent-registry.js +0 -91
  288. package/dist/protocol/rpc/define-rpc.js +0 -84
  289. package/dist/protocol/rpc/index.js +0 -3
  290. package/dist/protocol/rpc/rpc-registry.js +0 -159
  291. package/dist/protocol/rpc/rpc.js +0 -12
  292. package/dist/protocol/snapshot/index.js +0 -43
  293. package/dist/protocol/snapshot/snapshot-codec.js +0 -67
  294. package/dist/protocol/snapshot/snapshot-registry.js +0 -168
  295. package/dist/protocol/snapshot/snapshot.js +0 -30
  296. package/src/core/binary-codec/README.md +0 -60
  297. package/src/core/binary-codec/binary-codec.test.ts +0 -300
  298. package/src/core/binary-codec/binary-codec.ts +0 -448
  299. package/src/core/binary-codec/index.ts +0 -1
  300. package/src/core/events/README.md +0 -47
  301. package/src/core/events/event-system.test.ts +0 -243
  302. package/src/core/events/event-system.ts +0 -140
  303. package/src/core/events/index.ts +0 -1
  304. package/src/core/fixed-ticker/README.md +0 -77
  305. package/src/core/fixed-ticker/fixed-ticker.test.ts +0 -151
  306. package/src/core/fixed-ticker/fixed-ticker.ts +0 -169
  307. package/src/core/fixed-ticker/index.ts +0 -1
  308. package/src/core/generate-id/README.md +0 -18
  309. package/src/core/generate-id/generate-id.test.ts +0 -79
  310. package/src/core/generate-id/generate-id.ts +0 -37
  311. package/src/core/generate-id/index.ts +0 -1
  312. package/src/core/index.ts +0 -9
  313. package/src/core/lerp/README.md +0 -79
  314. package/src/core/lerp/index.ts +0 -1
  315. package/src/core/lerp/lerp.test.ts +0 -90
  316. package/src/core/lerp/lerp.ts +0 -42
  317. package/src/core/loop/README.md +0 -97
  318. package/src/core/loop/drivers/immediate.ts +0 -66
  319. package/src/core/loop/drivers/index.ts +0 -3
  320. package/src/core/loop/drivers/raf.ts +0 -67
  321. package/src/core/loop/drivers/timeout.ts +0 -77
  322. package/src/core/loop/index.ts +0 -2
  323. package/src/core/loop/loop.test.ts +0 -414
  324. package/src/core/loop/loop.ts +0 -71
  325. package/src/core/navmesh/README.md +0 -164
  326. package/src/core/navmesh/index.ts +0 -1
  327. package/src/core/navmesh/navmesh-worker-pool.ts +0 -236
  328. package/src/core/navmesh/navmesh-workers.test.ts +0 -356
  329. package/src/core/navmesh/navmesh.test.ts +0 -344
  330. package/src/core/navmesh/navmesh.ts +0 -1047
  331. package/src/core/navmesh/navmesh.worker.ts +0 -147
  332. package/src/core/pooled-codec/README.md +0 -70
  333. package/src/core/pooled-codec/index.ts +0 -1
  334. package/src/core/pooled-codec/pooled-codec.test.ts +0 -862
  335. package/src/core/pooled-codec/pooled-codec.ts +0 -504
  336. package/src/core/prediction/README.md +0 -64
  337. package/src/core/prediction/index.ts +0 -1
  338. package/src/core/prediction/prediction.test.ts +0 -423
  339. package/src/core/prediction/prediction.ts +0 -112
  340. package/src/ecs/README.md +0 -427
  341. package/src/ecs/benchmark.test.ts +0 -1645
  342. package/src/ecs/component-store.ts +0 -198
  343. package/src/ecs/component.ts +0 -90
  344. package/src/ecs/entity-handle.test.ts +0 -393
  345. package/src/ecs/entity-handle.ts +0 -563
  346. package/src/ecs/example.ts +0 -152
  347. package/src/ecs/index.ts +0 -4
  348. package/src/ecs/system-builder.ts +0 -309
  349. package/src/ecs/system.ts +0 -111
  350. package/src/ecs/world-systems.ts +0 -83
  351. package/src/ecs/world.test.ts +0 -310
  352. package/src/ecs/world.ts +0 -828
  353. package/src/index.ts +0 -28
  354. package/src/net/README.md +0 -474
  355. package/src/net/adapters/browser-websocket.ts +0 -86
  356. package/src/net/adapters/bun-websocket.ts +0 -292
  357. package/src/net/buffer-pool.ts +0 -106
  358. package/src/net/client.test.ts +0 -807
  359. package/src/net/client.ts +0 -695
  360. package/src/net/index.ts +0 -60
  361. package/src/net/server.test.ts +0 -799
  362. package/src/net/server.ts +0 -1116
  363. package/src/net/types.ts +0 -228
  364. package/src/net/validators.ts +0 -104
  365. package/src/protocol/README.md +0 -469
  366. package/src/protocol/index.ts +0 -93
  367. package/src/protocol/intent/define-intent.test.ts +0 -397
  368. package/src/protocol/intent/define-intent.ts +0 -182
  369. package/src/protocol/intent/index.ts +0 -94
  370. package/src/protocol/intent/intent-registry.test.ts +0 -198
  371. package/src/protocol/intent/intent-registry.ts +0 -112
  372. package/src/protocol/intent/intent.ts +0 -12
  373. package/src/protocol/rpc/define-rpc.test.ts +0 -141
  374. package/src/protocol/rpc/define-rpc.ts +0 -113
  375. package/src/protocol/rpc/index.ts +0 -3
  376. package/src/protocol/rpc/rpc-registry.test.ts +0 -168
  377. package/src/protocol/rpc/rpc-registry.ts +0 -176
  378. package/src/protocol/rpc/rpc.ts +0 -37
  379. package/src/protocol/snapshot/index.ts +0 -45
  380. package/src/protocol/snapshot/snapshot-codec.test.ts +0 -138
  381. package/src/protocol/snapshot/snapshot-codec.ts +0 -87
  382. package/src/protocol/snapshot/snapshot-registry.test.ts +0 -310
  383. package/src/protocol/snapshot/snapshot-registry.ts +0 -201
  384. package/src/protocol/snapshot/snapshot.test.ts +0 -76
  385. package/src/protocol/snapshot/snapshot.ts +0 -41
  386. /package/dist/{core → types/core}/binary-codec/index.d.ts +0 -0
  387. /package/dist/{core/loop/loop.d.ts → types/core/driver/driver.d.ts} +0 -0
  388. /package/dist/{core/loop → types/core/driver}/drivers/index.d.ts +0 -0
  389. /package/dist/{core → types/core}/events/index.d.ts +0 -0
  390. /package/dist/{core → types/core}/fixed-ticker/index.d.ts +0 -0
  391. /package/dist/{core → types/core}/generate-id/generate-id.d.ts +0 -0
  392. /package/dist/{core → types/core}/generate-id/index.d.ts +0 -0
  393. /package/dist/{core → types/core}/lerp/index.d.ts +0 -0
  394. /package/dist/{core → types/core}/lerp/lerp.d.ts +0 -0
  395. /package/dist/{core → types/core}/navmesh/index.d.ts +0 -0
  396. /package/dist/{core → types/core}/navmesh/navmesh-worker-pool.d.ts +0 -0
  397. /package/dist/{core → types/core}/navmesh/navmesh.worker.d.ts +0 -0
  398. /package/dist/{core → types/core}/pooled-codec/index.d.ts +0 -0
  399. /package/dist/{core → types/core}/pooled-codec/pooled-codec.d.ts +0 -0
  400. /package/dist/{core → types/core}/prediction/index.d.ts +0 -0
  401. /package/dist/{core → types/core}/prediction/prediction.d.ts +0 -0
  402. /package/dist/{ecs → types/ecs}/component-store.d.ts +0 -0
  403. /package/dist/{ecs → types/ecs}/component.d.ts +0 -0
  404. /package/dist/{ecs → types/ecs}/entity-handle.d.ts +0 -0
  405. /package/dist/{ecs → types/ecs}/example.d.ts +0 -0
  406. /package/dist/{ecs → types/ecs}/index.d.ts +0 -0
  407. /package/dist/{ecs → types/ecs}/world-systems.d.ts +0 -0
  408. /package/dist/{net → types/net}/adapters/browser-websocket.d.ts +0 -0
  409. /package/dist/{net → types/net}/adapters/bun-websocket.d.ts +0 -0
  410. /package/dist/{net → types/net}/buffer-pool.d.ts +0 -0
  411. /package/dist/{net → types/net}/client.d.ts +0 -0
  412. /package/dist/{net → types/net}/types.d.ts +0 -0
  413. /package/dist/{net → types/net}/validators.d.ts +0 -0
  414. /package/dist/{protocol → types/protocol}/index.d.ts +0 -0
  415. /package/dist/{protocol → types/protocol}/intent/intent-registry.d.ts +0 -0
  416. /package/dist/{protocol → types/protocol}/intent/intent.d.ts +0 -0
  417. /package/dist/{protocol → types/protocol}/rpc/define-rpc.d.ts +0 -0
  418. /package/dist/{protocol → types/protocol}/rpc/index.d.ts +0 -0
  419. /package/dist/{protocol → types/protocol}/rpc/rpc-registry.d.ts +0 -0
  420. /package/dist/{protocol → types/protocol}/rpc/rpc.d.ts +0 -0
  421. /package/dist/{protocol → types/protocol}/snapshot/index.d.ts +0 -0
  422. /package/dist/{protocol → types/protocol}/snapshot/snapshot-codec.d.ts +0 -0
  423. /package/dist/{protocol → types/protocol}/snapshot/snapshot-registry.d.ts +0 -0
  424. /package/dist/{protocol → types/protocol}/snapshot/snapshot.d.ts +0 -0
  425. /package/dist/{protocol/intent/intent.js → webgpu/types/2d/animation.test.d.ts} +0 -0
@@ -1,862 +0,0 @@
1
- import { describe, expect, test } from "bun:test";
2
- import {
3
- ObjectPool,
4
- PooledDecoder,
5
- PooledEncoder,
6
- PooledCodec,
7
- PooledArrayDecoder,
8
- } from "./pooled-codec";
9
- import { BinaryCodec, BinaryPrimitives, Schema } from "../binary-codec";
10
-
11
- describe("ObjectPool", () => {
12
- test("should create new object when pool is empty", () => {
13
- const pool = new ObjectPool(() => ({ value: 0 }));
14
- const obj = pool.acquire();
15
- expect(obj).toEqual({ value: 0 });
16
- });
17
-
18
- test("should reuse released objects", () => {
19
- const pool = new ObjectPool(() => ({ value: 0 }));
20
- const obj1 = pool.acquire();
21
- obj1.value = 42;
22
- pool.release(obj1);
23
-
24
- const obj2 = pool.acquire();
25
- expect(obj2.value).toBe(42);
26
- expect(obj2).toBe(obj1); // Same object reference
27
- });
28
-
29
- test("should handle multiple acquire/release cycles", () => {
30
- const pool = new ObjectPool(() => ({ count: 0 }));
31
-
32
- const obj1 = pool.acquire();
33
- obj1.count = 1;
34
- pool.release(obj1);
35
-
36
- const obj2 = pool.acquire();
37
- obj2.count = 2;
38
- pool.release(obj2);
39
-
40
- const obj3 = pool.acquire();
41
- expect(obj3.count).toBe(2); // Gets the last released object
42
- });
43
-
44
- test("should release multiple objects at once", () => {
45
- const pool = new ObjectPool(() => ({ id: 0 }));
46
-
47
- const objs = [
48
- pool.acquire(),
49
- pool.acquire(),
50
- pool.acquire(),
51
- ];
52
-
53
- objs.forEach((obj, i) => (obj.id = i));
54
- pool.releaseAll(objs);
55
-
56
- const reused1 = pool.acquire();
57
- const reused2 = pool.acquire();
58
- const reused3 = pool.acquire();
59
-
60
- expect([reused1.id, reused2.id, reused3.id].sort()).toEqual([0, 1, 2]);
61
- });
62
- });
63
-
64
- describe("PooledDecoder", () => {
65
- test("should decode data into pooled objects", () => {
66
- const schema: Schema<{ value: number }> = {
67
- value: BinaryPrimitives.f32,
68
- };
69
-
70
- const decoder = new PooledDecoder(schema);
71
-
72
- // Use BinaryCodec to encode the data first
73
- const data = { value: 10.5 };
74
- const buffer = BinaryCodec.encode(schema, data);
75
-
76
- const obj = decoder.decode(buffer);
77
- expect(obj.value).toBeCloseTo(10.5, 5);
78
- });
79
-
80
- test("should reuse released objects", () => {
81
- const schema: Schema<{ value: number }> = {
82
- value: BinaryPrimitives.u32,
83
- };
84
-
85
- const decoder = new PooledDecoder(schema);
86
-
87
- const buffer = new Uint8Array(4);
88
- const view = new DataView(buffer.buffer);
89
- view.setUint32(0, 42, false);
90
-
91
- const obj1 = decoder.decode(buffer);
92
- expect(obj1.value).toBe(42);
93
-
94
- decoder.release(obj1);
95
-
96
- view.setUint32(0, 100, false);
97
- const obj2 = decoder.decode(buffer);
98
- expect(obj2.value).toBe(100);
99
- expect(obj2).toBe(obj1); // Same object reference
100
- });
101
-
102
- test("should decode into existing target object", () => {
103
- const schema: Schema<{ value: number }> = {
104
- value: BinaryPrimitives.u8,
105
- };
106
-
107
- const decoder = new PooledDecoder(schema);
108
-
109
- // Use BinaryCodec to encode the data first
110
- const data = { value: 10 };
111
- const buffer = BinaryCodec.encode(schema, data);
112
- const target = { value: 0 };
113
-
114
- decoder.decodeInto(buffer, target);
115
- expect(target.value).toBe(10);
116
- });
117
- });
118
-
119
- describe("PooledArrayDecoder", () => {
120
- test("should decode multiple buffers into pooled objects", () => {
121
- const schema: Schema<{ id: number }> = {
122
- id: BinaryPrimitives.u32,
123
- };
124
-
125
- const arrayDecoder = new PooledArrayDecoder(schema);
126
-
127
- const buffers = [
128
- new Uint8Array([0, 0, 0, 1]),
129
- new Uint8Array([0, 0, 0, 2]),
130
- new Uint8Array([0, 0, 0, 3]),
131
- ];
132
-
133
- const objs = arrayDecoder.decodeAll(buffers);
134
- expect(objs.length).toBe(3);
135
- expect(objs[0].id).toBe(1);
136
- expect(objs[1].id).toBe(2);
137
- expect(objs[2].id).toBe(3);
138
- });
139
-
140
- test("should release multiple objects", () => {
141
- const schema: Schema<{ value: number }> = {
142
- value: BinaryPrimitives.u8,
143
- };
144
-
145
- const arrayDecoder = new PooledArrayDecoder(schema);
146
-
147
- // Use BinaryCodec to encode the data first
148
- const buffers = [
149
- BinaryCodec.encode(schema, { value: 10 }),
150
- BinaryCodec.encode(schema, { value: 20 }),
151
- BinaryCodec.encode(schema, { value: 30 }),
152
- ];
153
-
154
- const objs = arrayDecoder.decodeAll(buffers);
155
- const objValues = objs.map(o => o.value);
156
- expect(objValues).toEqual([10, 20, 30]);
157
-
158
- arrayDecoder.releaseAll(objs);
159
-
160
- // Decode again and verify objects are reused (checking references)
161
- const newObjs = arrayDecoder.decodeAll(buffers);
162
- // Objects should be reused (same references)
163
- let reuseCount = 0;
164
- for (const newObj of newObjs) {
165
- if (objs.includes(newObj)) reuseCount++;
166
- }
167
- expect(reuseCount).toBeGreaterThan(0);
168
- });
169
- });
170
-
171
- describe("PooledEncoder", () => {
172
- test("should encode objects into pooled buffers", () => {
173
- const schema: Schema<{ x: number; y: number }> = {
174
- x: BinaryPrimitives.f32,
175
- y: BinaryPrimitives.f32,
176
- };
177
-
178
- const encoder = new PooledEncoder(schema);
179
- const data = { x: 5.5, y: 10.5 };
180
-
181
- const buffer = encoder.encode(data);
182
- expect(buffer.length).toBe(8);
183
-
184
- const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
185
- expect(view.getFloat32(0, false)).toBeCloseTo(5.5, 5);
186
- expect(view.getFloat32(4, false)).toBeCloseTo(10.5, 5);
187
- });
188
-
189
- test("should reuse released buffers", () => {
190
- const schema: Schema<{ value: number }> = {
191
- value: BinaryPrimitives.u32,
192
- };
193
-
194
- const encoder = new PooledEncoder(schema, 16);
195
- const data1 = { value: 42 };
196
-
197
- const buffer1 = encoder.encode(data1);
198
- encoder.release(buffer1);
199
-
200
- const data2 = { value: 100 };
201
- const buffer2 = encoder.encode(data2);
202
-
203
- // Should reuse the same underlying buffer
204
- expect(buffer2.buffer).toBe(buffer1.buffer);
205
- });
206
-
207
- test("should handle custom buffer size", () => {
208
- const schema: Schema<{ id: number }> = {
209
- id: BinaryPrimitives.u8,
210
- };
211
-
212
- const encoder = new PooledEncoder(schema, 64);
213
- const data = { id: 5 };
214
-
215
- const buffer = encoder.encode(data);
216
- expect(buffer.length).toBe(1); // Only actual data
217
- });
218
- });
219
-
220
- describe("PooledCodec", () => {
221
- test("should encode and decode with pooling", () => {
222
- const schema: Schema<{ id: number }> = {
223
- id: BinaryPrimitives.u32,
224
- };
225
-
226
- const codec = new PooledCodec(schema);
227
- const data = { id: 123 };
228
-
229
- const encoded = codec.encode(data);
230
- const decoded = codec.decode(encoded);
231
-
232
- expect(decoded.id).toBe(123);
233
- });
234
-
235
- test("should reuse objects after release", () => {
236
- const schema: Schema<{ value: number }> = {
237
- value: BinaryPrimitives.u32,
238
- };
239
-
240
- const codec = new PooledCodec(schema);
241
-
242
- const encoded1 = codec.encode({ value: 42 });
243
- const decoded1 = codec.decode(encoded1);
244
- expect(decoded1.value).toBe(42);
245
-
246
- codec.release(decoded1);
247
-
248
- const encoded2 = codec.encode({ value: 100 });
249
- const decoded2 = codec.decode(encoded2);
250
- expect(decoded2.value).toBe(100);
251
- expect(decoded2).toBe(decoded1); // Same object
252
- });
253
-
254
- test("should handle multiple encode/decode cycles", () => {
255
- const schema: Schema<{ value: number }> = {
256
- value: BinaryPrimitives.u16,
257
- };
258
-
259
- const codec = new PooledCodec(schema);
260
-
261
- for (let i = 0; i < 100; i++) {
262
- const data = { value: i * 10 };
263
- const encoded = codec.encode(data);
264
- const decoded = codec.decode(encoded);
265
-
266
- expect(decoded.value).toBe(i * 10);
267
-
268
- codec.release(decoded);
269
- }
270
- });
271
-
272
- test("should work with single field schemas", () => {
273
- const schema: Schema<{
274
- id: number;
275
- }> = {
276
- id: BinaryPrimitives.u32,
277
- };
278
-
279
- const codec = new PooledCodec(schema);
280
- const data = {
281
- id: 999,
282
- };
283
-
284
- const encoded = codec.encode(data);
285
- const decoded = codec.decode(encoded);
286
-
287
- expect(decoded.id).toBe(999);
288
- });
289
- });
290
-
291
- describe("PooledCodec - Memory Efficiency", () => {
292
- test("should reduce allocations with pooling", () => {
293
- const schema: Schema<{ value: number }> = {
294
- value: BinaryPrimitives.u32,
295
- };
296
-
297
- const codec = new PooledCodec(schema);
298
- const objects: any[] = [];
299
-
300
- const times = 10000;
301
-
302
- // Encode and decode {times} times
303
- for (let i = 0; i < times; i++) {
304
- const encoded = codec.encode({ value: i });
305
- const decoded = codec.decode(encoded);
306
- objects.push(decoded);
307
- }
308
-
309
- // Release all
310
- objects.forEach((obj) => codec.release(obj));
311
-
312
- // Decode again - should reuse objects
313
- const newObjects: any[] = [];
314
- for (let i = 0; i < times; i++) {
315
- const encoded = codec.encode({ value: i });
316
- const decoded = codec.decode(encoded);
317
- newObjects.push(decoded);
318
- }
319
-
320
- // At least some objects should be reused
321
- let reusedCount = 0;
322
- for (const newObj of newObjects) {
323
- if (objects.includes(newObj)) {
324
- reusedCount++;
325
- }
326
- }
327
-
328
- expect(reusedCount).toBeGreaterThan(0);
329
- });
330
-
331
- test("should handle concurrent encode/decode without release", () => {
332
- const schema: Schema<{ id: number }> = {
333
- id: BinaryPrimitives.u16,
334
- };
335
-
336
- const codec = new PooledCodec(schema);
337
- const objects: any[] = [];
338
-
339
- // Create many objects without releasing
340
- for (let i = 0; i < 50; i++) {
341
- const encoded = codec.encode({ id: i });
342
- const decoded = codec.decode(encoded);
343
- objects.push(decoded);
344
- }
345
-
346
- expect(objects.length).toBe(50);
347
- objects.forEach((obj, i) => expect(obj.id).toBe(i));
348
- });
349
- });
350
-
351
- describe("PooledCodec.array", () => {
352
- test("should encode and decode arrays of objects", () => {
353
- const PlayerSchema = {
354
- entityId: BinaryPrimitives.u32,
355
- x: BinaryPrimitives.f32,
356
- y: BinaryPrimitives.f32,
357
- } satisfies Schema<{ entityId: number; x: number; y: number }>;
358
-
359
- const UpdateSchema = {
360
- tick: BinaryPrimitives.u32,
361
- players: PooledCodec.array(PlayerSchema),
362
- };
363
-
364
- const codec = new PooledCodec(UpdateSchema);
365
-
366
- // Encode
367
- const buffer = codec.encode({
368
- tick: 42,
369
- players: [
370
- { entityId: 1, x: 10.5, y: 20.5 },
371
- { entityId: 2, x: 30.5, y: 40.5 },
372
- ],
373
- });
374
-
375
- // Decode
376
- const snapshot = codec.decode(buffer);
377
-
378
- expect(snapshot.tick).toBe(42);
379
- expect(snapshot.players.length).toBe(2);
380
- expect(snapshot.players[0].entityId).toBe(1);
381
- expect(snapshot.players[0].x).toBeCloseTo(10.5, 5);
382
- expect(snapshot.players[0].y).toBeCloseTo(20.5, 5);
383
- expect(snapshot.players[1].entityId).toBe(2);
384
- expect(snapshot.players[1].x).toBeCloseTo(30.5, 5);
385
- expect(snapshot.players[1].y).toBeCloseTo(40.5, 5);
386
- });
387
-
388
- test("should handle empty arrays", () => {
389
- const ItemSchema = {
390
- id: BinaryPrimitives.u32,
391
- } satisfies Schema<{ id: number }>;
392
-
393
- const UpdateSchema = {
394
- tick: BinaryPrimitives.u16,
395
- items: PooledCodec.array(ItemSchema),
396
- };
397
-
398
- const codec = new PooledCodec(UpdateSchema);
399
-
400
- // Encode with empty array
401
- const buffer = codec.encode({
402
- tick: 100,
403
- items: [],
404
- });
405
-
406
- // Decode
407
- const snapshot = codec.decode(buffer);
408
-
409
- expect(snapshot.tick).toBe(100);
410
- expect(snapshot.items).toEqual([]);
411
- });
412
-
413
- test("should handle arrays with many items", () => {
414
- const PositionSchema = {
415
- x: BinaryPrimitives.f32,
416
- y: BinaryPrimitives.f32,
417
- } satisfies Schema<{ x: number; y: number }>;
418
-
419
- const UpdateSchema = {
420
- positions: PooledCodec.array(PositionSchema),
421
- };
422
-
423
- const codec = new PooledCodec(UpdateSchema);
424
-
425
- // Create 100 positions
426
- const positions = Array.from({ length: 100 }, (_, i) => ({
427
- x: i * 1.5,
428
- y: i * 2.5,
429
- }));
430
-
431
- // Encode
432
- const buffer = codec.encode({ positions });
433
-
434
- // Decode
435
- const snapshot = codec.decode(buffer);
436
-
437
- expect(snapshot.positions.length).toBe(100);
438
- for (let i = 0; i < 100; i++) {
439
- expect(snapshot.positions[i].x).toBeCloseTo(i * 1.5, 5);
440
- expect(snapshot.positions[i].y).toBeCloseTo(i * 2.5, 5);
441
- }
442
- });
443
-
444
- test("should work with multiple array fields", () => {
445
- const PlayerSchema = {
446
- id: BinaryPrimitives.u32,
447
- health: BinaryPrimitives.u8,
448
- } satisfies Schema<{ id: number; health: number }>;
449
-
450
- const EnemySchema = {
451
- id: BinaryPrimitives.u32,
452
- type: BinaryPrimitives.u8,
453
- } satisfies Schema<{ id: number; type: number }>;
454
-
455
- const UpdateSchema = {
456
- tick: BinaryPrimitives.u32,
457
- players: PooledCodec.array(PlayerSchema),
458
- enemies: PooledCodec.array(EnemySchema),
459
- };
460
-
461
- const codec = new PooledCodec(UpdateSchema);
462
-
463
- // Encode
464
- const buffer = codec.encode({
465
- tick: 50,
466
- players: [
467
- { id: 1, health: 100 },
468
- { id: 2, health: 75 },
469
- ],
470
- enemies: [
471
- { id: 10, type: 1 },
472
- { id: 11, type: 2 },
473
- { id: 12, type: 1 },
474
- ],
475
- });
476
-
477
- // Decode
478
- const snapshot = codec.decode(buffer);
479
-
480
- expect(snapshot.tick).toBe(50);
481
- expect(snapshot.players.length).toBe(2);
482
- expect(snapshot.players[0]).toEqual({ id: 1, health: 100 });
483
- expect(snapshot.players[1]).toEqual({ id: 2, health: 75 });
484
- expect(snapshot.enemies.length).toBe(3);
485
- expect(snapshot.enemies[0]).toEqual({ id: 10, type: 1 });
486
- expect(snapshot.enemies[1]).toEqual({ id: 11, type: 2 });
487
- expect(snapshot.enemies[2]).toEqual({ id: 12, type: 1 });
488
- });
489
- });
490
-
491
- describe("PooledCodec - Zero-Copy Encoding", () => {
492
- test("calculateSize should return correct size for simple schema", () => {
493
- const schema = {
494
- id: BinaryPrimitives.u32,
495
- x: BinaryPrimitives.f32,
496
- y: BinaryPrimitives.f32,
497
- };
498
-
499
- const codec = new PooledCodec(schema);
500
- const data = { id: 1, x: 10.5, y: 20.5 };
501
-
502
- const size = codec.calculateSize(data);
503
- expect(size).toBe(4 + 4 + 4); // u32 + f32 + f32 = 12 bytes
504
- });
505
-
506
- test("calculateSize should return correct size for schema with arrays", () => {
507
- const PlayerSchema = {
508
- entityId: BinaryPrimitives.u32,
509
- x: BinaryPrimitives.f32,
510
- y: BinaryPrimitives.f32,
511
- };
512
-
513
- const UpdateSchema = {
514
- tick: BinaryPrimitives.u32,
515
- players: PooledCodec.array(PlayerSchema),
516
- };
517
-
518
- const codec = new PooledCodec(UpdateSchema);
519
- const data = {
520
- tick: 42,
521
- players: [
522
- { entityId: 1, x: 10.5, y: 20.5 },
523
- { entityId: 2, x: 30.5, y: 40.5 },
524
- ],
525
- };
526
-
527
- const size = codec.calculateSize(data);
528
- // tick(4) + array_length(2) + 2 * (entityId(4) + x(4) + y(4))
529
- expect(size).toBe(4 + 2 + 2 * 12); // 30 bytes
530
- });
531
-
532
- test("encodeInto should write directly to buffer without allocations", () => {
533
- const schema = {
534
- id: BinaryPrimitives.u32,
535
- value: BinaryPrimitives.f32,
536
- };
537
-
538
- const codec = new PooledCodec(schema);
539
- const data = { id: 123, value: 45.67 };
540
-
541
- const buffer = new Uint8Array(100);
542
- const bytesWritten = codec.encodeInto(data, buffer, 10);
543
-
544
- expect(bytesWritten).toBe(8); // 4 + 4
545
-
546
- // Verify the data was written at the correct offset (using big-endian like BinaryPrimitives)
547
- const view = new DataView(buffer.buffer, buffer.byteOffset);
548
- expect(view.getUint32(10, false)).toBe(123);
549
- expect(view.getFloat32(14, false)).toBeCloseTo(45.67, 2);
550
- });
551
-
552
- test("encodeInto should produce same result as encode", () => {
553
- const PlayerSchema = {
554
- entityId: BinaryPrimitives.u32,
555
- x: BinaryPrimitives.f32,
556
- y: BinaryPrimitives.f32,
557
- };
558
-
559
- const UpdateSchema = {
560
- tick: BinaryPrimitives.u32,
561
- players: PooledCodec.array(PlayerSchema),
562
- };
563
-
564
- const codec = new PooledCodec(UpdateSchema);
565
- const data = {
566
- tick: 42,
567
- players: [
568
- { entityId: 1, x: 10.5, y: 20.5 },
569
- { entityId: 2, x: 30.5, y: 40.5 },
570
- ],
571
- };
572
-
573
- // Encode using the old method
574
- const encodedOld = codec.encode(data);
575
-
576
- // Encode using encodeInto
577
- const size = codec.calculateSize(data);
578
- const buffer = new Uint8Array(size);
579
- const bytesWritten = codec.encodeInto(data, buffer, 0);
580
-
581
- expect(bytesWritten).toBe(size);
582
- expect(Array.from(buffer)).toEqual(Array.from(encodedOld));
583
- });
584
-
585
- test("encodeInto should work with offset in target buffer", () => {
586
- const schema = {
587
- a: BinaryPrimitives.u16,
588
- b: BinaryPrimitives.u16,
589
- };
590
-
591
- const codec = new PooledCodec(schema);
592
- const data1 = { a: 100, b: 200 };
593
- const data2 = { a: 300, b: 400 };
594
-
595
- const buffer = new Uint8Array(20);
596
-
597
- // Write first object at offset 0
598
- const bytes1 = codec.encodeInto(data1, buffer, 0);
599
- expect(bytes1).toBe(4);
600
-
601
- // Write second object at offset 4
602
- const bytes2 = codec.encodeInto(data2, buffer, 4);
603
- expect(bytes2).toBe(4);
604
-
605
- // Verify both objects are in the buffer (using big-endian)
606
- const view = new DataView(buffer.buffer, buffer.byteOffset);
607
- expect(view.getUint16(0, false)).toBe(100);
608
- expect(view.getUint16(2, false)).toBe(200);
609
- expect(view.getUint16(4, false)).toBe(300);
610
- expect(view.getUint16(6, false)).toBe(400);
611
- });
612
-
613
- test("array field encodeInto should write directly without intermediate allocations", () => {
614
- const PlayerSchema = {
615
- id: BinaryPrimitives.u32,
616
- health: BinaryPrimitives.u8,
617
- };
618
-
619
- const arrayField = PooledCodec.array(PlayerSchema);
620
- const players = [
621
- { id: 1, health: 100 },
622
- { id: 2, health: 75 },
623
- { id: 3, health: 50 },
624
- ];
625
-
626
- const buffer = new Uint8Array(100);
627
- const bytesWritten = arrayField.encodeInto(players, buffer, 5);
628
-
629
- // 2 (length) + 3 * 5 (id:4 + health:1) = 17 bytes
630
- expect(bytesWritten).toBe(17);
631
-
632
- // Verify array length was written
633
- const view = new DataView(buffer.buffer, buffer.byteOffset);
634
- expect(view.getUint16(5, false)).toBe(3);
635
-
636
- // Verify first player (using big-endian)
637
- expect(view.getUint32(7, false)).toBe(1);
638
- expect(view.getUint8(11)).toBe(100);
639
- });
640
-
641
- test("calculateSize and encodeInto should work with multiple arrays", () => {
642
- const PlayerSchema = {
643
- id: BinaryPrimitives.u32,
644
- health: BinaryPrimitives.u8,
645
- };
646
-
647
- const EnemySchema = {
648
- id: BinaryPrimitives.u32,
649
- type: BinaryPrimitives.u8,
650
- };
651
-
652
- const UpdateSchema = {
653
- tick: BinaryPrimitives.u32,
654
- players: PooledCodec.array(PlayerSchema),
655
- enemies: PooledCodec.array(EnemySchema),
656
- };
657
-
658
- const codec = new PooledCodec(UpdateSchema);
659
- const data = {
660
- tick: 100,
661
- players: [
662
- { id: 1, health: 100 },
663
- { id: 2, health: 75 },
664
- ],
665
- enemies: [
666
- { id: 10, type: 1 },
667
- { id: 11, type: 2 },
668
- { id: 12, type: 3 },
669
- ],
670
- };
671
-
672
- const size = codec.calculateSize(data);
673
- // tick(4) + players_len(2) + 2*5 + enemies_len(2) + 3*5 = 4 + 2 + 10 + 2 + 15 = 33
674
- expect(size).toBe(33);
675
-
676
- const buffer = new Uint8Array(size);
677
- const bytesWritten = codec.encodeInto(data, buffer, 0);
678
- expect(bytesWritten).toBe(33);
679
-
680
- // Verify it can be decoded correctly
681
- const decoded = codec.decode(buffer);
682
- expect(decoded.tick).toBe(100);
683
- expect(decoded.players.length).toBe(2);
684
- expect(decoded.enemies.length).toBe(3);
685
- });
686
- });
687
-
688
- /**
689
- * Tests for DataView reuse optimization in PooledCodec.array()
690
- *
691
- * These tests verify that the shared encodeView/decodeView optimization
692
- * is safe under various usage patterns that might seem problematic.
693
- */
694
- describe("PooledCodec.array() - DataView Reuse Safety", () => {
695
- const playerSchema = {
696
- id: BinaryCodec.u32,
697
- health: BinaryCodec.u8,
698
- };
699
- test("same ArrayField instance used in nested schema (sequential)", () => {
700
- // Scenario: Reusing same ArrayField in multiple schema fields
701
- const playerArray = PooledCodec.array(playerSchema);
702
- const teamSchema = {
703
- teamA: playerArray, // Same instance
704
- teamB: playerArray, // Same instance
705
- };
706
- const codec = new PooledCodec(teamSchema);
707
- const data = {
708
- teamA: [
709
- { id: 1, health: 100 },
710
- { id: 2, health: 80 },
711
- ],
712
- teamB: [
713
- { id: 3, health: 90 },
714
- { id: 4, health: 70 },
715
- ],
716
- };
717
- const encoded = codec.encode(data);
718
- const decoded = codec.decode(encoded);
719
- // Verify no corruption
720
- expect(decoded.teamA[0].id).toBe(1);
721
- expect(decoded.teamA[0].health).toBe(100);
722
- expect(decoded.teamA[1].id).toBe(2);
723
- expect(decoded.teamA[1].health).toBe(80);
724
- expect(decoded.teamB[0].id).toBe(3);
725
- expect(decoded.teamB[0].health).toBe(90);
726
- expect(decoded.teamB[1].id).toBe(4);
727
- expect(decoded.teamB[1].health).toBe(70);
728
- });
729
- test("rapid sequential encode/decode (simulates game loop)", () => {
730
- // Scenario: High-frequency encoding like multiplayer snapshots
731
- const playerArray = PooledCodec.array(playerSchema);
732
- const iterations = 1000;
733
- for (let i = 0; i < iterations; i++) {
734
- const data = [
735
- { id: i, health: 100 },
736
- { id: i + 1, health: 80 },
737
- ];
738
- const encoded = playerArray.encode(data);
739
- const decoded = playerArray.decode(encoded);
740
- expect(decoded[0].id).toBe(i);
741
- expect(decoded[0].health).toBe(100);
742
- expect(decoded[1].id).toBe(i + 1);
743
- expect(decoded[1].health).toBe(80);
744
- }
745
- });
746
- test("async encode/decode with Promise.all (no corruption)", async () => {
747
- // Scenario: Multiple async operations using same ArrayField
748
- const playerArray = PooledCodec.array(playerSchema);
749
- async function encodeTask(taskId: number) {
750
- return playerArray.encode([
751
- { id: taskId * 10, health: 100 },
752
- { id: taskId * 10 + 1, health: 80 },
753
- ]);
754
- }
755
- // Run 10 encode operations "concurrently"
756
- const results = await Promise.all([
757
- encodeTask(1),
758
- encodeTask(2),
759
- encodeTask(3),
760
- encodeTask(4),
761
- encodeTask(5),
762
- encodeTask(6),
763
- encodeTask(7),
764
- encodeTask(8),
765
- encodeTask(9),
766
- encodeTask(10),
767
- ]);
768
- // Decode and verify each result
769
- for (let i = 0; i < results.length; i++) {
770
- const decoded = playerArray.decode(results[i]);
771
- const expectedId = (i + 1) * 10;
772
- expect(decoded[0].id).toBe(expectedId);
773
- expect(decoded[0].health).toBe(100);
774
- expect(decoded[1].id).toBe(expectedId + 1);
775
- expect(decoded[1].health).toBe(80);
776
- }
777
- });
778
- test("encode while decode is queued (microtask interleaving)", async () => {
779
- // Scenario: Encode and decode queued as microtasks
780
- const playerArray = PooledCodec.array(playerSchema);
781
- let encoded1: Uint8Array | null = null;
782
- let encoded2: Uint8Array | null = null;
783
- queueMicrotask(() => {
784
- encoded1 = playerArray.encode([{ id: 1, health: 100 }]);
785
- });
786
- queueMicrotask(() => {
787
- encoded2 = playerArray.encode([{ id: 2, health: 200 }]);
788
- });
789
- // Wait for microtasks to complete
790
- await new Promise((resolve) => setTimeout(resolve, 10));
791
- expect(encoded1).not.toBeNull();
792
- expect(encoded2).not.toBeNull();
793
- const decoded1 = playerArray.decode(encoded1!);
794
- const decoded2 = playerArray.decode(encoded2!);
795
- expect(decoded1[0].id).toBe(1);
796
- expect(decoded1[0].health).toBe(100);
797
- expect(decoded2[0].id).toBe(2);
798
- expect(decoded2[0].health).toBe(200);
799
- });
800
- test("buffer pool with different-sized arrays (reuse correctness)", () => {
801
- // Scenario: Encoding arrays of different sizes (buffer pool behavior)
802
- const playerArray = PooledCodec.array(playerSchema);
803
- // Small array
804
- const small = playerArray.encode([{ id: 1, health: 100 }]);
805
- const decodedSmall = playerArray.decode(small);
806
- expect(decodedSmall).toHaveLength(1);
807
- expect(decodedSmall[0].id).toBe(1);
808
- // Large array
809
- const largeData = Array.from({ length: 100 }, (_, i) => ({
810
- id: i,
811
- health: 100,
812
- }));
813
- const large = playerArray.encode(largeData);
814
- const decodedLarge = playerArray.decode(large);
815
- expect(decodedLarge).toHaveLength(100);
816
- expect(decodedLarge[0].id).toBe(0);
817
- expect(decodedLarge[99].id).toBe(99);
818
- // Small again (verifies buffer pool reuse doesn't corrupt)
819
- const small2 = playerArray.encode([{ id: 999, health: 50 }]);
820
- const decodedSmall2 = playerArray.decode(small2);
821
- expect(decodedSmall2).toHaveLength(1);
822
- expect(decodedSmall2[0].id).toBe(999);
823
- expect(decodedSmall2[0].health).toBe(50);
824
- });
825
- test("encodeInto with different buffers (zero-copy safety)", () => {
826
- // Scenario: Using encodeInto with external buffers
827
- const playerArray = PooledCodec.array(playerSchema);
828
- const data = [
829
- { id: 1, health: 100 },
830
- { id: 2, health: 80 },
831
- ];
832
- // Calculate size and allocate buffer
833
- const size = playerArray.calculateSize(data);
834
- const buffer = new Uint8Array(size);
835
- // Encode directly into buffer
836
- const bytesWritten = playerArray.encodeInto(data, buffer, 0);
837
- expect(bytesWritten).toBe(size);
838
- // Decode and verify
839
- const decoded = playerArray.decode(buffer);
840
- expect(decoded[0].id).toBe(1);
841
- expect(decoded[0].health).toBe(100);
842
- expect(decoded[1].id).toBe(2);
843
- expect(decoded[1].health).toBe(80);
844
- });
845
- test("stress test: 10k rapid encode/decode cycles", () => {
846
- // Scenario: Extreme throughput test
847
- const playerArray = PooledCodec.array(playerSchema);
848
- for (let i = 0; i < 10000; i++) {
849
- const data = [
850
- { id: i % 256, health: 100 },
851
- { id: (i + 1) % 256, health: 80 },
852
- ];
853
- const encoded = playerArray.encode(data);
854
- const decoded = playerArray.decode(encoded);
855
- // Spot check every 1000th iteration
856
- if (i % 1000 === 0) {
857
- expect(decoded[0].id).toBe(i % 256);
858
- expect(decoded[0].health).toBe(100);
859
- }
860
- }
861
- });
862
- });