@oasys/oecs 0.5.3 → 0.6.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 (510) hide show
  1. package/CHANGELOG.md +1399 -276
  2. package/README.md +327 -169
  3. package/dist/core/ecs/access_check.d.cts +31 -31
  4. package/dist/core/ecs/access_check.d.ts +31 -31
  5. package/dist/core/ecs/access_check.d.ts.map +1 -1
  6. package/dist/core/ecs/archetype.d.cts +273 -205
  7. package/dist/core/ecs/archetype.d.ts +273 -205
  8. package/dist/core/ecs/archetype.d.ts.map +1 -1
  9. package/dist/core/ecs/archetype_closure.d.cts +23 -0
  10. package/dist/core/ecs/archetype_closure.d.ts +23 -0
  11. package/dist/core/ecs/archetype_closure.d.ts.map +1 -0
  12. package/dist/core/ecs/archetype_graph.d.cts +34 -34
  13. package/dist/core/ecs/archetype_graph.d.ts +34 -34
  14. package/dist/core/ecs/archetype_graph.d.ts.map +1 -1
  15. package/dist/core/ecs/archetype_types.d.cts +55 -0
  16. package/dist/core/ecs/archetype_types.d.ts +55 -0
  17. package/dist/core/ecs/archetype_types.d.ts.map +1 -0
  18. package/dist/core/ecs/change_feed.d.cts +53 -0
  19. package/dist/core/ecs/change_feed.d.ts +53 -0
  20. package/dist/core/ecs/change_feed.d.ts.map +1 -0
  21. package/dist/core/ecs/changed_query.d.cts +36 -0
  22. package/dist/core/ecs/changed_query.d.ts +36 -0
  23. package/dist/core/ecs/changed_query.d.ts.map +1 -0
  24. package/dist/core/ecs/chunk_columns.d.cts +49 -0
  25. package/dist/core/ecs/chunk_columns.d.ts +49 -0
  26. package/dist/core/ecs/chunk_columns.d.ts.map +1 -0
  27. package/dist/core/ecs/command_log.d.cts +30 -30
  28. package/dist/core/ecs/command_log.d.ts +30 -30
  29. package/dist/core/ecs/command_log.d.ts.map +1 -1
  30. package/dist/core/ecs/component.d.cts +45 -44
  31. package/dist/core/ecs/component.d.ts +45 -44
  32. package/dist/core/ecs/component.d.ts.map +1 -1
  33. package/dist/core/ecs/component_registry.d.cts +53 -0
  34. package/dist/core/ecs/component_registry.d.ts +53 -0
  35. package/dist/core/ecs/component_registry.d.ts.map +1 -0
  36. package/dist/core/ecs/compute_backend.d.cts +18 -7
  37. package/dist/core/ecs/compute_backend.d.ts +18 -7
  38. package/dist/core/ecs/compute_backend.d.ts.map +1 -1
  39. package/dist/core/ecs/deferred_commands.d.cts +15 -14
  40. package/dist/core/ecs/deferred_commands.d.ts +15 -14
  41. package/dist/core/ecs/deferred_commands.d.ts.map +1 -1
  42. package/dist/core/ecs/dispatch_trace.d.cts +32 -31
  43. package/dist/core/ecs/dispatch_trace.d.ts +32 -31
  44. package/dist/core/ecs/dispatch_trace.d.ts.map +1 -1
  45. package/dist/core/ecs/ecs.d.cts +337 -276
  46. package/dist/core/ecs/ecs.d.ts +337 -276
  47. package/dist/core/ecs/ecs.d.ts.map +1 -1
  48. package/dist/core/ecs/ecs_memory.d.cts +134 -136
  49. package/dist/core/ecs/ecs_memory.d.ts +134 -136
  50. package/dist/core/ecs/ecs_memory.d.ts.map +1 -1
  51. package/dist/core/ecs/ecs_options.d.cts +89 -0
  52. package/dist/core/ecs/ecs_options.d.ts +89 -0
  53. package/dist/core/ecs/ecs_options.d.ts.map +1 -0
  54. package/dist/core/ecs/entity.d.cts +4 -4
  55. package/dist/core/ecs/entity.d.ts +4 -4
  56. package/dist/core/ecs/entity_allocator.d.cts +24 -22
  57. package/dist/core/ecs/entity_allocator.d.ts +24 -22
  58. package/dist/core/ecs/entity_allocator.d.ts.map +1 -1
  59. package/dist/core/ecs/event.d.cts +37 -23
  60. package/dist/core/ecs/event.d.ts +37 -23
  61. package/dist/core/ecs/event.d.ts.map +1 -1
  62. package/dist/core/ecs/facades.d.cts +12 -126
  63. package/dist/core/ecs/facades.d.ts +12 -126
  64. package/dist/core/ecs/facades.d.ts.map +1 -1
  65. package/dist/core/ecs/frame_stepper.d.cts +12 -12
  66. package/dist/core/ecs/frame_stepper.d.ts +12 -12
  67. package/dist/core/ecs/frame_stepper.d.ts.map +1 -1
  68. package/dist/core/ecs/frame_trace.d.cts +34 -34
  69. package/dist/core/ecs/frame_trace.d.ts +34 -34
  70. package/dist/core/ecs/frame_trace.d.ts.map +1 -1
  71. package/dist/core/ecs/host_commands.d.cts +107 -89
  72. package/dist/core/ecs/host_commands.d.ts +107 -89
  73. package/dist/core/ecs/host_commands.d.ts.map +1 -1
  74. package/dist/core/ecs/index.d.cts +22 -12
  75. package/dist/core/ecs/index.d.ts +22 -12
  76. package/dist/core/ecs/index.d.ts.map +1 -1
  77. package/dist/core/ecs/observer.d.cts +41 -122
  78. package/dist/core/ecs/observer.d.ts +41 -122
  79. package/dist/core/ecs/observer.d.ts.map +1 -1
  80. package/dist/core/ecs/phase.d.cts +79 -0
  81. package/dist/core/ecs/phase.d.ts +79 -0
  82. package/dist/core/ecs/phase.d.ts.map +1 -0
  83. package/dist/core/ecs/plugin.d.cts +125 -0
  84. package/dist/core/ecs/plugin.d.ts +125 -0
  85. package/dist/core/ecs/plugin.d.ts.map +1 -0
  86. package/dist/core/ecs/plugin_slots.d.cts +26 -0
  87. package/dist/core/ecs/plugin_slots.d.ts +26 -0
  88. package/dist/core/ecs/plugin_slots.d.ts.map +1 -0
  89. package/dist/core/ecs/query.d.cts +219 -568
  90. package/dist/core/ecs/query.d.ts +219 -568
  91. package/dist/core/ecs/query.d.ts.map +1 -1
  92. package/dist/core/ecs/query_cache.d.cts +130 -0
  93. package/dist/core/ecs/query_cache.d.ts +130 -0
  94. package/dist/core/ecs/query_cache.d.ts.map +1 -0
  95. package/dist/core/ecs/query_registry.d.cts +47 -0
  96. package/dist/core/ecs/query_registry.d.ts +47 -0
  97. package/dist/core/ecs/query_registry.d.ts.map +1 -0
  98. package/dist/core/ecs/query_terms.d.cts +126 -0
  99. package/dist/core/ecs/query_terms.d.ts +126 -0
  100. package/dist/core/ecs/query_terms.d.ts.map +1 -0
  101. package/dist/core/ecs/ref.d.cts +129 -16
  102. package/dist/core/ecs/ref.d.ts +129 -16
  103. package/dist/core/ecs/ref.d.ts.map +1 -1
  104. package/dist/core/ecs/relation.d.cts +105 -186
  105. package/dist/core/ecs/relation.d.ts +105 -186
  106. package/dist/core/ecs/relation.d.ts.map +1 -1
  107. package/dist/core/ecs/resource.d.cts +14 -14
  108. package/dist/core/ecs/resource.d.ts +14 -14
  109. package/dist/core/ecs/resource_registry.d.cts +6 -6
  110. package/dist/core/ecs/resource_registry.d.ts +6 -6
  111. package/dist/core/ecs/resource_registry.d.ts.map +1 -1
  112. package/dist/core/ecs/row_kinds.d.cts +24 -0
  113. package/dist/core/ecs/row_kinds.d.ts +24 -0
  114. package/dist/core/ecs/row_kinds.d.ts.map +1 -0
  115. package/dist/core/ecs/run_condition.d.cts +23 -23
  116. package/dist/core/ecs/run_condition.d.ts +23 -23
  117. package/dist/core/ecs/run_condition.d.ts.map +1 -1
  118. package/dist/core/ecs/schedule.d.cts +98 -114
  119. package/dist/core/ecs/schedule.d.ts +98 -114
  120. package/dist/core/ecs/schedule.d.ts.map +1 -1
  121. package/dist/core/ecs/schedule_plan.d.cts +33 -0
  122. package/dist/core/ecs/schedule_plan.d.ts +33 -0
  123. package/dist/core/ecs/schedule_plan.d.ts.map +1 -0
  124. package/dist/core/ecs/snapshot.d.cts +77 -0
  125. package/dist/core/ecs/snapshot.d.ts +77 -0
  126. package/dist/core/ecs/snapshot.d.ts.map +1 -0
  127. package/dist/core/ecs/snapshot_mount.d.cts +42 -0
  128. package/dist/core/ecs/snapshot_mount.d.ts +42 -0
  129. package/dist/core/ecs/snapshot_mount.d.ts.map +1 -0
  130. package/dist/core/ecs/sparse_store.d.cts +110 -53
  131. package/dist/core/ecs/sparse_store.d.ts +110 -53
  132. package/dist/core/ecs/sparse_store.d.ts.map +1 -1
  133. package/dist/core/ecs/store.d.cts +644 -511
  134. package/dist/core/ecs/store.d.ts +644 -511
  135. package/dist/core/ecs/store.d.ts.map +1 -1
  136. package/dist/core/ecs/store_layout_listener.d.cts +8 -8
  137. package/dist/core/ecs/store_layout_listener.d.ts +8 -8
  138. package/dist/core/ecs/store_types.d.cts +122 -0
  139. package/dist/core/ecs/store_types.d.ts +122 -0
  140. package/dist/core/ecs/store_types.d.ts.map +1 -0
  141. package/dist/core/ecs/system.d.cts +151 -66
  142. package/dist/core/ecs/system.d.ts +151 -66
  143. package/dist/core/ecs/system.d.ts.map +1 -1
  144. package/dist/core/ecs/system_context.d.cts +296 -0
  145. package/dist/core/ecs/system_context.d.ts +296 -0
  146. package/dist/core/ecs/system_context.d.ts.map +1 -0
  147. package/dist/core/ecs/system_set.d.cts +48 -0
  148. package/dist/core/ecs/system_set.d.ts +48 -0
  149. package/dist/core/ecs/system_set.d.ts.map +1 -0
  150. package/dist/core/ecs/utils/arrays.d.cts +15 -1
  151. package/dist/core/ecs/utils/arrays.d.ts +15 -1
  152. package/dist/core/ecs/utils/arrays.d.ts.map +1 -1
  153. package/dist/core/ecs/utils/error.d.cts +87 -4
  154. package/dist/core/ecs/utils/error.d.ts +87 -4
  155. package/dist/core/ecs/utils/error.d.ts.map +1 -1
  156. package/dist/core/ecs/utils/plugin_error.d.cts +10 -0
  157. package/dist/core/ecs/utils/plugin_error.d.ts +10 -0
  158. package/dist/core/ecs/utils/plugin_error.d.ts.map +1 -0
  159. package/dist/core/restore_errors.d.cts +30 -0
  160. package/dist/core/restore_errors.d.ts +30 -0
  161. package/dist/core/restore_errors.d.ts.map +1 -0
  162. package/dist/core/store/action_ring.d.cts +48 -49
  163. package/dist/core/store/action_ring.d.ts +48 -49
  164. package/dist/core/store/action_ring.d.ts.map +1 -1
  165. package/dist/core/store/allocator.d.cts +166 -114
  166. package/dist/core/store/allocator.d.ts +166 -114
  167. package/dist/core/store/allocator.d.ts.map +1 -1
  168. package/dist/core/store/buffer_backed_column.d.cts +21 -22
  169. package/dist/core/store/buffer_backed_column.d.ts +21 -22
  170. package/dist/core/store/buffer_backed_column.d.ts.map +1 -1
  171. package/dist/core/store/column_store.d.cts +138 -100
  172. package/dist/core/store/column_store.d.ts +138 -100
  173. package/dist/core/store/column_store.d.ts.map +1 -1
  174. package/dist/core/store/command_dispatch.d.cts +14 -15
  175. package/dist/core/store/command_dispatch.d.ts +14 -15
  176. package/dist/core/store/command_dispatch.d.ts.map +1 -1
  177. package/dist/core/store/command_ring.d.cts +41 -45
  178. package/dist/core/store/command_ring.d.ts +41 -45
  179. package/dist/core/store/command_ring.d.ts.map +1 -1
  180. package/dist/core/store/descriptor.d.cts +35 -18
  181. package/dist/core/store/descriptor.d.ts +35 -18
  182. package/dist/core/store/descriptor.d.ts.map +1 -1
  183. package/dist/core/store/entity_index.d.cts +34 -35
  184. package/dist/core/store/entity_index.d.ts +34 -35
  185. package/dist/core/store/entity_index.d.ts.map +1 -1
  186. package/dist/core/store/event_ring.d.cts +40 -42
  187. package/dist/core/store/event_ring.d.ts +40 -42
  188. package/dist/core/store/event_ring.d.ts.map +1 -1
  189. package/dist/core/store/extend.d.cts +15 -9
  190. package/dist/core/store/extend.d.ts +15 -9
  191. package/dist/core/store/extend.d.ts.map +1 -1
  192. package/dist/core/store/grow.d.cts +3 -3
  193. package/dist/core/store/grow.d.ts +3 -3
  194. package/dist/core/store/grow.d.ts.map +1 -1
  195. package/dist/core/store/header.d.cts +37 -33
  196. package/dist/core/store/header.d.ts +37 -33
  197. package/dist/core/store/header.d.ts.map +1 -1
  198. package/dist/core/store/index.d.cts +10 -10
  199. package/dist/core/store/index.d.ts +10 -10
  200. package/dist/core/store/index.d.ts.map +1 -1
  201. package/dist/core/store/layout_ops.d.cts +72 -63
  202. package/dist/core/store/layout_ops.d.ts +72 -63
  203. package/dist/core/store/layout_ops.d.ts.map +1 -1
  204. package/dist/core/store/region_table.d.cts +28 -21
  205. package/dist/core/store/region_table.d.ts +28 -21
  206. package/dist/core/store/region_table.d.ts.map +1 -1
  207. package/dist/core/store/snapshot.d.cts +31 -16
  208. package/dist/core/store/snapshot.d.ts +31 -16
  209. package/dist/core/store/snapshot.d.ts.map +1 -1
  210. package/dist/core/store/state_hash.d.cts +14 -14
  211. package/dist/core/store/state_hash.d.ts +14 -14
  212. package/dist/core/store/state_hash.d.ts.map +1 -1
  213. package/dist/core/store/store_regions.d.cts +10 -10
  214. package/dist/core/store/store_regions.d.ts +10 -10
  215. package/dist/core/store/store_regions.d.ts.map +1 -1
  216. package/dist/core/store/vendored_abi/abi.d.cts +27 -2
  217. package/dist/core/store/vendored_abi/abi.d.ts +27 -2
  218. package/dist/core/store/vendored_abi/abi.d.ts.map +1 -1
  219. package/dist/host_commands-B2KMx8O2.cjs +1 -0
  220. package/dist/host_commands-ClVPvhSa.cjs +2 -0
  221. package/dist/host_commands-CwxVQS1z.js +1524 -0
  222. package/dist/host_commands-nJvTy88E.js +1667 -0
  223. package/dist/index.cjs +1 -1
  224. package/dist/index.d.cts +16 -11
  225. package/dist/index.d.ts +16 -11
  226. package/dist/index.d.ts.map +1 -1
  227. package/dist/index.development.cjs +1 -1
  228. package/dist/index.development.js +6709 -5729
  229. package/dist/index.js +5664 -4743
  230. package/dist/internal.cjs +2 -2
  231. package/dist/internal.d.cts +5 -2
  232. package/dist/internal.d.ts +5 -2
  233. package/dist/internal.d.ts.map +1 -1
  234. package/dist/internal.development.cjs +1 -1
  235. package/dist/internal.development.js +70 -20
  236. package/dist/internal.js +138 -83
  237. package/dist/plugins/abi-D3V-QUSf.cjs +1 -0
  238. package/dist/plugins/abi-NP8pNxpd.js +42 -0
  239. package/dist/plugins/arrays-Dr_1hCjL.js +28 -0
  240. package/dist/plugins/arrays-Dt-Joc4i.cjs +1 -0
  241. package/dist/plugins/assertions-gtDVfbnQ.js +6 -0
  242. package/dist/plugins/assertions-z5GQd_bB.cjs +1 -0
  243. package/dist/{extensions → plugins}/editor/editor.d.cts +56 -56
  244. package/dist/{extensions → plugins}/editor/editor.d.ts +56 -56
  245. package/dist/plugins/editor/editor.d.ts.map +1 -0
  246. package/dist/{extensions → plugins}/editor/field_handle.d.cts +13 -13
  247. package/dist/{extensions → plugins}/editor/field_handle.d.ts +13 -13
  248. package/dist/plugins/editor/field_handle.d.ts.map +1 -0
  249. package/dist/plugins/editor/index.d.cts +22 -0
  250. package/dist/plugins/editor/index.d.ts +22 -0
  251. package/dist/plugins/editor/index.d.ts.map +1 -0
  252. package/dist/plugins/editor.cjs +1 -0
  253. package/dist/plugins/editor.d.cts +1 -0
  254. package/dist/plugins/editor.d.ts +1 -0
  255. package/dist/plugins/editor.development.cjs +1 -0
  256. package/dist/{extensions/editor/index.development.js → plugins/editor.development.js} +83 -66
  257. package/dist/{extensions/editor/index.js → plugins/editor.js} +83 -66
  258. package/dist/plugins/events/event_channel.d.cts +13 -0
  259. package/dist/plugins/events/event_channel.d.ts +13 -0
  260. package/dist/plugins/events/event_channel.d.ts.map +1 -0
  261. package/dist/plugins/events/event_registry.d.cts +22 -0
  262. package/dist/plugins/events/event_registry.d.ts +22 -0
  263. package/dist/plugins/events/event_registry.d.ts.map +1 -0
  264. package/dist/plugins/events/facade.d.cts +26 -0
  265. package/dist/plugins/events/facade.d.ts +26 -0
  266. package/dist/plugins/events/facade.d.ts.map +1 -0
  267. package/dist/plugins/events/index.d.cts +10 -0
  268. package/dist/plugins/events/index.d.ts +10 -0
  269. package/dist/plugins/events/index.d.ts.map +1 -0
  270. package/dist/plugins/events.cjs +1 -0
  271. package/dist/plugins/events.d.cts +1 -0
  272. package/dist/plugins/events.d.ts +1 -0
  273. package/dist/plugins/events.development.cjs +1 -0
  274. package/dist/plugins/events.development.js +174 -0
  275. package/dist/plugins/events.js +159 -0
  276. package/dist/plugins/observers/index.d.cts +23 -0
  277. package/dist/plugins/observers/index.d.ts +23 -0
  278. package/dist/plugins/observers/index.d.ts.map +1 -0
  279. package/dist/plugins/observers/observer_registry.d.cts +101 -0
  280. package/dist/plugins/observers/observer_registry.d.ts +101 -0
  281. package/dist/plugins/observers/observer_registry.d.ts.map +1 -0
  282. package/dist/plugins/observers.cjs +1 -0
  283. package/dist/plugins/observers.d.cts +1 -0
  284. package/dist/plugins/observers.d.ts +1 -0
  285. package/dist/plugins/observers.development.cjs +1 -0
  286. package/dist/plugins/observers.development.js +431 -0
  287. package/dist/plugins/observers.js +403 -0
  288. package/dist/plugins/relation_store-BsoegrZh.js +313 -0
  289. package/dist/plugins/relation_store-DQKSnxsm.cjs +1 -0
  290. package/dist/plugins/relation_store-RBhpcE28.cjs +1 -0
  291. package/dist/plugins/relation_store-RqW5Snx6.js +328 -0
  292. package/dist/plugins/relations/builtin_relations.d.cts +48 -0
  293. package/dist/plugins/relations/builtin_relations.d.ts +48 -0
  294. package/dist/plugins/relations/builtin_relations.d.ts.map +1 -0
  295. package/dist/plugins/relations/facade.d.cts +73 -0
  296. package/dist/plugins/relations/facade.d.ts +73 -0
  297. package/dist/plugins/relations/facade.d.ts.map +1 -0
  298. package/dist/plugins/relations/index.d.cts +11 -0
  299. package/dist/plugins/relations/index.d.ts +11 -0
  300. package/dist/plugins/relations/index.d.ts.map +1 -0
  301. package/dist/{core/ecs → plugins/relations}/relation_service.d.cts +93 -105
  302. package/dist/{core/ecs → plugins/relations}/relation_service.d.ts +93 -105
  303. package/dist/plugins/relations/relation_service.d.ts.map +1 -0
  304. package/dist/plugins/relations/relation_store.d.cts +177 -0
  305. package/dist/plugins/relations/relation_store.d.ts +177 -0
  306. package/dist/plugins/relations/relation_store.d.ts.map +1 -0
  307. package/dist/plugins/relations.cjs +1 -0
  308. package/dist/plugins/relations.d.cts +1 -0
  309. package/dist/plugins/relations.d.ts +1 -0
  310. package/dist/plugins/relations.development.cjs +1 -0
  311. package/dist/plugins/relations.development.js +603 -0
  312. package/dist/plugins/relations.js +553 -0
  313. package/dist/plugins/snapshots/index.d.cts +33 -0
  314. package/dist/plugins/snapshots/index.d.ts +33 -0
  315. package/dist/plugins/snapshots/index.d.ts.map +1 -0
  316. package/dist/plugins/snapshots/resume.d.cts +57 -0
  317. package/dist/plugins/snapshots/resume.d.ts +57 -0
  318. package/dist/plugins/snapshots/resume.d.ts.map +1 -0
  319. package/dist/plugins/snapshots/snapshot_service.d.cts +59 -0
  320. package/dist/plugins/snapshots/snapshot_service.d.ts +59 -0
  321. package/dist/plugins/snapshots/snapshot_service.d.ts.map +1 -0
  322. package/dist/plugins/snapshots.cjs +1 -0
  323. package/dist/plugins/snapshots.d.cts +1 -0
  324. package/dist/plugins/snapshots.d.ts +1 -0
  325. package/dist/plugins/snapshots.development.cjs +1 -0
  326. package/dist/plugins/snapshots.development.js +737 -0
  327. package/dist/plugins/snapshots.js +737 -0
  328. package/dist/plugins/solid/index.d.cts +8 -0
  329. package/dist/plugins/solid/index.d.ts +8 -0
  330. package/dist/plugins/solid/index.d.ts.map +1 -0
  331. package/dist/plugins/solid/solid.d.cts +97 -0
  332. package/dist/plugins/solid/solid.d.ts +97 -0
  333. package/dist/plugins/solid/solid.d.ts.map +1 -0
  334. package/dist/plugins/solid.cjs +1 -0
  335. package/dist/plugins/solid.d.cts +1 -0
  336. package/dist/plugins/solid.d.ts +1 -0
  337. package/dist/plugins/solid.development.cjs +1 -0
  338. package/dist/plugins/solid.development.js +319 -0
  339. package/dist/plugins/solid.js +319 -0
  340. package/dist/plugins/workers/index.d.cts +75 -0
  341. package/dist/plugins/workers/index.d.ts +75 -0
  342. package/dist/plugins/workers/index.d.ts.map +1 -0
  343. package/dist/plugins/workers/node_threads.d.cts +25 -0
  344. package/dist/plugins/workers/node_threads.d.ts +25 -0
  345. package/dist/plugins/workers/node_threads.d.ts.map +1 -0
  346. package/dist/plugins/workers/plan.d.cts +61 -0
  347. package/dist/plugins/workers/plan.d.ts +61 -0
  348. package/dist/plugins/workers/plan.d.ts.map +1 -0
  349. package/dist/plugins/workers/pool.d.cts +144 -0
  350. package/dist/plugins/workers/pool.d.ts +144 -0
  351. package/dist/plugins/workers/pool.d.ts.map +1 -0
  352. package/dist/plugins/workers/protocol.d.cts +112 -0
  353. package/dist/plugins/workers/protocol.d.ts +112 -0
  354. package/dist/plugins/workers/protocol.d.ts.map +1 -0
  355. package/dist/plugins/workers/worker_bind.d.cts +64 -0
  356. package/dist/plugins/workers/worker_bind.d.ts +64 -0
  357. package/dist/plugins/workers/worker_bind.d.ts.map +1 -0
  358. package/dist/plugins/workers/worker_loop.d.cts +14 -0
  359. package/dist/plugins/workers/worker_loop.d.ts +14 -0
  360. package/dist/plugins/workers/worker_loop.d.ts.map +1 -0
  361. package/dist/plugins/workers.cjs +1 -0
  362. package/dist/plugins/workers.d.cts +1 -0
  363. package/dist/plugins/workers.d.ts +1 -0
  364. package/dist/plugins/workers.development.cjs +1 -0
  365. package/dist/plugins/workers.development.js +596 -0
  366. package/dist/plugins/workers.js +474 -0
  367. package/dist/primitives.cjs +1 -1
  368. package/dist/primitives.d.cts +4 -4
  369. package/dist/primitives.d.ts +4 -4
  370. package/dist/primitives.development.cjs +1 -1
  371. package/dist/primitives.development.js +66 -22
  372. package/dist/primitives.js +66 -22
  373. package/dist/shared-BKl12xF1.js +132 -0
  374. package/dist/shared-Dk-pACZT.cjs +1 -0
  375. package/dist/shared.cjs +1 -1
  376. package/dist/shared.d.cts +7 -7
  377. package/dist/shared.d.ts +7 -7
  378. package/dist/shared.d.ts.map +1 -1
  379. package/dist/shared.development.cjs +1 -1
  380. package/dist/shared.development.js +4 -3
  381. package/dist/shared.js +4 -3
  382. package/dist/topological_sort-Cc_yXqPT.js +346 -0
  383. package/dist/topological_sort-vp1imU6D.cjs +1 -0
  384. package/dist/type_primitives/assertions.d.cts +12 -16
  385. package/dist/type_primitives/assertions.d.ts +12 -16
  386. package/dist/type_primitives/assertions.d.ts.map +1 -1
  387. package/dist/type_primitives/binary_heap/binary_heap.d.cts +2 -6
  388. package/dist/type_primitives/binary_heap/binary_heap.d.ts +2 -6
  389. package/dist/type_primitives/binary_heap/binary_heap.d.ts.map +1 -1
  390. package/dist/type_primitives/bitset/bitset.d.cts +7 -11
  391. package/dist/type_primitives/bitset/bitset.d.ts +7 -11
  392. package/dist/type_primitives/bitset/bitset.d.ts.map +1 -1
  393. package/dist/type_primitives/brand.d.cts +2 -7
  394. package/dist/type_primitives/brand.d.ts +2 -7
  395. package/dist/type_primitives/brand.d.ts.map +1 -1
  396. package/dist/type_primitives/error.d.cts +1 -2
  397. package/dist/type_primitives/error.d.ts +1 -2
  398. package/dist/type_primitives/error.d.ts.map +1 -1
  399. package/dist/type_primitives/index.d.cts +1 -1
  400. package/dist/type_primitives/index.d.ts +1 -1
  401. package/dist/type_primitives/sparse_map/sparse_map.d.cts +3 -7
  402. package/dist/type_primitives/sparse_map/sparse_map.d.ts +3 -7
  403. package/dist/type_primitives/sparse_map/sparse_map.d.ts.map +1 -1
  404. package/dist/type_primitives/sparse_set/sparse_set.d.cts +2 -6
  405. package/dist/type_primitives/sparse_set/sparse_set.d.ts +2 -6
  406. package/dist/type_primitives/sparse_set/sparse_set.d.ts.map +1 -1
  407. package/dist/type_primitives/topological_sort/topological_sort.d.cts +1 -5
  408. package/dist/type_primitives/topological_sort/topological_sort.d.ts +1 -5
  409. package/dist/type_primitives/topological_sort/topological_sort.d.ts.map +1 -1
  410. package/dist/type_primitives/typed_arrays/typed_arrays.d.cts +18 -17
  411. package/dist/type_primitives/typed_arrays/typed_arrays.d.ts +18 -17
  412. package/dist/type_primitives/typed_arrays/typed_arrays.d.ts.map +1 -1
  413. package/dist/utils/error.d.ts.map +1 -1
  414. package/dist/version.d.cts +4 -4
  415. package/dist/version.d.ts +4 -4
  416. package/dist/worker.cjs +1 -0
  417. package/dist/worker.d.cts +17 -0
  418. package/dist/worker.d.ts +17 -0
  419. package/dist/worker.d.ts.map +1 -0
  420. package/dist/worker.development.cjs +1 -0
  421. package/dist/worker.development.js +253 -0
  422. package/dist/worker.js +253 -0
  423. package/package.json +363 -191
  424. package/dist/core/ecs/builtin_relations.d.cts +0 -43
  425. package/dist/core/ecs/builtin_relations.d.ts +0 -43
  426. package/dist/core/ecs/builtin_relations.d.ts.map +0 -1
  427. package/dist/core/ecs/event_registry.d.cts +0 -22
  428. package/dist/core/ecs/event_registry.d.ts +0 -22
  429. package/dist/core/ecs/event_registry.d.ts.map +0 -1
  430. package/dist/core/ecs/relation_service.d.ts.map +0 -1
  431. package/dist/core/ecs/resume.d.cts +0 -85
  432. package/dist/core/ecs/resume.d.ts +0 -85
  433. package/dist/core/ecs/resume.d.ts.map +0 -1
  434. package/dist/core/ecs/snapshot_service.d.cts +0 -94
  435. package/dist/core/ecs/snapshot_service.d.ts +0 -94
  436. package/dist/core/ecs/snapshot_service.d.ts.map +0 -1
  437. package/dist/extensions/editor/editor.d.ts.map +0 -1
  438. package/dist/extensions/editor/field_handle.d.ts.map +0 -1
  439. package/dist/extensions/editor/index.cjs +0 -1
  440. package/dist/extensions/editor/index.d.cts +0 -21
  441. package/dist/extensions/editor/index.d.ts +0 -21
  442. package/dist/extensions/editor/index.d.ts.map +0 -1
  443. package/dist/extensions/editor/index.development.cjs +0 -1
  444. package/dist/extensions/reactive/ecs_sync.d.cts +0 -214
  445. package/dist/extensions/reactive/ecs_sync.d.ts +0 -214
  446. package/dist/extensions/reactive/ecs_sync.d.ts.map +0 -1
  447. package/dist/extensions/reactive/index.cjs +0 -1
  448. package/dist/extensions/reactive/index.d.cts +0 -23
  449. package/dist/extensions/reactive/index.d.ts +0 -23
  450. package/dist/extensions/reactive/index.d.ts.map +0 -1
  451. package/dist/extensions/reactive/index.development.cjs +0 -1
  452. package/dist/extensions/reactive/index.development.js +0 -215
  453. package/dist/extensions/reactive/index.js +0 -215
  454. package/dist/extensions/solid/index.cjs +0 -1
  455. package/dist/extensions/solid/index.d.cts +0 -6
  456. package/dist/extensions/solid/index.d.ts +0 -6
  457. package/dist/extensions/solid/index.d.ts.map +0 -1
  458. package/dist/extensions/solid/index.development.cjs +0 -1
  459. package/dist/extensions/solid/index.development.js +0 -40
  460. package/dist/extensions/solid/index.js +0 -36
  461. package/dist/extensions/solid/kernel_solid.d.cts +0 -45
  462. package/dist/extensions/solid/kernel_solid.d.ts +0 -45
  463. package/dist/extensions/solid/kernel_solid.d.ts.map +0 -1
  464. package/dist/host_commands-3jyFfWNg.js +0 -2326
  465. package/dist/host_commands-DNf0f6ko.cjs +0 -1
  466. package/dist/internal-C9jjL90H.js +0 -2485
  467. package/dist/internal-RZN14uMw.cjs +0 -2
  468. package/dist/interop-CT-REx0W.cjs +0 -1
  469. package/dist/interop-CcY6ASQc.js +0 -18
  470. package/dist/interop-DqxleBo7.js +0 -18
  471. package/dist/interop-T1HZ-Dpa.cjs +0 -1
  472. package/dist/kernel-Cz2Kxlwl.js +0 -240
  473. package/dist/kernel-DgyrLFjW.js +0 -227
  474. package/dist/kernel-sw7ScKWu.cjs +0 -1
  475. package/dist/kernel-yWV3XnAb.cjs +0 -1
  476. package/dist/reactive/array.d.cts +0 -24
  477. package/dist/reactive/array.d.ts +0 -24
  478. package/dist/reactive/array.d.ts.map +0 -1
  479. package/dist/reactive/index.cjs +0 -1
  480. package/dist/reactive/index.d.cts +0 -11
  481. package/dist/reactive/index.d.ts +0 -11
  482. package/dist/reactive/index.d.ts.map +0 -1
  483. package/dist/reactive/index.development.cjs +0 -1
  484. package/dist/reactive/index.development.js +0 -18
  485. package/dist/reactive/index.js +0 -18
  486. package/dist/reactive/interop.d.cts +0 -19
  487. package/dist/reactive/interop.d.ts +0 -19
  488. package/dist/reactive/interop.d.ts.map +0 -1
  489. package/dist/reactive/kernel.d.cts +0 -73
  490. package/dist/reactive/kernel.d.ts +0 -73
  491. package/dist/reactive/kernel.d.ts.map +0 -1
  492. package/dist/reactive/map.d.cts +0 -16
  493. package/dist/reactive/map.d.ts +0 -16
  494. package/dist/reactive/map.d.ts.map +0 -1
  495. package/dist/reactive/shallow.d.cts +0 -11
  496. package/dist/reactive/shallow.d.ts +0 -11
  497. package/dist/reactive/shallow.d.ts.map +0 -1
  498. package/dist/reactive/struct.d.cts +0 -10
  499. package/dist/reactive/struct.d.ts +0 -10
  500. package/dist/reactive/struct.d.ts.map +0 -1
  501. package/dist/shallow-9S1pY_Iw.js +0 -159
  502. package/dist/shallow-C5YmTbtb.cjs +0 -1
  503. package/dist/shallow-DQ8aG51_.cjs +0 -1
  504. package/dist/shallow-DfnAm9vG.js +0 -150
  505. package/dist/shared-BMXh9hxm.cjs +0 -1
  506. package/dist/shared-DQKK0i-E.js +0 -109
  507. package/dist/topological_sort-BDvEyb9W.cjs +0 -1
  508. package/dist/topological_sort-DK6EjpWa.js +0 -135
  509. package/dist/typed_arrays-BcXcnzB4.js +0 -258
  510. package/dist/typed_arrays-D3NmwtCG.cjs +0 -1
