@oasys/oecs 0.5.4 → 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 +1223 -266
  2. package/README.md +217 -112
  3. package/dist/core/ecs/access_check.d.cts +29 -29
  4. package/dist/core/ecs/access_check.d.ts +29 -29
  5. package/dist/core/ecs/access_check.d.ts.map +1 -1
  6. package/dist/core/ecs/archetype.d.cts +217 -209
  7. package/dist/core/ecs/archetype.d.ts +217 -209
  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 +33 -33
  13. package/dist/core/ecs/archetype_graph.d.ts +33 -33
  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 +26 -26
  28. package/dist/core/ecs/command_log.d.ts +26 -26
  29. package/dist/core/ecs/command_log.d.ts.map +1 -1
  30. package/dist/core/ecs/component.d.cts +43 -42
  31. package/dist/core/ecs/component.d.ts +43 -42
  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 +289 -270
  46. package/dist/core/ecs/ecs.d.ts +289 -270
  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 +20 -18
  57. package/dist/core/ecs/entity_allocator.d.ts +20 -18
  58. package/dist/core/ecs/entity_allocator.d.ts.map +1 -1
  59. package/dist/core/ecs/event.d.cts +36 -22
  60. package/dist/core/ecs/event.d.ts +36 -22
  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 +32 -32
  69. package/dist/core/ecs/frame_trace.d.ts +32 -32
  70. package/dist/core/ecs/frame_trace.d.ts.map +1 -1
  71. package/dist/core/ecs/host_commands.d.cts +103 -85
  72. package/dist/core/ecs/host_commands.d.ts +103 -85
  73. package/dist/core/ecs/host_commands.d.ts.map +1 -1
  74. package/dist/core/ecs/index.d.cts +21 -11
  75. package/dist/core/ecs/index.d.ts +21 -11
  76. package/dist/core/ecs/index.d.ts.map +1 -1
  77. package/dist/core/ecs/observer.d.cts +39 -120
  78. package/dist/core/ecs/observer.d.ts +39 -120
  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 +208 -578
  90. package/dist/core/ecs/query.d.ts +208 -578
  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 +100 -39
  102. package/dist/core/ecs/ref.d.ts +100 -39
  103. package/dist/core/ecs/ref.d.ts.map +1 -1
  104. package/dist/core/ecs/relation.d.cts +101 -182
  105. package/dist/core/ecs/relation.d.ts +101 -182
  106. package/dist/core/ecs/relation.d.ts.map +1 -1
  107. package/dist/core/ecs/resource.d.cts +13 -13
  108. package/dist/core/ecs/resource.d.ts +13 -13
  109. package/dist/core/ecs/resource_registry.d.cts +5 -5
  110. package/dist/core/ecs/resource_registry.d.ts +5 -5
  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 +91 -120
  119. package/dist/core/ecs/schedule.d.ts +91 -120
  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 +108 -51
  131. package/dist/core/ecs/sparse_store.d.ts +108 -51
  132. package/dist/core/ecs/sparse_store.d.ts.map +1 -1
  133. package/dist/core/ecs/store.d.cts +527 -473
  134. package/dist/core/ecs/store.d.ts +527 -473
  135. package/dist/core/ecs/store.d.ts.map +1 -1
  136. package/dist/core/ecs/store_layout_listener.d.cts +6 -6
  137. package/dist/core/ecs/store_layout_listener.d.ts +6 -6
  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 +146 -61
  142. package/dist/core/ecs/system.d.ts +146 -61
  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 +82 -6
  154. package/dist/core/ecs/utils/error.d.ts +82 -6
  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 +44 -44
  163. package/dist/core/store/action_ring.d.ts +44 -44
  164. package/dist/core/store/action_ring.d.ts.map +1 -1
  165. package/dist/core/store/allocator.d.cts +149 -95
  166. package/dist/core/store/allocator.d.ts +149 -95
  167. package/dist/core/store/allocator.d.ts.map +1 -1
  168. package/dist/core/store/buffer_backed_column.d.cts +17 -17
  169. package/dist/core/store/buffer_backed_column.d.ts +17 -17
  170. package/dist/core/store/buffer_backed_column.d.ts.map +1 -1
  171. package/dist/core/store/column_store.d.cts +124 -86
  172. package/dist/core/store/column_store.d.ts +124 -86
  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 +36 -39
  178. package/dist/core/store/command_ring.d.ts +36 -39
  179. package/dist/core/store/command_ring.d.ts.map +1 -1
  180. package/dist/core/store/descriptor.d.cts +34 -17
  181. package/dist/core/store/descriptor.d.ts +34 -17
  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 +36 -38
  187. package/dist/core/store/event_ring.d.ts +36 -38
  188. package/dist/core/store/event_ring.d.ts.map +1 -1
  189. package/dist/core/store/extend.d.cts +13 -7
  190. package/dist/core/store/extend.d.ts +13 -7
  191. package/dist/core/store/extend.d.ts.map +1 -1
  192. package/dist/core/store/grow.d.cts +2 -2
  193. package/dist/core/store/grow.d.ts +2 -2
  194. package/dist/core/store/grow.d.ts.map +1 -1
  195. package/dist/core/store/header.d.cts +31 -27
  196. package/dist/core/store/header.d.ts +31 -27
  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 +71 -62
  202. package/dist/core/store/layout_ops.d.ts +71 -62
  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 +12 -12
  211. package/dist/core/store/state_hash.d.ts +12 -12
  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 +15 -10
  225. package/dist/index.d.ts +15 -10
  226. package/dist/index.d.ts.map +1 -1
  227. package/dist/index.development.cjs +1 -1
  228. package/dist/index.development.js +5804 -5203
  229. package/dist/index.js +5323 -4764
  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 +54 -54
  244. package/dist/{extensions → plugins}/editor/editor.d.ts +54 -54
  245. package/dist/plugins/editor/editor.d.ts.map +1 -0
  246. package/dist/{extensions → plugins}/editor/field_handle.d.cts +12 -12
  247. package/dist/{extensions → plugins}/editor/field_handle.d.ts +12 -12
  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} +81 -64
  257. package/dist/{extensions/editor/index.js → plugins/editor.js} +81 -64
  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 +85 -97
  302. package/dist/{core/ecs → plugins/relations}/relation_service.d.ts +85 -97
  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 +16 -15
  411. package/dist/type_primitives/typed_arrays/typed_arrays.d.ts +16 -15
  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 +3 -3
  415. package/dist/version.d.ts +3 -3
  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-BlR3oZ3x.js +0 -2406
  465. package/dist/host_commands-C2cpU3yC.cjs +0 -1
  466. package/dist/internal-BoxWl4dG.js +0 -2565
  467. package/dist/internal-CGBEwfeB.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-Bs39EPh1.js +0 -150
  502. package/dist/shallow-C5YmTbtb.cjs +0 -1
  503. package/dist/shallow-CiFC70Dz.js +0 -159
  504. package/dist/shallow-DQ8aG51_.cjs +0 -1
  505. package/dist/shared-B4v0L1cw.js +0 -109
  506. package/dist/shared-DU78k0pU.cjs +0 -1
  507. package/dist/topological_sort-BDvEyb9W.cjs +0 -1
  508. package/dist/topological_sort-DK6EjpWa.js +0 -135
  509. package/dist/typed_arrays-D3NmwtCG.cjs +0 -1
  510. package/dist/typed_arrays-DIVwVy5_.js +0 -258
