@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
@@ -0,0 +1,101 @@
1
+ import { ComponentHandle } from '../../core/ecs/component.js';
2
+ import { SparseComponentDef } from '../../core/ecs/sparse_store.js';
3
+ import { SystemContext } from '../../core/ecs/system_context.js';
4
+ import { StructuralObserverEvents } from '../../core/ecs/store.js';
5
+ import { SystemDescriptor } from '../../core/ecs/system.js';
6
+ import { ObserverConfig, ObserverHandle, ObserverHooks, ObserverHost } from '../../core/ecs/observer.js';
7
+ /**
8
+ * Registry of component observers. Owned by the observers plugin, which builds
9
+ * it at install. The store calls `dispatchStructural` through its structural
10
+ * hook between fixed-point rounds of `flushStructural`, and the world calls
11
+ * `dispatchSet` through the plugin's settle hook at the post-update detection
12
+ * point.
13
+ */
14
+ export declare class ObserverRegistry implements ObserverHooks {
15
+ private readonly _store;
16
+ private readonly _ctx;
17
+ private readonly _entries;
18
+ /** ComponentID → its observers (structural + onSet). */
19
+ private readonly _byCid;
20
+ /** The entity-level onSet observers on sparse components, in registration
21
+ * order. */
22
+ private readonly _sparseEntries;
23
+ /** Per-`dispatchSet` cache of each sparse component's drain, so two
24
+ * observers on one sparse component fire over one snapshot. */
25
+ private readonly _sparseDrainCache;
26
+ /** Cached access-topological order. A register or a dispose invalidates it. */
27
+ private _topo;
28
+ private readonly _addBuckets;
29
+ private readonly _remBuckets;
30
+ private readonly _disBuckets;
31
+ private readonly _enaBuckets;
32
+ private _radixOut;
33
+ private readonly _radixC0;
34
+ private readonly _radixC1;
35
+ private readonly _setDrainCache;
36
+ constructor(_store: ObserverHost, _ctx: SystemContext);
37
+ get count(): number;
38
+ /** The synthesized `SystemDescriptor`s of every registered observer, in
39
+ * registration order (`dispose()` splices entries out, so none are stale).
40
+ * Fed into the `startup()` archetype-prewarm closure so an observer's declared
41
+ * `spawns` and `transitions` create their target archetypes eagerly, exactly as a
42
+ * system's do. Without this an archetype an observer spawns into or transitions to
43
+ * first-touches lazily mid-tick, the one asymmetry left in the otherwise
44
+ * uniform "no lazy archetypes" prewarm. */
45
+ descriptors(): SystemDescriptor[];
46
+ register(def: ComponentHandle | SparseComponentDef, config: ObserverConfig): ObserverHandle;
47
+ /** The sparse arm of `register`: an entity-level onSet, and nothing else.
48
+ * A sparse add and remove are immediate and touch no archetype, so there
49
+ * is no flush boundary to fire a structural observer at, and no archetype
50
+ * column for the archetype grain. */
51
+ private _registerSparse;
52
+ private _dispose;
53
+ /** Recompute the component's hot-path observation flags from its live
54
+ * observers and push them to the store (which owns the flags + fast-path
55
+ * counters). */
56
+ private _reconfigureComponent;
57
+ private _getTopo;
58
+ /**
59
+ * Fire onAdd, onRemove, onDisable and onEnable for one fixed-point round's
60
+ * effective events, in canonical order: access-topological across observers,
61
+ * entity-id order (radix) within each observer. Called through the store's
62
+ * structural hook after the batch commits. Observer callbacks may
63
+ * enqueue further structural ops (or toggles) onto the deferred buffers (the
64
+ * store loops until quiescent).
65
+ *
66
+ * The events arrive as flat `(comp, eid)` parallel arrays collected during the
67
+ * flush. This dispatch buckets by component once (O(K)), then walks observers
68
+ * in topo order so a producer's writes are visible to a consumer
69
+ * (glitch-free). A round
70
+ * carries either structural (add, remove) or toggle (disable, enable) events, never both,
71
+ * toggles drain only once add, remove and destroy are quiescent (`flushStructural`),
72
+ * but all four bucket uniformly. The empty pairs are no-ops. Within an
73
+ * observer the fire order is remove, add, disable, enable (the "leaving" edges
74
+ * before the "entering" edges).
75
+ */
76
+ dispatchStructural(ev: StructuralObserverEvents): void;
77
+ /** Radix-sort `eids` by entity index (canonical within-observer order), then
78
+ * fire `fn` per entity under the observer's access scope. */
79
+ private _fireEach;
80
+ private _bucket;
81
+ private _clearBuckets;
82
+ /**
83
+ * Fire onSet observers for the current frame, in canonical order. Per-entity
84
+ * onSet drains the opt-in dirty list, once for each changed entity.
85
+ * Archetype-granular onSet scans the change tick, once for each changed
86
+ * archetype column.
87
+ * Called through the plugin's settle hook, after every phase of the frame.
88
+ * `run` is the change tick advanced
89
+ * for this dispatch: above every system run of the frame, and the baseline
90
+ * each archetype-granular observer keeps for its next dispatch.
91
+ */
92
+ dispatchSet(run: number): void;
93
+ /** Fire one sparse observer over the members recorded since the last
94
+ * drain. The store's walk gives alive, member and enabled entities, so no
95
+ * check remains here. Canonical order by entity index, through the radix. */
96
+ private _dispatchSparseSet;
97
+ private _dispatchSetEntity;
98
+ private _dispatchSetArch;
99
+ private _yieldExisting;
100
+ }
101
+ //# sourceMappingURL=observer_registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observer_registry.d.ts","sourceRoot":"","sources":["../../../src/plugins/observers/observer_registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAkDK;AAGL,OAAO,KAAK,EAAgB,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAGtE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAe,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAClF,OAAO,EAIN,KAAK,gBAAgB,EACrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAEX,cAAc,EAEd,cAAc,EACd,aAAa,EACb,YAAY,EACZ,MAAM,yBAAyB,CAAC;AAwIjC;;;;;;GAMG;AACH,qBAAa,gBAAiB,YAAW,aAAa;IAqCpD,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IArCtB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuB;IAChD,wDAAwD;IACxD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsC;IAC7D;gBACY;IACZ,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAwB;IACvD;mEAC+D;IAC/D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAiC;IACnE,+EAA+E;IAC/E,OAAO,CAAC,KAAK,CAAgC;IAI7C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA+B;IAC3D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA+B;IAI3D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA+B;IAC3D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA+B;IAK3D,OAAO,CAAC,SAAS,CAAyB;IAC1C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;IACjD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;IAMjD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAkC;gBAG/C,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,aAAa;IAGrC,IAAI,KAAK,IAAI,MAAM,CAElB;IAED;;;;;;+CAM2C;IAC3C,WAAW,IAAI,gBAAgB,EAAE;IAQjC,QAAQ,CAAC,GAAG,EAAE,eAAe,GAAG,kBAAkB,EAAE,MAAM,EAAE,cAAc,GAAG,cAAc;IA4E3F;;;yCAGqC;IACrC,OAAO,CAAC,eAAe;IAwCvB,OAAO,CAAC,QAAQ;IAehB;;oBAEgB;IAChB,OAAO,CAAC,qBAAqB;IA0B7B,OAAO,CAAC,QAAQ;IAShB;;;;;;;;;;;;;;;;;OAiBG;IACH,kBAAkB,CAAC,EAAE,EAAE,wBAAwB,GAAG,IAAI;IA4CtD;iEAC6D;IAC7D,OAAO,CAAC,SAAS;IAcjB,OAAO,CAAC,OAAO;IAYf,OAAO,CAAC,aAAa;IAQrB;;;;;;;;;OASG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IA2B9B;;iFAE6E;IAC7E,OAAO,CAAC,kBAAkB;IAwB1B,OAAO,CAAC,kBAAkB;IA0D1B,OAAO,CAAC,gBAAgB;IAyBxB,OAAO,CAAC,cAAc;CA0BtB"}
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const S=require("../index.cjs"),E=require("./assertions-z5GQd_bB.cjs"),O=require("../internal.cjs"),u=require("./arrays-Dt-Joc4i.cjs"),f=!1,C=a=>E.unsafeCast(a),k=Object.freeze({reads:Object.freeze([]),writes:Object.freeze([]),spawns:Object.freeze([]),despawns:Object.freeze([]),transitions:Object.freeze([]),resourceReads:Object.freeze([]),resourceWrites:Object.freeze([]),sparseReads:Object.freeze([]),sparseWrites:Object.freeze([]),relationReads:Object.freeze([]),relationWrites:Object.freeze([])}),b="observers",g=Symbol.dispose??Symbol.for("Symbol.dispose"),y=(1<<20)-1;let w=0;function x(a,e){const t={...k,...e,id:C(w++),name:a,fn:B};return Object.freeze(t)}function B(){}function v(a){const e=new Set;if(a)for(let t=0;t<a.length;t++)e.add(a[t].id);return e}function R(a){const e=(n,o)=>n.cid-o.cid||n.id-o.id,t=new Map,i=new Map;for(const n of a)t.set(n,[]),i.set(n,0);for(const n of a)if(n.writes.size!==0)for(const o of a){if(n===o)continue;let d=!1;for(const c of n.writes)if(o.reads.has(c)){d=!0;break}d&&(t.get(n).push(o),i.set(o,i.get(o)+1))}const s=a.filter(n=>i.get(n)===0).sort(e),r=[];for(;s.length>0;){const n=s.shift();r.push(n);for(const o of t.get(n)){const d=i.get(o)-1;i.set(o,d),d===0&&(s.push(o),s.sort(e))}}if(r.length!==a.length){const n=new Set(r);for(const o of a.slice().sort(e))n.has(o)||r.push(o)}return r}class m{constructor(e,t){this._store=e,this._ctx=t}_entries=[];_byCid=new Map;_sparseEntries=[];_sparseDrainCache=new Map;_topo=null;_addBuckets=new Map;_remBuckets=new Map;_disBuckets=new Map;_enaBuckets=new Map;_radixOut=new Uint32Array(1024);_radixC0=new Int32Array(1024);_radixC1=new Int32Array(1024);_setDrainCache=new Map;get count(){return this._entries.length+this._sparseEntries.length}descriptors(){const e=[];for(let t=0;t<this._entries.length;t++)e.push(this._entries[t].descriptor);for(let t=0;t<this._sparseEntries.length;t++)e.push(this._sparseEntries[t].descriptor);return e}register(e,t){if(typeof e=="number")return this._registerSparse(e,t);const i=e.id;if(typeof i!="number")throw new S.ECSError(S.ECS_ERROR.OBSERVER_INVALID_CONFIG,"observe(): the definition is not a registered component. Observe a dense or a sparse component");const s=t.granularity??"archetype",r=t.onSet!==void 0&&s==="entity",n=t.onSet!==void 0&&s!=="entity",o=t.access??{},d=x(t.name??`observer(${O.componentDebugName(e)??i})`,o),c={id:d.id,cid:i,def:e,onAdd:t.onAdd,onRemove:t.onRemove,onDisable:t.onDisable,onEnable:t.onEnable,onSetEntity:r?t.onSet:void 0,onSetArch:n?t.onSet:void 0,descriptor:d,writes:v(o.writes),reads:v(o.reads),yieldExisting:t.yieldExisting??!1,lastSetTick:0,disposed:!1};this._entries.push(c);let l=this._byCid.get(i);l===void 0&&(l=[],this._byCid.set(i,l)),l.push(c),this._topo=null,this._reconfigureComponent(i),c.yieldExisting&&c.onAdd!==void 0&&this._yieldExisting(c);const h=()=>this._dispose(c);return{dispose:h,[g]:h}}_registerSparse(e,t){if(t.onSet===void 0||t.granularity!=="entity"||t.onAdd!==void 0||t.onRemove!==void 0||t.onDisable!==void 0||t.onEnable!==void 0)throw new S.ECSError(S.ECS_ERROR.OBSERVER_INVALID_CONFIG,'observe(): a sparse component takes onSet with granularity "entity" and no other callback. Move onAdd, onRemove, onDisable, onEnable and the archetype grain to a dense component');const i=x(t.name??`observer(sparse ${e})`,t.access??{}),s={id:i.id,sid:e,onSet:t.onSet,descriptor:i,disposed:!1};this._sparseEntries.push(s),this._store.configureSparseObservation(b,e,!0);const r=()=>{if(s.disposed)return;s.disposed=!0;const n=this._sparseEntries.indexOf(s);n>=0&&this._sparseEntries.splice(n,1);let o=!1;for(let d=0;d<this._sparseEntries.length;d++)this._sparseEntries[d].sid===e&&(o=!0);o||this._store.configureSparseObservation(b,e,!1)};return{dispose:r,[g]:r}}_dispose(e){if(e.disposed)return;e.disposed=!0;const t=this._entries.indexOf(e);t>=0&&this._entries.splice(t,1);const i=this._byCid.get(e.cid);if(i!==void 0){const s=i.indexOf(e);s>=0&&i.splice(s,1),i.length===0&&this._byCid.delete(e.cid)}this._topo=null,this._reconfigureComponent(e.cid)}_reconfigureComponent(e){const t=this._byCid.get(e);let i=!1,s=!1,r=!1,n=!1,o=!1;if(t!==void 0)for(let d=0;d<t.length;d++){const c=t[d];c.onAdd!==void 0&&(i=!0),c.onRemove!==void 0&&(s=!0),c.onDisable!==void 0&&(r=!0),c.onEnable!==void 0&&(n=!0),c.onSetEntity!==void 0&&(o=!0)}this._store.configureObservation(b,e,{add:i,remove:s,disable:r,enable:n,set:o})}_getTopo(){return this._topo===null&&(this._topo=R(this._entries)),this._topo}dispatchStructural(e){this._bucket(e.addComp,e.addEid,e.addLen,this._addBuckets),this._bucket(e.remComp,e.remEid,e.remLen,this._remBuckets),this._bucket(e.disComp,e.disEid,e.disLen,this._disBuckets),this._bucket(e.enaComp,e.enaEid,e.enaLen,this._enaBuckets);const t=this._getTopo();for(let i=0;i<t.length;i++){const s=t[i];if(!s.disposed){if(s.onRemove!==void 0){const r=this._remBuckets.get(s.cid);r!==void 0&&r.length>0&&this._fireEach(s,s.onRemove,r,"remove")}if(s.onAdd!==void 0){const r=this._addBuckets.get(s.cid);r!==void 0&&r.length>0&&this._fireEach(s,s.onAdd,r,"add")}if(s.onDisable!==void 0){const r=this._disBuckets.get(s.cid);r!==void 0&&r.length>0&&this._fireEach(s,s.onDisable,r,"disable")}if(s.onEnable!==void 0){const r=this._enaBuckets.get(s.cid);r!==void 0&&r.length>0&&this._fireEach(s,s.onEnable,r,"enable")}}}this._clearBuckets(this._addBuckets),this._clearBuckets(this._remBuckets),this._clearBuckets(this._disBuckets),this._clearBuckets(this._enaBuckets)}_fireEach(e,t,i,s){this._radixOut=u.radixSortByIndex(i,this._radixOut,this._radixC0,this._radixC1);try{const r=f?this._store.trace:null;for(let n=0;n<i.length;n++)t(E.unsafeCast(i[n]),this._ctx)}finally{}}_bucket(e,t,i,s){for(let r=0;r<i;r++){const n=e[r];let o=s.get(n);o===void 0&&(o=[],s.set(n,o)),o.push(t[r])}}_clearBuckets(e){for(const t of e.values())t.length=0}dispatchSet(e){if(this._entries.length===0&&this._sparseEntries.length===0)return;const t=this._getTopo(),i=this._setDrainCache;for(let r=0;r<t.length;r++){const n=t[r];n.onSetEntity!==void 0?this._dispatchSetEntity(n,i,e):n.onSetArch!==void 0&&this._dispatchSetArch(n,e)}i.clear();const s=this._sparseEntries;if(s.length!==0){const r=this._sparseDrainCache;for(let n=0;n<s.length;n++){const o=s[n];o.disposed||this._dispatchSparseSet(o,r,e)}r.clear()}}_dispatchSparseSet(e,t,i){let s=t.get(e.sid);if(s===void 0&&(s=this._store.drainSparseSet(e.sid,i),this._radixOut=u.radixSortByIndex(s,this._radixOut,this._radixC0,this._radixC1),t.set(e.sid,s)),s.length===0)return;const r=e.onSet;try{for(let n=0;n<s.length;n++)r(s[n],this._ctx)}finally{}}_dispatchSetEntity(e,t,i){let s=t.get(e.cid);s===void 0&&(s=this._store.drainSet(e.cid,i),this._radixOut=u.radixSortByIndex(s.scanned,this._radixOut,this._radixC0,this._radixC1),this._radixOut=u.radixSortByIndex(s.listed,this._radixOut,this._radixC0,this._radixC1),A(s.listed),t.set(e.cid,s));const r=s.scanned,n=s.listed,o=r.length,d=n.length;if(o===0&&d===0)return;const c=e.def,l=e.onSetEntity;try{let h=0,p=0;for(;h<o||p<d;){let _;if(p>=d||h<o&&(r[h]&y)<(n[p]&y))_=r[h++];else if(_=n[p++],!this._store.isAlive(_)||!this._store.hasComponent(_,c)||this._store.isDisabled(_))continue;l(_,this._ctx)}}finally{}}_dispatchSetArch(e,t){const i=e.onSetArch,s=e.lastSetTick;try{this._store.forEachChangedArchetype(e.cid,s,r=>{i(r,this._ctx)})}finally{}e.lastSetTick=t}_yieldExisting(e){const t=e.onAdd,i=this._store.collectEnabledWith(e.cid);if(i.length!==0){this._radixOut=u.radixSortByIndex(i,this._radixOut,this._radixC0,this._radixC1);try{for(let s=0;s<i.length;s++)t(E.unsafeCast(i[s]),this._ctx)}finally{}}}}function A(a){const e=a.length;if(e<2)return;let t=1;for(let i=1;i<e;i++)a[i]!==a[t-1]&&(a[t++]=a[i]);a.length=t}function D(){return{name:"observers",install(a){const e=new m(a.store,a.context);return a.onSettle(t=>e.dispatchSet(t)),a.onPrewarm(()=>e.descriptors()),a.changes.addStructuralHook(t=>e.dispatchStructural(t)),{observe(t,i){return e.register(t,i)}}}}}exports.ObserverRegistry=m;exports.observers=D;
@@ -0,0 +1 @@
1
+ export * from "./observers/index.cjs";
@@ -0,0 +1 @@
1
+ export * from "./observers/index.js";
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("../index.development.cjs"),v=require("./assertions-z5GQd_bB.cjs"),d=require("../internal.development.cjs"),p=require("./arrays-Dt-Joc4i.cjs"),S=!0,O=c=>{if(!(Number.isInteger(c)&&c>=0))throw new l.ECSError(l.ECS_ERROR.INVALID_SYSTEM_ID,`system id must be an integer >= 0, got ${c}`);return v.unsafeCast(c)},x=Object.freeze({reads:Object.freeze([]),writes:Object.freeze([]),spawns:Object.freeze([]),despawns:Object.freeze([]),transitions:Object.freeze([]),resourceReads:Object.freeze([]),resourceWrites:Object.freeze([]),sparseReads:Object.freeze([]),sparseWrites:Object.freeze([]),relationReads:Object.freeze([]),relationWrites:Object.freeze([])}),b="observers",C=Symbol.dispose??Symbol.for("Symbol.dispose"),y=(1<<20)-1;let R=0;function g(c,e){const t={...x,...e,id:O(R++),name:c,fn:w};return Object.freeze(t)}function w(){}function k(c){const e=new Set;if(c)for(let t=0;t<c.length;t++)e.add(c[t].id);return e}function A(c){const e=(s,o)=>s.cid-o.cid||s.id-o.id,t=new Map,i=new Map;for(const s of c)t.set(s,[]),i.set(s,0);for(const s of c)if(s.writes.size!==0)for(const o of c){if(s===o)continue;let a=!1;for(const h of s.writes)if(o.reads.has(h)){a=!0;break}a&&(t.get(s).push(o),i.set(o,i.get(o)+1))}const n=c.filter(s=>i.get(s)===0).sort(e),r=[];for(;n.length>0;){const s=n.shift();r.push(s);for(const o of t.get(s)){const a=i.get(o)-1;i.set(o,a),a===0&&(n.push(o),n.sort(e))}}if(r.length!==c.length){const s=new Set(r);for(const o of c.slice().sort(e))s.has(o)||r.push(o)}return r}class m{constructor(e,t){this._store=e,this._ctx=t}_entries=[];_byCid=new Map;_sparseEntries=[];_sparseDrainCache=new Map;_topo=null;_addBuckets=new Map;_remBuckets=new Map;_disBuckets=new Map;_enaBuckets=new Map;_radixOut=new Uint32Array(1024);_radixC0=new Int32Array(1024);_radixC1=new Int32Array(1024);_setDrainCache=new Map;get count(){return this._entries.length+this._sparseEntries.length}descriptors(){const e=[];for(let t=0;t<this._entries.length;t++)e.push(this._entries[t].descriptor);for(let t=0;t<this._sparseEntries.length;t++)e.push(this._sparseEntries[t].descriptor);return e}register(e,t){if(typeof e=="number")return this._registerSparse(e,t);const i=e.id;if(typeof i!="number")throw new l.ECSError(l.ECS_ERROR.OBSERVER_INVALID_CONFIG,"observe(): the definition is not a registered component. Observe a dense or a sparse component");const n=t.granularity??"archetype",r=t.onSet!==void 0&&n==="entity",s=t.onSet!==void 0&&n!=="entity";if(t.onSet===void 0&&t.granularity!==void 0)throw new l.ECSError(l.ECS_ERROR.OBSERVER_INVALID_CONFIG,"observe(): `granularity` is meaningless without `onSet`");if(t.onAdd===void 0&&t.onRemove===void 0&&t.onDisable===void 0&&t.onEnable===void 0&&t.onSet===void 0)throw new l.ECSError(l.ECS_ERROR.OBSERVER_INVALID_CONFIG,"observe(): at least one of onAdd, onRemove, onDisable, onEnable and onSet is required");const o=t.access??{},a=g(t.name??`observer(${d.componentDebugName(e)??i})`,o),h={id:a.id,cid:i,def:e,onAdd:t.onAdd,onRemove:t.onRemove,onDisable:t.onDisable,onEnable:t.onEnable,onSetEntity:r?t.onSet:void 0,onSetArch:s?t.onSet:void 0,descriptor:a,writes:k(o.writes),reads:k(o.reads),yieldExisting:t.yieldExisting??!1,lastSetTick:0,disposed:!1};this._entries.push(h);let f=this._byCid.get(i);f===void 0&&(f=[],this._byCid.set(i,f)),f.push(h),this._topo=null,this._reconfigureComponent(i),h.yieldExisting&&h.onAdd!==void 0&&this._yieldExisting(h);const _=()=>this._dispose(h);return{dispose:_,[C]:_}}_registerSparse(e,t){if(t.onSet===void 0||t.granularity!=="entity"||t.onAdd!==void 0||t.onRemove!==void 0||t.onDisable!==void 0||t.onEnable!==void 0)throw new l.ECSError(l.ECS_ERROR.OBSERVER_INVALID_CONFIG,'observe(): a sparse component takes onSet with granularity "entity" and no other callback. Move onAdd, onRemove, onDisable, onEnable and the archetype grain to a dense component');const i=g(t.name??`observer(sparse ${e})`,t.access??{}),n={id:i.id,sid:e,onSet:t.onSet,descriptor:i,disposed:!1};this._sparseEntries.push(n),this._store.configureSparseObservation(b,e,!0);const r=()=>{if(n.disposed)return;n.disposed=!0;const s=this._sparseEntries.indexOf(n);s>=0&&this._sparseEntries.splice(s,1);let o=!1;for(let a=0;a<this._sparseEntries.length;a++)this._sparseEntries[a].sid===e&&(o=!0);o||this._store.configureSparseObservation(b,e,!1)};return{dispose:r,[C]:r}}_dispose(e){if(e.disposed)return;e.disposed=!0;const t=this._entries.indexOf(e);t>=0&&this._entries.splice(t,1);const i=this._byCid.get(e.cid);if(i!==void 0){const n=i.indexOf(e);n>=0&&i.splice(n,1),i.length===0&&this._byCid.delete(e.cid)}this._topo=null,this._reconfigureComponent(e.cid)}_reconfigureComponent(e){const t=this._byCid.get(e);let i=!1,n=!1,r=!1,s=!1,o=!1;if(t!==void 0)for(let a=0;a<t.length;a++){const h=t[a];h.onAdd!==void 0&&(i=!0),h.onRemove!==void 0&&(n=!0),h.onDisable!==void 0&&(r=!0),h.onEnable!==void 0&&(s=!0),h.onSetEntity!==void 0&&(o=!0)}this._store.configureObservation(b,e,{add:i,remove:n,disable:r,enable:s,set:o})}_getTopo(){return this._topo===null&&(this._topo=A(this._entries)),this._topo}dispatchStructural(e){this._bucket(e.addComp,e.addEid,e.addLen,this._addBuckets),this._bucket(e.remComp,e.remEid,e.remLen,this._remBuckets),this._bucket(e.disComp,e.disEid,e.disLen,this._disBuckets),this._bucket(e.enaComp,e.enaEid,e.enaLen,this._enaBuckets);const t=this._getTopo(),i=d.accessCheck.current();for(let n=0;n<t.length;n++){const r=t[n];if(!r.disposed){if(r.onRemove!==void 0){const s=this._remBuckets.get(r.cid);s!==void 0&&s.length>0&&this._fireEach(r,r.onRemove,s,"remove")}if(r.onAdd!==void 0){const s=this._addBuckets.get(r.cid);s!==void 0&&s.length>0&&this._fireEach(r,r.onAdd,s,"add")}if(r.onDisable!==void 0){const s=this._disBuckets.get(r.cid);s!==void 0&&s.length>0&&this._fireEach(r,r.onDisable,s,"disable")}if(r.onEnable!==void 0){const s=this._enaBuckets.get(r.cid);s!==void 0&&s.length>0&&this._fireEach(r,r.onEnable,s,"enable")}}}i!==null&&d.accessCheck.enter(i),this._clearBuckets(this._addBuckets),this._clearBuckets(this._remBuckets),this._clearBuckets(this._disBuckets),this._clearBuckets(this._enaBuckets)}_fireEach(e,t,i,n){this._radixOut=p.radixSortByIndex(i,this._radixOut,this._radixC0,this._radixC1),d.accessCheck.enter(e.descriptor);try{const r=S?this._store.trace:null;for(let s=0;s<i.length;s++)t(v.unsafeCast(i[s]),this._ctx),S&&r?.observerFired(n,e.cid,i[s],e.descriptor)}finally{d.accessCheck.leave()}}_bucket(e,t,i,n){for(let r=0;r<i;r++){const s=e[r];let o=n.get(s);o===void 0&&(o=[],n.set(s,o)),o.push(t[r])}}_clearBuckets(e){for(const t of e.values())t.length=0}dispatchSet(e){if(this._entries.length===0&&this._sparseEntries.length===0)return;const t=d.accessCheck.current(),i=this._getTopo(),n=this._setDrainCache;for(let s=0;s<i.length;s++){const o=i[s];o.onSetEntity!==void 0?this._dispatchSetEntity(o,n,e):o.onSetArch!==void 0&&this._dispatchSetArch(o,e)}n.clear();const r=this._sparseEntries;if(r.length!==0){const s=this._sparseDrainCache;for(let o=0;o<r.length;o++){const a=r[o];a.disposed||this._dispatchSparseSet(a,s,e)}s.clear()}t!==null&&d.accessCheck.enter(t)}_dispatchSparseSet(e,t,i){let n=t.get(e.sid);if(n===void 0&&(n=this._store.drainSparseSet(e.sid,i),this._radixOut=p.radixSortByIndex(n,this._radixOut,this._radixC0,this._radixC1),t.set(e.sid,n)),n.length===0)return;const r=e.onSet;d.accessCheck.enter(e.descriptor);try{for(let s=0;s<n.length;s++)r(n[s],this._ctx),S&&this._store.trace?.observerFired("set",e.sid,n[s],e.descriptor)}finally{d.accessCheck.leave()}}_dispatchSetEntity(e,t,i){let n=t.get(e.cid);n===void 0&&(n=this._store.drainSet(e.cid,i),this._radixOut=p.radixSortByIndex(n.scanned,this._radixOut,this._radixC0,this._radixC1),this._radixOut=p.radixSortByIndex(n.listed,this._radixOut,this._radixC0,this._radixC1),B(n.listed),t.set(e.cid,n));const r=n.scanned,s=n.listed,o=r.length,a=s.length;if(o===0&&a===0)return;const h=e.def,f=e.onSetEntity;d.accessCheck.enter(e.descriptor);try{let _=0,E=0;for(;_<o||E<a;){let u;if(E>=a||_<o&&(r[_]&y)<(s[E]&y))u=r[_++];else if(u=s[E++],!this._store.isAlive(u)||!this._store.hasComponent(u,h)||this._store.isDisabled(u))continue;f(u,this._ctx),S&&this._store.trace?.observerFired("set",e.cid,u,e.descriptor)}}finally{d.accessCheck.leave()}}_dispatchSetArch(e,t){const i=e.onSetArch,n=e.lastSetTick;d.accessCheck.enter(e.descriptor);try{this._store.forEachChangedArchetype(e.cid,n,r=>{i(r,this._ctx),S&&this._store.trace?.observerFired("set",e.cid,-1,e.descriptor)})}finally{d.accessCheck.leave()}e.lastSetTick=t}_yieldExisting(e){const t=e.onAdd,i=this._store.collectEnabledWith(e.cid);if(i.length===0)return;this._radixOut=p.radixSortByIndex(i,this._radixOut,this._radixC0,this._radixC1);const n=d.accessCheck.current();d.accessCheck.enter(e.descriptor);try{for(let r=0;r<i.length;r++)t(v.unsafeCast(i[r]),this._ctx)}finally{d.accessCheck.leave(),n!==null&&d.accessCheck.enter(n)}}}function B(c){const e=c.length;if(e<2)return;let t=1;for(let i=1;i<e;i++)c[i]!==c[t-1]&&(c[t++]=c[i]);c.length=t}function I(){return{name:"observers",install(c){const e=new m(c.store,c.context);return c.onSettle(t=>e.dispatchSet(t)),c.onPrewarm(()=>e.descriptors()),c.changes.addStructuralHook(t=>e.dispatchStructural(t)),{observe(t,i){return e.register(t,i)}}}}}exports.ObserverRegistry=m;exports.observers=I;
@@ -0,0 +1,431 @@
1
+ import { ECSError as S, ECS_ERROR as v } from "../index.development.js";
2
+ import { u as m } from "./assertions-gtDVfbnQ.js";
3
+ import { componentDebugName as C, accessCheck as h } from "../internal.development.js";
4
+ import { r as p } from "./arrays-Dr_1hCjL.js";
5
+ const f = !0, k = (d) => {
6
+ if (!(Number.isInteger(d) && d >= 0))
7
+ throw new S(
8
+ v.INVALID_SYSTEM_ID,
9
+ `system id must be an integer >= 0, got ${d}`
10
+ );
11
+ return m(d);
12
+ }, w = Object.freeze({
13
+ reads: Object.freeze([]),
14
+ writes: Object.freeze([]),
15
+ spawns: Object.freeze([]),
16
+ despawns: Object.freeze([]),
17
+ transitions: Object.freeze([]),
18
+ resourceReads: Object.freeze([]),
19
+ resourceWrites: Object.freeze([]),
20
+ sparseReads: Object.freeze([]),
21
+ sparseWrites: Object.freeze([]),
22
+ relationReads: Object.freeze([]),
23
+ relationWrites: Object.freeze([])
24
+ }), b = "observers", g = Symbol.dispose ?? Symbol.for("Symbol.dispose"), y = (1 << 20) - 1;
25
+ let A = 0;
26
+ function O(d, e) {
27
+ const t = {
28
+ ...w,
29
+ ...e,
30
+ id: k(A++),
31
+ name: d,
32
+ fn: R
33
+ };
34
+ return Object.freeze(t);
35
+ }
36
+ function R() {
37
+ }
38
+ function x(d) {
39
+ const e = /* @__PURE__ */ new Set();
40
+ if (d) for (let t = 0; t < d.length; t++) e.add(d[t].id);
41
+ return e;
42
+ }
43
+ function B(d) {
44
+ const e = (s, o) => s.cid - o.cid || s.id - o.id, t = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map();
45
+ for (const s of d)
46
+ t.set(s, []), i.set(s, 0);
47
+ for (const s of d)
48
+ if (s.writes.size !== 0)
49
+ for (const o of d) {
50
+ if (s === o) continue;
51
+ let a = !1;
52
+ for (const c of s.writes)
53
+ if (o.reads.has(c)) {
54
+ a = !0;
55
+ break;
56
+ }
57
+ a && (t.get(s).push(o), i.set(o, i.get(o) + 1));
58
+ }
59
+ const n = d.filter((s) => i.get(s) === 0).sort(e), r = [];
60
+ for (; n.length > 0; ) {
61
+ const s = n.shift();
62
+ r.push(s);
63
+ for (const o of t.get(s)) {
64
+ const a = i.get(o) - 1;
65
+ i.set(o, a), a === 0 && (n.push(o), n.sort(e));
66
+ }
67
+ }
68
+ if (r.length !== d.length) {
69
+ const s = new Set(r);
70
+ for (const o of d.slice().sort(e)) s.has(o) || r.push(o);
71
+ }
72
+ return r;
73
+ }
74
+ class D {
75
+ constructor(e, t) {
76
+ this._store = e, this._ctx = t;
77
+ }
78
+ _entries = [];
79
+ /** ComponentID → its observers (structural + onSet). */
80
+ _byCid = /* @__PURE__ */ new Map();
81
+ /** The entity-level onSet observers on sparse components, in registration
82
+ * order. */
83
+ _sparseEntries = [];
84
+ /** Per-`dispatchSet` cache of each sparse component's drain, so two
85
+ * observers on one sparse component fire over one snapshot. */
86
+ _sparseDrainCache = /* @__PURE__ */ new Map();
87
+ /** Cached access-topological order. A register or a dispose invalidates it. */
88
+ _topo = null;
89
+ // --- dispatch scratch (reused, never reallocated in the hot loop) ---
90
+ // Per-component eid buckets for the current structural round, keyed by cid.
91
+ _addBuckets = /* @__PURE__ */ new Map();
92
+ _remBuckets = /* @__PURE__ */ new Map();
93
+ // Disable and enable buckets, populated only on a toggle-drain round
94
+ // (toggles drain once add, remove and destroy are quiescent, so a round carries
95
+ // either structural events or toggle events, never both).
96
+ _disBuckets = /* @__PURE__ */ new Map();
97
+ _enaBuckets = /* @__PURE__ */ new Map();
98
+ // The radix scratch is a typed array, grown by doubling, and never a plain
99
+ // array grown by a length assignment: JavaScriptCore turns the latter into a
100
+ // sparse store, and each element store in the pass becomes a hash insert.
101
+ // The drain of a large frame is far slower there for that reason.
102
+ _radixOut = new Uint32Array(1024);
103
+ _radixC0 = new Int32Array(1024);
104
+ _radixC1 = new Int32Array(1024);
105
+ // Per-`dispatchSet` cache of each component's drain, so a component with
106
+ // more than one per-entity onSet observer drains exactly once and fans the
107
+ // same snapshot out to every observer. Cleared at the end of each dispatch.
108
+ // (Bug: a second per-entity onSet observer on the same component used to
109
+ // see an empty list.)
110
+ _setDrainCache = /* @__PURE__ */ new Map();
111
+ get count() {
112
+ return this._entries.length + this._sparseEntries.length;
113
+ }
114
+ /** The synthesized `SystemDescriptor`s of every registered observer, in
115
+ * registration order (`dispose()` splices entries out, so none are stale).
116
+ * Fed into the `startup()` archetype-prewarm closure so an observer's declared
117
+ * `spawns` and `transitions` create their target archetypes eagerly, exactly as a
118
+ * system's do. Without this an archetype an observer spawns into or transitions to
119
+ * first-touches lazily mid-tick, the one asymmetry left in the otherwise
120
+ * uniform "no lazy archetypes" prewarm. */
121
+ descriptors() {
122
+ const e = [];
123
+ for (let t = 0; t < this._entries.length; t++) e.push(this._entries[t].descriptor);
124
+ for (let t = 0; t < this._sparseEntries.length; t++)
125
+ e.push(this._sparseEntries[t].descriptor);
126
+ return e;
127
+ }
128
+ register(e, t) {
129
+ if (typeof e == "number") return this._registerSparse(e, t);
130
+ const i = e.id;
131
+ if (typeof i != "number")
132
+ throw new S(
133
+ v.OBSERVER_INVALID_CONFIG,
134
+ "observe(): the definition is not a registered component. Observe a dense or a sparse component"
135
+ );
136
+ const n = t.granularity ?? "archetype", r = t.onSet !== void 0 && n === "entity", s = t.onSet !== void 0 && n !== "entity";
137
+ if (t.onSet === void 0 && t.granularity !== void 0)
138
+ throw new S(
139
+ v.OBSERVER_INVALID_CONFIG,
140
+ "observe(): `granularity` is meaningless without `onSet`"
141
+ );
142
+ if (t.onAdd === void 0 && t.onRemove === void 0 && t.onDisable === void 0 && t.onEnable === void 0 && t.onSet === void 0)
143
+ throw new S(
144
+ v.OBSERVER_INVALID_CONFIG,
145
+ "observe(): at least one of onAdd, onRemove, onDisable, onEnable and onSet is required"
146
+ );
147
+ const o = t.access ?? {}, a = O(
148
+ t.name ?? `observer(${C(e) ?? i})`,
149
+ o
150
+ ), c = {
151
+ // Share one identity space with the descriptor (used only for the
152
+ // topo tie-break + diagnostics).
153
+ id: a.id,
154
+ cid: i,
155
+ def: e,
156
+ onAdd: t.onAdd,
157
+ onRemove: t.onRemove,
158
+ onDisable: t.onDisable,
159
+ onEnable: t.onEnable,
160
+ onSetEntity: r ? t.onSet : void 0,
161
+ onSetArch: s ? t.onSet : void 0,
162
+ descriptor: a,
163
+ writes: x(o.writes),
164
+ reads: x(o.reads),
165
+ yieldExisting: t.yieldExisting ?? !1,
166
+ lastSetTick: 0,
167
+ disposed: !1
168
+ };
169
+ this._entries.push(c);
170
+ let u = this._byCid.get(i);
171
+ u === void 0 && (u = [], this._byCid.set(i, u)), u.push(c), this._topo = null, this._reconfigureComponent(i), c.yieldExisting && c.onAdd !== void 0 && this._yieldExisting(c);
172
+ const l = () => this._dispose(c);
173
+ return { dispose: l, [g]: l };
174
+ }
175
+ /** The sparse arm of `register`: an entity-level onSet, and nothing else.
176
+ * A sparse add and remove are immediate and touch no archetype, so there
177
+ * is no flush boundary to fire a structural observer at, and no archetype
178
+ * column for the archetype grain. */
179
+ _registerSparse(e, t) {
180
+ if (t.onSet === void 0 || t.granularity !== "entity" || t.onAdd !== void 0 || t.onRemove !== void 0 || t.onDisable !== void 0 || t.onEnable !== void 0)
181
+ throw new S(
182
+ v.OBSERVER_INVALID_CONFIG,
183
+ 'observe(): a sparse component takes onSet with granularity "entity" and no other callback. Move onAdd, onRemove, onDisable, onEnable and the archetype grain to a dense component'
184
+ );
185
+ const i = O(
186
+ t.name ?? `observer(sparse ${e})`,
187
+ t.access ?? {}
188
+ ), n = {
189
+ id: i.id,
190
+ sid: e,
191
+ onSet: t.onSet,
192
+ descriptor: i,
193
+ disposed: !1
194
+ };
195
+ this._sparseEntries.push(n), this._store.configureSparseObservation(b, e, !0);
196
+ const r = () => {
197
+ if (n.disposed) return;
198
+ n.disposed = !0;
199
+ const s = this._sparseEntries.indexOf(n);
200
+ s >= 0 && this._sparseEntries.splice(s, 1);
201
+ let o = !1;
202
+ for (let a = 0; a < this._sparseEntries.length; a++)
203
+ this._sparseEntries[a].sid === e && (o = !0);
204
+ o || this._store.configureSparseObservation(b, e, !1);
205
+ };
206
+ return { dispose: r, [g]: r };
207
+ }
208
+ _dispose(e) {
209
+ if (e.disposed) return;
210
+ e.disposed = !0;
211
+ const t = this._entries.indexOf(e);
212
+ t >= 0 && this._entries.splice(t, 1);
213
+ const i = this._byCid.get(e.cid);
214
+ if (i !== void 0) {
215
+ const n = i.indexOf(e);
216
+ n >= 0 && i.splice(n, 1), i.length === 0 && this._byCid.delete(e.cid);
217
+ }
218
+ this._topo = null, this._reconfigureComponent(e.cid);
219
+ }
220
+ /** Recompute the component's hot-path observation flags from its live
221
+ * observers and push them to the store (which owns the flags + fast-path
222
+ * counters). */
223
+ _reconfigureComponent(e) {
224
+ const t = this._byCid.get(e);
225
+ let i = !1, n = !1, r = !1, s = !1, o = !1;
226
+ if (t !== void 0)
227
+ for (let a = 0; a < t.length; a++) {
228
+ const c = t[a];
229
+ c.onAdd !== void 0 && (i = !0), c.onRemove !== void 0 && (n = !0), c.onDisable !== void 0 && (r = !0), c.onEnable !== void 0 && (s = !0), c.onSetEntity !== void 0 && (o = !0);
230
+ }
231
+ this._store.configureObservation(b, e, {
232
+ add: i,
233
+ remove: n,
234
+ disable: r,
235
+ enable: s,
236
+ set: o
237
+ });
238
+ }
239
+ _getTopo() {
240
+ return this._topo === null && (this._topo = B(this._entries)), this._topo;
241
+ }
242
+ // =======================================================
243
+ // Structural dispatch (onAdd and onRemove)
244
+ // =======================================================
245
+ /**
246
+ * Fire onAdd, onRemove, onDisable and onEnable for one fixed-point round's
247
+ * effective events, in canonical order: access-topological across observers,
248
+ * entity-id order (radix) within each observer. Called through the store's
249
+ * structural hook after the batch commits. Observer callbacks may
250
+ * enqueue further structural ops (or toggles) onto the deferred buffers (the
251
+ * store loops until quiescent).
252
+ *
253
+ * The events arrive as flat `(comp, eid)` parallel arrays collected during the
254
+ * flush. This dispatch buckets by component once (O(K)), then walks observers
255
+ * in topo order so a producer's writes are visible to a consumer
256
+ * (glitch-free). A round
257
+ * carries either structural (add, remove) or toggle (disable, enable) events, never both,
258
+ * toggles drain only once add, remove and destroy are quiescent (`flushStructural`),
259
+ * but all four bucket uniformly. The empty pairs are no-ops. Within an
260
+ * observer the fire order is remove, add, disable, enable (the "leaving" edges
261
+ * before the "entering" edges).
262
+ */
263
+ dispatchStructural(e) {
264
+ this._bucket(e.addComp, e.addEid, e.addLen, this._addBuckets), this._bucket(e.remComp, e.remEid, e.remLen, this._remBuckets), this._bucket(e.disComp, e.disEid, e.disLen, this._disBuckets), this._bucket(e.enaComp, e.enaEid, e.enaLen, this._enaBuckets);
265
+ const t = this._getTopo(), i = h.current();
266
+ for (let n = 0; n < t.length; n++) {
267
+ const r = t[n];
268
+ if (!r.disposed) {
269
+ if (r.onRemove !== void 0) {
270
+ const s = this._remBuckets.get(r.cid);
271
+ s !== void 0 && s.length > 0 && this._fireEach(r, r.onRemove, s, "remove");
272
+ }
273
+ if (r.onAdd !== void 0) {
274
+ const s = this._addBuckets.get(r.cid);
275
+ s !== void 0 && s.length > 0 && this._fireEach(r, r.onAdd, s, "add");
276
+ }
277
+ if (r.onDisable !== void 0) {
278
+ const s = this._disBuckets.get(r.cid);
279
+ s !== void 0 && s.length > 0 && this._fireEach(r, r.onDisable, s, "disable");
280
+ }
281
+ if (r.onEnable !== void 0) {
282
+ const s = this._enaBuckets.get(r.cid);
283
+ s !== void 0 && s.length > 0 && this._fireEach(r, r.onEnable, s, "enable");
284
+ }
285
+ }
286
+ }
287
+ i !== null && h.enter(i), this._clearBuckets(this._addBuckets), this._clearBuckets(this._remBuckets), this._clearBuckets(this._disBuckets), this._clearBuckets(this._enaBuckets);
288
+ }
289
+ /** Radix-sort `eids` by entity index (canonical within-observer order), then
290
+ * fire `fn` per entity under the observer's access scope. */
291
+ _fireEach(e, t, i, n) {
292
+ this._radixOut = p(i, this._radixOut, this._radixC0, this._radixC1), h.enter(e.descriptor);
293
+ try {
294
+ const r = f ? this._store.trace : null;
295
+ for (let s = 0; s < i.length; s++)
296
+ t(m(i[s]), this._ctx), f && r?.observerFired(n, e.cid, i[s], e.descriptor);
297
+ } finally {
298
+ h.leave();
299
+ }
300
+ }
301
+ _bucket(e, t, i, n) {
302
+ for (let r = 0; r < i; r++) {
303
+ const s = e[r];
304
+ let o = n.get(s);
305
+ o === void 0 && (o = [], n.set(s, o)), o.push(t[r]);
306
+ }
307
+ }
308
+ _clearBuckets(e) {
309
+ for (const t of e.values()) t.length = 0;
310
+ }
311
+ // =======================================================
312
+ // onSet dispatch (post-update detection point)
313
+ // =======================================================
314
+ /**
315
+ * Fire onSet observers for the current frame, in canonical order. Per-entity
316
+ * onSet drains the opt-in dirty list, once for each changed entity.
317
+ * Archetype-granular onSet scans the change tick, once for each changed
318
+ * archetype column.
319
+ * Called through the plugin's settle hook, after every phase of the frame.
320
+ * `run` is the change tick advanced
321
+ * for this dispatch: above every system run of the frame, and the baseline
322
+ * each archetype-granular observer keeps for its next dispatch.
323
+ */
324
+ dispatchSet(e) {
325
+ if (this._entries.length === 0 && this._sparseEntries.length === 0) return;
326
+ const t = h.current(), i = this._getTopo(), n = this._setDrainCache;
327
+ for (let s = 0; s < i.length; s++) {
328
+ const o = i[s];
329
+ o.onSetEntity !== void 0 ? this._dispatchSetEntity(o, n, e) : o.onSetArch !== void 0 && this._dispatchSetArch(o, e);
330
+ }
331
+ n.clear();
332
+ const r = this._sparseEntries;
333
+ if (r.length !== 0) {
334
+ const s = this._sparseDrainCache;
335
+ for (let o = 0; o < r.length; o++) {
336
+ const a = r[o];
337
+ a.disposed || this._dispatchSparseSet(a, s, e);
338
+ }
339
+ s.clear();
340
+ }
341
+ t !== null && h.enter(t);
342
+ }
343
+ /** Fire one sparse observer over the members recorded since the last
344
+ * drain. The store's walk gives alive, member and enabled entities, so no
345
+ * check remains here. Canonical order by entity index, through the radix. */
346
+ _dispatchSparseSet(e, t, i) {
347
+ let n = t.get(e.sid);
348
+ if (n === void 0 && (n = this._store.drainSparseSet(e.sid, i), this._radixOut = p(n, this._radixOut, this._radixC0, this._radixC1), t.set(e.sid, n)), n.length === 0) return;
349
+ const r = e.onSet;
350
+ h.enter(e.descriptor);
351
+ try {
352
+ for (let s = 0; s < n.length; s++)
353
+ r(n[s], this._ctx), f && this._store.trace?.observerFired("set", e.sid, n[s], e.descriptor);
354
+ } finally {
355
+ h.leave();
356
+ }
357
+ }
358
+ _dispatchSetEntity(e, t, i) {
359
+ let n = t.get(e.cid);
360
+ n === void 0 && (n = this._store.drainSet(e.cid, i), this._radixOut = p(n.scanned, this._radixOut, this._radixC0, this._radixC1), this._radixOut = p(n.listed, this._radixOut, this._radixC0, this._radixC1), I(n.listed), t.set(e.cid, n));
361
+ const r = n.scanned, s = n.listed, o = r.length, a = s.length;
362
+ if (o === 0 && a === 0) return;
363
+ const c = e.def, u = e.onSetEntity;
364
+ h.enter(e.descriptor);
365
+ try {
366
+ let l = 0, E = 0;
367
+ for (; l < o || E < a; ) {
368
+ let _;
369
+ if (E >= a || l < o && (r[l] & y) < (s[E] & y))
370
+ _ = r[l++];
371
+ else if (_ = s[E++], !this._store.isAlive(_) || !this._store.hasComponent(_, c) || this._store.isDisabled(_))
372
+ continue;
373
+ u(_, this._ctx), f && this._store.trace?.observerFired("set", e.cid, _, e.descriptor);
374
+ }
375
+ } finally {
376
+ h.leave();
377
+ }
378
+ }
379
+ _dispatchSetArch(e, t) {
380
+ const i = e.onSetArch, n = e.lastSetTick;
381
+ h.enter(e.descriptor);
382
+ try {
383
+ this._store.forEachChangedArchetype(e.cid, n, (r) => {
384
+ i(r, this._ctx), f && this._store.trace?.observerFired("set", e.cid, -1, e.descriptor);
385
+ });
386
+ } finally {
387
+ h.leave();
388
+ }
389
+ e.lastSetTick = t;
390
+ }
391
+ // =======================================================
392
+ // Seeding a new observer with the existing members
393
+ // =======================================================
394
+ _yieldExisting(e) {
395
+ const t = e.onAdd, i = this._store.collectEnabledWith(e.cid);
396
+ if (i.length === 0) return;
397
+ this._radixOut = p(i, this._radixOut, this._radixC0, this._radixC1);
398
+ const n = h.current();
399
+ h.enter(e.descriptor);
400
+ try {
401
+ for (let r = 0; r < i.length; r++) t(m(i[r]), this._ctx);
402
+ } finally {
403
+ h.leave(), n !== null && h.enter(n);
404
+ }
405
+ }
406
+ }
407
+ function I(d) {
408
+ const e = d.length;
409
+ if (e < 2) return;
410
+ let t = 1;
411
+ for (let i = 1; i < e; i++)
412
+ d[i] !== d[t - 1] && (d[t++] = d[i]);
413
+ d.length = t;
414
+ }
415
+ function V() {
416
+ return {
417
+ name: "observers",
418
+ install(d) {
419
+ const e = new D(d.store, d.context);
420
+ return d.onSettle((t) => e.dispatchSet(t)), d.onPrewarm(() => e.descriptors()), d.changes.addStructuralHook((t) => e.dispatchStructural(t)), {
421
+ observe(t, i) {
422
+ return e.register(t, i);
423
+ }
424
+ };
425
+ }
426
+ };
427
+ }
428
+ export {
429
+ D as ObserverRegistry,
430
+ V as observers
431
+ };