@@ -1,162 +1,167 @@
1
1
  import { Template, TemplateOverrides } from './store.cjs';
2
2
  import { FrameTraceSink } from './frame_trace.cjs';
3
- import { ObserverHandle, EntitySetObserverConfig, ArchetypeSetObserverConfig, StructuralObserverConfig } from './observer.cjs';
4
- import { ColumnStore, ColumnStoreRegionHandle, StoreRegionSpec } from '../store/index.cjs';
5
- import { ECSRelations, ECSEvents, ECSResources, ECSSnapshots } from './facades.cjs';
6
- import { SCHEDULE, SystemEntry, SystemSet, SystemSetConfig } from './schedule.cjs';
3
+ import { ColumnStore, ColumnStoreRegionHandle } from '../store/index.cjs';
4
+ import { ECSResources, ECSSnapshots } from './facades.cjs';
5
+ import { Plugin, PluginsOf } from './plugin.cjs';
6
+ import { Phase, PhaseConfig, SchedulePhase } from './phase.cjs';
7
7
  import { Archetype, ArchetypeID } from './archetype.cjs';
8
- import { SystemContext, Query, QueryBuilder, QueryCache, QueryResolver } from './query.cjs';
8
+ import { Query, QueryBuilder } from './query.cjs';
9
+ import { QueryCache, QueryResolver } from './query_cache.cjs';
10
+ import { QueryTerms } from './query_terms.cjs';
11
+ import { SystemContext } from './system_context.cjs';
9
12
  import { EntityID } from './entity.cjs';