@@ -1,2565 +0,0 @@
1
- import { D as st, h as j, w as Ne, g as rt } from "./shared-B4v0L1cw.js";
2
- import { S as ot, t as it } from "./topological_sort-DK6EjpWa.js";
3
- class Ye extends Error {
4
- constructor(e, n, r) {
5
- super(e), this.isOperational = n, this.context = r, this.name = this.constructor.name, Error.captureStackTrace(this, this.constructor);
6
- }
7
- }
8
- var me = /* @__PURE__ */ ((t) => (t.ASSERTION_FAIL_CONDITION = "ASSERTION_FAIL_CONDITION", t.VALIDATION_FAIL_CONDITION = "VALIDATION_FAIL_CONDITION", t.ASSERTION_FAIL_NON_NULLABLE = "ASSERTION_FAIL_NON_NULLABLE", t.ASSERTION_FAIL_UNREACHABLE = "ASSERTION_FAIL_UNREACHABLE", t))(me || {});
9
- class Ve extends Ye {
10
- constructor(e, n, r) {
11
- super(n, !1, r), this.category = e;
12
- }
13
- }
14
- const Rn = (t) => Number.isInteger(t) && t >= 0;
15
- function Dn(t, e, n) {
16
- if (!e(t))
17
- throw new Ve(
18
- me.VALIDATION_FAIL_CONDITION,
19
- `Expected value to meet validation: ${n}`
20
- );
21
- return t;
22
- }
23
- function On(t) {
24
- return t;
25
- }
26
- function at(t, e) {
27
- throw new Ve(
28
- me.ASSERTION_FAIL_UNREACHABLE,
29
- `Unhandled ${e}: ${String(t)}`
30
- );
31
- }
32
- var y = /* @__PURE__ */ ((t) => (t.EID_MAX_INDEX_OVERFLOW = "EID_MAX_INDEX_OVERFLOW", t.EID_MAX_GEN_OVERFLOW = "EID_MAX_GEN_OVERFLOW", t.COMPONENT_NOT_REGISTERED = "COMPONENT_NOT_REGISTERED", t.COMPONENT_LIMIT_EXCEEDED = "COMPONENT_LIMIT_EXCEEDED", t.ENTITY_NOT_ALIVE = "ENTITY_NOT_ALIVE", t.CIRCULAR_SYSTEM_DEPENDENCY = "CIRCULAR_SYSTEM_DEPENDENCY", t.DUPLICATE_SYSTEM = "DUPLICATE_SYSTEM", t.ARCHETYPE_NOT_FOUND = "ARCHETYPE_NOT_FOUND", t.RESOURCE_NOT_REGISTERED = "RESOURCE_NOT_REGISTERED", t.RESOURCE_ALREADY_REGISTERED = "RESOURCE_ALREADY_REGISTERED", t.EVENT_ALREADY_REGISTERED = "EVENT_ALREADY_REGISTERED", t.EVENT_NOT_REGISTERED = "EVENT_NOT_REGISTERED", t.FIELD_NOT_REGISTERED = "FIELD_NOT_REGISTERED", t.RELATION_NOT_REGISTERED = "RELATION_NOT_REGISTERED", t.RELATION_MODE_INVALID = "RELATION_MODE_INVALID", t.RELATION_MODE_MISMATCH = "RELATION_MODE_MISMATCH", t.RELATION_CYCLE = "RELATION_CYCLE", t.SPARSE_CACHE_KEY_OVERFLOW = "SPARSE_CACHE_KEY_OVERFLOW", t.SPARSE_QUERY_DENSE_PATH = "SPARSE_QUERY_DENSE_PATH", t.HIERARCHY_ALREADY_SET = "HIERARCHY_ALREADY_SET", t.HIERARCHY_INVALID_MAX_DEPTH = "HIERARCHY_INVALID_MAX_DEPTH", t.OBSERVER_NON_CONVERGENT = "OBSERVER_NON_CONVERGENT", t.OBSERVER_INVALID_CONFIG = "OBSERVER_INVALID_CONFIG", t.OBSERVER_ONSET_EMIT = "OBSERVER_ONSET_EMIT", t.INVALID_FIXED_TIMESTEP = "INVALID_FIXED_TIMESTEP", t.INVALID_MAX_FIXED_STEPS = "INVALID_MAX_FIXED_STEPS", t.INVALID_RECORDER_SCHEDULE = "INVALID_RECORDER_SCHEDULE", t.EMPTY_ARCHETYPE_MATERIALIZE = "EMPTY_ARCHETYPE_MATERIALIZE", t.COMPONENT_INDEX_INVARIANT = "COMPONENT_INDEX_INVARIANT", t.ARCHETYPE_ROW_INVARIANT = "ARCHETYPE_ROW_INVARIANT", t.OPTIONAL_TERM_NOT_DECLARED = "OPTIONAL_TERM_NOT_DECLARED", t.QUERY_ACCESS_UNDECLARED = "QUERY_ACCESS_UNDECLARED", t.ACCESS_UNDECLARED = "ACCESS_UNDECLARED", t.QUERY_NOT_SINGLETON = "QUERY_NOT_SINGLETON", t.INVALID_RUN_CONDITION = "INVALID_RUN_CONDITION", t.SYSTEM_FN_ARITY = "SYSTEM_FN_ARITY", t.PARTITION_APPEND_NEEDS_ENTITY_ROW = "PARTITION_APPEND_NEEDS_ENTITY_ROW", t.PARTITION_BULK_INTO_DISABLED = "PARTITION_BULK_INTO_DISABLED", t.ENTITY_NOT_DISABLED = "ENTITY_NOT_DISABLED", t.STRUCTURAL_DURING_ITERATION = "STRUCTURAL_DURING_ITERATION", t.BACKEND_ALREADY_ATTACHED = "BACKEND_ALREADY_ATTACHED", t.DETERMINISM_DISABLED = "DETERMINISM_DISABLED", t.NON_DETERMINISTIC_COLUMN_TYPE = "NON_DETERMINISTIC_COLUMN_TYPE", t.INVALID_MEMORY_OPTIONS = "INVALID_MEMORY_OPTIONS", t.STORE_CAP_EXCEEDED = "STORE_CAP_EXCEEDED", t.REGION_NOT_DECLARED = "REGION_NOT_DECLARED", t.COMMAND_LOG_TAG_COLLISION = "COMMAND_LOG_TAG_COLLISION", t.INVALID_FRAME_STEP = "INVALID_FRAME_STEP", t))(y || {});
33
- class T extends Ye {
34
- constructor(e, n, r) {
35
- super(n ?? e, !0, r), this.category = e;
36
- }
37
- }
38
- function Cn(t) {
39
- return t instanceof T;
40
- }
41
- const bn = -1, vn = -1, Un = Object.freeze(/* @__PURE__ */ Object.create(null)), Ln = 2654435769, Mn = 1367130551, F = 1024, $n = 0, ct = 31, Pn = 1 / 60, xn = 4, dt = 0, z = 20, He = (1 << z) - 1, $ = He, lt = ct - z, oe = (1 << lt) - 1, Bn = oe, Fn = oe - 1, Re = oe << z | $, kn = (t, e) => {
42
- {
43
- if (t < 0 || t > $)
44
- throw new T(y.EID_MAX_INDEX_OVERFLOW);
45
- if (e < 0 || e > oe)
46
- throw new T(y.EID_MAX_GEN_OVERFLOW);
47
- }
48
- return e << z | t;
49
- }, L = (t) => t & He, De = (t) => t >> z, Yn = (t, e, n) => new T(
50
- y.ENTITY_NOT_ALIVE,
51
- `${t}: entity ${e} (index ${L(e)}, generation ${De(
52
- e
53
- )}) is not alive${n ? ` — ${n}` : ""} (destroyed, never created, or a stale handle; guard with isAlive() first)`,
54
- { entity: e, index: L(e), generation: De(e), op: t }
55
- ), ge = /* @__PURE__ */ new WeakMap();
56
- function Vn(t, e) {
57
- ge.set(t, e);
58
- }
59
- function Hn(t) {
60
- return ge.get(t);
61
- }
62
- function ut(t) {
63
- const e = ge.get(t);
64
- return e !== void 0 ? `'${e}' (component ${t.id})` : `component ${t.id}`;
65
- }
66
- const ft = 827148627, ht = 0, ee = 4, _t = 52, m = {
67
- magic: 0,
68
- sim_abi_version: 4,
69
- view_stamp: 8,
70
- capacity: 12,
71
- archetype_count: 16,
72
- layout_descriptor_off: 20,
73
- command_ring_off: 24,
74
- action_ring_off: 28,
75
- entity_index_off: 32,
76
- event_ring_off: 36,
77
- region_table_off: 40,
78
- region_table_count: 44,
79
- bindings_off: 48
80
- }, q = 12, M = {
81
- region_id: 0,
82
- byte_offset: 4,
83
- byte_length: 8
84
- }, Ee = 16, O = {
85
- component_id: 0,
86
- field_id: 2,
87
- type_tag: 4,
88
- byte_off: 8,
89
- stride: 12
90
- }, pe = 36, N = {
91
- archetype_id: 0,
92
- component_mask: 4,
93
- row_count: 20,
94
- row_capacity: 24,
95
- column_count: 28,
96
- enabled_count: 32
97
- };
98
- function mt(t, e) {
99
- t.setUint32(m.magic, e.magic, !0), t.setUint32(m.sim_abi_version, e.simAbiVersion, !0), t.setUint32(m.view_stamp, e.viewStamp, !0), t.setUint32(m.capacity, e.capacity, !0), t.setUint32(m.archetype_count, e.archetypeCount, !0), t.setUint32(m.layout_descriptor_off, e.layoutDescriptorOff, !0), t.setUint32(m.command_ring_off, e.commandRingOff, !0), t.setUint32(m.action_ring_off, e.actionRingOff, !0), t.setUint32(m.entity_index_off, e.entityIndexOff, !0), t.setUint32(m.event_ring_off, e.eventRingOff, !0), t.setUint32(m.region_table_off, e.regionTableOff, !0), t.setUint32(m.region_table_count, e.regionTableCount, !0), t.setUint32(m.bindings_off, e.bindingsOff, !0);
100
- }
101
- function Gn(t) {
102
- return {
103
- magic: t.getUint32(m.magic, !0),
104
- simAbiVersion: t.getUint32(m.sim_abi_version, !0),
105
- viewStamp: t.getUint32(m.view_stamp, !0),
106
- capacity: t.getUint32(m.capacity, !0),
107
- archetypeCount: t.getUint32(m.archetype_count, !0),
108
- layoutDescriptorOff: t.getUint32(m.layout_descriptor_off, !0),
109
- commandRingOff: t.getUint32(m.command_ring_off, !0),
110
- actionRingOff: t.getUint32(m.action_ring_off, !0),
111
- entityIndexOff: t.getUint32(m.entity_index_off, !0),
112
- eventRingOff: t.getUint32(m.event_ring_off, !0),
113
- regionTableOff: t.getUint32(m.region_table_off, !0),
114
- regionTableCount: t.getUint32(m.region_table_count, !0),
115
- bindingsOff: t.getUint32(m.bindings_off, !0)
116
- };
117
- }
118
- const E = {
119
- u8: 0,
120
- i8: 1,
121
- u16: 2,
122
- i16: 3,
123
- u32: 4,
124
- i32: 5,
125
- f32: 6,
126
- f64: 7
127
- }, Oe = Object.freeze({
128
- [E.u8]: 1,
129
- [E.i8]: 1,
130
- [E.u16]: 2,
131
- [E.i16]: 2,
132
- [E.u32]: 4,
133
- [E.i32]: 4,
134
- [E.f32]: 4,
135
- [E.f64]: 8
136
- }), Wn = {
137
- u8: E.u8,
138
- i8: E.i8,
139
- u16: E.u16,
140
- i16: E.i16,
141
- u32: E.u32,
142
- i32: E.i32,
143
- f32: E.f32,
144
- f64: E.f64
145
- };
146
- function gt(t, e, n) {
147
- t.setUint16(e + O.component_id, n.componentId, !0), t.setUint16(e + O.field_id, n.fieldId, !0), t.setUint8(e + O.type_tag, n.typeTag), t.setUint32(e + O.byte_off, n.byteOff, !0), t.setUint16(e + O.stride, n.stride, !0);
148
- }
149
- function Et(t, e) {
150
- return {
151
- componentId: t.getUint16(e + O.component_id, !0),
152
- fieldId: t.getUint16(e + O.field_id, !0),
153
- typeTag: t.getUint8(e + O.type_tag),
154
- byteOff: t.getUint32(e + O.byte_off, !0),
155
- stride: t.getUint16(e + O.stride, !0)
156
- };
157
- }
158
- const Xn = ee * 32;
159
- function Ge(t) {
160
- return pe + t * Ee;
161
- }
162
- function pt(t, e, n) {
163
- t.setUint32(e + N.archetype_id, n.archetypeId, !0);
164
- for (let s = 0; s < ee; s++)
165
- t.setUint32(
166
- e + N.component_mask + s * 4,
167
- n.componentMask[s] ?? 0,
168
- !0
169
- );
170
- t.setUint32(e + N.row_count, n.rowCount, !0), t.setUint32(e + N.row_capacity, n.rowCapacity, !0), t.setUint32(e + N.column_count, n.columns.length, !0), t.setUint32(e + N.enabled_count, n.enabledCount, !0);
171
- let r = e + pe;
172
- for (let s = 0; s < n.columns.length; s++)
173
- gt(t, r, n.columns[s]), r += Ee;
174
- return r;
175
- }
176
- function yt(t, e) {
177
- const n = t.getUint32(e + N.column_count, !0), r = new Array(n);
178
- let s = e + pe;
179
- for (let i = 0; i < n; i++)
180
- r[i] = Et(t, s), s += Ee;
181
- const o = new Array(ee);
182
- for (let i = 0; i < ee; i++)
183
- o[i] = t.getUint32(
184
- e + N.component_mask + i * 4,
185
- !0
186
- );
187
- return {
188
- archetypeId: t.getUint32(e + N.archetype_id, !0),
189
- componentMask: o,
190
- rowCount: t.getUint32(e + N.row_count, !0),
191
- rowCapacity: t.getUint32(e + N.row_capacity, !0),
192
- enabledCount: t.getUint32(e + N.enabled_count, !0),
193
- columns: r
194
- };
195
- }
196
- function Tt(t, e, n) {
197
- let r = e;
198
- for (let s = 0; s < n.length; s++)
199
- r = pt(t, r, n[s]);
200
- return r;
201
- }
202
- function zn(t, e, n) {
203
- const r = new Array(n);
204
- let s = e;
205
- for (let o = 0; o < n; o++) {
206
- const i = yt(t, s);
207
- r[o] = i, s += Ge(i.columns.length);
208
- }
209
- return r;
210
- }
211
- function At(t) {
212
- let e = 0;
213
- for (let n = 0; n < t.length; n++)
214
- e += Ge(t[n].columns.length);
215
- return e;
216
- }
217
- const We = 16, P = 16, qn = 256, C = {
218
- write_head: 0,
219
- read_head: 4,
220
- capacity_slots: 8,
221
- overflow_flag: 12
222
- }, ye = 0;
223
- function Ce(t) {
224
- return We + t * P;
225
- }
226
- function It(t) {
227
- return t > 0 && (t & t - 1) === 0;
228
- }
229
- class v extends Error {
230
- constructor(e) {
231
- super(e), this.name = "CommandRingError";
232
- }
233
- }
234
- function wt(t, e, n) {
235
- if (!It(n))
236
- throw new v(
237
- `command ring capacity_slots must be a positive power of two (got ${n})`
238
- );
239
- t.setUint32(e + C.write_head, 0, !0), t.setUint32(e + C.read_head, 0, !0), t.setUint32(e + C.capacity_slots, n, !0), t.setUint32(e + C.overflow_flag, 0, !0);
240
- }
241
- function St(t, e) {
242
- return t.getUint32(e + C.write_head, !0);
243
- }
244
- function Nt(t, e) {
245
- return t.getUint32(e + C.read_head, !0);
246
- }
247
- function Rt(t, e) {
248
- return t.getUint32(e + C.capacity_slots, !0);
249
- }
250
- function Dt(t, e, n) {
251
- if (n.byteLength !== P - 1)
252
- throw new v(
253
- `outPayload must be ${P - 1} bytes (got ${n.byteLength})`
254
- );
255
- const r = St(t, e), s = Nt(t, e);
256
- if (r === s) return ye;
257
- const o = Rt(t, e), i = s & o - 1, a = e + We + i * P, c = t.getUint8(a), d = new Uint8Array(t.buffer, a + 1, P - 1);
258
- return n.set(d), t.setUint32(e + C.read_head, s + 1 >>> 0, !0), c;
259
- }
260
- function Ot(t, e, n) {
261
- let r = 0;
262
- const s = new Uint8Array(P - 1);
263
- for (; ; ) {
264
- const o = Dt(t, e, s);
265
- if (o === ye) return r;
266
- n(o, s.slice()), r++;
267
- }
268
- }
269
- const ie = 16, R = 12, te = {
270
- length: 0,
271
- capacity: 4
272
- // 8..16: pad to 16-byte alignment so the i32 arrays start aligned.
273
- }, U = 1 << 20;
274
- function be(t) {
275
- if (t < 0 || !Number.isInteger(t))
276
- throw new Xe(
277
- `entity index capacity must be a non-negative integer (got ${t})`
278
- );
279
- return ie + t * R;
280
- }
281
- function Ct(t) {
282
- return t + ie;
283
- }
284
- function bt(t, e) {
285
- return t + ie + e * 4;
286
- }
287
- function vt(t, e) {
288
- return t + ie + e * 8;
289
- }
290
- class Xe extends Error {
291
- constructor(e) {
292
- super(e), this.name = "EntityIndexError";
293
- }
294
- }
295
- function Ut(t, e, n) {
296
- if (n < 0 || !Number.isInteger(n))
297
- throw new Xe(
298
- `entity index capacity must be a non-negative integer (got ${n})`
299
- );
300
- t.setUint32(e + te.length, 0, !0), t.setUint32(e + te.capacity, n, !0);
301
- }
302
- function jn(t, e, n) {
303
- return {
304
- generations: new Int32Array(t, Ct(e), n),
305
- archetypes: new Int32Array(t, bt(e, n), n),
306
- rows: new Int32Array(t, vt(e, n), n)
307
- };
308
- }
309
- const Lt = 16, Mt = 16, Kn = 256, Y = {
310
- write_head: 0,
311
- read_head: 4,
312
- capacity_slots: 8,
313
- overflow_flag: 12
314
- };
315
- function ve(t) {
316
- return Lt + t * Mt;
317
- }
318
- function $t(t) {
319
- return t > 0 && (t & t - 1) === 0;
320
- }
321
- class Pt extends Error {
322
- constructor(e) {
323
- super(e), this.name = "EventRingError";
324
- }
325
- }
326
- function xt(t, e, n) {
327
- if (!$t(n))
328
- throw new Pt(
329
- `event ring capacity_slots must be a positive power of two (got ${n})`
330
- );
331
- t.setUint32(e + Y.write_head, 0, !0), t.setUint32(e + Y.read_head, 0, !0), t.setUint32(e + Y.capacity_slots, n, !0), t.setUint32(e + Y.overflow_flag, 0, !0);
332
- }
333
- const Bt = 16, Ft = 16, Qn = 256, V = {
334
- write_head: 0,
335
- read_head: 4,
336
- capacity_slots: 8,
337
- overflow_flag: 12
338
- }, kt = V.write_head / 4, Yt = V.read_head / 4, Vt = V.capacity_slots / 4, Ht = V.overflow_flag / 4;
339
- function Gt(t, e) {
340
- return new Int32Array(t.buffer, t.byteOffset + e, 4);
341
- }
342
- function Ue(t) {
343
- return Bt + t * Ft;
344
- }
345
- function Wt(t) {
346
- return t > 0 && (t & t - 1) === 0;
347
- }
348
- class Le extends Error {
349
- constructor(e) {
350
- super(e), this.name = "ActionRingError";
351
- }
352
- }
353
- function Xt(t, e, n) {
354
- if (!Wt(n))
355
- throw new Le(
356
- `action ring capacity_slots must be a positive power of two (got ${n})`
357
- );
358
- if ((t.byteOffset + e) % 4 !== 0)
359
- throw new Le(
360
- `action ring header must be 4-byte aligned for Atomics (view.byteOffset ${t.byteOffset} + ringOff ${e} is not a multiple of 4)`
361
- );
362
- const r = Gt(t, e);
363
- Atomics.store(r, kt, 0), Atomics.store(r, Yt, 0), Atomics.store(r, Vt, n), Atomics.store(r, Ht, 0);
364
- }
365
- const K = [
366
- {
367
- name: "command_ring",
368
- headerOff: "command_ring_off",
369
- sizeFromOptions: (t) => t.commandRingCapacitySlots !== void 0 ? Ce(t.commandRingCapacitySlots) : 0,
370
- init: (t, e, n) => wt(t, e, n.commandRingCapacitySlots),
371
- regionBytes: (t, e) => Ce(t.getUint32(e + C.capacity_slots, !0)),
372
- readOptions: (t, e, n) => {
373
- n.commandRingCapacitySlots = t.getUint32(
374
- e + C.capacity_slots,
375
- !0
376
- );
377
- }
378
- },
379
- {
380
- name: "entity_index",
381
- headerOff: "entity_index_off",
382
- sizeFromOptions: (t) => t.entityIndexCapacity !== void 0 ? be(t.entityIndexCapacity) : 0,
383
- init: (t, e, n) => Ut(t, e, n.entityIndexCapacity),
384
- regionBytes: (t, e) => be(t.getUint32(e + te.capacity, !0)),
385
- readOptions: (t, e, n) => {
386
- n.entityIndexCapacity = t.getUint32(e + te.capacity, !0);
387
- }
388
- },
389
- {
390
- name: "event_ring",
391
- headerOff: "event_ring_off",
392
- sizeFromOptions: (t) => t.eventRingCapacitySlots !== void 0 ? ve(t.eventRingCapacitySlots) : 0,
393
- init: (t, e, n) => xt(t, e, n.eventRingCapacitySlots),
394
- regionBytes: (t, e) => ve(t.getUint32(e + Y.capacity_slots, !0)),
395
- readOptions: (t, e, n) => {
396
- n.eventRingCapacitySlots = t.getUint32(
397
- e + Y.capacity_slots,
398
- !0
399
- );
400
- }
401
- },
402
- {
403
- name: "action_ring",
404
- headerOff: "action_ring_off",
405
- sizeFromOptions: (t) => t.actionRingCapacitySlots !== void 0 ? Ue(t.actionRingCapacitySlots) : 0,
406
- init: (t, e, n) => Xt(t, e, n.actionRingCapacitySlots),
407
- regionBytes: (t, e) => Ue(t.getUint32(e + V.capacity_slots, !0)),
408
- readOptions: (t, e, n) => {
409
- n.actionRingCapacitySlots = t.getUint32(
410
- e + V.capacity_slots,
411
- !0
412
- );
413
- }
414
- }
415
- ];
416
- class J extends Error {
417
- constructor(e) {
418
- super(e), this.name = "RegionRegistryError";
419
- }
420
- }
421
- function ze(t) {
422
- return t * q;
423
- }
424
- function Te(t, e) {
425
- const n = t.getUint32(m.region_table_count, !0);
426
- if (e + ze(n) > t.byteLength)
427
- throw new J(
428
- `region table of ${n} entries at byte ${e} overruns the buffer (${t.byteLength} bytes)`
429
- );
430
- return n;
431
- }
432
- function zt(t) {
433
- const e = /* @__PURE__ */ new Set();
434
- for (let n = 0; n < t.length; n++) {
435
- const r = t[n];
436
- if (!Number.isInteger(r.id) || r.id <= 0)
437
- throw new J(
438
- `region "${r.name}" has invalid id ${r.id} — region ids must be positive integers (0 is the absent sentinel)`
439
- );
440
- if (e.has(r.id))
441
- throw new J(
442
- `duplicate region id ${r.id} (region "${r.name}") — ids must be distinct within a consumer's region set`
443
- );
444
- if (e.add(r.id), !Number.isInteger(r.bytes) || r.bytes <= 0)
445
- throw new J(
446
- `region "${r.name}" (id ${r.id}) has invalid byte size ${r.bytes} — must be a positive integer`
447
- );
448
- }
449
- }
450
- function qt(t, e, n) {
451
- t.setUint32(e + M.region_id, n.regionId, !0), t.setUint32(e + M.byte_offset, n.byteOffset, !0), t.setUint32(e + M.byte_length, n.byteLength, !0);
452
- }
453
- function qe(t, e) {
454
- return {
455
- regionId: t.getUint32(e + M.region_id, !0),
456
- byteOffset: t.getUint32(e + M.byte_offset, !0),
457
- byteLength: t.getUint32(e + M.byte_length, !0)
458
- };
459
- }
460
- function jt(t, e, n) {
461
- for (let r = 0; r < n.length; r++)
462
- qt(t, e + r * q, n[r]);
463
- }
464
- function Kt(t, e, n) {
465
- const r = new Array(n);
466
- for (let s = 0; s < n; s++)
467
- r[s] = qe(t, e + s * q);
468
- return r;
469
- }
470
- function Zn(t) {
471
- const e = t.getUint32(m.region_table_off, !0);
472
- if (e === 0) return [];
473
- const n = Te(t, e);
474
- return Kt(t, e, n);
475
- }
476
- function Jn(t, e) {
477
- const n = t.getUint32(m.region_table_off, !0);
478
- if (n === 0) return 0;
479
- const r = Te(t, n);
480
- for (let s = 0; s < r; s++) {
481
- const o = n + s * q;
482
- if (t.getUint32(o + M.region_id, !0) === e)
483
- return t.getUint32(o + M.byte_offset, !0);
484
- }
485
- return 0;
486
- }
487
- function es(t, e) {
488
- const n = t.getUint32(m.region_table_off, !0);
489
- if (n === 0) return null;
490
- const r = Te(t, n);
491
- for (let s = 0; s < r; s++) {
492
- const o = qe(t, n + s * q);
493
- if (o.regionId === e) return o;
494
- }
495
- return null;
496
- }
497
- function Qt(t, e) {
498
- return t << 16 | e;
499
- }
500
- const Ae = 2 ** 31;
501
- class je extends Error {
502
- constructor(e) {
503
- super(
504
- `SAB column layout offset ${e} reaches or exceeds the 2³¹ (${Ae}-byte) ceiling. Past 2 GiB the signed-32-bit bitwise alignment math wraps to negative/misaligned offsets. This is a structural limit independent of the (default 256 MiB) allocator cap — a single SAB cannot back more than ~2 GiB of column data.`
505
- ), this.name = "StoreLayoutOverflowError";
506
- }
507
- }
508
- function Ke(t, e) {
509
- if (t + e > Ae)
510
- throw new je(t);
511
- return t + (e - 1) & ~(e - 1);
512
- }
513
- function Zt(t, e, n, r) {
514
- switch (e) {
515
- case E.u8:
516
- return new Uint8Array(t, n, r);
517
- case E.i8:
518
- return new Int8Array(t, n, r);
519
- case E.u16:
520
- return new Uint16Array(t, n, r);
521
- case E.i16:
522
- return new Int16Array(t, n, r);
523
- case E.u32:
524
- return new Uint32Array(t, n, r);
525
- case E.i32:
526
- return new Int32Array(t, n, r);
527
- case E.f32:
528
- return new Float32Array(t, n, r);
529
- case E.f64:
530
- return new Float64Array(t, n, r);
531
- }
532
- }
533
- function Jt(t, e, n = 0) {
534
- const s = At(
535
- t.map((a) => ({
536
- archetypeId: a.archetypeId,
537
- componentMask: a.componentMask,
538
- rowCount: 0,
539
- enabledCount: 0,
540
- rowCapacity: a.rowCapacity,
541
- columns: a.columns.map((c) => ({
542
- componentId: c.componentId,
543
- fieldId: c.fieldId,
544
- typeTag: c.typeTag,
545
- byteOff: 0,
546
- stride: Oe[c.typeTag]
547
- }))
548
- }))
549
- ) + n;
550
- let o = e + s;
551
- const i = new Array(t.length);
552
- for (let a = 0; a < t.length; a++) {
553
- const c = t[a], d = new Array(c.columns.length);
554
- for (let l = 0; l < c.columns.length; l++) {
555
- const f = c.columns[l], h = Oe[f.typeTag];
556
- o = Ke(o, h), d[l] = {
557
- componentId: f.componentId,
558
- fieldId: f.fieldId,
559
- typeTag: f.typeTag,
560
- byteOff: o,
561
- stride: h
562
- }, o += h * c.rowCapacity;
563
- }
564
- i[a] = {
565
- archetypeId: c.archetypeId,
566
- componentMask: c.componentMask,
567
- rowCount: 0,
568
- enabledCount: 0,
569
- rowCapacity: c.rowCapacity,
570
- columns: d
571
- };
572
- }
573
- if (o > Ae)
574
- throw new je(o);
575
- return { descriptors: i, totalBytes: o, regionBytes: s };
576
- }
577
- function ts(t) {
578
- const e = t;
579
- return typeof e._regionBytes == "number" && typeof e._allocator == "function" && typeof e._reservedDescriptorBytes == "number";
580
- }
581
- function ns(t, e = st, n = {}) {
582
- const r = {};
583
- let s = _t;
584
- for (let w = 0; w < K.length; w++) {
585
- const b = K[w], G = b.sizeFromOptions(n);
586
- r[b.headerOff] = G === 0 ? 0 : s, s += G;
587
- }
588
- const o = n.regions ?? [];
589
- zt(o);
590
- const i = o.length, a = i > 0 ? s : 0;
591
- s += ze(i);
592
- const c = new Array(i);
593
- for (let w = 0; w < o.length; w++) {
594
- const b = o[w];
595
- c[w] = { regionId: b.id, byteOffset: s, byteLength: b.bytes }, s += b.bytes;
596
- }
597
- const d = n.bindingsRegionBytes ?? 0, l = d === 0 ? 0 : s;
598
- s += d;
599
- const f = s, { descriptors: h, totalBytes: g, regionBytes: p } = Jt(
600
- t,
601
- f,
602
- n.reservedDescriptorBytes ?? 0
603
- ), u = e(g), _ = new DataView(u), I = {
604
- magic: ft,
605
- simAbiVersion: ht,
606
- viewStamp: 0,
607
- capacity: g,
608
- archetypeCount: t.length,
609
- layoutDescriptorOff: f,
610
- bindingsOff: l,
611
- regionTableOff: a,
612
- regionTableCount: i,
613
- // `regionOffsets` stays keyed by the snake ABI field names (it also indexes
614
- // `STORE_HEADER_OFFSETS`); map its 4 entries onto the camelCase header fields.
615
- commandRingOff: r.command_ring_off,
616
- entityIndexOff: r.entity_index_off,
617
- eventRingOff: r.event_ring_off,
618
- actionRingOff: r.action_ring_off
619
- };
620
- mt(_, I), d > 0 && new Uint8Array(u, l, d).fill(0);
621
- for (let w = 0; w < K.length; w++) {
622
- const b = K[w], G = r[b.headerOff];
623
- G !== 0 && b.init(_, G, n);
624
- }
625
- a !== 0 && jt(_, a, c);
626
- for (let w = 0; w < o.length; w++)
627
- o[w].init(_, c[w].byteOffset);
628
- Tt(_, f, h);
629
- const B = en(u, h);
630
- return {
631
- buffer: u,
632
- view: _,
633
- header: I,
634
- archetypes: B,
635
- _regionBytes: p,
636
- _allocator: e,
637
- // Carry the headroom policy with the store so the realloc slow path
638
- // (`optionsFromOld`) can re-reserve the same margin.
639
- _reservedDescriptorBytes: n.reservedDescriptorBytes ?? 0
640
- };
641
- }
642
- function en(t, e) {
643
- const n = /* @__PURE__ */ new Map();
644
- for (let r = 0; r < e.length; r++) {
645
- const s = e[r], o = new Array(s.columns.length), i = /* @__PURE__ */ new Map();
646
- for (let a = 0; a < s.columns.length; a++) {
647
- const c = s.columns[a], d = {
648
- componentId: c.componentId,
649
- fieldId: c.fieldId,
650
- typeTag: c.typeTag,
651
- byteOff: c.byteOff,
652
- stride: c.stride,
653
- view: Zt(t, c.typeTag, c.byteOff, s.rowCapacity)
654
- };
655
- o[a] = d, i.set(Qt(c.componentId, c.fieldId), d);
656
- }
657
- n.set(s.archetypeId, {
658
- archetypeId: s.archetypeId,
659
- componentMask: s.componentMask,
660
- rowCapacity: s.rowCapacity,
661
- columns: i,
662
- columnsInOrder: o
663
- });
664
- }
665
- return n;
666
- }
667
- const tn = 2166136261, Qe = 16777619;
668
- function de(t, e) {
669
- return t = (t ^ e & 255) >>> 0, Math.imul(t, Qe) >>> 0;
670
- }
671
- function ss(t, e) {
672
- return t = (t ^ e >>> 0) >>> 0, Math.imul(t, Qe) >>> 0;
673
- }
674
- class rs {
675
- /** entity index → field-value row (length = field count; `[]` for a tag). */
676
- _data = new ot();
677
- fieldNames;
678
- fieldTypes;
679
- fieldIndex;
680
- constructor(e, n) {
681
- this.fieldNames = e, this.fieldTypes = n;
682
- const r = /* @__PURE__ */ Object.create(null);
683
- for (let s = 0; s < e.length; s++) r[e[s]] = s;
684
- this.fieldIndex = r;
685
- }
686
- /** Number of entities holding this sparse component. */
687
- get size() {
688
- return this._data.size;
689
- }
690
- /** Live entity indices that hold this component (dense, iteration order is
691
- * SparseMap insertion/swap order — NOT canonical). Used by the hot query
692
- * integration path; for the determinism surface use
693
- * `canonicalIndices` instead. */
694
- get indices() {
695
- return this._data.keys;
696
- }
697
- /** Live entity indices in **canonical** (ascending) order — the determinism
698
- * ordering for `stateHash` + snapshot/restore. The native
699
- * `indices` getter is insertion/swap order and would make two worlds with
700
- * identical contents reached by different add/remove histories diverge, so
701
- * the cold determinism paths sort here. Allocates a sorted copy each call;
702
- * never call it on the hot query path. Indices are 20-bit entity indices,
703
- * so the subtraction comparator can't overflow. */
704
- canonicalIndices() {
705
- return this._data.keys.slice().sort((e, n) => e - n);
706
- }
707
- /** The field-value row for `index` (length = field count; `[]` for a tag),
708
- * or `undefined` if `index` isn't a member. Read-only view for the
709
- * determinism paths (`stateHash`, snapshot); mutate via `setField`. */
710
- getRow(e) {
711
- return this._data.get(e);
712
- }
713
- /** Drop all membership + data. Restore path only — `restoreSparseStores`
714
- * repopulates a cleared store from snapshot bytes. */
715
- clear() {
716
- this._data.clear();
717
- }
718
- /** Insert the positional field-value `row` for `index`, taking ownership of
719
- * the array. Restore path only; bypasses the name→index mapping `setRow`
720
- * does, because snapshot bytes are already positional. */
721
- setRawRow(e, n) {
722
- this._data.set(e, n);
723
- }
724
- has(e) {
725
- return this._data.has(e);
726
- }
727
- /** Insert or overwrite the row for `index`, building it from `values`.
728
- * Fields absent from `values` default to 0; a tag stores `[]`. */
729
- setRow(e, n) {
730
- const r = this.fieldNames, s = new Array(r.length);
731
- for (let o = 0; o < r.length; o++) {
732
- const i = n[r[o]];
733
- s[o] = i === void 0 ? 0 : i;
734
- }
735
- this._data.set(e, s);
736
- }
737
- /** Drop `index`'s membership + data. Returns whether it was present. */
738
- remove(e) {
739
- return this._data.delete(e);
740
- }
741
- /** Read one field, or `undefined` if `index` doesn't hold this component. */
742
- getField(e, n) {
743
- const r = this._data.get(e);
744
- return r === void 0 ? void 0 : r[n];
745
- }
746
- /** Write one field. Returns `false` (no-op) if `index` isn't a member. */
747
- setField(e, n, r) {
748
- const s = this._data.get(e);
749
- return s === void 0 ? !1 : (s[n] = r, !0);
750
- }
751
- }
752
- class A extends Error {
753
- constructor(e) {
754
- super(e), this.name = "SparseRestoreError";
755
- }
756
- }
757
- const Ie = 12, we = 4, H = 8;
758
- function Se(t, e) {
759
- let n = tn;
760
- const r = (s) => {
761
- for (let o = 0; o < s.length; o++) n = de(n, s.charCodeAt(o));
762
- };
763
- for (let s = 0; s < t.length; s++)
764
- r(t[s]), n = de(n, 31), r(e[s]), n = de(n, 30);
765
- return n >>> 0;
766
- }
767
- function os(t) {
768
- let e = 4;
769
- for (let o = 0; o < t.length; o++) {
770
- const i = t[o], a = i.fieldNames.length;
771
- e += Ie + i.size * (we + a * H);
772
- }
773
- const n = new Uint8Array(e), r = new DataView(n.buffer);
774
- let s = 0;
775
- r.setUint32(s, t.length, !0), s += 4;
776
- for (let o = 0; o < t.length; o++) {
777
- const i = t[o], a = i.fieldNames.length, c = i.canonicalIndices();
778
- r.setUint32(s, a, !0), s += 4, r.setUint32(s, Se(i.fieldNames, i.fieldTypes), !0), s += 4, r.setUint32(s, c.length, !0), s += 4;
779
- for (let d = 0; d < c.length; d++) {
780
- const l = c[d];
781
- r.setUint32(s, l, !0), s += 4;
782
- const f = i.getRow(l);
783
- for (let h = 0; h < a; h++)
784
- r.setFloat64(s, f[h], !0), s += H;
785
- }
786
- }
787
- return n;
788
- }
789
- function is(t, e) {
790
- const n = new DataView(e.buffer, e.byteOffset, e.byteLength), r = e.byteLength;
791
- let s = 0;
792
- const o = (a) => {
793
- if (s + a > r)
794
- throw new A(
795
- `sparse snapshot truncated: need ${a} more bytes at offset ${s}, have ${r - s}`
796
- );
797
- };
798
- o(4);
799
- const i = n.getUint32(s, !0);
800
- if (s += 4, i !== t.length)
801
- throw new A(
802
- `sparse store count mismatch: snapshot=${i}, registered=${t.length}`
803
- );
804
- for (let a = 0; a < t.length; a++) {
805
- const c = t[a];
806
- o(Ie);
807
- const d = n.getUint32(s, !0);
808
- s += 4;
809
- const l = n.getUint32(s, !0);
810
- s += 4;
811
- const f = n.getUint32(s, !0);
812
- if (s += 4, d !== c.fieldNames.length)
813
- throw new A(
814
- `sparse store ${a} field-count mismatch: snapshot=${d}, registered=${c.fieldNames.length}`
815
- );
816
- const h = Se(c.fieldNames, c.fieldTypes);
817
- if (l !== h)
818
- throw new A(
819
- `sparse store ${a} schema identity mismatch: snapshot hash=${l}, registered=${h} (same field count, different field names/types — likely a registration-order divergence between the snapshot and restore worlds)`
820
- );
821
- c.clear();
822
- for (let g = 0; g < f; g++) {
823
- o(we + d * H);
824
- const p = n.getUint32(s, !0);
825
- if (s += 4, p > $)
826
- throw new A(
827
- `sparse store ${a} member ${g} entity index ${p} exceeds MAX_INDEX (${$})`
828
- );
829
- const u = new Array(d);
830
- for (let _ = 0; _ < d; _++)
831
- u[_] = n.getFloat64(s, !0), s += H;
832
- c.setRawRow(p, u);
833
- }
834
- }
835
- if (s !== r)
836
- throw new A(
837
- `sparse snapshot has ${r - s} trailing bytes after the last store (not a canonical encoding)`
838
- );
839
- }
840
- function as(t, e) {
841
- const n = new DataView(e.buffer, e.byteOffset, e.byteLength), r = e.byteLength;
842
- let s = 0;
843
- const o = (a) => {
844
- if (s + a > r)
845
- throw new A(
846
- `sparse snapshot truncated: need ${a} more bytes at offset ${s}, have ${r - s}`
847
- );
848
- };
849
- o(4);
850
- const i = n.getUint32(s, !0);
851
- if (s += 4, i !== t.length)
852
- throw new A(
853
- `sparse store count mismatch: snapshot=${i}, registered=${t.length}`
854
- );
855
- for (let a = 0; a < t.length; a++) {
856
- const c = t[a];
857
- o(Ie);
858
- const d = n.getUint32(s, !0);
859
- s += 4;
860
- const l = n.getUint32(s, !0);
861
- s += 4;
862
- const f = n.getUint32(s, !0);
863
- if (s += 4, d !== c.fieldNames.length)
864
- throw new A(
865
- `sparse store ${a} field-count mismatch: snapshot=${d}, registered=${c.fieldNames.length}`
866
- );
867
- const h = Se(c.fieldNames, c.fieldTypes);
868
- if (l !== h)
869
- throw new A(
870
- `sparse store ${a} schema identity mismatch: snapshot hash=${l}, registered=${h} (same field count, different field names/types — likely a registration-order divergence between the snapshot and restore worlds)`
871
- );
872
- for (let g = 0; g < f; g++) {
873
- o(we + d * H);
874
- const p = n.getUint32(s, !0);
875
- if (s += 4, p > $)
876
- throw new A(
877
- `sparse store ${a} member ${g} entity index ${p} exceeds MAX_INDEX (${$})`
878
- );
879
- s += d * H;
880
- }
881
- }
882
- if (s !== r)
883
- throw new A(
884
- `sparse snapshot has ${r - s} trailing bytes after the last store (not a canonical encoding)`
885
- );
886
- }
887
- const Me = 2147483647, cs = "orphan", nn = "target", sn = Object.freeze({});
888
- class Ze {
889
- /** `true` → one target per source (target in the sparse field); `false` →
890
- * a set of targets per source. The cardinality discriminant survives as a
891
- * field because it is part of the snapshot header and the traversal/`targetOf`
892
- * mode guards — but the forward *mechanics* are virtual, not branched on it. */
893
- exclusive;
894
- /** Backing sparse component def: `{ target: f64 }` when exclusive, a tag when
895
- * multi. Carries membership (and the target, when exclusive). */
896
- sparse;
897
- /** Cleanup policy applied to this relation's sources when a target is
898
- * destroyed. `orphan` (the default) is a no-op — the link dangles
899
- * safely. `Store` reads this at destroy-flush off `sourcesOf`. */
900
- onDeleteTarget;
901
- /** The backing sparse store instance. Owned for registration/liveness by
902
- * `Store`, but the relation drives the forward/membership rows on it directly
903
- * — that is the cardinality interaction this class now encapsulates. */
904
- _store;
905
- /** target `EntityID` → set of source `EntityID`s. Keyed by the full id, not
906
- * the index, so a recycled target slot can't alias a dead target's sources.
907
- * An entry is dropped the moment its set empties (`unlinkReverse`). */
908
- _reverse = /* @__PURE__ */ new Map();
909
- constructor(e, n, r, s) {
910
- this.exclusive = e, this.sparse = n, this._store = r, this.onDeleteTarget = s;
911
- }
912
- // --- shared reverse index (cardinality-agnostic) ---
913
- /** Record that `src` points at `tgt` in the reverse index. */
914
- linkReverse(e, n) {
915
- let r = this._reverse.get(e);
916
- r === void 0 && (r = /* @__PURE__ */ new Set(), this._reverse.set(e, r)), r.add(n);
917
- }
918
- /** Drop the `src → tgt` edge from the reverse index, removing the target's
919
- * entry entirely once its last source is gone (so a dead-target key doesn't
920
- * linger with an empty set). */
921
- unlinkReverse(e, n) {
922
- const r = this._reverse.get(e);
923
- r !== void 0 && (r.delete(n), r.size === 0 && this._reverse.delete(e));
924
- }
925
- /** Drop every reverse-index entry whose **target** is no longer alive,
926
- * returning the count dropped. The `orphan` policy intentionally
927
- * leaves a destroyed target's reverse entry intact (the link dangles
928
- * safely), so a long-lived source that orphan-points at a stream of
929
- * short-lived targets and never re-targets/dies accumulates dead-target keys
930
- * without bound. This is the reclaim primitive behind `Store.compactRelations`
931
- * — a cold path the host calls at scene/snapshot boundaries. It is
932
- * cardinality-free (reverse-index only), so it lives on the base unchanged.
933
- *
934
- * Pure index reclaim: the **forward** links (the exclusive sparse target
935
- * field, the multi forward set) are left untouched, so `targetOf` /
936
- * `targetsOf` still return the dangling dead handle exactly as `orphan`
937
- * promises. The reverse index is derived, so dropping a dead-target entry
938
- * changes nothing observable except `sourcesOf` on that dead handle (which
939
- * goes from the dangling sources to `[]` — meaningless either way, the target
940
- * is gone) and is faithfully rebuilt by snapshot/restore from the surviving
941
- * forward links. Only the **target** role can leak here: a destroyed *source*
942
- * is already unlinked from every reverse set by `purgeSource`, so a live
943
- * target's set never holds a dead source. `isAlive` is supplied by `Store`,
944
- * which owns entity liveness. Deleting during `Map` key iteration is
945
- * well-defined — already-visited and not-yet-reached keys are unaffected. */
946
- pruneDeadReverse(e) {
947
- let n = 0;
948
- for (const r of this._reverse.keys())
949
- e(r) || (this._reverse.delete(r), n++);
950
- return n;
951
- }
952
- /** Sources that point at `tgt`, ascending by id (deterministic, cold-path
953
- * sort) — empty when none. */
954
- sourcesOf(e) {
955
- const n = this._reverse.get(e);
956
- if (n === void 0 || n.size === 0) return [];
957
- const r = new Array(n.size);
958
- let s = 0;
959
- return n.forEach((o) => {
960
- r[s++] = o;
961
- }), r.sort((o, i) => o - i), r;
962
- }
963
- /** Drop every derived side index — the reverse index and (for multi) the
964
- * forward target sets. Restore path only (`restoreRelations`): the side
965
- * indices are rebuilt from scratch, so they're cleared first to stay
966
- * idempotent when restoring into a dirty world. The backing sparse store is
967
- * cleared separately by `restoreSparseStores`. */
968
- resetIndices() {
969
- this._reverse.clear(), this._resetForward();
970
- }
971
- }
972
- class rn extends Ze {
973
- constructor(e, n, r) {
974
- super(!0, e, n, r);
975
- }
976
- _resetForward() {
977
- }
978
- link(e, n) {
979
- const r = L(e), s = this._store.getField(r, 0);
980
- if (s !== void 0) {
981
- if (s === n) return;
982
- this.unlinkReverse(s, e);
983
- }
984
- this._store.setRow(r, { [nn]: n }), this.linkReverse(n, e);
985
- }
986
- unlink(e, n) {
987
- const r = L(e), s = this._store.getField(r, 0);
988
- s !== void 0 && (n !== void 0 && s !== n || (this.unlinkReverse(s, e), this._store.remove(r)));
989
- }
990
- purgeSource(e) {
991
- const n = L(e), r = this._store.getField(n, 0);
992
- r !== void 0 && this.unlinkReverse(r, e);
993
- }
994
- singleTarget(e) {
995
- const n = this._store.getField(e, 0);
996
- return n === void 0 ? void 0 : n;
997
- }
998
- targetsOf(e) {
999
- const n = this._store.getField(e, 0);
1000
- return n === void 0 ? [] : [n];
1001
- }
1002
- has(e) {
1003
- return this._store.has(e);
1004
- }
1005
- forEachCanonicalTargetSet(e) {
1006
- }
1007
- forEachCanonicalPair(e, n) {
1008
- const r = this._store.canonicalIndices();
1009
- for (let s = 0; s < r.length; s++) {
1010
- const o = r[s];
1011
- n(e(o), this._store.getField(o, 0));
1012
- }
1013
- }
1014
- rebuildReverseFromForward(e) {
1015
- const n = this._store.indices;
1016
- for (let r = 0; r < n.length; r++) {
1017
- const s = n[r];
1018
- this.linkReverse(this._store.getField(s, 0), e(s));
1019
- }
1020
- }
1021
- restoreAddTarget() {
1022
- throw new A(
1023
- "exclusive relation has no multi forward sources to restore (snapshot header should have guarded this)"
1024
- );
1025
- }
1026
- }
1027
- class on extends Ze {
1028
- /** source entity **index** → set of target `EntityID`s. Keyed by source index
1029
- * so destroy-purge — which has the freed index — can drop it in O(1). An
1030
- * entry is removed the moment its set empties. */
1031
- _forward = /* @__PURE__ */ new Map();
1032
- constructor(e, n, r) {
1033
- super(!1, e, n, r);
1034
- }
1035
- _resetForward() {
1036
- this._forward.clear();
1037
- }
1038
- link(e, n) {
1039
- const r = L(e);
1040
- let s = this._forward.get(r);
1041
- s === void 0 && (s = /* @__PURE__ */ new Set(), this._forward.set(r, s), this._store.setRow(r, sn)), s.add(n), this.linkReverse(n, e);
1042
- }
1043
- unlink(e, n) {
1044
- const r = L(e), s = this._forward.get(r);
1045
- if (s !== void 0) {
1046
- if (n === void 0) {
1047
- this._forward.delete(r), s.forEach((o) => this.unlinkReverse(o, e)), this._store.remove(r);
1048
- return;
1049
- }
1050
- s.has(n) && (s.delete(n), this.unlinkReverse(n, e), s.size === 0 && (this._forward.delete(r), this._store.remove(r)));
1051
- }
1052
- }
1053
- purgeSource(e) {
1054
- const n = L(e), r = this._forward.get(n);
1055
- r !== void 0 && (this._forward.delete(n), r.forEach((s) => this.unlinkReverse(s, e)));
1056
- }
1057
- singleTarget() {
1058
- }
1059
- targetsOf(e) {
1060
- const n = this._forward.get(e);
1061
- if (n === void 0 || n.size === 0) return [];
1062
- const r = new Array(n.size);
1063
- let s = 0;
1064
- return n.forEach((o) => {
1065
- r[s++] = o;
1066
- }), r.sort((o, i) => o - i), r;
1067
- }
1068
- has(e) {
1069
- return this._store.has(e);
1070
- }
1071
- forEachCanonicalTargetSet(e) {
1072
- const n = Array.from(this._forward.keys()).sort((r, s) => r - s);
1073
- for (let r = 0; r < n.length; r++) {
1074
- const s = this.targetsOf(n[r]);
1075
- s.length !== 0 && e(n[r], s);
1076
- }
1077
- }
1078
- forEachCanonicalPair(e, n) {
1079
- this.forEachCanonicalTargetSet((r, s) => {
1080
- const o = e(r);
1081
- for (let i = 0; i < s.length; i++) n(o, s[i]);
1082
- });
1083
- }
1084
- rebuildReverseFromForward() {
1085
- }
1086
- restoreAddTarget(e, n, r) {
1087
- let s = this._forward.get(e);
1088
- s === void 0 && (s = /* @__PURE__ */ new Set(), this._forward.set(e, s)), s.add(n), this.linkReverse(n, r);
1089
- }
1090
- }
1091
- function ds(t, e, n, r) {
1092
- return t ? new rn(e, n, r) : new on(e, n, r);
1093
- }
1094
- const Je = 4, et = 4, tt = 8, ne = 8;
1095
- function ls(t) {
1096
- const e = new Array(t.length);
1097
- let n = 4;
1098
- for (let i = 0; i < t.length; i++) {
1099
- n += Je;
1100
- const a = t[i];
1101
- if (a.exclusive) {
1102
- e[i] = null;
1103
- continue;
1104
- }
1105
- const c = [];
1106
- a.forEachCanonicalTargetSet((d, l) => c.push([d, l])), e[i] = c, n += et;
1107
- for (let d = 0; d < c.length; d++)
1108
- n += tt + c[d][1].length * ne;
1109
- }
1110
- const r = new Uint8Array(n), s = new DataView(r.buffer);
1111
- let o = 0;
1112
- s.setUint32(o, t.length, !0), o += 4;
1113
- for (let i = 0; i < t.length; i++) {
1114
- s.setUint32(o, t[i].exclusive ? 0 : 1, !0), o += 4;
1115
- const a = e[i];
1116
- if (a !== null) {
1117
- s.setUint32(o, a.length, !0), o += 4;
1118
- for (let c = 0; c < a.length; c++) {
1119
- const d = a[c][0], l = a[c][1];
1120
- s.setUint32(o, d, !0), o += 4, s.setUint32(o, l.length, !0), o += 4;
1121
- for (let f = 0; f < l.length; f++)
1122
- s.setFloat64(o, l[f], !0), o += ne;
1123
- }
1124
- }
1125
- }
1126
- return r;
1127
- }
1128
- function us(t, e, n) {
1129
- const r = new DataView(e.buffer, e.byteOffset, e.byteLength), s = e.byteLength;
1130
- let o = 0;
1131
- const i = (c) => {
1132
- if (o + c > s)
1133
- throw new A(
1134
- `relation snapshot truncated: need ${c} more bytes at offset ${o}, have ${s - o}`
1135
- );
1136
- };
1137
- for (let c = 0; c < t.length; c++) t[c].resetIndices();
1138
- i(4);
1139
- const a = r.getUint32(o, !0);
1140
- if (o += 4, a !== t.length)
1141
- throw new A(
1142
- `relation count mismatch: snapshot=${a}, registered=${t.length}`
1143
- );
1144
- for (let c = 0; c < t.length; c++) {
1145
- const d = t[c];
1146
- i(Je);
1147
- const l = r.getUint32(o, !0);
1148
- if (o += 4, l === 1 === d.exclusive)
1149
- throw new A(
1150
- `relation ${c} cardinality mismatch: snapshot ${l ? "multi" : "exclusive"}, registered ${d.exclusive ? "exclusive" : "multi"}`
1151
- );
1152
- if (d.exclusive) continue;
1153
- i(et);
1154
- const f = r.getUint32(o, !0);
1155
- o += 4;
1156
- for (let h = 0; h < f; h++) {
1157
- i(tt);
1158
- const g = r.getUint32(o, !0);
1159
- o += 4;
1160
- const p = r.getUint32(o, !0);
1161
- if (o += 4, g > $)
1162
- throw new A(
1163
- `relation ${c} source index ${g} exceeds MAX_INDEX (${$})`
1164
- );
1165
- i(p * ne);
1166
- const u = n(g);
1167
- for (let _ = 0; _ < p; _++) {
1168
- const I = r.getFloat64(o, !0);
1169
- o += ne;
1170
- const B = I;
1171
- if (!Number.isInteger(B) || B < 0 || B > Re)
1172
- throw new A(
1173
- `relation ${c} target ${B} is not a well-formed packed EntityID (expected an integer in [0, ${Re}])`
1174
- );
1175
- d.restoreAddTarget(g, I, u);
1176
- }
1177
- }
1178
- }
1179
- if (o !== s)
1180
- throw new A(
1181
- `relation snapshot has ${s - o} trailing bytes after the last relation (not a canonical encoding)`
1182
- );
1183
- }
1184
- const $e = /* @__PURE__ */ new WeakMap();
1185
- function an(t) {
1186
- const e = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Set(), o = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Set(), c = /* @__PURE__ */ new Set(), d = /* @__PURE__ */ new Set(), l = /* @__PURE__ */ new Set();
1187
- for (let u = 0; u < t.writes.length; u++) {
1188
- const _ = t.writes[u].id;
1189
- n.add(_), e.add(_), r.add(_);
1190
- }
1191
- for (let u = 0; u < t.reads.length; u++)
1192
- e.add(t.reads[u].id);
1193
- for (let u = 0; u < t.spawns.length; u++) {
1194
- const _ = t.spawns[u];
1195
- for (let I = 0; I < _.length; I++)
1196
- r.add(_[I].id);
1197
- }
1198
- for (let u = 0; u < t.transitions.length; u++) {
1199
- const _ = t.transitions[u];
1200
- if (_.add)
1201
- for (let I = 0; I < _.add.length; I++)
1202
- r.add(_.add[I].id);
1203
- if (_.remove)
1204
- for (let I = 0; I < _.remove.length; I++)
1205
- s.add(_.remove[I].id);
1206
- }
1207
- for (let u = 0; u < t.despawns.length; u++)
1208
- s.add(t.despawns[u].id);
1209
- for (let u = 0; u < t.resourceReads.length; u++)
1210
- o.add(t.resourceReads[u]);
1211
- for (let u = 0; u < t.resourceWrites.length; u++) {
1212
- const _ = t.resourceWrites[u];
1213
- i.add(_), o.add(_);
1214
- }
1215
- const f = t.sparseWrites;
1216
- if (f !== void 0)
1217
- for (let u = 0; u < f.length; u++) {
1218
- const _ = f[u];
1219
- c.add(_), a.add(_);
1220
- }
1221
- const h = t.sparseReads;
1222
- if (h !== void 0)
1223
- for (let u = 0; u < h.length; u++) a.add(h[u]);
1224
- const g = t.relationWrites;
1225
- if (g !== void 0)
1226
- for (let u = 0; u < g.length; u++) {
1227
- const _ = g[u];
1228
- l.add(_), d.add(_);
1229
- }
1230
- const p = t.relationReads;
1231
- if (p !== void 0)
1232
- for (let u = 0; u < p.length; u++)
1233
- d.add(p[u]);
1234
- return {
1235
- reads: e,
1236
- writes: n,
1237
- addAllowed: r,
1238
- removeAllowed: s,
1239
- hasDespawns: t.despawns.length > 0,
1240
- resourceReads: o,
1241
- resourceWrites: i,
1242
- sparseReads: a,
1243
- sparseWrites: c,
1244
- relationReads: d,
1245
- relationWrites: l
1246
- };
1247
- }
1248
- function cn(t) {
1249
- const e = $e.get(t);
1250
- if (e !== void 0) return e;
1251
- const n = an(t);
1252
- return $e.set(t, n), n;
1253
- }
1254
- const Pe = /* @__PURE__ */ new WeakMap();
1255
- function dn(t) {
1256
- const e = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set();
1257
- if (t.reads !== void 0)
1258
- for (let r = 0; r < t.reads.length; r++) e.add(t.reads[r].id);
1259
- if (t.resourceReads !== void 0)
1260
- for (let r = 0; r < t.resourceReads.length; r++)
1261
- n.add(t.resourceReads[r]);
1262
- return {
1263
- reads: e,
1264
- writes: /* @__PURE__ */ new Set(),
1265
- addAllowed: /* @__PURE__ */ new Set(),
1266
- removeAllowed: /* @__PURE__ */ new Set(),
1267
- hasDespawns: !1,
1268
- resourceReads: n,
1269
- resourceWrites: /* @__PURE__ */ new Set(),
1270
- sparseReads: /* @__PURE__ */ new Set(),
1271
- sparseWrites: /* @__PURE__ */ new Set(),
1272
- relationReads: /* @__PURE__ */ new Set(),
1273
- relationWrites: /* @__PURE__ */ new Set()
1274
- };
1275
- }
1276
- function ln(t) {
1277
- const e = Pe.get(t);
1278
- if (e !== void 0) return e;
1279
- const n = dn(t);
1280
- return Pe.set(t, n), n;
1281
- }
1282
- class un {
1283
- active = null;
1284
- sets = null;
1285
- // The label used in violation messages. Tracks `active` for a system span,
1286
- // but a run-condition span has no descriptor — only this name — so the
1287
- // failure helpers read the label here rather than off `active`.
1288
- activeName = null;
1289
- // An `exclusive` system has full world access: every check_* below
1290
- // passes for the whole span. Kept as an explicit flag (rather than leaving
1291
- // `sets` null) so `isActive()` stays truthful inside the span.
1292
- exclusive = !1;
1293
- enter(e) {
1294
- this.active = e, this.activeName = e.name ?? `system_${e.id}`, this.exclusive = e.exclusive === !0, this.sets = this.exclusive ? null : cn(e);
1295
- }
1296
- /** Open a reads-only span for a run condition. No descriptor — a
1297
- * condition can gate a whole SystemSet, so it isn't attributable to one
1298
- * system — just its declared reads/resource_reads and a name for diagnostics.
1299
- * Paired with `leave()`. */
1300
- enterCondition(e) {
1301
- this.active = null, this.activeName = e.name, this.sets = ln(e);
1302
- }
1303
- leave() {
1304
- this.active = null, this.activeName = null, this.sets = null, this.exclusive = !1;
1305
- }
1306
- isActive() {
1307
- return this.sets !== null || this.exclusive;
1308
- }
1309
- /** Current system descriptor, if any. Null during a run-condition span. */
1310
- current() {
1311
- return this.active;
1312
- }
1313
- checkRead(e) {
1314
- this.sets !== null && (this.sets.reads.has(e.id) || this.failComponent("read", e, "reads"));
1315
- }
1316
- checkWrite(e) {
1317
- this.sets !== null && (this.sets.writes.has(e.id) || this.failComponent("write", e, "writes"));
1318
- }
1319
- checkAdd(e) {
1320
- this.sets !== null && (this.sets.addAllowed.has(e.id) || this.failComponent("addComponent", e, "spawns / transitions.add / writes"));
1321
- }
1322
- checkRemove(e) {
1323
- this.sets !== null && (this.sets.removeAllowed.has(e.id) || this.failComponent("removeComponent", e, "despawns / transitions.remove"));
1324
- }
1325
- checkDestroy() {
1326
- if (this.sets === null || this.sets.hasDespawns) return;
1327
- const e = this.activeName;
1328
- throw new T(
1329
- y.ACCESS_UNDECLARED,
1330
- `system '${e}' called despawn but didn't declare any despawns — declare the components this system removes via despawn in its 'despawns'`,
1331
- { system: e, op: "despawn" }
1332
- );
1333
- }
1334
- checkResourceRead(e) {
1335
- if (this.sets === null) return;
1336
- const n = e;
1337
- this.sets.resourceReads.has(n) || this.failResource("read", e, "resourceReads");
1338
- }
1339
- checkResourceWrite(e) {
1340
- if (this.sets === null) return;
1341
- const n = e;
1342
- this.sets.resourceWrites.has(n) || this.failResource("write", e, "resourceWrites");
1343
- }
1344
- // --- Sparse component / relation checks ---
1345
- // Keyed against the dedicated sparse/relation sets, NOT the dense
1346
- // `reads`/`writes` sets — the id spaces are disjoint by construction (see
1347
- // file header). `def as unknown as number` recovers the SparseComponentID /
1348
- // RelationID the branded handle erases to at runtime.
1349
- checkSparseRead(e) {
1350
- if (this.sets === null) return;
1351
- const n = e;
1352
- this.sets.sparseReads.has(n) || this.failSparse("read", n, "sparseReads");
1353
- }
1354
- checkSparseWrite(e) {
1355
- if (this.sets === null) return;
1356
- const n = e;
1357
- this.sets.sparseWrites.has(n) || this.failSparse("write", n, "sparseWrites");
1358
- }
1359
- checkRelationRead(e) {
1360
- if (this.sets === null) return;
1361
- const n = e;
1362
- this.sets.relationReads.has(n) || this.failRelation("read", n, "relationReads");
1363
- }
1364
- checkRelationWrite(e) {
1365
- if (this.sets === null) return;
1366
- const n = e;
1367
- this.sets.relationWrites.has(n) || this.failRelation("write", n, "relationWrites");
1368
- }
1369
- /** A `(*, T)` wildcard (`Query.forEachRelatedTo`) reads every
1370
- * relation's reverse index, so it can't name a specific relation — it is
1371
- * authorised by the `ANY_RELATION` sentinel in `relationReads`. Honoured here
1372
- * exactly like a per-relation read, just keyed on the reserved sentinel id
1373
- * (which computeSets folds into `relationReads` like any other entry). */
1374
- checkRelationReadAny() {
1375
- this.sets !== null && (this.sets.relationReads.has(Me) || this.failRelation(
1376
- "(*, T) wildcard read",
1377
- Me,
1378
- "relationReads (as ANY_RELATION)"
1379
- ));
1380
- }
1381
- // --- Optional query-term scope ---
1382
- // `Query.forEach` and `ChangedQuery.forEach` push the iterating query's
1383
- // `_optional` term list for the span of the callback;
1384
- // `Archetype.getOptionalColumnRead` then verifies the fetched component was
1385
- // declared via `.optional(T)` — the term that authorizes the optional fetch.
1386
- // This is what makes the optional term *consumed* rather than decorative: like
1387
- // `reads:[T]` for required access, `.optional(T)` is the fetch's declaration,
1388
- // checked here in `DEV`. A stack (not a single slot) handles re-entrant /
1389
- // nested `forEach`. The optional scope is independent of the per-system
1390
- // `enter`/`leave` above — a host-side `ecs.query(...).forEach` outside any
1391
- // system still establishes one. No active scope ⇒ lenient: a manual
1392
- // `query.archetypes` walk can't be attributed to an optional declaration, so it
1393
- // isn't checked — mirroring the unchecked outside-of-system calls in the header.
1394
- //
1395
- // CAVEAT: the gate always attributes to the INNERMOST active
1396
- // `forEach`. If you nest `forEach` and call `getOptionalColumnRead` on an
1397
- // OUTER query's archetype inside the inner loop, it is checked against the inner
1398
- // query's terms (a false throw or false pass). Per-query attribution isn't worth
1399
- // the complexity for a dev-only assertion; iterate one query at a time, or read
1400
- // the outer span before entering the inner loop.
1401
- optionalScopes = [];
1402
- enterOptionalScope(e) {
1403
- this.optionalScopes.push(e);
1404
- }
1405
- leaveOptionalScope() {
1406
- this.optionalScopes.pop();
1407
- }
1408
- checkOptionalFetch(e) {
1409
- const n = this.optionalScopes.length;
1410
- if (n === 0) return;
1411
- const r = this.optionalScopes[n - 1], s = e.id;
1412
- for (let o = 0; o < r.length; o++)
1413
- if (r[o] === s) return;
1414
- throw new T(
1415
- y.OPTIONAL_TERM_NOT_DECLARED,
1416
- `getOptionalColumnRead fetched optional component ${s} but the iterating query didn't declare it — add .optional(component) to the query before fetching it`
1417
- );
1418
- }
1419
- failComponent(e, n, r) {
1420
- const s = this.activeName, o = ut(n);
1421
- throw new T(
1422
- y.ACCESS_UNDECLARED,
1423
- `system '${s}' performed ${e} on ${o} but didn't declare it — add it to '${r}' (see docs/api/systems.md)`,
1424
- { system: s, op: e, component: n.id }
1425
- );
1426
- }
1427
- failSparse(e, n, r) {
1428
- const s = this.activeName;
1429
- throw new T(
1430
- y.ACCESS_UNDECLARED,
1431
- `system '${s}' performed ${e} on sparse component ${n} but didn't declare it — add it to '${r}' (see docs/api/systems.md)`,
1432
- { system: s, op: e, sparse: n }
1433
- );
1434
- }
1435
- failRelation(e, n, r) {
1436
- const s = this.activeName;
1437
- throw new T(
1438
- y.ACCESS_UNDECLARED,
1439
- `system '${s}' performed ${e} on relation ${n} but didn't declare it — add it to '${r}' (see docs/api/systems.md)`,
1440
- { system: s, op: e, relation: n }
1441
- );
1442
- }
1443
- failResource(e, n, r) {
1444
- const s = this.activeName, o = n.description ?? "<unnamed>";
1445
- throw new T(
1446
- y.ACCESS_UNDECLARED,
1447
- `system '${s}' performed resource ${e} on '${o}' but didn't declare it — add the resource key to '${r}' (see docs/api/systems.md)`,
1448
- { system: s, op: e, resource: o }
1449
- );
1450
- }
1451
- }
1452
- const Q = new un(), fn = "/packages/engine/src/core/ecs/";
1453
- class hn {
1454
- activeCache = null;
1455
- repoRootCache = null;
1456
- buf = /* @__PURE__ */ new Map();
1457
- callsiteCache = /* @__PURE__ */ new Map();
1458
- isActive() {
1459
- if (this.activeCache !== null) return this.activeCache;
1460
- const n = globalThis.process?.env?.VISUAL_INTEL_TRACE;
1461
- return this.activeCache = n === "1" || n === "true";
1462
- }
1463
- repoRoot() {
1464
- if (this.repoRootCache !== null) return this.repoRootCache;
1465
- const e = globalThis.process;
1466
- return this.repoRootCache = e?.cwd?.() ?? "";
1467
- }
1468
- resolveCallsite() {
1469
- return mn(
1470
- new Error().stack ?? null,
1471
- this.repoRoot(),
1472
- this.callsiteCache
1473
- );
1474
- }
1475
- record(e, n, r) {
1476
- const s = this.resolveCallsite();
1477
- if (!s) return;
1478
- const o = `${e} ${n} ${r} ${s}`;
1479
- this.buf.set(o, (this.buf.get(o) ?? 0) + 1);
1480
- }
1481
- recordEmit(e) {
1482
- this.record("ecs-events", "emit", e);
1483
- }
1484
- recordRead(e) {
1485
- this.record("ecs-events", "read", e);
1486
- }
1487
- recordResourceRead(e) {
1488
- this.record("resources", "read", e);
1489
- }
1490
- recordResourceWrite(e) {
1491
- this.record("resources", "write", e);
1492
- }
1493
- recordResourceRegister(e) {
1494
- this.record("resources", "register", e);
1495
- }
1496
- recordResourceRemove(e) {
1497
- this.record("resources", "remove", e);
1498
- }
1499
- recordSendAction(e) {
1500
- this.record("actions", "send_action", e);
1501
- }
1502
- recordHandleAction(e) {
1503
- this.record("actions", "handle_action", e);
1504
- }
1505
- snapshot() {
1506
- const e = {
1507
- "ecs-events": { emit: [], read: [] },
1508
- actions: { send_action: [], handle_action: [] },
1509
- resources: { read: [], write: [], register: [], remove: [] }
1510
- };
1511
- for (const [n, r] of this.buf.entries()) {
1512
- const [s, o, i, a] = n.split(" ");
1513
- if (!s || !o || a === void 0) continue;
1514
- const d = { key: s === "actions" ? Number(i) : i, file: a, count: r }, f = e[s][o];
1515
- f && f.push(d);
1516
- }
1517
- for (const n of Object.values(e))
1518
- for (const r of Object.values(n))
1519
- r.sort((s, o) => {
1520
- if (s.file !== o.file) return s.file < o.file ? -1 : 1;
1521
- const i = String(s.key), a = String(o.key);
1522
- return i < a ? -1 : i > a ? 1 : 0;
1523
- });
1524
- return {
1525
- schemaVersion: 1,
1526
- capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
1527
- channels: e
1528
- };
1529
- }
1530
- reset() {
1531
- this.buf.clear(), this.callsiteCache.clear(), this.activeCache = null, this.repoRootCache = null;
1532
- }
1533
- }
1534
- function _n(t) {
1535
- const e = /\(([^)]+):\d+:\d+\)\s*$/.exec(t);
1536
- if (e) return e[1] ?? null;
1537
- const n = /at\s+([^\s][^()]*?):\d+:\d+\s*$/.exec(t);
1538
- return n && (n[1] ?? "").trim() || null;
1539
- }
1540
- function mn(t, e, n) {
1541
- if (!t) return null;
1542
- const r = t.split(`
1543
- `);
1544
- for (let s = 0; s < r.length; s++) {
1545
- const o = r[s], i = n?.get(o);
1546
- if (i !== void 0) {
1547
- if (i === null) continue;
1548
- return i;
1549
- }
1550
- const a = _n(o);
1551
- if (!a) {
1552
- n?.set(o, null);
1553
- continue;
1554
- }
1555
- if (a.includes(fn)) {
1556
- n?.set(o, null);
1557
- continue;
1558
- }
1559
- const c = gn(a, e);
1560
- return n?.set(o, c), c;
1561
- }
1562
- return null;
1563
- }
1564
- function gn(t, e) {
1565
- let n = t;
1566
- return n.startsWith("file://") && (n = n.slice(7)), e && n.startsWith(e + "/") && (n = n.slice(e.length + 1)), n.replace(/\\/g, "/");
1567
- }
1568
- const fs = new hn();
1569
- var x = /* @__PURE__ */ ((t) => (t.PRE_STARTUP = "PRE_STARTUP", t.STARTUP = "STARTUP", t.POST_STARTUP = "POST_STARTUP", t.FIXED_UPDATE = "FIXED_UPDATE", t.PRE_UPDATE = "PRE_UPDATE", t.UPDATE = "UPDATE", t.POST_UPDATE = "POST_UPDATE", t))(x || {});
1570
- const le = [
1571
- "PRE_STARTUP",
1572
- "STARTUP",
1573
- "POST_STARTUP"
1574
- /* POST_STARTUP */
1575
- ], ue = [
1576
- "PRE_UPDATE",
1577
- "UPDATE",
1578
- "POST_UPDATE"
1579
- /* POST_UPDATE */
1580
- ];
1581
- function hs(t) {
1582
- return Object.freeze({ name: t });
1583
- }
1584
- function En(t) {
1585
- return !("fn" in t);
1586
- }
1587
- const X = Object.freeze([]);
1588
- function fe(t) {
1589
- return t === void 0 ? X : Array.isArray(t) ? t : [t];
1590
- }
1591
- class _s {
1592
- labelSystems = /* @__PURE__ */ new Map();
1593
- // Sorted descriptors for a phase, paired with the `systemLastRun` slot of each
1594
- // — cached together so `runLabel` resolves both with the one `Map.get` it
1595
- // already paid, and the per-system lookup inside the loop is array indexing.
1596
- sortedCache = /* @__PURE__ */ new Map();
1597
- systemIndex = /* @__PURE__ */ new Map();
1598
- // Previous-run tick per scheduled system — a packed array, NOT a `Map` keyed
1599
- // on the descriptor. `runLabel` reads it and writes it back once per system
1600
- // per phase. A profile of a dispatch-bound schedule shows that those two `Map`
1601
- // operations, and not the system bodies, are where most of the phase loop goes
1602
- // — they hash an object identity twice for each system in each frame.
1603
- //
1604
- // Indexed by a SCHEDULE-LOCAL slot, not by `SystemDescriptor.id`. Ids come
1605
- // from a per-world counter, so two descriptors registered with two different
1606
- // worlds both get id 0 — scheduling them into a third world would alias them
1607
- // onto one slot and let the system that runs more often overwrite the other's
1608
- // last-run tick (silently widening its `changed()` window). Slots are handed
1609
- // out per Schedule, so identity comes from this schedule's own numbering.
1610
- systemLastRun = [];
1611
- // Descriptor → its `systemLastRun` slot. Consulted only by `addSystems` /
1612
- // `removeSystem`; the run loop never touches it (the slot travels in the
1613
- // phase plan).
1614
- //
1615
- // `removeSystem` MUST delete from this map. It is the only strong reference
1616
- // the Schedule keeps to a descriptor once its node is gone, and a descriptor
1617
- // closes over whatever its `fn` captured — leaving the entry behind pins that
1618
- // for the world's lifetime. (The `Map` this replaced was deleted on remove;
1619
- // forgetting to do the same here leaked every descriptor ever scheduled.)
1620
- lastRunSlots = /* @__PURE__ */ new Map();
1621
- // Slots freed by `removeSystem`, handed back out by `_assignLastRunSlot`.
1622
- // Without reuse the array would grow by one per `addSystems` call — unbounded
1623
- // under a workload that toggles systems on and off each frame.
1624
- freeLastRunSlots = [];
1625
- // Nesting depth of a drive (`runStartup` / `runUpdate` / `runFixedUpdate`).
1626
- // Non-zero means a phase plan is live and `runLabel`'s loop may still write
1627
- // `systemLastRun` through the `slots` array it captured, which is what makes
1628
- // recycling a freed slot unsafe right now — see `_assignLastRunSlot`.
1629
- _driveDepth = 0;
1630
- // Only systems carrying a run condition or set membership. The hot
1631
- // loop skips the per-system gate probe entirely when this is empty, so a
1632
- // schedule that uses no conditions runs byte-for-byte the original path.
1633
- gatedSystems = /* @__PURE__ */ new Map();
1634
- // Live set configuration, read at sort time (ordering) and run time
1635
- // (conditions) so `configureSet` is order-independent w.r.t. `addSystems`.
1636
- setConditions = /* @__PURE__ */ new Map();
1637
- setOrdering = /* @__PURE__ */ new Map();
1638
- nextInsertionOrder = 0;
1639
- // The opt-in compute backend, or null (the default — pure-TS). When
1640
- // set, a scheduled system carrying a `backendHandle` runs `backend.run(...)`
1641
- // instead of its `fn`. `null` is the byte-for-byte no-backend path: `runLabel`
1642
- // hoists this to a local and only reads `desc.backendHandle` when non-null,
1643
- // so a no-backend ECS never touches the routing field.
1644
- _backend = null;
1645
- /** Dev-diagnostic sink (`ECSOptions.onWarn`); defaults to `console.warn`.
1646
- * The only schedule diagnostic today is `warnDroppedEdge`. */
1647
- onWarn;
1648
- /** The `FIXED_UPDATE` node list, held directly for `hasFixedSystems`. */
1649
- _fixedNodes = [];
1650
- constructor(e) {
1651
- this.onWarn = e ?? ((n) => console.warn(n));
1652
- for (let n = 0; n < le.length; n++)
1653
- this.labelSystems.set(le[n], []);
1654
- this.labelSystems.set("FIXED_UPDATE", this._fixedNodes);
1655
- for (let n = 0; n < ue.length; n++)
1656
- this.labelSystems.set(ue[n], []);
1657
- }
1658
- addSystems(e, ...n) {
1659
- for (const r of n) {
1660
- const s = "system" in r, o = s ? r.system : r, i = s ? r.ordering : void 0, a = s ? fe(r.runIf) : X, c = s ? fe(r.set) : X;
1661
- if (this.systemIndex.has(o))
1662
- throw new T(
1663
- y.DUPLICATE_SYSTEM,
1664
- `System ${o.name ?? o.id} is already scheduled`
1665
- );
1666
- const d = {
1667
- descriptor: o,
1668
- insertionOrder: this.nextInsertionOrder++,
1669
- before: new Set(i?.before ?? []),
1670
- after: new Set(i?.after ?? []),
1671
- conditions: a,
1672
- sets: c
1673
- };
1674
- this.labelSystems.get(e).push(d), this.systemIndex.set(o, e), this._assignLastRunSlot(o), (a.length > 0 || c.length > 0) && this.gatedSystems.set(o, d), this.sortedCache.delete(e);
1675
- }
1676
- }
1677
- /**
1678
- * Configure a `SystemSet` — its shared run condition(s) and/or
1679
- * ordering, inherited by every member. Additive and order-independent w.r.t.
1680
- * `addSystems`: conditions accumulate (ANDed), ordering targets union, and
1681
- * a member added before or after this call picks the configuration up.
1682
- */
1683
- configureSet(e, n) {
1684
- const r = fe(n.runIf);
1685
- if (r.length > 0) {
1686
- const s = this.setConditions.get(e);
1687
- s === void 0 ? this.setConditions.set(e, [...r]) : s.push(...r);
1688
- }
1689
- if (n.before !== void 0 || n.after !== void 0) {
1690
- let s = this.setOrdering.get(e);
1691
- s === void 0 && (s = { before: /* @__PURE__ */ new Set(), after: /* @__PURE__ */ new Set() }, this.setOrdering.set(e, s));
1692
- for (const o of n.before ?? X) s.before.add(o);
1693
- for (const o of n.after ?? X) s.after.add(o);
1694
- this.sortedCache.clear();
1695
- }
1696
- }
1697
- removeSystem(e) {
1698
- const n = this.systemIndex.get(e);
1699
- if (n === void 0) return;
1700
- const r = this.labelSystems.get(n), s = r.findIndex((i) => i.descriptor === e);
1701
- if (s !== -1) {
1702
- const i = r.length - 1;
1703
- s !== i && (r[s] = r[i]), r.pop();
1704
- for (const a of r)
1705
- a.before.delete(e), a.after.delete(e);
1706
- }
1707
- this.systemIndex.delete(e);
1708
- const o = this.lastRunSlots.get(e);
1709
- o !== void 0 && (this.systemLastRun[o] = 0, this.lastRunSlots.delete(e), this.freeLastRunSlots.push(o)), this.gatedSystems.delete(e), this.sortedCache.clear();
1710
- }
1711
- /** Attach (or, with `null`, detach) the opt-in compute backend. Driven
1712
- * by `ECS.attachBackend`; routes any scheduled system carrying a
1713
- * `backendHandle` to `backend.run(handle)` in place of its `fn`. */
1714
- setBackend(e) {
1715
- this._backend = e;
1716
- }
1717
- // The three drive entry points each bracket their phases with `_driveDepth`,
1718
- // so `_assignLastRunSlot` will not recycle a `systemLastRun` slot that a phase
1719
- // plan captured by `runLabel`'s loop may still write to — see the guard there
1720
- // for the hazard it closes.
1721
- //
1722
- // Held across the WHOLE drive, not per phase: one `try`/`finally` per frame
1723
- // instead of one per phase (three, for an update). The difference is
1724
- // measurable on a dispatch-bound schedule, where the system bodies do almost
1725
- // no work. The wider window is also the more
1726
- // conservative one, and slots still recycle freely between frames — the only
1727
- // property `freeLastRunSlots` needs to stay bounded. Written out at each of
1728
- // the three sites rather than wrapped in a helper taking a callback, which
1729
- // would put a closure allocation and an indirect call on the per-frame path.
1730
- runStartup(e, n) {
1731
- this._driveDepth++;
1732
- try {
1733
- for (const r of le)
1734
- this.runLabel(r, e, dt, n);
1735
- } finally {
1736
- this._driveDepth--;
1737
- }
1738
- }
1739
- runUpdate(e, n, r) {
1740
- this._driveDepth++;
1741
- try {
1742
- for (const s of ue)
1743
- this.runLabel(s, e, n, r);
1744
- } finally {
1745
- this._driveDepth--;
1746
- }
1747
- }
1748
- runFixedUpdate(e, n, r) {
1749
- this._driveDepth++;
1750
- try {
1751
- this.runLabel("FIXED_UPDATE", e, n, r);
1752
- } finally {
1753
- this._driveDepth--;
1754
- }
1755
- }
1756
- hasFixedSystems() {
1757
- return this._fixedNodes.length > 0;
1758
- }
1759
- getAllSystems() {
1760
- const e = [];
1761
- for (const n of this.labelSystems.values())
1762
- for (const r of n)
1763
- e.push(r.descriptor);
1764
- return e;
1765
- }
1766
- hasSystem(e) {
1767
- return this.systemIndex.has(e);
1768
- }
1769
- /** Hand `descriptor` its `systemLastRun` slot, keeping the array packed (no
1770
- * holes ⇒ no undefined-check on the read in `runLabel`, which is the whole
1771
- * point of it not being a `Map`). Idempotent for a descriptor already in this
1772
- * schedule — `getSorted` re-asks for every system it sorts. A descriptor that
1773
- * was removed and re-added gets a *fresh* slot starting at tick 0, which is
1774
- * what the previous `Map`-based bookkeeping did (`delete` on remove, `set(…, 0)`
1775
- * on re-add). */
1776
- _assignLastRunSlot(e) {
1777
- let n = this.lastRunSlots.get(e);
1778
- if (n === void 0) {
1779
- const r = this._driveDepth === 0 ? this.freeLastRunSlots.pop() : void 0;
1780
- r !== void 0 ? (n = r, this.systemLastRun[n] = 0) : (n = this.systemLastRun.length, this.systemLastRun.push(0)), this.lastRunSlots.set(e, n);
1781
- }
1782
- return n;
1783
- }
1784
- clear() {
1785
- for (const e of this.labelSystems.values())
1786
- e.length = 0;
1787
- this.sortedCache.clear(), this.systemIndex.clear(), this._driveDepth === 0 ? this.systemLastRun.length = 0 : this.systemLastRun.fill(0), this.lastRunSlots.clear(), this.freeLastRunSlots.length = 0, this.gatedSystems.clear(), this.setConditions.clear(), this.setOrdering.clear();
1788
- }
1789
- runLabel(e, n, r, s) {
1790
- const o = this.getSorted(e), i = o.sorted, a = o.slots, c = this.gatedSystems.size > 0, d = this._backend, l = c ? /* @__PURE__ */ new Map() : void 0;
1791
- for (let f = 0; f < i.length; f++) {
1792
- const h = i[f];
1793
- if (c) {
1794
- const p = this.gatedSystems.get(h);
1795
- if (p !== void 0 && !this.shouldRun(p, n, l)) continue;
1796
- }
1797
- n.lastRunTick = this.systemLastRun[a[f]];
1798
- const g = d !== null ? h.backendHandle : void 0;
1799
- Q.enter(h), n._trace?.systemStart(h, e);
1800
- try {
1801
- g !== void 0 ? d.run(g) : h.fn?.(n, r);
1802
- } finally {
1803
- n._trace?.systemEnd(h), Q.leave();
1804
- }
1805
- this.systemLastRun[a[f]] = s;
1806
- }
1807
- n._trace?.flushBegin(e), n.flush(), n._trace?.flushEnd(e), n._trace?.phaseBoundary(e);
1808
- }
1809
- /**
1810
- * Whether a gated system runs this tick — the AND of its own conditions and
1811
- * every set it belongs to. A set's conditions are evaluated at most once per
1812
- * phase (memoized in `setVerdicts`) and the verdict gates every member of the
1813
- * set uniformly; a `configureSet` between phases is still honored because the
1814
- * memo lives only for a single `runLabel` pass. Short-circuits on the first
1815
- * `false`. The system's own conditions evaluate per system, in canonical order.
1816
- *
1817
- * SEMANTIC NOTE: this evaluates a set's conditions once-per-set-per-phase
1818
- * rather than once-per-member. Equivalent for pure RunConditions; observably
1819
- * different only if a set condition reads state mutated earlier in the SAME
1820
- * phase (resources write immediately). That is intentional — the set gates as a
1821
- * unit, so all its members share one verdict for the phase.
1822
- */
1823
- shouldRun(e, n, r) {
1824
- if (e.conditions.length > 0 && !this.evalConditions(e.conditions, n))
1825
- return !1;
1826
- for (let s = 0; s < e.sets.length; s++) {
1827
- const o = e.sets[s];
1828
- let i = r.get(o);
1829
- if (i === void 0) {
1830
- const a = this.setConditions.get(o);
1831
- i = a === void 0 || a.length === 0 ? !0 : this.evalConditions(a, n), r.set(o, i);
1832
- }
1833
- if (!i) return !1;
1834
- }
1835
- return !0;
1836
- }
1837
- /** Evaluate a condition list with AND semantics. Each predicate runs inside a
1838
- * reads-only `accessCheck` span (dev), so a condition that reads an
1839
- * undeclared resource — or attempts any mutation — throws. */
1840
- evalConditions(e, n) {
1841
- for (let r = 0; r < e.length; r++) {
1842
- const s = e[r];
1843
- Q.enterCondition(s);
1844
- let o;
1845
- try {
1846
- o = s.evaluate(n);
1847
- } finally {
1848
- Q.leave();
1849
- }
1850
- if (!o) return !1;
1851
- }
1852
- return !0;
1853
- }
1854
- getSorted(e) {
1855
- const n = this.sortedCache.get(e);
1856
- if (n !== void 0) return n;
1857
- const r = this.labelSystems.get(e), s = this.sortSystems(r, e), o = new Int32Array(s.length);
1858
- for (let a = 0; a < s.length; a++) o[a] = this._assignLastRunSlot(s[a]);
1859
- const i = { sorted: s, slots: o };
1860
- return this.sortedCache.set(e, i), i;
1861
- }
1862
- /**
1863
- * Delegates to the shared topologicalSort utility.
1864
- * Builds the dependency edge map from before/after constraints, then
1865
- * catches any cycle TypeError and re-throws as ECSError.
1866
- */
1867
- sortSystems(e, n) {
1868
- if (e.length === 0) return [];
1869
- const r = [], s = /* @__PURE__ */ new Map(), o = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Map();
1870
- for (const l of e) {
1871
- r.push(l.descriptor), s.set(l.descriptor, l.insertionOrder), o.add(l.descriptor);
1872
- for (let f = 0; f < l.sets.length; f++) {
1873
- const h = l.sets[f];
1874
- let g = i.get(h);
1875
- g === void 0 && (g = [], i.set(h, g)), g.push(l.descriptor);
1876
- }
1877
- }
1878
- const a = /* @__PURE__ */ new Map();
1879
- for (const l of e)
1880
- a.set(l.descriptor, []);
1881
- for (const l of e) {
1882
- this.resolveEdges(
1883
- l.descriptor,
1884
- l.before,
1885
- "before",
1886
- o,
1887
- i,
1888
- a,
1889
- n
1890
- ), this.resolveEdges(l.descriptor, l.after, "after", o, i, a, n);
1891
- for (let f = 0; f < l.sets.length; f++) {
1892
- const h = this.setOrdering.get(l.sets[f]);
1893
- h !== void 0 && (this.resolveEdges(
1894
- l.descriptor,
1895
- h.before,
1896
- "before",
1897
- o,
1898
- i,
1899
- a,
1900
- n
1901
- ), this.resolveEdges(
1902
- l.descriptor,
1903
- h.after,
1904
- "after",
1905
- o,
1906
- i,
1907
- a,
1908
- n
1909
- ));
1910
- }
1911
- }
1912
- const c = (l, f) => s.get(l) - s.get(f), d = (l) => l.name ?? `system_${l.id}`;
1913
- try {
1914
- return it(r, a, c, d);
1915
- } catch (l) {
1916
- throw l instanceof TypeError ? new T(
1917
- y.CIRCULAR_SYSTEM_DEPENDENCY,
1918
- `Circular system dependency detected in ${n}: ${l.message}`
1919
- ) : l;
1920
- }
1921
- }
1922
- /**
1923
- * Add the topo edges for one ordering list. For `"before"` the source
1924
- * runs before each target (edge source→target); for `"after"` it runs after
1925
- * each target (edge target→source). A `SystemSet` target expands to every
1926
- * member within this phase (self-edges skipped, so a member ordered against
1927
- * its own set is a no-op); a descriptor target absent from this phase is
1928
- * dropped — with a dev warning only for a concrete system, since a set
1929
- * legitimately expands to nothing when its members live in another phase.
1930
- */
1931
- resolveEdges(e, n, r, s, o, i, a) {
1932
- for (const c of n) {
1933
- if (En(c)) {
1934
- const d = o.get(c);
1935
- if (d === void 0) continue;
1936
- for (let l = 0; l < d.length; l++) {
1937
- const f = d[l];
1938
- f !== e && this.addDirectedEdge(e, f, r, i);
1939
- }
1940
- continue;
1941
- }
1942
- if (!s.has(c)) {
1943
- this.warnDroppedEdge(e, c, r, a);
1944
- continue;
1945
- }
1946
- this.addDirectedEdge(e, c, r, i);
1947
- }
1948
- }
1949
- /** Push one directed edge into the adjacency map. Both endpoints are known to
1950
- * be in this phase (callers guard), so `edges.get(...)` is non-null. */
1951
- addDirectedEdge(e, n, r, s) {
1952
- r === "before" ? s.get(e).push(n) : s.get(n).push(e);
1953
- }
1954
- /**
1955
- * Dev-only diagnostic for an ordering edge that was dropped during sort.
1956
- *
1957
- * Cross-label ordering is impossible by design (`nodeSet` is per-label), so
1958
- * a target registered in *another* phase is skipped silently — that's the
1959
- * intended isolation. But a target unknown to *every* phase is almost
1960
- * certainly a typo or a system that was never scheduled; without this warning
1961
- * the constraint vanishes and the system runs in insertion-order tiebreak as
1962
- * if unconstrained, with nothing to distinguish mistake from intent. Compiled
1963
- * out of production builds by the `DEV` guards at the call sites.
1964
- */
1965
- warnDroppedEdge(e, n, r, s) {
1966
- if (this.systemIndex.has(n)) return;
1967
- const o = (i) => i.name ?? `system_${i.id}`;
1968
- this.onWarn(
1969
- `Schedule[${s}]: \`${o(e)}\` declares \`${r}\` ordering against \`${o(n)}\`, which is not registered in any phase — the constraint is ignored. Check for a typo or a missing add_systems() call.`
1970
- );
1971
- }
1972
- }
1973
- const se = 1024, re = 1024 * se, xe = 64 * se, W = 256 * re, Be = 3, pn = 64, yn = 8, Fe = 4 * re, ke = (t) => 2 ** Math.ceil(Math.log2(Math.max(1, t))), Z = (t) => 2 ** Math.floor(Math.log2(Math.max(1, t))), k = (t, e, n) => Math.min(n, Math.max(e, t)), S = (t) => t >= re ? `${(t / re).toFixed(1)} MiB` : t >= se ? `${(t / se).toFixed(0)} KiB` : `${t} B`;
1974
- function D(t, e) {
1975
- if (!Number.isInteger(e) || e <= 0)
1976
- throw new T(
1977
- y.INVALID_MEMORY_OPTIONS,
1978
- `memory.${t} must be a positive integer (got ${e})`
1979
- );
1980
- }
1981
- function ms(t) {
1982
- const e = ["budget", "maxBytes", "wasm", "allocator", "heap", "shared"].filter(
1983
- (s) => t !== void 0 && t[s] !== void 0
1984
- );
1985
- if (e.length > 1)
1986
- throw new T(
1987
- y.INVALID_MEMORY_OPTIONS,
1988
- `memory takes at most one of budget | maxBytes | wasm | allocator | heap | shared (got: ${e.join(", ")})`
1989
- );
1990
- const n = t?.columnCapacity;
1991
- if (n !== void 0 && D("columnCapacity", n), t?.budget !== void 0) {
1992
- const { entities: s } = t.budget, o = t.budget.archetypes ?? yn, i = t.budget.bytesPerEntity ?? pn;
1993
- if (D("budget.entities", s), D("budget.archetypes", o), D("budget.bytesPerEntity", i), s > 1 << 20)
1994
- throw new T(
1995
- y.INVALID_MEMORY_OPTIONS,
1996
- `memory.budget.entities=${s} exceeds the EntityID index space (1<<20 = ${1 << 20})`
1997
- );
1998
- const a = n ?? k(ke(Math.ceil(s / o)), 64, 1 << 20), c = k(ke(s * 2), 4096, 1 << 20), d = c * R, l = s * i * Be, f = Ke(
1999
- Math.max(d + l, Fe),
2000
- xe
2001
- );
2002
- return {
2003
- source: "budget",
2004
- allocator: j(f),
2005
- columnCapacity: a,
2006
- entityIndexCapacity: c,
2007
- capBytes: f,
2008
- intentLabel: `budget of ${s} entities`,
2009
- budgetEntities: s,
2010
- derivation: [
2011
- `columnCapacity = ${n !== void 0 ? `${a} (pinned)` : `pow2(${s}/${o} per archetype) = ${a}`}`,
2012
- `entityIndex = pow2(2 × ${s}) = ${c} slots × ${R} B = ${S(d)}`,
2013
- `columns = ${s} × ${i} B × ${Be} (double+holes headroom) = ${S(l)}`,
2014
- `cap = align64K(max(index + columns, ${S(Fe)} floor)) = ${S(f)}`
2015
- ],
2016
- wasmMemory: null
2017
- };
2018
- }
2019
- if (t?.maxBytes !== void 0) {
2020
- D("maxBytes", t.maxBytes);
2021
- const s = n ?? F, o = k(
2022
- Z(t.maxBytes / 4 / R),
2023
- 4096,
2024
- U
2025
- );
2026
- return {
2027
- source: "maxBytes",
2028
- allocator: j(t.maxBytes),
2029
- columnCapacity: s,
2030
- entityIndexCapacity: o,
2031
- capBytes: t.maxBytes,
2032
- intentLabel: `explicit cap of ${S(t.maxBytes)}`,
2033
- budgetEntities: null,
2034
- derivation: [
2035
- `cap = ${S(t.maxBytes)} (caller-declared)`,
2036
- `columnCapacity = ${s} (${n !== void 0 ? "pinned" : "default"})`,
2037
- `entityIndex = floor_pow2(cap/4 ÷ ${R} B) = ${o} slots`
2038
- ],
2039
- wasmMemory: null
2040
- };
2041
- }
2042
- if (t?.wasm !== void 0) {
2043
- const s = t.wasm, o = n ?? F;
2044
- if (s.memory !== void 0) {
2045
- if (!(s.memory.buffer instanceof SharedArrayBuffer))
2046
- throw new T(
2047
- y.INVALID_MEMORY_OPTIONS,
2048
- "memory.wasm.memory must be constructed with `shared: true` — the SAB substrate requires a SharedArrayBuffer-backed WebAssembly.Memory"
2049
- );
2050
- return {
2051
- source: "wasm",
2052
- allocator: Ne(s.memory),
2053
- columnCapacity: o,
2054
- entityIndexCapacity: U,
2055
- // The JS API hides a Memory's `maximum`; the caller declared it.
2056
- capBytes: null,
2057
- intentLabel: "caller-supplied WebAssembly.Memory",
2058
- budgetEntities: null,
2059
- derivation: [
2060
- "backing = wasm_memory_allocator(memory) — zero-copy with the sim (is_in_place ✓)",
2061
- "cap = the Memory's own `maximum` (declared by the caller; not readable from JS)",
2062
- `columnCapacity = ${o} (${n !== void 0 ? "pinned" : "default"})`
2063
- ],
2064
- wasmMemory: s.memory
2065
- };
2066
- }
2067
- D("wasm.maximumPages", s.maximumPages);
2068
- const i = s.initialPages ?? Math.min(32, s.maximumPages);
2069
- if (D("wasm.initialPages", i), i > s.maximumPages)
2070
- throw new T(
2071
- y.INVALID_MEMORY_OPTIONS,
2072
- `memory.wasm.initialPages (${i}) exceeds maximumPages (${s.maximumPages})`
2073
- );
2074
- const a = new WebAssembly.Memory({
2075
- initial: i,
2076
- maximum: s.maximumPages,
2077
- shared: !0
2078
- }), c = s.maximumPages * xe, d = k(
2079
- Z(c / 4 / R),
2080
- 4096,
2081
- U
2082
- );
2083
- return {
2084
- source: "wasm",
2085
- allocator: Ne(a),
2086
- columnCapacity: o,
2087
- entityIndexCapacity: d,
2088
- capBytes: c,
2089
- intentLabel: `engine-constructed WebAssembly.Memory (max ${s.maximumPages} pages)`,
2090
- budgetEntities: null,
2091
- derivation: [
2092
- `cap = ${s.maximumPages} pages × 64 KiB = ${S(c)} (Memory maximum)`,
2093
- `initial = ${i} pages (${s.initialPages !== void 0 ? "declared" : "default"})`,
2094
- `entityIndex = floor_pow2(cap/4 ÷ ${R} B) = ${d} slots`,
2095
- `columnCapacity = ${o} (${n !== void 0 ? "pinned" : "default"})`
2096
- ],
2097
- wasmMemory: a
2098
- };
2099
- }
2100
- if (t?.allocator !== void 0) {
2101
- if (t.allocator.isInPlace !== !0)
2102
- throw new T(
2103
- y.INVALID_MEMORY_OPTIONS,
2104
- "memory.allocator must declare `isInPlace: true`: a live Store's flush loops hoist entity-index views across grows, so a non-in-place allocator (e.g. DEFAULT_SAB_ALLOCATOR) corrupts the entity→row mapping. Use growableSabAllocator / wasmMemoryAllocator; non-in-place allocators are snapshot/test sizing only."
2105
- );
2106
- const s = n ?? F, o = t.capBytesHint;
2107
- return o !== void 0 && D("capBytesHint", o), {
2108
- source: "allocator",
2109
- allocator: t.allocator,
2110
- columnCapacity: s,
2111
- entityIndexCapacity: U,
2112
- capBytes: o ?? null,
2113
- intentLabel: o !== void 0 ? `custom in-place allocator (cap hint ${S(o)})` : "custom in-place allocator",
2114
- budgetEntities: null,
2115
- derivation: [
2116
- "backing = caller allocator (is_in_place ✓ checked at construction)",
2117
- o !== void 0 ? `cap = ${S(o)} (caller hint — diagnostics only; the allocator owns the real cap)` : "cap = allocator-owned (no hint)",
2118
- `columnCapacity = ${s} (${n !== void 0 ? "pinned" : "default"})`
2119
- ],
2120
- wasmMemory: null
2121
- };
2122
- }
2123
- if (t?.heap !== void 0) {
2124
- t.heap.maxBytes !== void 0 && D("heap.maxBytes", t.heap.maxBytes);
2125
- const s = t.heap.maxBytes ?? W, o = n ?? F, i = k(
2126
- Z(s / 4 / R),
2127
- 4096,
2128
- U
2129
- );
2130
- return {
2131
- source: "heap",
2132
- allocator: j(s),
2133
- columnCapacity: o,
2134
- entityIndexCapacity: i,
2135
- capBytes: s,
2136
- intentLabel: `pure-TS heap backing (${S(s)} growable cap, no SharedArrayBuffer)`,
2137
- budgetEntities: null,
2138
- derivation: [
2139
- `backing = heap_arraybuffer_allocator(${S(s)}) — fixed ArrayBuffer reserved at the cap, no SAB / no COOP+COEP (is_in_place ✓)`,
2140
- "trade-off: no worker offload / no WASM backend (both need a transferable SharedArrayBuffer)",
2141
- `columnCapacity = ${o} (${n !== void 0 ? "pinned" : "default"})`,
2142
- `entityIndex = floor_pow2(cap/4 ÷ ${R} B) = ${i} slots`
2143
- ],
2144
- wasmMemory: null
2145
- };
2146
- }
2147
- if (t?.shared !== void 0) {
2148
- t.shared.maxBytes !== void 0 && D("shared.maxBytes", t.shared.maxBytes);
2149
- const s = t.shared.maxBytes ?? W, o = n ?? F, i = k(
2150
- Z(s / 4 / R),
2151
- 4096,
2152
- U
2153
- );
2154
- return {
2155
- source: "shared",
2156
- allocator: rt(s),
2157
- columnCapacity: o,
2158
- entityIndexCapacity: i,
2159
- capBytes: s,
2160
- intentLabel: `shared SharedArrayBuffer backing (${S(s)} growable cap, needs COOP/COEP)`,
2161
- budgetEntities: null,
2162
- derivation: [
2163
- `backing = growable_sab_allocator(${S(s)}) — growable SharedArrayBuffer (is_in_place ✓); needs cross-origin isolation`,
2164
- "enables worker offload + a WASM compute backend (transferable SharedArrayBuffer)",
2165
- `columnCapacity = ${o} (${n !== void 0 ? "pinned" : "default"})`,
2166
- `entityIndex = floor_pow2(cap/4 ÷ ${R} B) = ${i} slots`
2167
- ],
2168
- wasmMemory: null
2169
- };
2170
- }
2171
- const r = n ?? F;
2172
- return {
2173
- source: "default",
2174
- allocator: j(),
2175
- columnCapacity: r,
2176
- entityIndexCapacity: U,
2177
- capBytes: W,
2178
- intentLabel: `default sizing (${S(W)} growable cap)`,
2179
- budgetEntities: null,
2180
- derivation: [
2181
- `cap = ${S(W)} (heap_arraybuffer_allocator default)`,
2182
- `columnCapacity = ${r} (${n !== void 0 ? "pinned" : "DEFAULT_COLUMN_CAPACITY"})`,
2183
- `entityIndex = ${U} slots (full EntityID space, ~12 MiB virtual)`
2184
- ],
2185
- wasmMemory: null
2186
- };
2187
- }
2188
- function gs(t, e) {
2189
- return { def: t, values: e };
2190
- }
2191
- function he(t, e) {
2192
- switch (e.kind) {
2193
- case "spawn": {
2194
- const n = t.commands.spawn();
2195
- for (const r of e.components)
2196
- t.commands.add(n, r.def, r.values);
2197
- return e.onSpawned?.(n), n;
2198
- }
2199
- case "despawn":
2200
- t.commands.despawn(e.eid);
2201
- return;
2202
- case "add_component":
2203
- t.commands.add(e.eid, e.def, e.values);
2204
- return;
2205
- case "remove_component":
2206
- t.commands.remove(e.eid, e.def);
2207
- return;
2208
- case "set_field":
2209
- if (!t.hasComponent(e.eid, e.def))
2210
- throw new T(
2211
- y.COMPONENT_NOT_REGISTERED,
2212
- `host set_field on entity ${e.eid} targets a component it does not have. If you added that component via a host command this same frame, the add is deferred to the phase flush while set_field is immediate — carry the value in add_component/spawnEntry instead of a separate set_field, or set it next frame. (host write seam)`
2213
- );
2214
- t.setField(e.eid, e.def, e.field, e.value);
2215
- return;
2216
- case "disable":
2217
- t.commands.disable(e.eid);
2218
- return;
2219
- case "enable":
2220
- t.commands.enable(e.eid);
2221
- return;
2222
- default:
2223
- return at(e, "HostCommand kind");
2224
- }
2225
- }
2226
- class Tn {
2227
- queued = [];
2228
- spawn(e, n) {
2229
- return this.queued.push({ kind: "spawn", components: e, onSpawned: n }), this;
2230
- }
2231
- despawn(e) {
2232
- return this.queued.push({ kind: "despawn", eid: e }), this;
2233
- }
2234
- /** Attach `def` (with complete `values`) to `entityId` (deferred to the
2235
- * drain). The namespaced-handle grammar — the queue is a commands buffer, so
2236
- * it drops the noun (`add`, not `addComponent`), matching `ctx.commands.add`
2237
- * and the queue's own bare `spawn`/`despawn`/`disable`/`enable`. Values are
2238
- * complete (transport carries explicit intent per field; see `spawnEntry`),
2239
- * unlike the authoring-side bundle sugar. */
2240
- add(e, n, r) {
2241
- return this.queued.push({ kind: "add_component", eid: e, def: n, values: r }), this;
2242
- }
2243
- /** Detach `def` from `entityId` (deferred to the drain). Bare `remove`
2244
- * matching `ctx.commands.remove` — see `add`. */
2245
- remove(e, n) {
2246
- return this.queued.push({ kind: "remove_component", eid: e, def: n }), this;
2247
- }
2248
- /** Set `field` of `def` on `entityId`. Applied IMMEDIATELY at the drain, unlike
2249
- * the deferred structural ops — so `def` must already be on `entityId`. Do NOT
2250
- * `add`/`spawn` `def` and `setField` it in the same frame: the add is
2251
- * still pending its flush when the immediate set runs (carry the value in
2252
- * `add`/`spawnEntry` instead). `applyHostCommand` throws an
2253
- * actionable error in `DEV` if you do. */
2254
- setField(e, n, r, s) {
2255
- return this.queued.push({ kind: "set_field", eid: e, def: n, field: r, value: s }), this;
2256
- }
2257
- disable(e) {
2258
- return this.queued.push({ kind: "disable", eid: e }), this;
2259
- }
2260
- enable(e) {
2261
- return this.queued.push({ kind: "enable", eid: e }), this;
2262
- }
2263
- /** Enqueue a pre-built command. The path for a SAB-ring codec, an editor's
2264
- * reified inverse, or a replay log — all of which produce `HostCommand` data
2265
- * directly rather than calling the typed sugar above. */
2266
- push(e) {
2267
- return this.queued.push(e), this;
2268
- }
2269
- /** Commands buffered but not yet applied. */
2270
- get pending() {
2271
- return this.queued.length;
2272
- }
2273
- /** Drop every buffered command without applying it — e.g. abandoning
2274
- * queued edits on a scene unload. Returns how many were dropped. Does not
2275
- * touch commands already drained into the world. */
2276
- clear() {
2277
- const e = this.queued.length;
2278
- return this.queued.length = 0, e;
2279
- }
2280
- /**
2281
- * Apply and clear every buffered command. Called by the blessed apply system
2282
- * inside its schedule span; not part of the host-facing surface. Returns the
2283
- * count applied.
2284
- *
2285
- * `tap`, when present, is invoked with each command in apply order just before
2286
- * it is applied — the record/replay hook ({@link HostCommandRecorder}). It is
2287
- * an OPT-IN observer: the tap-free path keeps the original tight loop, so an
2288
- * un-recorded drain pays nothing.
2289
- */
2290
- drain(e, n) {
2291
- const r = this.queued.length;
2292
- if (r === 0) return 0;
2293
- if (n === void 0)
2294
- for (let s = 0; s < r; s++) he(e, this.queued[s]);
2295
- else
2296
- for (let s = 0; s < r; s++) {
2297
- const o = this.queued[s];
2298
- n(o), he(e, o);
2299
- }
2300
- return this.queued.splice(0, r), r;
2301
- }
2302
- }
2303
- const nt = P - 1;
2304
- function An(t) {
2305
- if (t === ye)
2306
- throw new v(
2307
- "cannot bind opCode 0 (reserved as the command-ring empty-slot marker)"
2308
- );
2309
- if (t < 0 || t > 255 || !Number.isInteger(t))
2310
- throw new v(`command opCode must be a u8 in [1, 255] (got ${t})`);
2311
- }
2312
- function ae(t) {
2313
- const e = new Uint8Array(nt);
2314
- return new DataView(e.buffer).setUint32(0, t, !0), e;
2315
- }
2316
- function ce(t) {
2317
- return new DataView(t.buffer, t.byteOffset, t.byteLength).getUint32(0, !0);
2318
- }
2319
- function Es(t, e) {
2320
- return {
2321
- encode(n) {
2322
- if (n.kind !== "set_field")
2323
- throw new v(
2324
- `ringSetFieldCodec encodes a "set_field" command (got "${n.kind}")`
2325
- );
2326
- const r = new Uint8Array(nt), s = new DataView(r.buffer);
2327
- return s.setUint32(0, n.eid, !0), s.setFloat64(4, n.value, !0), r;
2328
- },
2329
- decode(n) {
2330
- const r = new DataView(n.buffer, n.byteOffset, n.byteLength);
2331
- return {
2332
- kind: "set_field",
2333
- // boundary: branded-ID bridging — a decoded `u32` is an `EntityID` handle.
2334
- eid: r.getUint32(0, !0),
2335
- // schema-erased into the flat HostCommand union (the callable def is invariant in S).
2336
- def: t,
2337
- field: e,
2338
- value: r.getFloat64(4, !0)
2339
- };
2340
- }
2341
- };
2342
- }
2343
- function ps() {
2344
- return {
2345
- encode(t) {
2346
- if (t.kind !== "despawn")
2347
- throw new v(
2348
- `ringDespawnCodec encodes a "despawn" command (got "${t.kind}")`
2349
- );
2350
- return ae(t.eid);
2351
- },
2352
- decode: (t) => ({ kind: "despawn", eid: ce(t) })
2353
- };
2354
- }
2355
- function ys() {
2356
- return {
2357
- encode(t) {
2358
- if (t.kind !== "disable")
2359
- throw new v(
2360
- `ringDisableCodec encodes a "disable" command (got "${t.kind}")`
2361
- );
2362
- return ae(t.eid);
2363
- },
2364
- decode: (t) => ({ kind: "disable", eid: ce(t) })
2365
- };
2366
- }
2367
- function Ts() {
2368
- return {
2369
- encode(t) {
2370
- if (t.kind !== "enable")
2371
- throw new v(
2372
- `ringEnableCodec encodes an "enable" command (got "${t.kind}")`
2373
- );
2374
- return ae(t.eid);
2375
- },
2376
- decode: (t) => ({ kind: "enable", eid: ce(t) })
2377
- };
2378
- }
2379
- function As(t) {
2380
- return {
2381
- encode(e) {
2382
- if (e.kind !== "remove_component")
2383
- throw new v(
2384
- `ringRemoveComponentCodec encodes a "remove_component" command (got "${e.kind}")`
2385
- );
2386
- return ae(e.eid);
2387
- },
2388
- decode: (e) => ({ kind: "remove_component", eid: ce(e), def: t })
2389
- };
2390
- }
2391
- class Is {
2392
- appliers = /* @__PURE__ */ new Map();
2393
- /** Bind a raw ctx-aware applier to `opCode`. Re-binding replaces. */
2394
- on(e, n) {
2395
- return An(e), this.appliers.set(e, n), this;
2396
- }
2397
- /** Unbind `opCode`. Returns whether a binding was removed; subsequent
2398
- * slots carrying it hit the unknown-opcode path. */
2399
- off(e) {
2400
- return this.appliers.delete(e);
2401
- }
2402
- /** Bind a `HostCommand` codec to `opCode`: each matching slot is decoded and
2403
- * run through `applyHostCommand` — the SAME dispatch the typed queue uses.
2404
- * A drain-time `tap` (record/replay) sees the decoded command before it
2405
- * applies, so ring-sourced commands share one log with the typed transport. */
2406
- onCommand(e, n) {
2407
- return this.on(e, (r, s, o) => {
2408
- const i = n.decode(s);
2409
- o?.(i), he(r, i);
2410
- });
2411
- }
2412
- /** Drain every pending slot, dispatching each to its bound applier. Unbound
2413
- * opcodes are skipped (the read head still advances — matching
2414
- * `drainCommandRing` / `CommandDispatcher`). Returns slots drained. `tap`,
2415
- * when present, is forwarded to each applier as the record/replay hook;
2416
- * only `onCommand`-bound (generic `HostCommand`) opcodes surface to it. */
2417
- drain(e, n, r, s) {
2418
- return Ot(n, r, (o, i) => {
2419
- const a = this.appliers.get(o);
2420
- a !== void 0 && a(e, i, s);
2421
- });
2422
- }
2423
- }
2424
- const In = /* @__PURE__ */ new Set([
2425
- x.PRE_STARTUP,
2426
- x.STARTUP,
2427
- x.POST_STARTUP
2428
- ]), _e = /* @__PURE__ */ new WeakMap();
2429
- function ws(t, e) {
2430
- const n = _e.get(e);
2431
- if (n === void 0) return !1;
2432
- for (const r of n) t.removeSystem(r);
2433
- return _e.delete(e), e.clear(), !0;
2434
- }
2435
- function Ss(t, e) {
2436
- const n = new Tn(), r = [];
2437
- _e.set(n, r);
2438
- const s = e?.name ?? "host_command_apply", o = e?.ring, i = e?.recorder, a = i?.record, c = e?.schedules ?? [x.PRE_STARTUP, x.PRE_UPDATE];
2439
- if (i !== void 0 && c.includes(x.FIXED_UPDATE))
2440
- throw new T(
2441
- y.INVALID_RECORDER_SCHEDULE,
2442
- "install_host_command_seam: a recorder cannot drain on SCHEDULE.FIXED_UPDATE — it would log the fixed-step dt instead of the host update(dt) and diverge on replay. Use a variable-update phase (PRE_UPDATE/UPDATE/POST_UPDATE)."
2443
- );
2444
- for (const d of c) {
2445
- const l = !In.has(d), f = t.registerSystem({
2446
- name: `${s}:${d}`,
2447
- // `reads`/`writes` are required by `SystemConfig` but empty here: the
2448
- // apply system declares nothing because it mutates components not known
2449
- // at registration. Full world access: the host may queue mutations to
2450
- // anything. The deferred-flush apply point is unchanged, so structural
2451
- // safety holds; `exclusive` only waives the DEV access check.
2452
- reads: [],
2453
- writes: [],
2454
- exclusive: !0,
2455
- fn: (h, g) => {
2456
- if (i !== void 0 && l && i.openTick(h.ecsTick, g), n.drain(h, a), o !== void 0) {
2457
- const p = t.columnStore, u = p.header.commandRingOff;
2458
- u !== 0 && o.drain(h, p.view, u, a);
2459
- }
2460
- }
2461
- });
2462
- t.addSystems(d, f), r.push(f);
2463
- }
2464
- return n;
2465
- }
2466
- export {
2467
- ss as $,
2468
- Jn as A,
2469
- N as B,
2470
- pt as C,
2471
- F as D,
2472
- T as E,
2473
- Ge as F,
2474
- ie as G,
2475
- te as H,
2476
- $n as I,
2477
- os as J,
2478
- ls as K,
2479
- A as L,
2480
- is as M,
2481
- vn as N,
2482
- us as O,
2483
- as as P,
2484
- Wn as Q,
2485
- nn as R,
2486
- m as S,
2487
- Oe as T,
2488
- bn as U,
2489
- ee as V,
2490
- U as W,
2491
- jn as X,
2492
- es as Y,
2493
- pe as Z,
2494
- Ee as _,
2495
- _t as a,
2496
- tn as a0,
2497
- Qe as a1,
2498
- Un as a2,
2499
- De as a3,
2500
- Re as a4,
2501
- He as a5,
2502
- Xn as a6,
2503
- Vn as a7,
2504
- rs as a8,
2505
- z as a9,
2506
- ps as aA,
2507
- ys as aB,
2508
- Ts as aC,
2509
- As as aD,
2510
- nt as aE,
2511
- $ as aF,
2512
- oe as aG,
2513
- Fn as aH,
2514
- Qn as aa,
2515
- qn as ab,
2516
- Kn as ac,
2517
- fs as ad,
2518
- ut as ae,
2519
- ms as af,
2520
- _s as ag,
2521
- Pn as ah,
2522
- xn as ai,
2523
- Ln as aj,
2524
- Mn as ak,
2525
- x as al,
2526
- hs as am,
2527
- Ss as an,
2528
- ws as ao,
2529
- he as ap,
2530
- Tn as aq,
2531
- gs as ar,
2532
- Me as as,
2533
- Cn as at,
2534
- W as au,
2535
- Be as av,
2536
- pn as aw,
2537
- yn as ax,
2538
- Is as ay,
2539
- Es as az,
2540
- ft as b,
2541
- ht as c,
2542
- zn as d,
2543
- en as e,
2544
- y as f,
2545
- L as g,
2546
- Q as h,
2547
- Rn as i,
2548
- Qt as j,
2549
- Hn as k,
2550
- cs as l,
2551
- ds as m,
2552
- Yn as n,
2553
- kn as o,
2554
- Bn as p,
2555
- ns as q,
2556
- Gn as r,
2557
- Ke as s,
2558
- Ae as t,
2559
- On as u,
2560
- Dn as v,
2561
- je as w,
2562
- K as x,
2563
- Zn as y,
2564
- ts as z
2565
- };