@oasys/oecs 0.3.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (324) hide show
  1. package/CHANGELOG.md +553 -0
  2. package/README.md +207 -267
  3. package/dist/core/ecs/access_check.d.cts +77 -0
  4. package/dist/core/ecs/access_check.d.ts +77 -0
  5. package/dist/core/ecs/access_check.d.ts.map +1 -0
  6. package/dist/core/ecs/archetype.d.cts +486 -0
  7. package/dist/core/ecs/archetype.d.ts +486 -0
  8. package/dist/core/ecs/archetype.d.ts.map +1 -0
  9. package/dist/core/ecs/archetype_graph.d.cts +96 -0
  10. package/dist/core/ecs/archetype_graph.d.ts +96 -0
  11. package/dist/core/ecs/archetype_graph.d.ts.map +1 -0
  12. package/dist/core/ecs/builtin_relations.d.cts +43 -0
  13. package/dist/core/ecs/builtin_relations.d.ts +43 -0
  14. package/dist/core/ecs/builtin_relations.d.ts.map +1 -0
  15. package/dist/core/ecs/command_log.d.cts +116 -0
  16. package/dist/core/ecs/command_log.d.ts +116 -0
  17. package/dist/core/ecs/command_log.d.ts.map +1 -0
  18. package/dist/core/ecs/component.d.cts +176 -0
  19. package/dist/core/ecs/component.d.ts +176 -0
  20. package/dist/core/ecs/component.d.ts.map +1 -0
  21. package/dist/core/ecs/compute_backend.d.cts +37 -0
  22. package/dist/core/ecs/compute_backend.d.ts +37 -0
  23. package/dist/core/ecs/compute_backend.d.ts.map +1 -0
  24. package/dist/core/ecs/debug_names.d.cts +7 -0
  25. package/dist/core/ecs/debug_names.d.ts +7 -0
  26. package/dist/core/ecs/debug_names.d.ts.map +1 -0
  27. package/dist/core/ecs/deferred_commands.d.cts +55 -0
  28. package/dist/core/ecs/deferred_commands.d.ts +55 -0
  29. package/dist/core/ecs/deferred_commands.d.ts.map +1 -0
  30. package/dist/core/ecs/dispatch_trace.d.cts +93 -0
  31. package/dist/core/ecs/dispatch_trace.d.ts +93 -0
  32. package/dist/core/ecs/dispatch_trace.d.ts.map +1 -0
  33. package/dist/core/ecs/ecs.d.cts +562 -0
  34. package/dist/core/ecs/ecs.d.ts +562 -0
  35. package/dist/core/ecs/ecs.d.ts.map +1 -0
  36. package/dist/core/ecs/ecs_memory.d.cts +179 -0
  37. package/dist/core/ecs/ecs_memory.d.ts +179 -0
  38. package/dist/core/ecs/ecs_memory.d.ts.map +1 -0
  39. package/dist/core/ecs/entity.d.cts +34 -0
  40. package/dist/core/ecs/entity.d.ts +34 -0
  41. package/dist/core/ecs/entity.d.ts.map +1 -0
  42. package/dist/core/ecs/entity_allocator.d.cts +59 -0
  43. package/dist/core/ecs/entity_allocator.d.ts +59 -0
  44. package/dist/core/ecs/entity_allocator.d.ts.map +1 -0
  45. package/dist/core/ecs/event.d.cts +79 -0
  46. package/dist/core/ecs/event.d.ts +79 -0
  47. package/dist/core/ecs/event.d.ts.map +1 -0
  48. package/dist/core/ecs/event_registry.d.cts +22 -0
  49. package/dist/core/ecs/event_registry.d.ts +22 -0
  50. package/dist/core/ecs/event_registry.d.ts.map +1 -0
  51. package/dist/core/ecs/facades.d.cts +158 -0
  52. package/dist/core/ecs/facades.d.ts +158 -0
  53. package/dist/core/ecs/facades.d.ts.map +1 -0
  54. package/dist/core/ecs/frame_stepper.d.cts +58 -0
  55. package/dist/core/ecs/frame_stepper.d.ts +58 -0
  56. package/dist/core/ecs/frame_stepper.d.ts.map +1 -0
  57. package/dist/core/ecs/frame_trace.d.cts +133 -0
  58. package/dist/core/ecs/frame_trace.d.ts +133 -0
  59. package/dist/core/ecs/frame_trace.d.ts.map +1 -0
  60. package/dist/core/ecs/host_commands.d.cts +274 -0
  61. package/dist/core/ecs/host_commands.d.ts +274 -0
  62. package/dist/core/ecs/host_commands.d.ts.map +1 -0
  63. package/dist/core/ecs/index.d.cts +46 -0
  64. package/dist/core/ecs/index.d.ts +46 -0
  65. package/dist/core/ecs/index.d.ts.map +1 -0
  66. package/dist/core/ecs/observer.d.cts +173 -0
  67. package/dist/core/ecs/observer.d.ts +173 -0
  68. package/dist/core/ecs/observer.d.ts.map +1 -0
  69. package/dist/core/ecs/query.d.cts +718 -0
  70. package/dist/core/ecs/query.d.ts +718 -0
  71. package/dist/core/ecs/query.d.ts.map +1 -0
  72. package/dist/core/ecs/ref.d.cts +31 -0
  73. package/dist/core/ecs/ref.d.ts +31 -0
  74. package/dist/core/ecs/ref.d.ts.map +1 -0
  75. package/dist/core/ecs/relation.d.cts +243 -0
  76. package/dist/core/ecs/relation.d.ts +243 -0
  77. package/dist/core/ecs/relation.d.ts.map +1 -0
  78. package/dist/core/ecs/relation_service.d.cts +235 -0
  79. package/dist/core/ecs/relation_service.d.ts +235 -0
  80. package/dist/core/ecs/relation_service.d.ts.map +1 -0
  81. package/dist/core/ecs/resource.d.cts +53 -0
  82. package/dist/core/ecs/resource.d.ts +53 -0
  83. package/dist/core/ecs/resource.d.ts.map +1 -0
  84. package/dist/core/ecs/resource_registry.d.cts +20 -0
  85. package/dist/core/ecs/resource_registry.d.ts +20 -0
  86. package/dist/core/ecs/resource_registry.d.ts.map +1 -0
  87. package/dist/core/ecs/resume.d.cts +85 -0
  88. package/dist/core/ecs/resume.d.ts +85 -0
  89. package/dist/core/ecs/resume.d.ts.map +1 -0
  90. package/dist/core/ecs/run_condition.d.cts +81 -0
  91. package/dist/core/ecs/run_condition.d.ts +81 -0
  92. package/dist/core/ecs/run_condition.d.ts.map +1 -0
  93. package/dist/core/ecs/schedule.d.cts +142 -0
  94. package/dist/core/ecs/schedule.d.ts +142 -0
  95. package/dist/core/ecs/schedule.d.ts.map +1 -0
  96. package/dist/core/ecs/snapshot_service.d.cts +94 -0
  97. package/dist/core/ecs/snapshot_service.d.ts +94 -0
  98. package/dist/core/ecs/snapshot_service.d.ts.map +1 -0
  99. package/dist/core/ecs/sparse_store.d.cts +110 -0
  100. package/dist/core/ecs/sparse_store.d.ts +110 -0
  101. package/dist/core/ecs/sparse_store.d.ts.map +1 -0
  102. package/dist/core/ecs/store.d.cts +950 -0
  103. package/dist/core/ecs/store.d.ts +950 -0
  104. package/dist/core/ecs/store.d.ts.map +1 -0
  105. package/dist/core/ecs/store_layout_listener.d.cts +23 -0
  106. package/dist/core/ecs/store_layout_listener.d.ts +23 -0
  107. package/dist/core/ecs/store_layout_listener.d.ts.map +1 -0
  108. package/dist/core/ecs/system.d.cts +250 -0
  109. package/dist/core/ecs/system.d.ts +250 -0
  110. package/dist/core/ecs/system.d.ts.map +1 -0
  111. package/dist/core/ecs/utils/arrays.d.cts +7 -0
  112. package/dist/{utils → core/ecs/utils}/arrays.d.ts +2 -1
  113. package/dist/core/ecs/utils/arrays.d.ts.map +1 -0
  114. package/dist/core/ecs/utils/constants.d.ts +12 -0
  115. package/dist/core/ecs/utils/constants.d.ts.map +1 -0
  116. package/dist/core/ecs/utils/error.d.cts +61 -0
  117. package/dist/core/ecs/utils/error.d.ts +61 -0
  118. package/dist/core/ecs/utils/error.d.ts.map +1 -0
  119. package/dist/core/store/action_ring.d.cts +136 -0
  120. package/dist/core/store/action_ring.d.ts +136 -0
  121. package/dist/core/store/action_ring.d.ts.map +1 -0
  122. package/dist/core/store/allocator.d.cts +238 -0
  123. package/dist/core/store/allocator.d.ts +238 -0
  124. package/dist/core/store/allocator.d.ts.map +1 -0
  125. package/dist/core/store/buffer_backed_column.d.cts +69 -0
  126. package/dist/core/store/buffer_backed_column.d.ts +69 -0
  127. package/dist/core/store/buffer_backed_column.d.ts.map +1 -0
  128. package/dist/core/store/column_store.d.cts +273 -0
  129. package/dist/core/store/column_store.d.ts +273 -0
  130. package/dist/core/store/column_store.d.ts.map +1 -0
  131. package/dist/core/store/command_dispatch.d.cts +52 -0
  132. package/dist/core/store/command_dispatch.d.ts +52 -0
  133. package/dist/core/store/command_dispatch.d.ts.map +1 -0
  134. package/dist/core/store/command_ring.d.cts +107 -0
  135. package/dist/core/store/command_ring.d.ts +107 -0
  136. package/dist/core/store/command_ring.d.ts.map +1 -0
  137. package/dist/core/store/descriptor.d.cts +80 -0
  138. package/dist/core/store/descriptor.d.ts +80 -0
  139. package/dist/core/store/descriptor.d.ts.map +1 -0
  140. package/dist/core/store/entity_index.d.cts +108 -0
  141. package/dist/core/store/entity_index.d.ts +108 -0
  142. package/dist/core/store/entity_index.d.ts.map +1 -0
  143. package/dist/core/store/event_ring.d.cts +95 -0
  144. package/dist/core/store/event_ring.d.ts +95 -0
  145. package/dist/core/store/event_ring.d.ts.map +1 -0
  146. package/dist/core/store/extend.d.cts +39 -0
  147. package/dist/core/store/extend.d.ts +39 -0
  148. package/dist/core/store/extend.d.ts.map +1 -0
  149. package/dist/core/store/grow.d.cts +34 -0
  150. package/dist/core/store/grow.d.ts +34 -0
  151. package/dist/core/store/grow.d.ts.map +1 -0
  152. package/dist/core/store/header.d.cts +64 -0
  153. package/dist/core/store/header.d.ts +64 -0
  154. package/dist/core/store/header.d.ts.map +1 -0
  155. package/dist/core/store/index.d.cts +17 -0
  156. package/dist/core/store/index.d.ts +17 -0
  157. package/dist/core/store/index.d.ts.map +1 -0
  158. package/dist/core/store/layout_ops.d.cts +152 -0
  159. package/dist/core/store/layout_ops.d.ts +152 -0
  160. package/dist/core/store/layout_ops.d.ts.map +1 -0
  161. package/dist/core/store/region_table.d.cts +74 -0
  162. package/dist/core/store/region_table.d.ts +74 -0
  163. package/dist/core/store/region_table.d.ts.map +1 -0
  164. package/dist/core/store/snapshot.d.cts +43 -0
  165. package/dist/core/store/snapshot.d.ts +43 -0
  166. package/dist/core/store/snapshot.d.ts.map +1 -0
  167. package/dist/core/store/state_hash.d.cts +38 -0
  168. package/dist/core/store/state_hash.d.ts +38 -0
  169. package/dist/core/store/state_hash.d.ts.map +1 -0
  170. package/dist/core/store/store_regions.d.cts +38 -0
  171. package/dist/core/store/store_regions.d.ts +38 -0
  172. package/dist/core/store/store_regions.d.ts.map +1 -0
  173. package/dist/core/store/vendored_abi/abi.d.cts +43 -0
  174. package/dist/core/store/vendored_abi/abi.d.ts +43 -0
  175. package/dist/core/store/vendored_abi/abi.d.ts.map +1 -0
  176. package/dist/dev_flag.d.cts +17 -0
  177. package/dist/dev_flag.d.ts +17 -0
  178. package/dist/dev_flag.d.ts.map +1 -0
  179. package/dist/extensions/editor/editor.d.cts +170 -0
  180. package/dist/extensions/editor/editor.d.ts +170 -0
  181. package/dist/extensions/editor/editor.d.ts.map +1 -0
  182. package/dist/extensions/editor/field_handle.d.cts +40 -0
  183. package/dist/extensions/editor/field_handle.d.ts +40 -0
  184. package/dist/extensions/editor/field_handle.d.ts.map +1 -0
  185. package/dist/extensions/editor/index.cjs +1 -0
  186. package/dist/extensions/editor/index.d.cts +21 -0
  187. package/dist/extensions/editor/index.d.ts +21 -0
  188. package/dist/extensions/editor/index.d.ts.map +1 -0
  189. package/dist/extensions/editor/index.js +237 -0
  190. package/dist/extensions/reactive/ecs_sync.d.cts +214 -0
  191. package/dist/extensions/reactive/ecs_sync.d.ts +214 -0
  192. package/dist/extensions/reactive/ecs_sync.d.ts.map +1 -0
  193. package/dist/extensions/reactive/index.cjs +1 -0
  194. package/dist/extensions/reactive/index.d.cts +23 -0
  195. package/dist/extensions/reactive/index.d.ts +23 -0
  196. package/dist/extensions/reactive/index.d.ts.map +1 -0
  197. package/dist/extensions/reactive/index.js +215 -0
  198. package/dist/extensions/solid/index.cjs +1 -0
  199. package/dist/extensions/solid/index.d.cts +6 -0
  200. package/dist/extensions/solid/index.d.ts +6 -0
  201. package/dist/extensions/solid/index.d.ts.map +1 -0
  202. package/dist/extensions/solid/index.js +36 -0
  203. package/dist/extensions/solid/kernel_solid.d.cts +45 -0
  204. package/dist/extensions/solid/kernel_solid.d.ts +45 -0
  205. package/dist/extensions/solid/kernel_solid.d.ts.map +1 -0
  206. package/dist/host_commands-BF8QMi3c.cjs +1 -0
  207. package/dist/host_commands-i4cAeyL5.js +2318 -0
  208. package/dist/index.cjs +1 -1
  209. package/dist/index.d.cts +66 -0
  210. package/dist/index.d.ts +65 -12
  211. package/dist/index.d.ts.map +1 -1
  212. package/dist/index.js +7080 -1289
  213. package/dist/internal.cjs +2 -0
  214. package/dist/internal.d.cts +20 -0
  215. package/dist/internal.d.ts +20 -0
  216. package/dist/internal.d.ts.map +1 -0
  217. package/dist/internal.js +141 -0
  218. package/dist/interop-CT-REx0W.cjs +1 -0
  219. package/dist/interop-CcY6ASQc.js +18 -0
  220. package/dist/kernel-DgyrLFjW.js +227 -0
  221. package/dist/kernel-yWV3XnAb.cjs +1 -0
  222. package/dist/primitives.cjs +1 -0
  223. package/dist/primitives.d.cts +18 -0
  224. package/dist/primitives.d.ts +18 -0
  225. package/dist/primitives.d.ts.map +1 -0
  226. package/dist/primitives.js +45 -0
  227. package/dist/reactive/array.d.cts +24 -0
  228. package/dist/reactive/array.d.ts +24 -0
  229. package/dist/reactive/array.d.ts.map +1 -0
  230. package/dist/reactive/index.cjs +1 -0
  231. package/dist/reactive/index.d.cts +11 -0
  232. package/dist/reactive/index.d.ts +11 -0
  233. package/dist/reactive/index.d.ts.map +1 -0
  234. package/dist/reactive/index.js +18 -0
  235. package/dist/reactive/interop.d.cts +19 -0
  236. package/dist/reactive/interop.d.ts +19 -0
  237. package/dist/reactive/interop.d.ts.map +1 -0
  238. package/dist/reactive/kernel.d.cts +73 -0
  239. package/dist/reactive/kernel.d.ts +73 -0
  240. package/dist/reactive/kernel.d.ts.map +1 -0
  241. package/dist/reactive/map.d.cts +16 -0
  242. package/dist/reactive/map.d.ts +16 -0
  243. package/dist/reactive/map.d.ts.map +1 -0
  244. package/dist/reactive/shallow.d.cts +11 -0
  245. package/dist/reactive/shallow.d.ts +11 -0
  246. package/dist/reactive/shallow.d.ts.map +1 -0
  247. package/dist/reactive/struct.d.cts +10 -0
  248. package/dist/reactive/struct.d.ts +10 -0
  249. package/dist/reactive/struct.d.ts.map +1 -0
  250. package/dist/shallow-DQ8aG51_.cjs +1 -0
  251. package/dist/shallow-DfnAm9vG.js +150 -0
  252. package/dist/shared-BU1Cd40h.js +103 -0
  253. package/dist/shared-BymrGTyR.cjs +1 -0
  254. package/dist/shared.cjs +1 -0
  255. package/dist/shared.d.cts +22 -0
  256. package/dist/shared.d.ts +22 -0
  257. package/dist/shared.d.ts.map +1 -0
  258. package/dist/shared.js +7 -0
  259. package/dist/topological_sort-BDvEyb9W.cjs +1 -0
  260. package/dist/topological_sort-DK6EjpWa.js +135 -0
  261. package/dist/type_primitives/assertions.d.cts +32 -0
  262. package/dist/type_primitives/assertions.d.ts +25 -9
  263. package/dist/type_primitives/assertions.d.ts.map +1 -1
  264. package/dist/type_primitives/binary_heap/binary_heap.d.cts +37 -0
  265. package/dist/type_primitives/binary_heap/binary_heap.d.ts +6 -2
  266. package/dist/type_primitives/binary_heap/binary_heap.d.ts.map +1 -1
  267. package/dist/type_primitives/bitset/bitset.d.cts +54 -0
  268. package/dist/type_primitives/bitset/bitset.d.ts +16 -4
  269. package/dist/type_primitives/bitset/bitset.d.ts.map +1 -1
  270. package/dist/type_primitives/brand.d.cts +23 -0
  271. package/dist/type_primitives/brand.d.ts +6 -1
  272. package/dist/type_primitives/brand.d.ts.map +1 -1
  273. package/dist/type_primitives/error.d.cts +16 -0
  274. package/dist/type_primitives/error.d.ts +8 -3
  275. package/dist/type_primitives/error.d.ts.map +1 -1
  276. package/dist/type_primitives/index.d.cts +13 -0
  277. package/dist/type_primitives/index.d.ts +12 -9
  278. package/dist/type_primitives/index.d.ts.map +1 -1
  279. package/dist/type_primitives/sparse_map/sparse_map.d.cts +30 -0
  280. package/dist/type_primitives/sparse_map/sparse_map.d.ts +7 -3
  281. package/dist/type_primitives/sparse_map/sparse_map.d.ts.map +1 -1
  282. package/dist/type_primitives/sparse_set/sparse_set.d.cts +28 -0
  283. package/dist/type_primitives/sparse_set/sparse_set.d.ts +4 -0
  284. package/dist/type_primitives/sparse_set/sparse_set.d.ts.map +1 -1
  285. package/dist/type_primitives/topological_sort/topological_sort.d.cts +29 -0
  286. package/dist/type_primitives/topological_sort/topological_sort.d.ts +7 -3
  287. package/dist/type_primitives/topological_sort/topological_sort.d.ts.map +1 -1
  288. package/dist/type_primitives/typed_arrays/typed_arrays.d.cts +127 -0
  289. package/dist/type_primitives/typed_arrays/typed_arrays.d.ts +53 -16
  290. package/dist/type_primitives/typed_arrays/typed_arrays.d.ts.map +1 -1
  291. package/dist/typed_arrays-BcXcnzB4.js +258 -0
  292. package/dist/typed_arrays-D3NmwtCG.cjs +1 -0
  293. package/dist/utils/error.d.cts +6 -0
  294. package/dist/utils/error.d.ts +2 -20
  295. package/dist/utils/error.d.ts.map +1 -1
  296. package/dist/version.d.cts +10 -0
  297. package/dist/version.d.ts +10 -0
  298. package/dist/version.d.ts.map +1 -0
  299. package/package.json +115 -5
  300. package/dist/archetype.d.ts +0 -108
  301. package/dist/archetype.d.ts.map +0 -1
  302. package/dist/component.d.ts +0 -45
  303. package/dist/component.d.ts.map +0 -1
  304. package/dist/ecs.d.ts +0 -104
  305. package/dist/ecs.d.ts.map +0 -1
  306. package/dist/entity.d.ts +0 -11
  307. package/dist/entity.d.ts.map +0 -1
  308. package/dist/event.d.ts +0 -30
  309. package/dist/event.d.ts.map +0 -1
  310. package/dist/query.d.ts +0 -94
  311. package/dist/query.d.ts.map +0 -1
  312. package/dist/ref.d.ts +0 -23
  313. package/dist/ref.d.ts.map +0 -1
  314. package/dist/resource.d.ts +0 -23
  315. package/dist/resource.d.ts.map +0 -1
  316. package/dist/schedule.d.ts +0 -45
  317. package/dist/schedule.d.ts.map +0 -1
  318. package/dist/store.d.ts +0 -118
  319. package/dist/store.d.ts.map +0 -1
  320. package/dist/system.d.ts +0 -16
  321. package/dist/system.d.ts.map +0 -1
  322. package/dist/utils/arrays.d.ts.map +0 -1
  323. package/dist/utils/constants.d.ts.map +0 -1
  324. /package/dist/{utils/constants.d.ts → core/ecs/utils/constants.d.cts} +0 -0