10
- import { ReadonlyComponentRef } from './ref.cjs';
13
+ import { ComponentCursor, ReadonlyComponentCursor, ReadonlyComponentRef } from './ref.cjs';
11
14
  import { ComponentDef, ComponentHandle, ComponentRegisterOptions, ComponentSchema, CompleteFieldValues, Bundle, BundleOrDef, StrictBundles, DefsOf } from './component.cjs';
12
15
  import { SparseComponentDef, SparseComponentID } from './sparse_store.cjs';
13
16
  import { RelationDef } from './relation.cjs';
14
17
  import { SystemFn, SystemConfig, SystemDescriptor, TypedSystemConfig, DenseAccessDecl, SpawnsAccessDecl, DespawnsAccessDecl, TransitionsAccessDecl, SparseAccessDecl, RelationsAccessDecl, ResourcesAccessDecl } from './system.cjs';
18
+ import { SystemEntry, SystemSet, SystemSetConfig } from './system_set.cjs';
15
19
  import { BitSet, TypedArrayTag } from '../../type_primitives/index.cjs';
16
20
  import { StoreLayoutListener } from './store_layout_listener.cjs';
17
21
  import { ComputeBackend } from './compute_backend.cjs';
18
- import { ResolvedECSMemory, ECSMemoryOptions } from './ecs_memory.cjs';
19
- export interface ECSOptions {
20
- fixedTimestep?: number;
21
- maxFixedSteps?: number;
22
- /** Sink for dev-mode engine diagnostics (currently the schedule's
23
- * dropped-ordering-edge warning). Defaults to `console.warn`. Mirrors the
24
- * `FrameTraceSink` seam's injectable style no global logger. */
25
- onWarn?: (message: string) => void;
26
- /** How the world's memory is sized and backed (#682) — the single
27
- * sizing surface, replacing the pre-release `initialCapacity` +
28
- * `bufferAllocator` pair. Express intent through exactly one arm:
29
- * `{ budget: { entities } }` (derive everything), `{ maxBytes }`
30
- * (explicit cap), `{ wasm: { memory } | { maximumPages } }` (the SAB
31
- * IS a WebAssembly.Memory zero-copy with a WASM `ComputeBackend`), or
32
- * `{ allocator }` (expert escape hatch, in-place-typed per ADR-0008).
33
- * Omitted growable backing with a 256 MiB cap and 1024-row columns.
34
- * The resolved plan is exposed as `ECS.memoryPlan`. */
35
- memory?: ECSMemoryOptions;
36
- /** Consumer-declared SAB regions (#623), forwarded to `Store`. Each
37
- * `StoreRegionSpec` carries an opaque `region_id`, a precomputed byte size,
38
- * and an `init` closure; the engine lays them out generically and exposes
39
- * them via `regionHandle(id)` / `regionOffset(id)`. A game (e.g.
40
- * `@internal/sim`'s region specs) supplies these — the engine ships no
41
- * game regions of its own. Replaces the eight game-named region options
42
- * (`terrain_map_radius`, `spatial_grid_*`, `army_*`, `flow_field_*`,
43
- * `actionRingCapacitySlots`) the ECS used to carry. (ADR-0018.) */
44
- regions?: readonly StoreRegionSpec[];
45
- /** Byte size of the opt-in sim-bindings region (#625), forwarded to `Store`.
46
- * A consumer that attaches a WASM `ComputeBackend` passes its own size — for
47
- * this game, `@internal/sim`'s `SIM_BINDINGS_BYTES` (computed from the binding
48
- * manifest) so the host can publish the `(component_id, field_id)` IDs the
49
- * accelerated systems read. Omitted / 0 no region: a pure-TS world pays
50
- * nothing for the WASM seam. The size is a runtime input, not an engine ABI
51
- * constant, since #625 de-welded it from the generated ABI. */
52
- bindingsRegionBytes?: number;
53
- /** Opt into the **determinism surface** (#626 / ADR-0020), forwarded to
54
- * `Store`. Default `false`. When `false`, the canonical-ordering methods
55
- * (`stateHash`, `snapshotSparse`, `restoreSparse`) throw
56
- * `DETERMINISM_DISABLED`; when `true`, today's replay/hash behavior is
57
- * reproduced bit-for-bit. Determinism is the implementer's choice our
58
- * server match opts in (replay verification), the client stays off (it rolls
59
- * back via diffs, not re-sim). The flag gates ONLY that surface: memory-safety
60
- * invariants (the in-place SAB allocator, ADR-0008) and the `enabled_count`
61
- * partition are always-on regardless. */
62
- deterministic?: boolean;
63
- }
64
- export declare class ECS implements QueryResolver {
65
- private readonly store;
66
- private readonly schedule;
67
- private readonly ctx;
68
- /** Component observers (#517 §1 / ADR-0013). Inert until `observe(...)` is
69
- * called the structural-flush fast path is byte-for-byte unchanged. */
70
- private readonly _observers;
71
- /** Relations: register/add/remove/has, wildcard + traversal reads,
72
- * reverse-index compaction. See `ECSRelations`. */
73
- readonly relations: ECSRelations;
74
- /** Host-side event channels + signals: register/registerSignal/emit/read
75
- * (system-side `ctx.emit` is unchanged). See `ECSEvents`. */
76
- readonly events: ECSEvents;
77
- /** World resources: register/get/set/remove/has. See `ECSResources`. */
22
+ import { ResolvedECSMemory } from './ecs_memory.cjs';
23
+ import { ECSOptions } from './ecs_options.cjs';
24
+ import { computeArchetypeClosure } from './archetype_closure.cjs';
25
+ /** `ECSOptions` moved to `ecs_options.ts` with the guards that read it. The
26
+ * re-export holds the name a caller already imports from this module. */
27
+ export type { ECSOptions };
28
+ /** The plugins installed on a world. Each optional subsystem contributes
29
+ * its facade property here, so a world that never installed one cannot name it.
30
+ * The empty default keeps `ECS` usable unparameterised. */
31
+ export type Plugins = object;
32
+ export declare class ECS<C extends Plugins = object> implements QueryResolver {
33
+ /** Phantom. Carries the installed-plugin surface so `C` is measurable
34
+ * to the compiler. Declared, never assigned, and erased from the emitted
35
+ * JavaScript, so it costs a world nothing. */
36
+ readonly __plugins?: C;
37
+ /** Build a world with plugins installed.
38
+ *
39
+ * The returned type is the world intersected with the facades its plugins
40
+ * contribute, so `ECS.create({ plugins: [relations()] }).relations` type-checks
41
+ * and the same read on a bare `new ECS()` does not. Reach for `new ECS()`
42
+ * when the world needs none of the optional subsystems: that world does not
43
+ * carry their code.
44
+ *
45
+ * @example
46
+ * import { relations } from "@oasys/oecs/relations";
47
+ * const world = ECS.create({ plugins: [relations()] });
48
+ * world.relations.register();
49
+ */
50
+ static create<const P extends readonly Plugin<object>[]>(options?: ECSOptions & {
51
+ readonly plugins?: P;
52
+ }): ECS<PluginsOf<P>> & PluginsOf<P>;
53
+ /** The host a plugin installs through. Built per world, once per
54
+ * install. Cold path. */
55
+ private _pluginHost;
56
+ /** Where this world's bytes are, for a plugin that reads them directly.
57
+ * Built once, at install.
58
+ *
59
+ * `backing` is a getter, because a reader can attach after a grow, and a
60
+ * grow replaces the buffer the world started with. The wasm memory
61
+ * survives a grow, so it answers first. Cold path. */
62
+ private _pluginMemory;
63
+ private readonly _store;
64
+ private readonly _schedule;
65
+ private readonly _ctx;
66
+ /** What each plugin contributes to the archetype closure `startup()`
67
+ * plants. Empty on a world that installed no such plugin, and read once, at
68
+ * startup. */
69
+ private readonly _prewarmSources;
70
+ /** What each plugin ends when the world goes away, in install order. */
71
+ private readonly _disposeHooks;
72
+ /** The consumers of the tick-tail detection point, in install order. Each
73
+ * one runs once per `update()` with the change tick of the point. Empty on
74
+ * a world that installed no consumer, and the tail reads the length once. */
75
+ private readonly _settleHooks;
76
+ /** World resources, to register, get, set, remove and test. See
77
+ * `ECSResources`. */
78
78
  readonly resources: ECSResources;
79
- /** Determinism surface: capture/restore (full + sparse), stateHash,
80
- * the `deterministic` flag. See `ECSSnapshots`. */
79
+ /** Determinism: `stateHash()` and the `deterministic` flag, both properties
80
+ * of the world itself. Capture and restore are not here. They arrive with
81
+ * the snapshot plugin, which replaces this with a widened facade, so a
82
+ * world that never installs it carries no serialization code. */
81
83
  readonly snapshots: ECSSnapshots;
82
- private readonly systems;
83
- private nextSystemId;
84
+ private readonly _systems;
85
+ private _nextSystemId;
84
86
  private _tick;
85
87
  private _updating;
86
88
  private _fixedTimestep;
87
89
  private _accumulator;
88
90
  private _maxFixedSteps;
89
- private readonly scratchMask;
91
+ private readonly _scratchMask;
90
92
  private _nextQueryIdCounter;
91
- /** @internal Query-composition caches (QueryResolver seam) not public API. */
92
- readonly _caches: QueryCache;
93
+ /** @internal Query-composition caches (QueryResolver seam), not public API. */
94
+ readonly caches: QueryCache;
93
95
  private readonly _layoutSubscribers;
94
96
  private _backend;
97
+ private _routePlanner;
95
98
  private readonly _memory;
96
- /** What `ECSOptions.memory` resolved to (#682): backing allocator kind,
99
+ /** What `ECSOptions.memory` resolved to: backing allocator kind,
97
100
  * column capacity, entity-index reservation, byte cap, and a
98
- * human-readable derivation trace. Diagnostics surface log it when
101
+ * human-readable derivation trace. Diagnostics surface, log it when
99
102
  * sizing questions come up instead of reverse-engineering the SAB. */
100
103
  get memoryPlan(): ResolvedECSMemory;
101
104
  /** The backing `WebAssembly.Memory` when `memory.wasm` was used (both
102
105
  * bring-your-own and engine-constructed), else `null`. A consumer hands
103
- * this to its WASM `ComputeBackend` so the sim and the live columns
106
+ * this to its WASM `ComputeBackend` so the module and the live columns
104
107
  * share the same bytes. */
105
108
  get wasmMemory(): WebAssembly.Memory | null;
106
109
  constructor(options?: ECSOptions);
107
110
  /** Batch variant of `regionHandle` for hosts wiring several consumer
108
- * regions at startup: returns the handles in argument order, never null
109
- * throws ONE `REGION_NOT_DECLARED` naming every missing region id instead
111
+ * regions at startup: returns the handles in argument order, never null,
112
+ * throws one `REGION_NOT_DECLARED` naming every missing region id instead
110
113
  * of a null-guard per region. Same staleness rule as `regionHandle`:
111
114
  * re-fetch after a SAB grow. */
112
115
  regionHandles(...regionIds: number[]): ColumnStoreRegionHandle[];
113
- /** Subscribe to SAB-layout publications. `listener.setLayout(0)` is
114
- * called immediately to seed the initial layout, then again after
115
- * every SAB grow / extend (the `view_stamp` republish protocol).
116
- * Returns an unsubscribe function.
116
+ /** Subscribe to store-layout publications. `listener.setLayout(storeBase)`
117
+ * is called immediately to seed the initial layout, then again after every
118
+ * grow and extend (the `view_stamp` republish protocol). The argument is the
119
+ * byte offset of the header inside the backing, and every offset the
120
+ * listener then reads from the bytes is relative to it. Returns an
121
+ * unsubscribe function.
117
122
  *
118
- * The engine has no concept of what subscribes it publishes SAB layouts
123
+ * The engine has no concept of what subscribes. It publishes SAB layouts
119
124
  * and walks away. A consumer subscribes whatever wrapper it owns (a compute
120
125
  * backend, a Worker proxy, a debug recorder) and drives it from its own
121
126
  * code. A `ComputeBackend` is subscribed automatically by `attachBackend`,
122
127
  * so most consumers call that rather than this directly. */
123
- onStoreLayoutPublished(listener: StoreLayoutListener): () => void;
124
- /** Attach an opt-in compute backend (#622). Default is none: a bare `ECS`
128
+ subscribeLayout(listener: StoreLayoutListener): () => void;
129
+ /** Attach an opt-in compute backend. Default is none: a bare `ECS`
125
130
  * runs pure-TS systems and the schedule's dispatch is byte-for-byte the
126
131
  * no-backend path. Once attached, a scheduled system carrying a
127
132
  * `backendHandle` (its `SystemConfig`) is executed via `backend.run(handle)`
128
- * instead of its `fn` closure; systems without a handle are unaffected.
133
+ * instead of its `fn` closure. Systems without a handle are unaffected.
129
134
  *
130
135
  * The backend is also subscribed as a SAB-layout listener (seeded now, then
131
- * republished on every grow), folding in the `onStoreLayoutPublished` seam.
136
+ * republished on every grow), folding in the `subscribeLayout` seam.
132
137
  * Returns a detach function that unsubscribes the layout listener and reverts
133
138
  * the schedule to the pure-TS path.
134
139
  *
135
140
  * One backend per ECS: attaching while one is already attached throws in
136
141
  * `DEV` (detach first). The engine never inspects the backend beyond
137
- * `setLayout` / `run` it carries no game vocabulary. */
142
+ * `setLayout` and `run`. It carries no game vocabulary. */
138
143
  attachBackend(backend: ComputeBackend): () => void;
139
144
  get fixedTimestep(): number;
140
145
  set fixedTimestep(value: number);
141
146
  get fixedAlpha(): number;
142
- /** Attach (or detach with `null`) a per-world frame-trace sink (ADR-0030):
147
+ /** Attach (or detach with `null`) a per-world frame-trace sink:
143
148
  * the engine then fires structured `FrameTraceSink` events at each system,
144
149
  * flush, command, observer firing, and event during `update()`, so a consumer
145
150
  * can reconstruct exactly what travelled through the ECS each frame. The sink
146
151
  * also receives a `phaseBoundary(phase)` at each phase's post-flush settle
147
- * point the safe seam to read `stateHash()` between phases of one frame and
148
- * bisect a divergence to the exact phase (#797 / ADR-0032). The seam is
149
- * `DEV`-gated end to end in a production build this setter keeps an empty
150
- * body and the world never retains a sink. The sink only observes; it does not
152
+ * point, the safe seam to read `stateHash()` between phases of one frame and
153
+ * bisect a divergence to the exact phase. The seam is
154
+ * `DEV`-gated end to end, in a production build this setter keeps an empty
155
+ * body and the world never retains a sink. The sink only observes. It does not
151
156
  * perturb `stateHash`, ordering, or any behaviour. */
152
157
  setTrace(sink: FrameTraceSink | null): void;
153
158
  /**
154
159
  * Register a dense component and get back its typed handle. Record syntax
155
- * gives per-field type control; the array shorthand types every field the
156
- * same (default `"f64"` rejected on a `{ deterministic: true }` world
157
- * (#777), pass an explicit integer type there). An empty schema `{}` is a
160
+ * gives per-field type control. The array shorthand types every field the
161
+ * same (default `"f64"`, rejected on a `{ deterministic: true }` world,
162
+ * pass an explicit integer type there). An empty schema `{}` is a
158
163
  * tag. `opts.name` labels dev-mode diagnostics (`'Pos' (component 5)`
159
- * instead of `component 5`) diagnostic only, no behavioural effect.
164
+ * instead of `component 5`), diagnostic only, no behavioural effect.
160
165
  *
161
166
  * The handle is *callable*: `Pos({ x: 1 })` mints a `Bundle` for the
162
167
  * attach surfaces (`spawnBundle`, `ctx.commands.spawn`, `addComponent`).
@@ -165,7 +170,7 @@ export declare class ECS implements QueryResolver {
165
170
  * const Pos = ecs.registerComponent({ x: "f64", y: "f64" });
166
171
  * const Hp = ecs.registerComponent(["current", "max"], "i32");
167
172
  * const Frozen = ecs.registerComponent({}, { name: "Frozen" }); // tag
168
- * ecs.getField(e, Pos, "x"); // field names/types flow from the schema
173
+ * ecs.getField(e, Pos, "x"); // field names and types flow from the schema
169
174
  */
170
175
  registerComponent<S extends Record<string, TypedArrayTag>>(schema: S, opts?: ComponentRegisterOptions): ComponentDef<S>;
171
176
  registerComponent<const F extends readonly string[], T extends TypedArrayTag = "f64">(fields: F, type?: T, opts?: ComponentRegisterOptions): ComponentDef<{
@@ -176,35 +181,42 @@ export declare class ECS implements QueryResolver {
176
181
  readonly [K in F[number]]: T;
177
182
  }>;
178
183
  /**
179
- * Spawn an entity, immediately. Bare `spawn()` creates an empty entity
184
+ * Spawn an entity, immediately. Bare `spawn()` creates an empty entity,
180
185
  * attach components afterward. `spawn(template, overrides?)` lands
181
186
  * directly in the template's archetype with zero archetype transitions,
182
187
  * applying optional flat per-field overrides on top of the template
183
188
  * defaults. Inside a system use `ctx.commands.spawn(...)` instead.
184
189
  *
190
+ * `spawn` takes a template. It does not take a component definition, and it
191
+ * does not take a bundle. For components with no template, use `spawnBundle`.
192
+ *
185
193
  * @example
186
194
  * const e = ecs.spawn();
187
195
  * ecs.addComponent(e, Pos, { x: 0, y: 0 });
188
196
  *
189
- * const Bullet = ecs.template([{ def: Pos, values: { x: 0, y: 0 } }]);
197
+ * // Build a template from callable bundles.
198
+ * const Bullet = ecs.template(Pos({ x: 0, y: 0 }), Vel({ vx: 1, vy: 0 }));
190
199
  * const b = ecs.spawn(Bullet, { x: 5 }); // override a template default
200
+ *
201
+ * // One entity, components given directly, no template.
202
+ * const c = ecs.spawnBundle(Pos({ x: 0, y: 0 }), Vel({ vx: 1, vy: 0 }));
191
203
  */
192
204
  spawn(): EntityID;
193
205
  spawn<Defs extends readonly ComponentDef[]>(template: Template<Defs>, overrides?: TemplateOverrides<Defs>): EntityID;
194
206
  /**
195
- * Spawn an entity from varargs bundles (§bundles) — the immediate
207
+ * Spawn an entity from varargs bundles, the immediate
196
208
  * host-side analog of `ctx.commands.spawn`, and the same callable-bundle
197
- * grammar as `addComponents` / `template`. `ecs.spawnBundle(Pos({x,y}),
198
- * Vel({vx:1}), IsEnemy)` collapses the attach shapes into one; each item is
209
+ * grammar as `addComponents` and `template`. `ecs.spawnBundle(Pos({x,y}),
210
+ * Vel({vx:1}), IsEnemy)` collapses the attach shapes into one. Each item is
199
211
  * checked against its own def's schema (`StrictBundles`). Bundles are applied
200
- * immediately; a single combined-archetype insertion (one transition instead
201
- * of one-per-component) is a later optimization for now this mirrors the
212
+ * immediately. A single combined-archetype insertion (one transition instead
213
+ * of one-per-component) is a later optimization, for now this mirrors the
202
214
  * per-component `addComponent` path (unlike `addComponents`, which batches).
203
215
  *
204
- * Immediate inside a system use the deferred `ctx.commands.spawn(...)`
216
+ * Immediate, inside a system use the deferred `ctx.commands.spawn(...)`
205
217
  * (calling this from a system body throws in DEV). Note the redirect trades
206
218
  * timing: `commands.spawn` returns the id now but defers the attaches to the
207
- * phase flush, so the entity sits in its empty/partial archetype until then
219
+ * phase flush, so the entity sits in its empty and partial archetype until then,
208
220
  * unlike `spawnBundle`'s immediate, fully-populated archetype.
209
221
  */
210
222
  spawnBundle<Items extends readonly BundleOrDef[]>(...items: StrictBundles<Items>): EntityID;
@@ -212,32 +224,34 @@ export declare class ECS implements QueryResolver {
212
224
  * shared `overrides` object to every spawned row (same typed keys as
213
225
  * `spawn`). Field writes are O(columns) (one `TypedArray.fill` per
214
226
  * column), not O(count×columns). Returns the new ids in spawn order.
215
- * Immediate inside a system use `ctx.commands.spawn` per entity (calling
227
+ * Immediate, inside a system use `ctx.commands.spawn` per entity (calling
216
228
  * this from a system body throws in DEV). */
217
229
  spawnMany<Defs extends readonly ComponentDef[]>(template: Template<Defs>, count: number, overrides?: TemplateOverrides<Defs>): EntityID[];
218
230
  /** DEV-only: throw when an *immediate* host structural mutator is called
219
- * from inside one of THIS world's system bodies (or an observer / onAdded
220
- * hook — they run in the same access spans). One rule for every host
221
- * structural mutator despawn, add/remove(Components), batchAdd/Remove,
222
- * disable/enable, AND the spawn family (spawn/spawnBundle/spawnMany): an
223
- * immediate structural op mid-schedule can move or swap rows a running query
224
- * is walking — or, for a spawn-append into that archetype, trip a column
225
- * realloc under it and it is invisible to observers. The archetype-level
231
+ * from inside one of this world's system bodies. An observer callback and an
232
+ * `onAdded` hook run in the same access span, so the guard covers them too.
233
+ * One rule covers every host structural mutator: `despawn`, `addComponent`,
234
+ * `addComponents`, `removeComponent`, `removeComponents`,
235
+ * `batchAddComponent`, `batchRemoveComponent`, `disable`, `enable`, and the
236
+ * spawn family (`spawn`, `spawnBundle` and `spawnMany`).
237
+ * An immediate structural op mid-schedule can move or swap rows
238
+ * a running query is walking. A spawn-append into that archetype can trip a
239
+ * column realloc under it. Neither is visible to observers. The archetype-level
226
240
  * `_iterDepth` guard only catches mutations touching the archetype currently
227
241
  * being iterated (and the append paths skip even that), so an op landing
228
- * elsewhere would silently skip observers; the receiver rule ("inside a
242
+ * elsewhere would silently skip observers. The receiver rule ("inside a
229
243
  * system, use ctx.commands") is enforced wholesale here.
230
244
  *
231
- * `_updating` scopes the guard to THIS world: the accessCheck slot is
245
+ * `_updating` scopes the guard to this world: the accessCheck slot is
232
246
  * process-global, so without it a system of world A mutating world B (a
233
- * supported #785 pattern B is not mid-iteration) would false-throw. */
234
- private _assertHostMutationOutsideSystem;
235
- /** Immediately destroy an entity `ecs.despawn(e); ecs.isAlive(e)` is
247
+ * supported pattern. B is not mid-iteration) would false-throw. */
248
+ private _assertOutsideSystem;
249
+ /** Immediately destroy an entity, `ecs.despawn(e); ecs.isAlive(e)` is
236
250
  * `false` on the next line, matching the immediacy of every other host
237
251
  * facade mutation. Inside a system the buffered path is
238
- * `ctx.commands.despawn` (applied at the phase flush); calling this from
239
- * a system body throws in DEV, since an immediate destroy mid-iteration
240
- * can invalidate rows the running query is walking. */
252
+ * `ctx.commands.despawn`, applied at the phase flush. A call from a system
253
+ * body throws in DEV, because an immediate destroy mid-iteration can
254
+ * invalidate rows the running query is walking. */
241
255
  despawn(entityId: EntityID): this;
242
256
  /** Disable `entityId` (idempotent). Excluded from default queries until re-enabled. */
243
257
  disable(entityId: EntityID): this;
@@ -245,61 +259,125 @@ export declare class ECS implements QueryResolver {
245
259
  enable(entityId: EntityID): this;
246
260
  /**
247
261
  * Attach a component to an entity, immediately (inside a system, use the
248
- * deferred `ctx.commands.add`). Three shapes: a bare def attaches a tag; a
249
- * bundle (`Pos({ x: 1 })`) zero-fills omitted fields; the explicit
262
+ * deferred `ctx.commands.add`). Three shapes: a bare def attaches a tag. A
263
+ * bundle (`Pos({ x: 1 })`) zero-fills omitted fields. The explicit
250
264
  * `(e, def, values)` form demands every field, so a typo'd or missing
251
265
  * field is a compile error.
252
266
  *
253
267
  * @example
254
268
  * ecs.addComponent(e, Frozen); // tag
255
- * ecs.addComponent(e, Pos({ x: 1 })); // bundle y zero-fills
269
+ * ecs.addComponent(e, Pos({ x: 1 })); // bundle, y zero-fills
256
270
  * ecs.addComponent(e, Pos, { x: 1, y: 2 }); // complete values
257
271
  */
258
272
  addComponent(entityId: EntityID, def: ComponentDef<Record<string, never>>): this;
259
273
  addComponent<S extends ComponentSchema>(entityId: EntityID, bundle: Bundle<S>): this;
260
274
  addComponent<S extends ComponentSchema>(entityId: EntityID, def: ComponentDef<S>, values: CompleteFieldValues<S>): this;
261
275
  /** Batch-attach several components in one archetype transition. Takes the
262
- * same callable-bundle varargs as `spawnBundle` `world.addComponents(e,
263
- * Pos({ x, y }), Vel({ vx }), Frozen)` each item checked against its own
264
- * def's schema (a misspelled or cross-component field is a compile error;
265
- * tags refuse values). Omitted fields zero-fill. */
276
+ * same callable-bundle varargs as `spawnBundle`, `world.addComponents(e,
277
+ * Pos({ x, y }), Vel({ vx }), Frozen)`, each item checked against its own
278
+ * def's schema (a misspelled or cross-component field is a compile error,
279
+ * and a tag refuses values). Omitted fields zero-fill. */
266
280
  addComponents<Items extends readonly BundleOrDef[]>(entityId: EntityID, ...items: StrictBundles<Items>): this;
267
281
  removeComponent(entityId: EntityID, def: ComponentDef): this;
268
- /** Detach several components in one archetype transition the varargs
269
- * mirror of `addComponents` (bare defs; removing needs no values). */
282
+ /** Detach several components in one archetype transition, the varargs
283
+ * mirror of `addComponents` (bare defs, removing needs no values). */
270
284
  removeComponents(entityId: EntityID, ...defs: ComponentDef[]): this;
271
285
  /**
272
- * Bulk add a component to ALL entities in the given archetype.
286
+ * Bulk add a component to all entities in the given archetype.
273
287
  * O(columns) via TypedArray.set() instead of O(N×columns).
274
288
  *
275
289
  * Takes an `ArchetypeID` (from `ArchetypeView.id`) rather than a concrete
276
- * `Archetype` the concrete type is internal (issue #378).
290
+ * `Archetype`, the concrete type is internal.
277
291
  */
278
292
  batchAddComponent(src: ArchetypeID, def: ComponentDef<Record<string, never>>): this;
279
293
  batchAddComponent<S extends ComponentSchema>(src: ArchetypeID, def: ComponentDef<S>, values: CompleteFieldValues<S>): this;
280
294
  /**
281
- * Bulk remove a component from ALL entities in the given archetype.
295
+ * Bulk remove a component from all entities in the given archetype.
282
296
  * O(columns) via TypedArray.set() instead of O(N×columns).
283
297
  *
284
- * Takes an `ArchetypeID` (from `ArchetypeView.id`); see `batchAddComponent`.
298
+ * Takes an `ArchetypeID`, from `ArchetypeView.id`. See `batchAddComponent`.
285
299
  */
286
300
  batchRemoveComponent(src: ArchetypeID, def: ComponentDef): this;
287
301
  getField<S extends ComponentSchema>(entityId: EntityID, def: ComponentDef<S>, field: string & keyof S): number;
288
- /** Host-side parity with `SystemContext.refRead` (POLISH_AUDIT M7): a
289
- * read-only whole-component view for tooling/tests, instead of reading
290
- * field-by-field. Same advisory-`readonly` semantics as the ctx variant;
291
- * no `_changedTick` bump. Dev-throws on a dead entity, or when the entity
292
- * doesn't hold the component (tags included no fields, nothing to ref).
302
+ /** Host-side parity with `SystemContext.refRead`: a
303
+ * read-only whole-component view for tooling and tests, instead of reading
304
+ * field-by-field. Same advisory-`readonly` semantics as the ctx variant,
305
+ * and no `_changedTick` bump. Dev-throws on a dead entity, or when the entity
306
+ * doesn't hold the component (tags included, no fields, nothing to ref).
293
307
  *
294
308
  * **Staleness:** unlike ctx refs (protected by deferred structural changes
295
- * until the phase flush), host-side structural mutations apply immediately
296
- * any `addComponent`/`removeComponent`/`despawn` after creating the ref can
309
+ * until the phase flush), host-side structural mutations apply immediately,
310
+ * any `addComponent`, `removeComponent` and `despawn` after creating the ref can
297
311
  * row-swap so the old ref silently reads *another entity's* data. The ref is
298
- * only valid until the next structural mutation; treat it as an immediate
312
+ * only valid until the next structural mutation. Treat it as an immediate
299
313
  * single-expression read and re-create it after any structural change. */
300
314
  refRead<S extends ComponentSchema>(def: ComponentDef<S>, entityId: EntityID): ReadonlyComponentRef<S>;
301
- /** Total sibling of {@link getField} (POLISH_AUDIT #9): `undefined` when the
302
- * entity is dead or doesn't hold the component, instead of a dev throw /
315
+ /**
316
+ * A re-pointable single-entity cursor over `def`, the by-id sweep accessor.
317
+ *
318
+ * `refRead` resolves an entity one time, and each field after that is almost
319
+ * free. But it allocates one accessor for each entity. That allocation is the
320
+ * largest part of the cost of a read of one field by id, because to make an
321
+ * accessor and to read through it costs much more than to move an accessor
322
+ * that exists. In a loop over a list of entities, the allocation is not
323
+ * necessary: the code discards each accessor, and it then makes an equal
324
+ * accessor for the next entity. You make a cursor one time, and you then
325
+ * move it again:
326
+ *
327
+ * const p = ecs.cursor(Pos);
328
+ * for (let i = 0; i < ids.length; i++) {
329
+ * p.at(ids[i]);
330
+ * p.x += p.y
331
+ * }
332
+ *
333
+ * Reach for it when you touch many entities by id. Reach for `refRead` or
334
+ * `ref` for a single entity, and for `forEachChunk` whenever a query can express
335
+ * the set. A column walk resolves nothing for each row, so it stays quicker
336
+ * than a cursor, a cursor removes the allocation, not the resolution.
337
+ *
338
+ * Mutable, every `at()` stamps the component's change tick, like `ctx.ref`.
339
+ * See `cursorRead` for the read-only variant.
340
+ *
341
+ * **Staleness:** safer than a held ref, because `at()` re-resolves the
342
+ * archetype and row each time, a structural mutation between two `at()` calls
343
+ * cannot make it read the wrong entity. Only the window between one `at()` and
344
+ * the field accesses following it must be free of structural mutation.
345
+ */
346
+ cursor<S extends ComponentSchema>(def: ComponentDef<S>): ComponentCursor<S>;
347
+ /** Read-only {@link cursor}: no change-tick stamp on `at()`. Advisory only,
348
+ * same caveat as `refRead` (the setters exist on the shared prototype). */
349
+ cursorRead<S extends ComponentSchema>(def: ComponentDef<S>): ReadonlyComponentCursor<S>;
350
+ /**
351
+ * A re-pointable single-entity cursor over a sparse component, the sparse
352
+ * sibling of {@link cursor}, and the fastest read by id the engine has.
353
+ *
354
+ * A sparse component's columns are indexed by entity index, so `at(entity)`
355
+ * writes one field and a field access is one load: there is no archetype
356
+ * and no row to resolve, which is what a dense cursor must do on every
357
+ * `at()`. Make the cursor one time and move it in the loop:
358
+ *
359
+ * const hp = ecs.sparseCursor(Health);
360
+ * for (let i = 0; i < ids.length; i++) {
361
+ * hp.at(ids[i]);
362
+ * hp.current -= damage[i];
363
+ * }
364
+ *
365
+ * Mutable, like `cursor`. Once the component keeps row ticks
366
+ * (`trackRows`, or an entity-level `onSet`), `at()` records the entity for
367
+ * them, as the dense cursor does. See `sparseCursorRead` for the read-only
368
+ * variant.
369
+ *
370
+ * **Membership:** in development `at()` throws when the entity is dead or
371
+ * does not hold the component. In production it does not test, and a read
372
+ * then gives whatever the column holds at that index. Test with `hasSparse`
373
+ * first when the component can be absent.
374
+ */
375
+ sparseCursor<S extends ComponentSchema>(def: SparseComponentDef<S>): ComponentCursor<S>;
376
+ /** Read-only {@link sparseCursor}. Advisory only, same caveat as
377
+ * `cursorRead` (the setters exist on the shared prototype). */
378
+ sparseCursorRead<S extends ComponentSchema>(def: SparseComponentDef<S>): ReadonlyComponentCursor<S>;
379
+ /** Total sibling of {@link getField}: `undefined` when the
380
+ * entity is dead or doesn't hold the component, instead of a dev throw and a
303
381
  * prod garbage read. The safe way to probe-and-read in one call:
304
382
  * `ecs.tryGetField(e, Health, "current") ?? 0`. */
305
383
  tryGetField<S extends ComponentSchema>(entityId: EntityID, def: ComponentDef<S>, field: string & keyof S): number | undefined;
@@ -311,63 +389,72 @@ export declare class ECS implements QueryResolver {
311
389
  updateField<S extends ComponentSchema>(entityId: EntityID, def: ComponentDef<S>, field: string & keyof S, fn: (current: number) => number): number;
312
390
  /**
313
391
  * Get the live, cached query matching entities that have **all** of
314
- * `defs`. Queries are deduplicated by mask calling this twice with the
315
- * same terms returns the same instance so build once at setup and reuse;
316
- * the view stays live as archetypes appear. Refine with `.and()` /
317
- * `.without()` / `.anyOf()`; iterate with `eachChunk` (mutating hot path),
392
+ * `defs`. Queries are deduplicated by mask, calling this twice with the
393
+ * same terms returns the same instance, so build once at setup and reuse.
394
+ * The view stays live as archetypes appear. Refine with `.and()`,
395
+ * `.not()` or `.or()`. Iterate with `forEachChunk` (mutating hot path),
318
396
  * `forEach` (per-archetype), or `forEachEntity` (per-entity).
319
397
  *
320
398
  * @example
321
399
  * const movers = ecs.query(Pos, Vel);
322
- * movers.eachChunk((cols, count) => {
400
+ * movers.forEachChunk((cols, count) => {
323
401
  * const { x, y } = cols.mut(Pos);
324
402
  * const { vx, vy } = cols.read(Vel);
325
403
  * for (let i = 0; i < count; i++) { x[i] += vx[i]; y[i] += vy[i]; }
326
404
  * });
327
405
  */
328
406
  query<T extends ComponentDef[]>(...defs: T): Query<T>;
329
- _nextQueryId(): number;
330
- /** QueryResolver implementation creates or retrieves a cached Query. */
331
- _resolveQuery(include: BitSet, exclude: BitSet | null, anyOf: BitSet | null, defs: readonly ComponentDef[]): Query<any>;
407
+ nextQueryId(): number;
408
+ /** QueryResolver implementation, creates or retrieves a cached Query.
409
+ *
410
+ * **Mask ownership: borrowed.** The three mask arguments are read, never
411
+ * retained, the mint path copies each one into the `Query`, into the dedup
412
+ * entry, and (via `Store.registerQuery`) into the registered-query record.
413
+ * So callers may pass a scratch mask they intend to reuse (`ecs.query`) or
414
+ * a live mask they still own (`Query.and`, `.not` and `.or` pass
415
+ * `this._include` etc.). Do not add a caller-side `.copy()` "for safety":
416
+ * on the cache-hit path that is a per-call BitSet + `number[]` allocation
417
+ * for nothing. */
418
+ resolveQuery(include: BitSet, exclude: BitSet | null, anyOf: BitSet | null, defs: readonly ComponentDef[]): Query<any>;
332
419
  /**
333
420
  * Register a system and get its scheduling handle. The config form is the
334
- * production shape: it declares the access surface (`reads` / `writes` are
335
- * mandatory; `spawns` / `despawns` / resource and sparse/relation terms
336
- * optional), which is enforced at runtime in dev *and* narrows `ctx` at
421
+ * production shape. It declares the access surface. `reads` and `writes` are
422
+ * mandatory. The `spawns`, `despawns`, resource, sparse and relation terms
423
+ * are optional. The runtime enforces the surface in dev, and it narrows `ctx` at
337
424
  * the type level so undeclared access fails to compile. Registration does
338
- * not schedule pass the returned descriptor to
425
+ * not schedule, pass the returned descriptor to
339
426
  * `ecs.addSystems(SCHEDULE.UPDATE, ...)`.
340
427
  *
341
428
  * @example
342
- * // Full config declared access, dev-checked and compile-checked
429
+ * // Full config, declared access, dev-checked and compile-checked
343
430
  * const move = ecs.registerSystem({
344
431
  * reads: [Vel],
345
432
  * writes: [Pos],
346
433
  * fn(ctx, dt) {
347
- * movers.eachChunk((cols, count) => { ... });
434
+ * movers.forEachChunk((cols, count) => { ... });
348
435
  * },
349
436
  * });
350
437
  * ecs.addSystems(SCHEDULE.UPDATE, move);
351
438
  *
352
439
  * @example
353
- * // Bare function (no declared access any component touch throws in dev)
440
+ * // Bare function (no declared access, any component touch throws in dev)
354
441
  * ecs.registerSystem((ctx, dt) => { ... });
355
442
  * // Function + query builder (query resolved at registration time)
356
- * ecs.registerSystem((q, ctx, dt) => { q.forEach((arch) => { ... }); }, (qb) => qb.with(Pos, Vel));
443
+ * ecs.registerSystem((q, ctx, dt) => { q.forEach((arch) => { ... }); }, (qb) => qb.and(Pos, Vel));
357
444
  */
358
445
  registerSystem(fn: SystemFn): SystemDescriptor;
359
446
  registerSystem<Defs extends readonly ComponentDef[]>(fn: (q: Query<Defs>, ctx: SystemContext, dt: number) => void, queryFn: (qb: QueryBuilder) => Query<Defs>): SystemDescriptor;
360
- /** `exclusive: true` grants full world access at runtime (§system.ts), so
361
- * the context stays fully permissive at the type layer too. Declared BEFORE
447
+ /** `exclusive: true` grants full world access at runtime (system.ts), so
448
+ * the context stays fully permissive at the type layer too. Declared before
362
449
  * the typed-config overload so exclusive configs never get narrowed. */
363
450
  registerSystem(config: SystemConfig & {
364
451
  readonly exclusive: true;
365
452
  }): SystemDescriptor;
366
- /** Config form (§typestate, system.ts): the declaration lists are inferred
367
- * as literal tuples and `fn` / `onAdded` receive
368
- * `SystemContext<DeclaredAccess<…>>` undeclared access fails to compile
453
+ /** Config form (system.ts): the declaration lists are inferred
454
+ * as literal tuples, and `fn` and `onAdded` receive
455
+ * `SystemContext<DeclaredAccess<…>>`, undeclared access fails to compile
369
456
  * with the same taxonomy the runtime `accessCheck` throws with in
370
- * `DEV`. A config VALUE typed as plain `SystemConfig` (dynamically
457
+ * `DEV`. A config value typed as plain `SystemConfig` (dynamically
371
458
  * built) still matches: its erased declaration lists compute a permissive
372
459
  * access record. Escape hatch: annotate `fn(ctx: SystemContext, dt)`
373
460
  * explicitly to keep a system permissive at compile time. */
@@ -376,10 +463,10 @@ export declare class ECS implements QueryResolver {
376
463
  get systemCount(): number;
377
464
  /**
378
465
  * Run the startup phases, once, before the first `update()`. Prewarms
379
- * every archetype the registered systems/observers can produce, runs each
466
+ * every archetype the registered systems and observers can produce, runs each
380
467
  * system's `onAdded` hook, then the `PRE_STARTUP` → `STARTUP` →
381
468
  * `POST_STARTUP` schedule. Events emitted during startup are drained at
382
- * its tail they do not leak into frame 1.
469
+ * its tail. They do not leak into frame 1.
383
470
  *
384
471
  * @example
385
472
  * ecs.addSystems(SCHEDULE.UPDATE, move);
@@ -387,15 +474,15 @@ export declare class ECS implements QueryResolver {
387
474
  * ecs.update(1 / 60); // now tick every frame
388
475
  */
389
476
  startup(): void;
390
- /** Compute the archetype closure from every registered system's AND
477
+ /** Compute the archetype closure from every registered system's and
391
478
  * observer's `spawns` + `transitions` and ask the store to plant the
392
479
  * whole set in one `extendColumnStore` call. Observers carry the same
393
480
  * access shape systems do (a synthesized `SystemDescriptor`), so an
394
- * observer that spawns/transitions gets its target archetype prewarmed
395
- * too rather than first-touching lazily mid-tick (#768). Exposed as
396
- * `private` because the only caller is `startup()`; visible to tests via
397
- * the `archetype_count` delta on the public ECS facade. */
398
- private prewarmArchetypes;
481
+ * observer that spawns and transitions gets its target archetype prewarmed
482
+ * too rather than first-touching lazily mid-tick. Exposed as
483
+ * `private` because the only caller is `startup()`. Visible to tests via
484
+ * the `archetypeCount` delta on the public ECS facade. */
485
+ private _prewarmArchetypes;
399
486
  /**
400
487
  * Advance the world one frame. Runs the fixed-timestep accumulator loop
401
488
  * (`FIXED_UPDATE`, when any fixed system is registered), then
@@ -414,65 +501,63 @@ export declare class ECS implements QueryResolver {
414
501
  */
415
502
  update(dt: number): void;
416
503
  dispose(): void;
417
- /** Register an archetype template (#462). Resolves the component set +
418
- * default field values to a target archetype once (creating it if absent
419
- * fits the prewarm model), so later `spawn` / `spawnMany` calls land
420
- * entities directly in that archetype with **zero archetype transitions**.
504
+ /** Register an archetype template. Resolves the component set +
505
+ * default field values to a target archetype once (creating it if absent,
506
+ * fits the prewarm model), so a later `spawn` or `spawnMany` call lands
507
+ * entities directly in that archetype with no archetype transition.
421
508
  *
422
509
  * const Bullet = ecs.template(Position({ x: 0, y: 0 }), Velocity({ vx: 0, vy: 0 }));
423
510
  *
424
- * Takes the same callable-bundle varargs as `spawnBundle` / `addComponents`
425
- * (each item schema-checked against its own def); the resulting
511
+ * Takes the same callable-bundle varargs as `spawnBundle` and
512
+ * `addComponents`, each item schema-checked against its own def. The resulting
426
513
  * `Template<[Position, Velocity]>` keeps the typed key set that `spawn`'s
427
- * `overrides` map over. Not a pass-through it normalizes bundles to the
514
+ * `overrides` map over. Not a pass-through. It normalizes bundles to the
428
515
  * store's entry shape, so it lives here with the other real logic, not in the
429
- * delegation band. The big win is multi-component entities and bulk spawns; a
516
+ * delegation band. The big win is multi-component entities and bulk spawns. A
430
517
  * single-component spawn is no faster than `spawn` + `addComponent`, which
431
- * already bump-allocates a fresh entity into the target archetype. See
432
- * ADR-0010. */
518
+ * already bump-allocates a fresh entity into the target archetype. */
433
519
  template<Items extends readonly BundleOrDef[]>(...items: StrictBundles<Items>): Template<DefsOf<Items>>;
434
520
  /** Resolve a consumer-declared SAB region's byte offset by `region_id`, or
435
- * 0 when absent. Generic, de-gamed replacement (#623) for the removed
436
- * game-named accessors; pair with the consumer's own region module to
521
+ * 0 when absent. Generic, de-gamed replacement for the removed
522
+ * game-named accessors. Pair with the consumer's own region module to
437
523
  * materialise a typed view. Delegates to `Store.regionOffset`. */
438
524
  regionOffset(regionId: number): number;
439
525
  /** A handle (`{ buffer, view, offset, bytes }`) to a consumer-declared SAB
440
526
  * region resolved by `region_id`, or `null` when absent. A consumer's
441
527
  * region module builds a TypedArray view over the region's span from this.
442
- * Re-fetch after a SAB grow. Delegates to `Store.regionHandle`. (#623) */
528
+ * Re-fetch after a SAB grow. Delegates to `Store.regionHandle`. */
443
529
  regionHandle(regionId: number): ColumnStoreRegionHandle | null;
444
530
  /** Look up the field index a component reserves for `fieldName`. The
445
531
  * index is assigned by `registerComponent` in insertion order and is
446
532
  * stable for the lifetime of the ECS. Used by systems that need to
447
- * pass `(component_id, field_id)` pairs across the WASM FFI the Zig
448
- * side identifies columns by these numeric IDs. */
533
+ * pass `(component_id, field_id)` pairs across the WASM FFI, because the
534
+ * module identifies columns by these numeric ids. */
449
535
  fieldId<S extends Record<string, TypedArrayTag>>(def: ComponentDef<S>, fieldName: Extract<keyof S, string>): number;
450
536
  /** Resolve an archetype's row index to the `EntityID` at that slot.
451
537
  * A WASM system that drains events from the event ring as
452
538
  * `(archId, row, …)` payloads uses this to convert the (archId, row)
453
539
  * pair into the `EntityID` the `ctx.emit(...)` API expects.
454
- * Throws if the (archId, row) pair is out of range. (#250 / Phase 4
455
- * PR 4D) */
540
+ * Throws if the (archId, row) pair is out of range. */
456
541
  entityIdAtRow(archetypeId: number, row: number): EntityID;
457
542
  /** The single SAB backing every archetype's column views. Exposed for
458
- * snapshot/restore, `columnStoreStateHash`-based determinism checks, and
459
- * Phase 2+ WASM/worker hand-off paths. Mutation flows through the
460
- * usual `addComponent` / `removeComponent` / `flush` APIs; readers
543
+ * snapshot and restore, `columnStoreStateHash`-based determinism checks, and
544
+ * WASM or worker hand-off paths. Mutation flows through the
545
+ * usual `addComponent`, `removeComponent` and `flush` APIs. Readers
461
546
  * that hold a column view across a grow must consult
462
- * `header.view_stamp` to detect a republish (#171 §8.1). */
547
+ * `header.view_stamp` to detect a republish. */
463
548
  get columnStore(): ColumnStore;
464
549
  /** Count of live archetypes (including the empty one). Surfaces the
465
- * Store-side `archetype_count` so Phase C tests can assert the
466
- * pre-warmed closure was materialised; equally useful for diagnostics. */
550
+ * Store-side `archetype_count` so tests can assert the
551
+ * pre-warmed closure was materialised. Equally useful for diagnostics. */
467
552
  get archetypeCount(): number;
468
553
  registerTag(): ComponentDef<Record<string, never>>;
469
- /** Register a sparse tag (empty schema) membership only, no data. */
554
+ /** Register a sparse tag (empty schema), membership only, no data. */
470
555
  registerSparseTag(): SparseComponentDef<Record<string, never>>;
471
556
  isAlive(entityId: EntityID): boolean;
472
557
  get entityCount(): number;
473
558
  hasComponent(entityId: EntityID, def: ComponentDef): boolean;
474
- /** Whether `entityId` is currently disabled. Toggle via `disable` / `enable`
475
- * (immediate, above the band they carry the in-system dev guard). */
559
+ /** Whether `entityId` is currently disabled. Toggle with `disable` or `enable`
560
+ * (immediate, above the band. They carry the in-system dev guard). */
476
561
  isDisabled(entityId: EntityID): boolean;
477
562
  addSparse(entityId: EntityID, def: SparseComponentDef<Record<string, never>>): this;
478
563
  addSparse<S extends ComponentSchema>(entityId: EntityID, def: SparseComponentDef<S>, values: CompleteFieldValues<S>): this;
@@ -480,65 +565,62 @@ export declare class ECS implements QueryResolver {
480
565
  hasSparse(entityId: EntityID, def: SparseComponentDef): boolean;
481
566
  getSparseField<S extends ComponentSchema>(entityId: EntityID, def: SparseComponentDef<S>, field: string & keyof S): number;
482
567
  setSparseField<S extends ComponentSchema>(entityId: EntityID, def: SparseComponentDef<S>, field: string & keyof S, value: number): void;
483
- _getLastRunTick(): number;
484
- /** Current ECS write tick the tick `eachChunk` stamps via `cols.mut` (§eachChunk). */
485
- _getCurrentTick(): number;
486
- _getQueryDirtyEpoch(): number;
487
- /** QueryResolver implementation — sparse-membership match path (#469). */
488
- _forEachSparseMatch(include: BitSet, exclude: BitSet | null, anyOf: BitSet | null, sparseInclude: readonly SparseComponentID[], sparseExclude: readonly SparseComponentID[], denseArchetypes: readonly Archetype[], cb: (entityId: EntityID) => void, includeDisabled: boolean): void;
489
- /** QueryResolver implementation — backing sparse id of a relation, for the
490
- * `(R, *)` wildcard term (`Query.withRelation`, #579). */
491
- _relationBackingSparseId(def: RelationDef): SparseComponentID;
492
- /** QueryResolver implementation — `(*, T)` wildcard match path (#579). */
493
- _forEachRelationTargetMatch(target: EntityID, include: BitSet, exclude: BitSet | null, anyOf: BitSet | null, sparseInclude: readonly SparseComponentID[], sparseExclude: readonly SparseComponentID[], includeDisabled: boolean, cb: (entityId: EntityID) => void): void;
494
- /** QueryResolver implementation depth-ordered hierarchy match path (#581). */
495
- _forEachHierarchyMatch(include: BitSet, exclude: BitSet | null, anyOf: BitSet | null, sparseInclude: readonly SparseComponentID[], sparseExclude: readonly SparseComponentID[], denseArchetypes: readonly Archetype[], relation: RelationDef, maxDepth: number, includeDisabled: boolean, cb: (entityId: EntityID) => void): void;
496
- addSystems(label: SCHEDULE, ...entries: (SystemDescriptor | SystemEntry)[]): this;
568
+ getLastRunTick(): number;
569
+ /** The change tick, the stamp `forEachChunk` makes via `cols.mut`. */
570
+ getChangeTick(): number;
571
+ /** QueryResolver implementation: a chunk loop took `cols.ticks(def)`. */
572
+ noteScan(cid: number): void;
573
+ getQueryDirtyEpoch(): number;
574
+ /** QueryResolver implementation, sparse-membership match path. */
575
+ forEachSparseMatch(include: BitSet, exclude: BitSet | null, anyOf: BitSet | null, terms: QueryTerms, denseArchetypes: readonly Archetype[], cb: (entityId: EntityID) => void): void;
576
+ /** QueryResolver implementation, backing sparse id of a relation, for the
577
+ * `(R, *)` wildcard term (`Query.andRelation`). */
578
+ relationBackingSparseId(def: RelationDef, api: string): SparseComponentID;
579
+ /** QueryResolver implementation, `(*, T)` wildcard match path. */
580
+ forEachTargetMatch(target: EntityID, include: BitSet, exclude: BitSet | null, anyOf: BitSet | null, terms: QueryTerms, cb: (entityId: EntityID) => void): void;
581
+ /** QueryResolver implementation, depth-ordered hierarchy match path. */
582
+ forEachHierarchyMatch(include: BitSet, exclude: BitSet | null, anyOf: BitSet | null, terms: QueryTerms, denseArchetypes: readonly Archetype[], relation: RelationDef, maxDepth: number, cb: (entityId: EntityID) => void): void;
583
+ addSystems(phase: SchedulePhase, ...entries: (SystemDescriptor | SystemEntry)[]): this;
584
+ /**
585
+ * Add one phase to a loop, and hand back its handle. Setup only, cold path.
586
+ *
587
+ * A plugin that owns a slot no longer contends for insertion order inside a
588
+ * phase the application also writes to. `before` and `after` order the new
589
+ * phase against the other phases of the same loop, built-in or added.
590
+ *
591
+ * The handle belongs to this world, and identity and not name decides which
592
+ * phase it is, the rule `systemSet` follows.
593
+ *
594
+ * @example
595
+ * const physics = ecs.addPhase("physics", {
596
+ * loop: "update",
597
+ * after: [SCHEDULE.PRE_UPDATE],
598
+ * before: [SCHEDULE.UPDATE]
599
+ * });
600
+ * ecs.addSystems(physics, integrate);
601
+ */
602
+ addPhase(name: string, config: PhaseConfig): Phase;
497
603
  /**
498
- * Configure a `SystemSet` (#576) — the shared run condition and/or ordering
604
+ * Configure a `SystemSet`, the shared run condition, or its ordering,
499
605
  * every member inherits. Additive and order-independent with respect to
500
606
  * `addSystems`: see `Schedule.configureSet`. Returns `this` to chain.
501
607
  */
502
608
  configureSet(set: SystemSet, config: SystemSetConfig): this;
503
609
  /**
504
- * Register a per-component observer (#517 §1 / ADR-0013). Reactions that were
505
- * hand-polled every tick — "on `Death` added → spawn corpse", "on `HexPos`
506
- * set mark the spatial index" become declarative.
507
- *
508
- * - **`onAdd` / `onRemove`** `(eid, ctx)` fire at the structural-flush
509
- * boundary, after the batch commits, in canonical order (access-topological
510
- * across observers, entity-id order within), looping to a fixed point so
511
- * cascades settle. Determinism: a `stateHash` replay reproduces regardless
512
- * of the order ops were queued.
513
- * - **`onDisable` / `onEnable`** `(eid, ctx)` fire at the same flush boundary
514
- * when an entity carrying the component is *disabled* / *enabled* (#577,
515
- * ADR-0023), once per net transition, for every component the entity carries
516
- * (a disable is a soft remove of the whole mask from default queries). Like
517
- * `onAdd`/`onRemove`, an *immediate* `ecs.disable()` does not fire — only
518
- * the deferred `ctx.commands.disable()` toggle does. `yieldExisting` seeds enabled
519
- * members only, so a disabled entity is correctly absent at seed.
520
- * - **`onSet`** fires at the post-update detection point. Default
521
- * `granularity: "archetype"` fires `(arch, ctx)` once per changed
522
- * archetype-column (the consumer iterates `arch.entityCount` rows) — free,
523
- * reusing the change tick. `granularity: "entity"` fires `(eid, ctx)` once
524
- * per changed entity, draining the opt-in per-row dirty list (registering it
525
- * enables dirty tracking for the component; the producer records via
526
- * `ctx.setField` automatically, or `ctx.markChanged` in a `getColumn`
527
- * hot loop).
528
- *
529
- * Observer callbacks that touch ECS state must declare it via `access`
530
- * (merged over an all-empty declaration) — undeclared access throws in
531
- * `DEV`, and those decls drive the firing order. `yieldExisting` replays
532
- * `onAdd` over current matches on registration. Register at world-build time
533
- * (before `startup()`); the returned handle's `dispose()` unregisters.
610
+ * Keep a change tick for each row of `def`, the row grain of change
611
+ * detection. `cols.ticksRead(def)` and `changed(def).forEachChunk` read it
612
+ * against `cols.since`, and every write path stamps it: `setField`, `ref`,
613
+ * a cursor, `markChanged`, and a store into `cols.ticks(def)`. An `onSet`
614
+ * observer with entity granularity turns it on as well. Costs one word for
615
+ * each row of every archetype that holds `def`, and one store on each by-id
616
+ * write. Never turned off. Idempotent. A sparse component keeps one tick
617
+ * for each entity index instead, read through `ctx.sparseChanged`.
534
618
  */
535
- observe(def: ComponentHandle, config: StructuralObserverConfig): ObserverHandle;
536
- observe(def: ComponentHandle, config: EntitySetObserverConfig): ObserverHandle;
537
- observe(def: ComponentHandle, config: ArchetypeSetObserverConfig): ObserverHandle;
619
+ trackRows(def: ComponentHandle | SparseComponentDef): void;
538
620
  /**
539
621
  * Stamp every SAB-backed archetype's live `length` into its SAB
540
622
  * descriptor's `row_count` field. **You usually don't need to call
541
- * this directly** `update()` publishes at tick start and
623
+ * this directly**, `update()` publishes at tick start and
542
624
  * `SystemContext.flush()` publishes at every phase boundary, so any
543
625
  * WASM scan running inside the schedule sees fresh counts for free.
544
626
  * This is an escape hatch for code that mutates archetype state
@@ -547,34 +629,13 @@ export declare class ECS implements QueryResolver {
547
629
  *
548
630
  * Cheap: walks the descriptor region once, does no column I/O.
549
631
  */
550
- publishArchetypeRowCounts(): void;
632
+ publishRowCounts(): void;
551
633
  flush(): void;
552
634
  }
553
- /** Phase C of issue #213 — archetype closure from a descriptor set.
554
- *
555
- * Each descriptor is a system or an observer's synthesized `SystemDescriptor`
556
- * (#768) — both carry `spawns` + `transitions`. Seeds the worklist with every
557
- * descriptor's `spawns`; iteratively applies every descriptor's `transitions`
558
- * to every discovered mask whose components cover the transition's `whenHas`.
559
- * Returns the union of seeds + reachable targets, deduplicated by hash-bucketed
560
- * mask equality.
561
- *
562
- * Termination: every transition either monotonically grows the mask (add
563
- * outpacing remove), monotonically shrinks it, or returns a mask the
564
- * `seen` map already holds. Because the universe of masks is bounded by
565
- * `2^|components|` (and in practice the in-tree spawn/transition set is
566
- * tiny — ~20 masks at most), the worklist is finite and we exit when it
567
- * empties.
568
- *
569
- * Liberal `whenHas` per design doc §6.6 — over-approximation is fine; an
570
- * unreachable transition target costs one descriptor row at the SAB tail,
571
- * not column bytes. Empty `spawns` + `transitions` short-circuit to zero.
572
- */
573
- declare function computeArchetypeClosure(descriptors: Iterable<SystemDescriptor>): BitSet[];
574
- /** @internal — test seam for the closure walk. Exposed so the prewarm
575
- * tests can exercise the BFS without standing up a full Store. */
635
+ /** @internal, test seam for the closure walk that `archetype_closure.ts`
636
+ * holds. Exposed so the prewarm tests can exercise the walk without standing
637
+ * up a full Store. */
576
638
  export declare const _ecsInternals: {
577
639
  computeArchetypeClosure: typeof computeArchetypeClosure;
578
640
  };
579
- export {};
580
641
  //# sourceMappingURL=ecs.d.ts.map