@@ -0,0 +1,12 @@
1
+ export declare const UNASSIGNED = -1;
2
+ export declare const NO_SWAP = -1;
3
+ export declare const EMPTY_VALUES: Record<string, number>;
4
+ export declare const HASH_GOLDEN_RATIO = 2654435769;
5
+ export declare const HASH_SECONDARY_PRIME = 1367130551;
6
+ export declare const DEFAULT_COLUMN_CAPACITY = 1024;
7
+ export declare const INITIAL_GENERATION = 0;
8
+ export declare const TOTAL_PACKED_BITS = 31;
9
+ export declare const DEFAULT_FIXED_TIMESTEP: number;
10
+ export declare const DEFAULT_MAX_FIXED_STEPS = 4;
11
+ export declare const STARTUP_DELTA_TIME = 0;
12
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/core/ecs/utils/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,KAAK,CAAC;AAC7B,eAAO,MAAM,OAAO,KAAK,CAAC;AAC1B,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAsC,CAAC;AAGvF,eAAO,MAAM,iBAAiB,aAAa,CAAC;AAC5C,eAAO,MAAM,oBAAoB,aAAa,CAAC;AAG/C,eAAO,MAAM,uBAAuB,OAAO,CAAC;AAG5C,eAAO,MAAM,kBAAkB,IAAI,CAAC;AACpC,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAGpC,eAAO,MAAM,sBAAsB,QAAS,CAAC;AAC7C,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAGzC,eAAO,MAAM,kBAAkB,IAAI,CAAC"}
@@ -0,0 +1,61 @@
1
+ import { AppError } from '../../../utils/error.cjs';
2
+ export declare enum ECS_ERROR {
3
+ EID_MAX_INDEX_OVERFLOW = "EID_MAX_INDEX_OVERFLOW",
4
+ EID_MAX_GEN_OVERFLOW = "EID_MAX_GEN_OVERFLOW",
5
+ COMPONENT_NOT_REGISTERED = "COMPONENT_NOT_REGISTERED",
6
+ COMPONENT_LIMIT_EXCEEDED = "COMPONENT_LIMIT_EXCEEDED",
7
+ ENTITY_NOT_ALIVE = "ENTITY_NOT_ALIVE",
8
+ CIRCULAR_SYSTEM_DEPENDENCY = "CIRCULAR_SYSTEM_DEPENDENCY",
9
+ DUPLICATE_SYSTEM = "DUPLICATE_SYSTEM",
10
+ ARCHETYPE_NOT_FOUND = "ARCHETYPE_NOT_FOUND",
11
+ RESOURCE_NOT_REGISTERED = "RESOURCE_NOT_REGISTERED",
12
+ RESOURCE_ALREADY_REGISTERED = "RESOURCE_ALREADY_REGISTERED",
13
+ EVENT_ALREADY_REGISTERED = "EVENT_ALREADY_REGISTERED",
14
+ EVENT_NOT_REGISTERED = "EVENT_NOT_REGISTERED",
15
+ FIELD_NOT_REGISTERED = "FIELD_NOT_REGISTERED",
16
+ RELATION_NOT_REGISTERED = "RELATION_NOT_REGISTERED",
17
+ RELATION_MODE_INVALID = "RELATION_MODE_INVALID",
18
+ RELATION_MODE_MISMATCH = "RELATION_MODE_MISMATCH",
19
+ RELATION_CYCLE = "RELATION_CYCLE",
20
+ SPARSE_CACHE_KEY_OVERFLOW = "SPARSE_CACHE_KEY_OVERFLOW",
21
+ SPARSE_QUERY_DENSE_PATH = "SPARSE_QUERY_DENSE_PATH",
22
+ HIERARCHY_ALREADY_SET = "HIERARCHY_ALREADY_SET",
23
+ HIERARCHY_INVALID_MAX_DEPTH = "HIERARCHY_INVALID_MAX_DEPTH",
24
+ OBSERVER_NON_CONVERGENT = "OBSERVER_NON_CONVERGENT",
25
+ OBSERVER_INVALID_CONFIG = "OBSERVER_INVALID_CONFIG",
26
+ OBSERVER_ONSET_EMIT = "OBSERVER_ONSET_EMIT",
27
+ INVALID_FIXED_TIMESTEP = "INVALID_FIXED_TIMESTEP",
28
+ INVALID_MAX_FIXED_STEPS = "INVALID_MAX_FIXED_STEPS",
29
+ INVALID_RECORDER_SCHEDULE = "INVALID_RECORDER_SCHEDULE",
30
+ EMPTY_ARCHETYPE_MATERIALIZE = "EMPTY_ARCHETYPE_MATERIALIZE",
31
+ COMPONENT_INDEX_INVARIANT = "COMPONENT_INDEX_INVARIANT",
32
+ OPTIONAL_TERM_NOT_DECLARED = "OPTIONAL_TERM_NOT_DECLARED",
33
+ QUERY_ACCESS_UNDECLARED = "QUERY_ACCESS_UNDECLARED",
34
+ /** A system touched a component/sparse/relation/resource it didn't declare
35
+ * in its access surface — distinct from *_NOT_REGISTERED (which means the
36
+ * thing was never registered with the world at all). */
37
+ ACCESS_UNDECLARED = "ACCESS_UNDECLARED",
38
+ /** `Query.singleEntity` found 0 or >1 matches (dev-only assertion). */
39
+ QUERY_NOT_SINGLETON = "QUERY_NOT_SINGLETON",
40
+ /** A run-condition factory was given invalid arguments (dev-only). */
41
+ INVALID_RUN_CONDITION = "INVALID_RUN_CONDITION",
42
+ SYSTEM_FN_ARITY = "SYSTEM_FN_ARITY",
43
+ PARTITION_APPEND_NEEDS_ENTITY_ROW = "PARTITION_APPEND_NEEDS_ENTITY_ROW",
44
+ PARTITION_BULK_INTO_DISABLED = "PARTITION_BULK_INTO_DISABLED",
45
+ ENTITY_NOT_DISABLED = "ENTITY_NOT_DISABLED",
46
+ STRUCTURAL_DURING_ITERATION = "STRUCTURAL_DURING_ITERATION",
47
+ BACKEND_ALREADY_ATTACHED = "BACKEND_ALREADY_ATTACHED",
48
+ DETERMINISM_DISABLED = "DETERMINISM_DISABLED",
49
+ NON_DETERMINISTIC_COLUMN_TYPE = "NON_DETERMINISTIC_COLUMN_TYPE",
50
+ INVALID_MEMORY_OPTIONS = "INVALID_MEMORY_OPTIONS",
51
+ STORE_CAP_EXCEEDED = "STORE_CAP_EXCEEDED",
52
+ REGION_NOT_DECLARED = "REGION_NOT_DECLARED",
53
+ COMMAND_LOG_TAG_COLLISION = "COMMAND_LOG_TAG_COLLISION",
54
+ INVALID_FRAME_STEP = "INVALID_FRAME_STEP"
55
+ }
56
+ export declare class ECSError extends AppError {
57
+ readonly category: ECS_ERROR;
58
+ constructor(category: ECS_ERROR, message?: string, context?: Record<string, unknown>);
59
+ }
60
+ export declare function isEcsError(error: unknown): error is ECSError;
61
+ //# sourceMappingURL=error.d.ts.map
@@ -0,0 +1,61 @@
1
+ import { AppError } from '../../../utils/error.js';
2
+ export declare enum ECS_ERROR {
3
+ EID_MAX_INDEX_OVERFLOW = "EID_MAX_INDEX_OVERFLOW",
4
+ EID_MAX_GEN_OVERFLOW = "EID_MAX_GEN_OVERFLOW",
5
+ COMPONENT_NOT_REGISTERED = "COMPONENT_NOT_REGISTERED",
6
+ COMPONENT_LIMIT_EXCEEDED = "COMPONENT_LIMIT_EXCEEDED",
7
+ ENTITY_NOT_ALIVE = "ENTITY_NOT_ALIVE",
8
+ CIRCULAR_SYSTEM_DEPENDENCY = "CIRCULAR_SYSTEM_DEPENDENCY",
9
+ DUPLICATE_SYSTEM = "DUPLICATE_SYSTEM",
10
+ ARCHETYPE_NOT_FOUND = "ARCHETYPE_NOT_FOUND",
11
+ RESOURCE_NOT_REGISTERED = "RESOURCE_NOT_REGISTERED",
12
+ RESOURCE_ALREADY_REGISTERED = "RESOURCE_ALREADY_REGISTERED",
13
+ EVENT_ALREADY_REGISTERED = "EVENT_ALREADY_REGISTERED",
14
+ EVENT_NOT_REGISTERED = "EVENT_NOT_REGISTERED",
15
+ FIELD_NOT_REGISTERED = "FIELD_NOT_REGISTERED",
16
+ RELATION_NOT_REGISTERED = "RELATION_NOT_REGISTERED",
17
+ RELATION_MODE_INVALID = "RELATION_MODE_INVALID",
18
+ RELATION_MODE_MISMATCH = "RELATION_MODE_MISMATCH",
19
+ RELATION_CYCLE = "RELATION_CYCLE",
20
+ SPARSE_CACHE_KEY_OVERFLOW = "SPARSE_CACHE_KEY_OVERFLOW",
21
+ SPARSE_QUERY_DENSE_PATH = "SPARSE_QUERY_DENSE_PATH",
22
+ HIERARCHY_ALREADY_SET = "HIERARCHY_ALREADY_SET",
23
+ HIERARCHY_INVALID_MAX_DEPTH = "HIERARCHY_INVALID_MAX_DEPTH",
24
+ OBSERVER_NON_CONVERGENT = "OBSERVER_NON_CONVERGENT",
25
+ OBSERVER_INVALID_CONFIG = "OBSERVER_INVALID_CONFIG",
26
+ OBSERVER_ONSET_EMIT = "OBSERVER_ONSET_EMIT",
27
+ INVALID_FIXED_TIMESTEP = "INVALID_FIXED_TIMESTEP",
28
+ INVALID_MAX_FIXED_STEPS = "INVALID_MAX_FIXED_STEPS",
29
+ INVALID_RECORDER_SCHEDULE = "INVALID_RECORDER_SCHEDULE",
30
+ EMPTY_ARCHETYPE_MATERIALIZE = "EMPTY_ARCHETYPE_MATERIALIZE",
31
+ COMPONENT_INDEX_INVARIANT = "COMPONENT_INDEX_INVARIANT",
32
+ OPTIONAL_TERM_NOT_DECLARED = "OPTIONAL_TERM_NOT_DECLARED",
33
+ QUERY_ACCESS_UNDECLARED = "QUERY_ACCESS_UNDECLARED",
34
+ /** A system touched a component/sparse/relation/resource it didn't declare
35
+ * in its access surface — distinct from *_NOT_REGISTERED (which means the
36
+ * thing was never registered with the world at all). */
37
+ ACCESS_UNDECLARED = "ACCESS_UNDECLARED",
38
+ /** `Query.singleEntity` found 0 or >1 matches (dev-only assertion). */
39
+ QUERY_NOT_SINGLETON = "QUERY_NOT_SINGLETON",
40
+ /** A run-condition factory was given invalid arguments (dev-only). */
41
+ INVALID_RUN_CONDITION = "INVALID_RUN_CONDITION",
42
+ SYSTEM_FN_ARITY = "SYSTEM_FN_ARITY",
43
+ PARTITION_APPEND_NEEDS_ENTITY_ROW = "PARTITION_APPEND_NEEDS_ENTITY_ROW",
44
+ PARTITION_BULK_INTO_DISABLED = "PARTITION_BULK_INTO_DISABLED",
45
+ ENTITY_NOT_DISABLED = "ENTITY_NOT_DISABLED",
46
+ STRUCTURAL_DURING_ITERATION = "STRUCTURAL_DURING_ITERATION",
47
+ BACKEND_ALREADY_ATTACHED = "BACKEND_ALREADY_ATTACHED",
48
+ DETERMINISM_DISABLED = "DETERMINISM_DISABLED",
49
+ NON_DETERMINISTIC_COLUMN_TYPE = "NON_DETERMINISTIC_COLUMN_TYPE",
50
+ INVALID_MEMORY_OPTIONS = "INVALID_MEMORY_OPTIONS",
51
+ STORE_CAP_EXCEEDED = "STORE_CAP_EXCEEDED",
52
+ REGION_NOT_DECLARED = "REGION_NOT_DECLARED",
53
+ COMMAND_LOG_TAG_COLLISION = "COMMAND_LOG_TAG_COLLISION",
54
+ INVALID_FRAME_STEP = "INVALID_FRAME_STEP"
55
+ }
56
+ export declare class ECSError extends AppError {
57
+ readonly category: ECS_ERROR;
58
+ constructor(category: ECS_ERROR, message?: string, context?: Record<string, unknown>);
59
+ }
60
+ export declare function isEcsError(error: unknown): error is ECSError;
61
+ //# sourceMappingURL=error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../../../src/core/ecs/utils/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,oBAAY,SAAS;IACpB,sBAAsB,2BAA2B;IACjD,oBAAoB,yBAAyB;IAC7C,wBAAwB,6BAA6B;IACrD,wBAAwB,6BAA6B;IACrD,gBAAgB,qBAAqB;IACrC,0BAA0B,+BAA+B;IACzD,gBAAgB,qBAAqB;IACrC,mBAAmB,wBAAwB;IAC3C,uBAAuB,4BAA4B;IACnD,2BAA2B,gCAAgC;IAC3D,wBAAwB,6BAA6B;IACrD,oBAAoB,yBAAyB;IAC7C,oBAAoB,yBAAyB;IAC7C,uBAAuB,4BAA4B;IACnD,qBAAqB,0BAA0B;IAC/C,sBAAsB,2BAA2B;IACjD,cAAc,mBAAmB;IACjC,yBAAyB,8BAA8B;IACvD,uBAAuB,4BAA4B;IACnD,qBAAqB,0BAA0B;IAC/C,2BAA2B,gCAAgC;IAC3D,uBAAuB,4BAA4B;IACnD,uBAAuB,4BAA4B;IACnD,mBAAmB,wBAAwB;IAC3C,sBAAsB,2BAA2B;IACjD,uBAAuB,4BAA4B;IACnD,yBAAyB,8BAA8B;IACvD,2BAA2B,gCAAgC;IAC3D,yBAAyB,8BAA8B;IACvD,0BAA0B,+BAA+B;IACzD,uBAAuB,4BAA4B;IACnD;;4DAEwD;IACxD,iBAAiB,sBAAsB;IACvC,uEAAuE;IACvE,mBAAmB,wBAAwB;IAC3C,sEAAsE;IACtE,qBAAqB,0BAA0B;IAC/C,eAAe,oBAAoB;IACnC,iCAAiC,sCAAsC;IACvE,4BAA4B,iCAAiC;IAC7D,mBAAmB,wBAAwB;IAC3C,2BAA2B,gCAAgC;IAC3D,wBAAwB,6BAA6B;IACrD,oBAAoB,yBAAyB;IAC7C,6BAA6B,kCAAkC;IAC/D,sBAAsB,2BAA2B;IACjD,kBAAkB,uBAAuB;IACzC,mBAAmB,wBAAwB;IAC3C,yBAAyB,8BAA8B;IACvD,kBAAkB,uBAAuB;CACzC;AAED,qBAAa,QAAS,SAAQ,QAAQ;aAEpB,QAAQ,EAAE,SAAS;gBAAnB,QAAQ,EAAE,SAAS,EACnC,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAIlC;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE5D"}
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Action ring — main-thread producer / worker-thread consumer SPSC ring
3
+ * for client input intents (`send_action`-shaped bytes). Plan §6.5 task
4
+ * 3 / `docs/ideas/buffer-wasm-sim-plan-2026-05-14T1600.md`.
5
+ *
6
+ * Same on-the-wire shape as `command_ring.ts`, but with two practical
7
+ * differences:
8
+ *
9
+ * 1. Producer/consumer roles flip — the action ring is main → worker,
10
+ * whereas the command ring is sim → host.
11
+ * 2. Slot payload carries a `length` prefix because client actions are
12
+ * variable-width (the encoded bytes that would normally go straight
13
+ * to the WebSocket). `payload[0]` is the length in bytes; bytes
14
+ * `[1..1+length)` are the action payload itself.
15
+ *
16
+ * Layout (identical to command ring header):
17
+ *
18
+ * [ write_head: u32 ] monotonic; modulo `capacity_slots` for slot
19
+ * [ read_head: u32 ] monotonic
20
+ * [ capacity: u32 ] slot count, power-of-two
21
+ * [ overflow: u32 ] 0 = OK; 1 = ring exhausted (producer side)
22
+ * [ slot 0: 16 B ] length: u8, payload: [15]u8
23
+ * [ slot 1: 16 B ] ...
24
+ *
25
+ * SPSC contract:
26
+ * - Producer: main thread, from `GameNetworkClient.send_action`. Pushes
27
+ * one entry per user action; `Atomics.store`s `write_head` after each.
28
+ * - Consumer: sim worker, drained on each `apply_diff` / `apply_snapshot`
29
+ * boundary. `Atomics.store`s `read_head` after each pop.
30
+ * - Today's consumer is a no-op observer (logs / counts in DEV) — the
31
+ * wire path still goes main → WebSocket → server. PR 5N migrates the
32
+ * `PredictionReconciler` into the worker so the action ring becomes
33
+ * load-bearing for client-side prediction.
34
+ *
35
+ * Overflow:
36
+ * - If main writes a slot when `(write_head - read_head) === capacity`,
37
+ * it sets `overflow = 1` and the push returns `false`. The server
38
+ * send path is independent (`_transport.send(...)` ran first), so an
39
+ * overflow doesn't drop the action — it only drops worker
40
+ * observability for that one entry.
41
+ *
42
+ * Atomics: the head fields (`write_head` / `read_head`) are the
43
+ * cross-thread synchronization edge — the producer runs on the main
44
+ * thread, the consumer in the sim worker, and both alias the same
45
+ * `SharedArrayBuffer`. The producer writes the slot bytes, then
46
+ * `Atomics.store`s `write_head`; the consumer `Atomics.load`s
47
+ * `write_head` before touching the slot, reads it, then `Atomics.store`s
48
+ * `read_head`. These SeqCst ops establish the happens-before that a
49
+ * plain `DataView` write does not under the JS memory model (#374):
50
+ * without them the worker could observe a bumped `write_head` before the
51
+ * producer's `setUint8(len)` + payload `set()` are visible and read a
52
+ * torn/stale slot, and the producer could read a stale `read_head`
53
+ * (false overflow, or overwrite a slot mid-read). Slot payload bytes
54
+ * stay on plain `DataView` / `Uint8Array` ops — the head Atomics fence
55
+ * them, so no per-byte atomic is needed. A future PR may still add an
56
+ * `Atomics.wait/notify` pair so the worker can block between actions
57
+ * instead of polling — additive change, no layout shift.
58
+ */
59
+ /** Total bytes for the ring header. Identical to `command_ring`. */
60
+ export declare const ACTION_RING_HEADER_BYTES = 16;
61
+ /** Fixed slot size — 1-byte length + 15-byte payload. */
62
+ export declare const ACTION_RING_SLOT_BYTES = 16;
63
+ /** Default ring capacity in slots. Sized for ~250 ms of click-spam at 60
64
+ * Hz on the high end of human input rates; 256 × 16 B = 4 KiB + 16 B
65
+ * header. */
66
+ export declare const ACTION_RING_DEFAULT_CAPACITY_SLOTS = 256;
67
+ /** Max payload bytes per slot (slot size minus the length prefix). All
68
+ * actions defined in `packages/protocol/src/actions.ts` encode to under
69
+ * 8 bytes, so this is comfortably above today's max. */
70
+ export declare const ACTION_RING_MAX_PAYLOAD_BYTES: number;
71
+ /** Byte offsets within the ring header. Matches `command_ring` so a
72
+ * future shared helper can normalise across both rings without per-ring
73
+ * arithmetic. */
74
+ export declare const ACTION_RING_HEADER_OFFSETS: {
75
+ readonly write_head: 0;
76
+ readonly read_head: 4;
77
+ readonly capacity_slots: 8;
78
+ readonly overflow_flag: 12;
79
+ };
80
+ /** Total bytes the ring occupies for `capacity_slots` slots. */
81
+ export declare function actionRingBytes(capacitySlots: number): number;
82
+ export declare class ActionRingError extends Error {
83
+ constructor(message: string);
84
+ }
85
+ /** Initialise the ring header at `ringOff` in the SAB. Zeroes heads
86
+ * and the overflow flag; sets `capacity_slots`. Slot bytes are left
87
+ * as-is (callers normally allocate the ring on a zero-initialised SAB). */
88
+ export declare function initActionRing(view: DataView, ringOff: number, capacitySlots: number): void;
89
+ /** Read live ring-header fields. Heads are stored signed but returned
90
+ * unsigned (`>>> 0`) so the monotonic-counter arithmetic below is
91
+ * identical to the prior `getUint32` behaviour. */
92
+ export declare function actionRingWriteHead(view: DataView, ringOff: number): number;
93
+ export declare function actionRingReadHead(view: DataView, ringOff: number): number;
94
+ export declare function actionRingCapacitySlots(view: DataView, ringOff: number): number;
95
+ export declare function actionRingOverflow(view: DataView, ringOff: number): boolean;
96
+ /** Pending entry count = `(write_head - read_head) mod 2^32`. */
97
+ export declare function pendingActionCount(view: DataView, ringOff: number): number;
98
+ /** Push an action into the ring. `payload` must be in
99
+ * `[1, ACTION_RING_MAX_PAYLOAD_BYTES]`; longer payloads — and **empty**
100
+ * ones — are an `ActionRingError` (the producer is the only caller and it
101
+ * can size its inputs ahead of time). The zero-length rejection closes the
102
+ * lower-bound footgun: a 0-byte slot is indistinguishable from
103
+ * `popAction`'s empty-ring sentinel (`0`), so admitting one would let it
104
+ * masquerade as "ring empty". No encoder produces a 0-byte payload, so this
105
+ * only ever rejects the ABI-skew bug case (#430). Returns `false` on
106
+ * overflow and sets the overflow flag. */
107
+ export declare function pushAction(view: DataView, ringOff: number, payload: Uint8Array): boolean;
108
+ /** Pop one action from the ring. Returns the byte length written into
109
+ * `outPayload`, or `0` if the ring was empty. `outPayload` must be at
110
+ * least `ACTION_RING_MAX_PAYLOAD_BYTES`; only the first `length` bytes
111
+ * are meaningful after a non-zero return.
112
+ *
113
+ * NOTE: a `0` return is ambiguous — it means "ring empty" OR "a 0-byte
114
+ * slot" (the latter only reachable via ABI-skew, since `pushAction`
115
+ * rejects empty payloads). Callers that loop must decide emptiness from
116
+ * the heads (`pendingActionCount` / `write_head === read_head`), not
117
+ * from this return value; see `drainActionRing` and #430. */
118
+ export declare function popAction(view: DataView, ringOff: number, outPayload: Uint8Array): number;
119
+ /** Drain every pending action, invoking `handler(payload)` per entry.
120
+ * The `payload` passed to the handler is a freshly-copied
121
+ * `Uint8Array(length)` so handlers can hold it past the next pop without
122
+ * aliasing the scratch buffer. Returns the number of actions drained.
123
+ *
124
+ * Termination is decided from the heads (`pendingActionCount`), NOT from
125
+ * `popAction`'s return value. A genuine 0-byte slot returns `0` — the same
126
+ * value `popAction` yields on an empty ring — so terminating on `len === 0`
127
+ * would silently consume the zero-length entry and strand everything queued
128
+ * behind it for a tick (#430). The heads check is SPSC-safe: this consumer
129
+ * is the sole reader, so a non-zero pending count cannot race to empty before
130
+ * the `popAction` below. */
131
+ export declare function drainActionRing(view: DataView, ringOff: number, handler: (payload: Uint8Array) => void): number;
132
+ /** Clear the overflow flag. The producer sets it on a failed push; the
133
+ * consumer can reset it once it has observed and logged the condition,
134
+ * so a single overflow doesn't keep firing dev assertions. */
135
+ export declare function clearActionRingOverflow(view: DataView, ringOff: number): void;
136
+ //# sourceMappingURL=action_ring.d.ts.map
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Action ring — main-thread producer / worker-thread consumer SPSC ring
3
+ * for client input intents (`send_action`-shaped bytes). Plan §6.5 task
4
+ * 3 / `docs/ideas/buffer-wasm-sim-plan-2026-05-14T1600.md`.
5
+ *
6
+ * Same on-the-wire shape as `command_ring.ts`, but with two practical
7
+ * differences:
8
+ *
9
+ * 1. Producer/consumer roles flip — the action ring is main → worker,
10
+ * whereas the command ring is sim → host.
11
+ * 2. Slot payload carries a `length` prefix because client actions are
12
+ * variable-width (the encoded bytes that would normally go straight
13
+ * to the WebSocket). `payload[0]` is the length in bytes; bytes
14
+ * `[1..1+length)` are the action payload itself.
15
+ *
16
+ * Layout (identical to command ring header):
17
+ *
18
+ * [ write_head: u32 ] monotonic; modulo `capacity_slots` for slot
19
+ * [ read_head: u32 ] monotonic
20
+ * [ capacity: u32 ] slot count, power-of-two
21
+ * [ overflow: u32 ] 0 = OK; 1 = ring exhausted (producer side)
22
+ * [ slot 0: 16 B ] length: u8, payload: [15]u8
23
+ * [ slot 1: 16 B ] ...
24
+ *
25
+ * SPSC contract:
26
+ * - Producer: main thread, from `GameNetworkClient.send_action`. Pushes
27
+ * one entry per user action; `Atomics.store`s `write_head` after each.
28
+ * - Consumer: sim worker, drained on each `apply_diff` / `apply_snapshot`
29
+ * boundary. `Atomics.store`s `read_head` after each pop.
30
+ * - Today's consumer is a no-op observer (logs / counts in DEV) — the
31
+ * wire path still goes main → WebSocket → server. PR 5N migrates the
32
+ * `PredictionReconciler` into the worker so the action ring becomes
33
+ * load-bearing for client-side prediction.
34
+ *
35
+ * Overflow:
36
+ * - If main writes a slot when `(write_head - read_head) === capacity`,
37
+ * it sets `overflow = 1` and the push returns `false`. The server
38
+ * send path is independent (`_transport.send(...)` ran first), so an
39
+ * overflow doesn't drop the action — it only drops worker
40
+ * observability for that one entry.
41
+ *
42
+ * Atomics: the head fields (`write_head` / `read_head`) are the
43
+ * cross-thread synchronization edge — the producer runs on the main
44
+ * thread, the consumer in the sim worker, and both alias the same
45
+ * `SharedArrayBuffer`. The producer writes the slot bytes, then
46
+ * `Atomics.store`s `write_head`; the consumer `Atomics.load`s
47
+ * `write_head` before touching the slot, reads it, then `Atomics.store`s
48
+ * `read_head`. These SeqCst ops establish the happens-before that a
49
+ * plain `DataView` write does not under the JS memory model (#374):
50
+ * without them the worker could observe a bumped `write_head` before the
51
+ * producer's `setUint8(len)` + payload `set()` are visible and read a
52
+ * torn/stale slot, and the producer could read a stale `read_head`
53
+ * (false overflow, or overwrite a slot mid-read). Slot payload bytes
54
+ * stay on plain `DataView` / `Uint8Array` ops — the head Atomics fence
55
+ * them, so no per-byte atomic is needed. A future PR may still add an
56
+ * `Atomics.wait/notify` pair so the worker can block between actions
57
+ * instead of polling — additive change, no layout shift.
58
+ */
59
+ /** Total bytes for the ring header. Identical to `command_ring`. */
60
+ export declare const ACTION_RING_HEADER_BYTES = 16;
61
+ /** Fixed slot size — 1-byte length + 15-byte payload. */
62
+ export declare const ACTION_RING_SLOT_BYTES = 16;
63
+ /** Default ring capacity in slots. Sized for ~250 ms of click-spam at 60
64
+ * Hz on the high end of human input rates; 256 × 16 B = 4 KiB + 16 B
65
+ * header. */
66
+ export declare const ACTION_RING_DEFAULT_CAPACITY_SLOTS = 256;
67
+ /** Max payload bytes per slot (slot size minus the length prefix). All
68
+ * actions defined in `packages/protocol/src/actions.ts` encode to under
69
+ * 8 bytes, so this is comfortably above today's max. */
70
+ export declare const ACTION_RING_MAX_PAYLOAD_BYTES: number;
71
+ /** Byte offsets within the ring header. Matches `command_ring` so a
72
+ * future shared helper can normalise across both rings without per-ring
73
+ * arithmetic. */
74
+ export declare const ACTION_RING_HEADER_OFFSETS: {
75
+ readonly write_head: 0;
76
+ readonly read_head: 4;
77
+ readonly capacity_slots: 8;
78
+ readonly overflow_flag: 12;
79
+ };
80
+ /** Total bytes the ring occupies for `capacity_slots` slots. */
81
+ export declare function actionRingBytes(capacitySlots: number): number;
82
+ export declare class ActionRingError extends Error {
83
+ constructor(message: string);
84
+ }
85
+ /** Initialise the ring header at `ringOff` in the SAB. Zeroes heads
86
+ * and the overflow flag; sets `capacity_slots`. Slot bytes are left
87
+ * as-is (callers normally allocate the ring on a zero-initialised SAB). */
88
+ export declare function initActionRing(view: DataView, ringOff: number, capacitySlots: number): void;
89
+ /** Read live ring-header fields. Heads are stored signed but returned
90
+ * unsigned (`>>> 0`) so the monotonic-counter arithmetic below is
91
+ * identical to the prior `getUint32` behaviour. */
92
+ export declare function actionRingWriteHead(view: DataView, ringOff: number): number;
93
+ export declare function actionRingReadHead(view: DataView, ringOff: number): number;
94
+ export declare function actionRingCapacitySlots(view: DataView, ringOff: number): number;
95
+ export declare function actionRingOverflow(view: DataView, ringOff: number): boolean;
96
+ /** Pending entry count = `(write_head - read_head) mod 2^32`. */
97
+ export declare function pendingActionCount(view: DataView, ringOff: number): number;
98
+ /** Push an action into the ring. `payload` must be in
99
+ * `[1, ACTION_RING_MAX_PAYLOAD_BYTES]`; longer payloads — and **empty**
100
+ * ones — are an `ActionRingError` (the producer is the only caller and it
101
+ * can size its inputs ahead of time). The zero-length rejection closes the
102
+ * lower-bound footgun: a 0-byte slot is indistinguishable from
103
+ * `popAction`'s empty-ring sentinel (`0`), so admitting one would let it
104
+ * masquerade as "ring empty". No encoder produces a 0-byte payload, so this
105
+ * only ever rejects the ABI-skew bug case (#430). Returns `false` on
106
+ * overflow and sets the overflow flag. */
107
+ export declare function pushAction(view: DataView, ringOff: number, payload: Uint8Array): boolean;
108
+ /** Pop one action from the ring. Returns the byte length written into
109
+ * `outPayload`, or `0` if the ring was empty. `outPayload` must be at
110
+ * least `ACTION_RING_MAX_PAYLOAD_BYTES`; only the first `length` bytes
111
+ * are meaningful after a non-zero return.
112
+ *
113
+ * NOTE: a `0` return is ambiguous — it means "ring empty" OR "a 0-byte
114
+ * slot" (the latter only reachable via ABI-skew, since `pushAction`
115
+ * rejects empty payloads). Callers that loop must decide emptiness from
116
+ * the heads (`pendingActionCount` / `write_head === read_head`), not
117
+ * from this return value; see `drainActionRing` and #430. */
118
+ export declare function popAction(view: DataView, ringOff: number, outPayload: Uint8Array): number;
119
+ /** Drain every pending action, invoking `handler(payload)` per entry.
120
+ * The `payload` passed to the handler is a freshly-copied
121
+ * `Uint8Array(length)` so handlers can hold it past the next pop without
122
+ * aliasing the scratch buffer. Returns the number of actions drained.
123
+ *
124
+ * Termination is decided from the heads (`pendingActionCount`), NOT from
125
+ * `popAction`'s return value. A genuine 0-byte slot returns `0` — the same
126
+ * value `popAction` yields on an empty ring — so terminating on `len === 0`
127
+ * would silently consume the zero-length entry and strand everything queued
128
+ * behind it for a tick (#430). The heads check is SPSC-safe: this consumer
129
+ * is the sole reader, so a non-zero pending count cannot race to empty before
130
+ * the `popAction` below. */
131
+ export declare function drainActionRing(view: DataView, ringOff: number, handler: (payload: Uint8Array) => void): number;
132
+ /** Clear the overflow flag. The producer sets it on a failed push; the
133
+ * consumer can reset it once it has observed and logged the condition,
134
+ * so a single overflow doesn't keep firing dev assertions. */
135
+ export declare function clearActionRingOverflow(view: DataView, ringOff: number): void;
136
+ //# sourceMappingURL=action_ring.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action_ring.d.ts","sourceRoot":"","sources":["../../../src/core/store/action_ring.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AAEH,oEAAoE;AACpE,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAE3C,yDAAyD;AACzD,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC;;aAEa;AACb,eAAO,MAAM,kCAAkC,MAAM,CAAC;AAEtD;;wDAEwD;AACxD,eAAO,MAAM,6BAA6B,QAA6B,CAAC;AAExE;;iBAEiB;AACjB,eAAO,MAAM,0BAA0B;;;;;CAK7B,CAAC;AAwBX,gEAAgE;AAChE,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAE7D;AAMD,qBAAa,eAAgB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAI3B;AAED;;2EAE2E;AAC3E,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,CAiB3F;AAED;;mDAEmD;AACnD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAE3E;AACD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAE1E;AACD,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAE/E;AACD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAE3E;AAED,iEAAiE;AACjE,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAE1E;AAED;;;;;;;;0CAQ0C;AAC1C,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAoCxF;AAED;;;;;;;;;6DAS6D;AAC7D,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,MAAM,CAwBzF;AAED;;;;;;;;;;;4BAW4B;AAC5B,wBAAgB,eAAe,CAC9B,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,IAAI,GACpC,MAAM,CAUR;AAED;;8DAE8D;AAC9D,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAE7E"}