@oasys/oecs 0.5.2 → 0.5.4

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 (189) hide show
  1. package/CHANGELOG.md +208 -14
  2. package/README.md +198 -145
  3. package/dist/core/ecs/access_check.d.cts +3 -3
  4. package/dist/core/ecs/access_check.d.ts +3 -3
  5. package/dist/core/ecs/archetype.d.cts +103 -43
  6. package/dist/core/ecs/archetype.d.ts +103 -43
  7. package/dist/core/ecs/archetype.d.ts.map +1 -1
  8. package/dist/core/ecs/archetype_graph.d.cts +8 -8
  9. package/dist/core/ecs/archetype_graph.d.ts +8 -8
  10. package/dist/core/ecs/archetype_graph.d.ts.map +1 -1
  11. package/dist/core/ecs/builtin_relations.d.cts +1 -1
  12. package/dist/core/ecs/builtin_relations.d.ts +1 -1
  13. package/dist/core/ecs/command_log.d.cts +4 -4
  14. package/dist/core/ecs/command_log.d.ts +4 -4
  15. package/dist/core/ecs/command_log.d.ts.map +1 -1
  16. package/dist/core/ecs/component.d.cts +4 -4
  17. package/dist/core/ecs/component.d.ts +4 -4
  18. package/dist/core/ecs/deferred_commands.d.cts +1 -1
  19. package/dist/core/ecs/deferred_commands.d.ts +1 -1
  20. package/dist/core/ecs/deferred_commands.d.ts.map +1 -1
  21. package/dist/core/ecs/ecs.d.cts +85 -43
  22. package/dist/core/ecs/ecs.d.ts +85 -43
  23. package/dist/core/ecs/ecs.d.ts.map +1 -1
  24. package/dist/core/ecs/ecs_memory.d.cts +15 -15
  25. package/dist/core/ecs/ecs_memory.d.ts +15 -15
  26. package/dist/core/ecs/ecs_memory.d.ts.map +1 -1
  27. package/dist/core/ecs/entity_allocator.d.cts +6 -6
  28. package/dist/core/ecs/entity_allocator.d.ts +6 -6
  29. package/dist/core/ecs/entity_allocator.d.ts.map +1 -1
  30. package/dist/core/ecs/event.d.cts +2 -2
  31. package/dist/core/ecs/event.d.ts +2 -2
  32. package/dist/core/ecs/event_registry.d.cts +1 -1
  33. package/dist/core/ecs/event_registry.d.ts +1 -1
  34. package/dist/core/ecs/event_registry.d.ts.map +1 -1
  35. package/dist/core/ecs/facades.d.cts +15 -15
  36. package/dist/core/ecs/facades.d.ts +15 -15
  37. package/dist/core/ecs/facades.d.ts.map +1 -1
  38. package/dist/core/ecs/frame_trace.d.cts +2 -2
  39. package/dist/core/ecs/frame_trace.d.ts +2 -2
  40. package/dist/core/ecs/host_commands.d.cts +12 -12
  41. package/dist/core/ecs/host_commands.d.ts +12 -12
  42. package/dist/core/ecs/host_commands.d.ts.map +1 -1
  43. package/dist/core/ecs/index.d.cts +1 -1
  44. package/dist/core/ecs/index.d.ts +1 -1
  45. package/dist/core/ecs/index.d.ts.map +1 -1
  46. package/dist/core/ecs/observer.d.cts +9 -9
  47. package/dist/core/ecs/observer.d.ts +9 -9
  48. package/dist/core/ecs/observer.d.ts.map +1 -1
  49. package/dist/core/ecs/query.d.cts +91 -70
  50. package/dist/core/ecs/query.d.ts +91 -70
  51. package/dist/core/ecs/query.d.ts.map +1 -1
  52. package/dist/core/ecs/ref.d.cts +53 -1
  53. package/dist/core/ecs/ref.d.ts +53 -1
  54. package/dist/core/ecs/ref.d.ts.map +1 -1
  55. package/dist/core/ecs/relation.d.cts +15 -15
  56. package/dist/core/ecs/relation.d.ts +15 -15
  57. package/dist/core/ecs/relation.d.ts.map +1 -1
  58. package/dist/core/ecs/relation_service.d.cts +14 -14
  59. package/dist/core/ecs/relation_service.d.ts +14 -14
  60. package/dist/core/ecs/relation_service.d.ts.map +1 -1
  61. package/dist/core/ecs/resource.d.cts +1 -1
  62. package/dist/core/ecs/resource.d.ts +1 -1
  63. package/dist/core/ecs/resource_registry.d.cts +2 -2
  64. package/dist/core/ecs/resource_registry.d.ts +2 -2
  65. package/dist/core/ecs/resume.d.cts +3 -3
  66. package/dist/core/ecs/resume.d.ts +3 -3
  67. package/dist/core/ecs/resume.d.ts.map +1 -1
  68. package/dist/core/ecs/schedule.d.cts +22 -9
  69. package/dist/core/ecs/schedule.d.ts +22 -9
  70. package/dist/core/ecs/schedule.d.ts.map +1 -1
  71. package/dist/core/ecs/snapshot_service.d.cts +3 -3
  72. package/dist/core/ecs/snapshot_service.d.ts +3 -3
  73. package/dist/core/ecs/sparse_store.d.cts +6 -6
  74. package/dist/core/ecs/sparse_store.d.ts +6 -6
  75. package/dist/core/ecs/sparse_store.d.ts.map +1 -1
  76. package/dist/core/ecs/store.d.cts +189 -110
  77. package/dist/core/ecs/store.d.ts +189 -110
  78. package/dist/core/ecs/store.d.ts.map +1 -1
  79. package/dist/core/ecs/store_layout_listener.d.cts +2 -2
  80. package/dist/core/ecs/store_layout_listener.d.ts +2 -2
  81. package/dist/core/ecs/system.d.cts +8 -8
  82. package/dist/core/ecs/system.d.ts +8 -8
  83. package/dist/core/ecs/system.d.ts.map +1 -1
  84. package/dist/core/ecs/utils/error.d.cts +7 -0
  85. package/dist/core/ecs/utils/error.d.ts +7 -0
  86. package/dist/core/ecs/utils/error.d.ts.map +1 -1
  87. package/dist/core/store/action_ring.d.cts +7 -8
  88. package/dist/core/store/action_ring.d.ts +7 -8
  89. package/dist/core/store/action_ring.d.ts.map +1 -1
  90. package/dist/core/store/allocator.d.cts +58 -35
  91. package/dist/core/store/allocator.d.ts +58 -35
  92. package/dist/core/store/allocator.d.ts.map +1 -1
  93. package/dist/core/store/buffer_backed_column.d.cts +5 -6
  94. package/dist/core/store/buffer_backed_column.d.ts +5 -6
  95. package/dist/core/store/buffer_backed_column.d.ts.map +1 -1
  96. package/dist/core/store/column_store.d.cts +23 -23
  97. package/dist/core/store/column_store.d.ts +23 -23
  98. package/dist/core/store/column_store.d.ts.map +1 -1
  99. package/dist/core/store/command_dispatch.d.cts +1 -1
  100. package/dist/core/store/command_dispatch.d.ts +1 -1
  101. package/dist/core/store/command_ring.d.cts +6 -7
  102. package/dist/core/store/command_ring.d.ts +6 -7
  103. package/dist/core/store/command_ring.d.ts.map +1 -1
  104. package/dist/core/store/descriptor.d.cts +2 -2
  105. package/dist/core/store/descriptor.d.ts +2 -2
  106. package/dist/core/store/entity_index.d.cts +3 -3
  107. package/dist/core/store/entity_index.d.ts +3 -3
  108. package/dist/core/store/event_ring.d.cts +7 -7
  109. package/dist/core/store/event_ring.d.ts +7 -7
  110. package/dist/core/store/extend.d.cts +2 -2
  111. package/dist/core/store/extend.d.ts +2 -2
  112. package/dist/core/store/extend.d.ts.map +1 -1
  113. package/dist/core/store/grow.d.cts +1 -1
  114. package/dist/core/store/grow.d.ts +1 -1
  115. package/dist/core/store/grow.d.ts.map +1 -1
  116. package/dist/core/store/header.d.cts +9 -9
  117. package/dist/core/store/header.d.ts +9 -9
  118. package/dist/core/store/header.d.ts.map +1 -1
  119. package/dist/core/store/layout_ops.d.cts +25 -7
  120. package/dist/core/store/layout_ops.d.ts +25 -7
  121. package/dist/core/store/layout_ops.d.ts.map +1 -1
  122. package/dist/core/store/state_hash.d.cts +3 -3
  123. package/dist/core/store/state_hash.d.ts +3 -3
  124. package/dist/extensions/editor/editor.d.cts +4 -4
  125. package/dist/extensions/editor/editor.d.ts +4 -4
  126. package/dist/extensions/editor/editor.d.ts.map +1 -1
  127. package/dist/extensions/editor/field_handle.d.cts +1 -1
  128. package/dist/extensions/editor/field_handle.d.ts +1 -1
  129. package/dist/extensions/editor/index.d.cts +2 -2
  130. package/dist/extensions/editor/index.d.ts +2 -2
  131. package/dist/extensions/editor/index.development.js +4 -4
  132. package/dist/extensions/editor/index.js +4 -4
  133. package/dist/extensions/reactive/ecs_sync.d.cts +4 -4
  134. package/dist/extensions/reactive/ecs_sync.d.ts +4 -4
  135. package/dist/extensions/reactive/index.d.cts +4 -4
  136. package/dist/extensions/reactive/index.d.ts +4 -4
  137. package/dist/extensions/reactive/index.development.js +3 -3
  138. package/dist/extensions/reactive/index.js +3 -3
  139. package/dist/extensions/solid/index.d.cts +1 -1
  140. package/dist/extensions/solid/index.d.ts +1 -1
  141. package/dist/extensions/solid/index.development.js +1 -1
  142. package/dist/extensions/solid/index.js +1 -1
  143. package/dist/extensions/solid/kernel_solid.d.cts +1 -1
  144. package/dist/extensions/solid/kernel_solid.d.ts +1 -1
  145. package/dist/extensions/solid/kernel_solid.d.ts.map +1 -1
  146. package/dist/{host_commands-BI8pEmjH.js → host_commands-BlR3oZ3x.js} +473 -393
  147. package/dist/host_commands-C2cpU3yC.cjs +1 -0
  148. package/dist/index.cjs +1 -1
  149. package/dist/index.d.cts +2 -2
  150. package/dist/index.d.ts +2 -2
  151. package/dist/index.d.ts.map +1 -1
  152. package/dist/index.development.cjs +1 -1
  153. package/dist/index.development.js +3345 -2963
  154. package/dist/index.js +1496 -1131
  155. package/dist/{internal-BMDgWZbt.js → internal-BoxWl4dG.js} +410 -330
  156. package/dist/internal-CGBEwfeB.cjs +2 -0
  157. package/dist/internal.cjs +1 -1
  158. package/dist/internal.development.cjs +1 -1
  159. package/dist/internal.development.js +1 -1
  160. package/dist/internal.js +1 -1
  161. package/dist/primitives.development.js +1 -1
  162. package/dist/primitives.js +1 -1
  163. package/dist/reactive/index.d.cts +2 -2
  164. package/dist/reactive/index.d.ts +2 -2
  165. package/dist/reactive/index.development.js +1 -1
  166. package/dist/reactive/index.js +1 -1
  167. package/dist/reactive/kernel.d.cts +5 -5
  168. package/dist/reactive/kernel.d.ts +5 -5
  169. package/dist/reactive/shallow.d.cts +1 -1
  170. package/dist/reactive/shallow.d.ts +1 -1
  171. package/dist/{shallow-DfnAm9vG.js → shallow-Bs39EPh1.js} +1 -1
  172. package/dist/{shallow-9S1pY_Iw.js → shallow-CiFC70Dz.js} +1 -1
  173. package/dist/{shared-BU1Cd40h.js → shared-B4v0L1cw.js} +41 -35
  174. package/dist/shared-DU78k0pU.cjs +1 -0
  175. package/dist/shared.cjs +1 -1
  176. package/dist/shared.d.cts +1 -1
  177. package/dist/shared.d.ts +1 -1
  178. package/dist/shared.development.cjs +1 -1
  179. package/dist/shared.development.js +1 -1
  180. package/dist/shared.js +1 -1
  181. package/dist/type_primitives/typed_arrays/typed_arrays.d.cts +2 -2
  182. package/dist/type_primitives/typed_arrays/typed_arrays.d.ts +2 -2
  183. package/dist/{typed_arrays-BcXcnzB4.js → typed_arrays-DIVwVy5_.js} +1 -1
  184. package/dist/version.d.cts +2 -2
  185. package/dist/version.d.ts +2 -2
  186. package/package.json +1 -1
  187. package/dist/host_commands-CxhpzMx9.cjs +0 -1
  188. package/dist/internal-LiTSB_tG.cjs +0 -2
  189. package/dist/shared-BymrGTyR.cjs +0 -1
@@ -1,5 +1,5 @@
1
1
  import { S as et, t as tt } from "./topological_sort-DK6EjpWa.js";
2
- import { D as nt, h as K, w as we, g as st } from "./shared-BU1Cd40h.js";
2
+ import { D as nt, h as K, w as Se, g as st } from "./shared-B4v0L1cw.js";
3
3
  class Be extends Error {
4
4
  constructor(t, n, r) {
5
5
  super(t), this.isOperational = n, this.context = r, this.name = this.constructor.name, Error.captureStackTrace(this, this.constructor);
@@ -23,24 +23,24 @@ function ot(e, t) {
23
23
  `Unhandled ${t}: ${String(e)}`
24
24
  );
25
25
  }
26
- var w = /* @__PURE__ */ ((e) => (e.EID_MAX_INDEX_OVERFLOW = "EID_MAX_INDEX_OVERFLOW", e.EID_MAX_GEN_OVERFLOW = "EID_MAX_GEN_OVERFLOW", e.COMPONENT_NOT_REGISTERED = "COMPONENT_NOT_REGISTERED", e.COMPONENT_LIMIT_EXCEEDED = "COMPONENT_LIMIT_EXCEEDED", e.ENTITY_NOT_ALIVE = "ENTITY_NOT_ALIVE", e.CIRCULAR_SYSTEM_DEPENDENCY = "CIRCULAR_SYSTEM_DEPENDENCY", e.DUPLICATE_SYSTEM = "DUPLICATE_SYSTEM", e.ARCHETYPE_NOT_FOUND = "ARCHETYPE_NOT_FOUND", e.RESOURCE_NOT_REGISTERED = "RESOURCE_NOT_REGISTERED", e.RESOURCE_ALREADY_REGISTERED = "RESOURCE_ALREADY_REGISTERED", e.EVENT_ALREADY_REGISTERED = "EVENT_ALREADY_REGISTERED", e.EVENT_NOT_REGISTERED = "EVENT_NOT_REGISTERED", e.FIELD_NOT_REGISTERED = "FIELD_NOT_REGISTERED", e.RELATION_NOT_REGISTERED = "RELATION_NOT_REGISTERED", e.RELATION_MODE_INVALID = "RELATION_MODE_INVALID", e.RELATION_MODE_MISMATCH = "RELATION_MODE_MISMATCH", e.RELATION_CYCLE = "RELATION_CYCLE", e.SPARSE_CACHE_KEY_OVERFLOW = "SPARSE_CACHE_KEY_OVERFLOW", e.SPARSE_QUERY_DENSE_PATH = "SPARSE_QUERY_DENSE_PATH", e.HIERARCHY_ALREADY_SET = "HIERARCHY_ALREADY_SET", e.HIERARCHY_INVALID_MAX_DEPTH = "HIERARCHY_INVALID_MAX_DEPTH", e.OBSERVER_NON_CONVERGENT = "OBSERVER_NON_CONVERGENT", e.OBSERVER_INVALID_CONFIG = "OBSERVER_INVALID_CONFIG", e.OBSERVER_ONSET_EMIT = "OBSERVER_ONSET_EMIT", e.INVALID_FIXED_TIMESTEP = "INVALID_FIXED_TIMESTEP", e.INVALID_MAX_FIXED_STEPS = "INVALID_MAX_FIXED_STEPS", e.INVALID_RECORDER_SCHEDULE = "INVALID_RECORDER_SCHEDULE", e.EMPTY_ARCHETYPE_MATERIALIZE = "EMPTY_ARCHETYPE_MATERIALIZE", e.COMPONENT_INDEX_INVARIANT = "COMPONENT_INDEX_INVARIANT", e.OPTIONAL_TERM_NOT_DECLARED = "OPTIONAL_TERM_NOT_DECLARED", e.QUERY_ACCESS_UNDECLARED = "QUERY_ACCESS_UNDECLARED", e.ACCESS_UNDECLARED = "ACCESS_UNDECLARED", e.QUERY_NOT_SINGLETON = "QUERY_NOT_SINGLETON", e.INVALID_RUN_CONDITION = "INVALID_RUN_CONDITION", e.SYSTEM_FN_ARITY = "SYSTEM_FN_ARITY", e.PARTITION_APPEND_NEEDS_ENTITY_ROW = "PARTITION_APPEND_NEEDS_ENTITY_ROW", e.PARTITION_BULK_INTO_DISABLED = "PARTITION_BULK_INTO_DISABLED", e.ENTITY_NOT_DISABLED = "ENTITY_NOT_DISABLED", e.STRUCTURAL_DURING_ITERATION = "STRUCTURAL_DURING_ITERATION", e.BACKEND_ALREADY_ATTACHED = "BACKEND_ALREADY_ATTACHED", e.DETERMINISM_DISABLED = "DETERMINISM_DISABLED", e.NON_DETERMINISTIC_COLUMN_TYPE = "NON_DETERMINISTIC_COLUMN_TYPE", e.INVALID_MEMORY_OPTIONS = "INVALID_MEMORY_OPTIONS", e.STORE_CAP_EXCEEDED = "STORE_CAP_EXCEEDED", e.REGION_NOT_DECLARED = "REGION_NOT_DECLARED", e.COMMAND_LOG_TAG_COLLISION = "COMMAND_LOG_TAG_COLLISION", e.INVALID_FRAME_STEP = "INVALID_FRAME_STEP", e))(w || {});
27
- class S extends Be {
26
+ var S = /* @__PURE__ */ ((e) => (e.EID_MAX_INDEX_OVERFLOW = "EID_MAX_INDEX_OVERFLOW", e.EID_MAX_GEN_OVERFLOW = "EID_MAX_GEN_OVERFLOW", e.COMPONENT_NOT_REGISTERED = "COMPONENT_NOT_REGISTERED", e.COMPONENT_LIMIT_EXCEEDED = "COMPONENT_LIMIT_EXCEEDED", e.ENTITY_NOT_ALIVE = "ENTITY_NOT_ALIVE", e.CIRCULAR_SYSTEM_DEPENDENCY = "CIRCULAR_SYSTEM_DEPENDENCY", e.DUPLICATE_SYSTEM = "DUPLICATE_SYSTEM", e.ARCHETYPE_NOT_FOUND = "ARCHETYPE_NOT_FOUND", e.RESOURCE_NOT_REGISTERED = "RESOURCE_NOT_REGISTERED", e.RESOURCE_ALREADY_REGISTERED = "RESOURCE_ALREADY_REGISTERED", e.EVENT_ALREADY_REGISTERED = "EVENT_ALREADY_REGISTERED", e.EVENT_NOT_REGISTERED = "EVENT_NOT_REGISTERED", e.FIELD_NOT_REGISTERED = "FIELD_NOT_REGISTERED", e.RELATION_NOT_REGISTERED = "RELATION_NOT_REGISTERED", e.RELATION_MODE_INVALID = "RELATION_MODE_INVALID", e.RELATION_MODE_MISMATCH = "RELATION_MODE_MISMATCH", e.RELATION_CYCLE = "RELATION_CYCLE", e.SPARSE_CACHE_KEY_OVERFLOW = "SPARSE_CACHE_KEY_OVERFLOW", e.SPARSE_QUERY_DENSE_PATH = "SPARSE_QUERY_DENSE_PATH", e.HIERARCHY_ALREADY_SET = "HIERARCHY_ALREADY_SET", e.HIERARCHY_INVALID_MAX_DEPTH = "HIERARCHY_INVALID_MAX_DEPTH", e.OBSERVER_NON_CONVERGENT = "OBSERVER_NON_CONVERGENT", e.OBSERVER_INVALID_CONFIG = "OBSERVER_INVALID_CONFIG", e.OBSERVER_ONSET_EMIT = "OBSERVER_ONSET_EMIT", e.INVALID_FIXED_TIMESTEP = "INVALID_FIXED_TIMESTEP", e.INVALID_MAX_FIXED_STEPS = "INVALID_MAX_FIXED_STEPS", e.INVALID_RECORDER_SCHEDULE = "INVALID_RECORDER_SCHEDULE", e.EMPTY_ARCHETYPE_MATERIALIZE = "EMPTY_ARCHETYPE_MATERIALIZE", e.COMPONENT_INDEX_INVARIANT = "COMPONENT_INDEX_INVARIANT", e.ARCHETYPE_ROW_INVARIANT = "ARCHETYPE_ROW_INVARIANT", e.OPTIONAL_TERM_NOT_DECLARED = "OPTIONAL_TERM_NOT_DECLARED", e.QUERY_ACCESS_UNDECLARED = "QUERY_ACCESS_UNDECLARED", e.ACCESS_UNDECLARED = "ACCESS_UNDECLARED", e.QUERY_NOT_SINGLETON = "QUERY_NOT_SINGLETON", e.INVALID_RUN_CONDITION = "INVALID_RUN_CONDITION", e.SYSTEM_FN_ARITY = "SYSTEM_FN_ARITY", e.PARTITION_APPEND_NEEDS_ENTITY_ROW = "PARTITION_APPEND_NEEDS_ENTITY_ROW", e.PARTITION_BULK_INTO_DISABLED = "PARTITION_BULK_INTO_DISABLED", e.ENTITY_NOT_DISABLED = "ENTITY_NOT_DISABLED", e.STRUCTURAL_DURING_ITERATION = "STRUCTURAL_DURING_ITERATION", e.BACKEND_ALREADY_ATTACHED = "BACKEND_ALREADY_ATTACHED", e.DETERMINISM_DISABLED = "DETERMINISM_DISABLED", e.NON_DETERMINISTIC_COLUMN_TYPE = "NON_DETERMINISTIC_COLUMN_TYPE", e.INVALID_MEMORY_OPTIONS = "INVALID_MEMORY_OPTIONS", e.STORE_CAP_EXCEEDED = "STORE_CAP_EXCEEDED", e.REGION_NOT_DECLARED = "REGION_NOT_DECLARED", e.COMMAND_LOG_TAG_COLLISION = "COMMAND_LOG_TAG_COLLISION", e.INVALID_FRAME_STEP = "INVALID_FRAME_STEP", e))(S || {});
27
+ class w extends Be {
28
28
  constructor(t, n, r) {
29
29
  super(n ?? t, !0, r), this.category = t;
30
30
  }
31
31
  }
32
32
  function An(e) {
33
- return e instanceof S;
33
+ return e instanceof w;
34
34
  }
35
- const In = -1, wn = -1, Sn = Object.freeze(/* @__PURE__ */ Object.create(null)), Nn = 2654435769, Dn = 1367130551, B = 1024, Rn = 0, it = 31, On = 1 / 60, bn = 4, at = 0, z = 20, Ye = (1 << z) - 1, P = Ye, ct = it - z, _e = (1 << ct) - 1, Cn = _e, Un = _e - 1, Se = _e << z | P, vn = (e, t) => t << z | e, k = (e) => e & Ye, Ln = (e) => e >> z, he = /* @__PURE__ */ new WeakMap();
35
+ const In = -1, Sn = -1, wn = Object.freeze(/* @__PURE__ */ Object.create(null)), Nn = 2654435769, Dn = 1367130551, B = 1024, Rn = 0, it = 31, On = 1 / 60, bn = 4, at = 0, z = 20, Ye = (1 << z) - 1, $ = Ye, ct = it - z, he = (1 << ct) - 1, Cn = he, Un = he - 1, we = he << z | $, vn = (e, t) => t << z | e, k = (e) => e & Ye, Ln = (e) => e >> z, _e = /* @__PURE__ */ new WeakMap();
36
36
  function Mn(e, t) {
37
- he.set(e, t);
37
+ _e.set(e, t);
38
38
  }
39
- function $n(e) {
40
- return he.get(e);
39
+ function Pn(e) {
40
+ return _e.get(e);
41
41
  }
42
42
  function dt(e) {
43
- const t = he.get(e);
43
+ const t = _e.get(e);
44
44
  return t !== void 0 ? `'${t}' (component ${e.id})` : `component ${e.id}`;
45
45
  }
46
46
  const lt = 827148627, ut = 0, J = 4, ft = 52, m = {
@@ -75,10 +75,10 @@ const lt = 827148627, ut = 0, J = 4, ft = 52, m = {
75
75
  column_count: 28,
76
76
  enabled_count: 32
77
77
  };
78
- function _t(e, t) {
78
+ function ht(e, t) {
79
79
  e.setUint32(m.magic, t.magic, !0), e.setUint32(m.sim_abi_version, t.simAbiVersion, !0), e.setUint32(m.view_stamp, t.viewStamp, !0), e.setUint32(m.capacity, t.capacity, !0), e.setUint32(m.archetype_count, t.archetypeCount, !0), e.setUint32(m.layout_descriptor_off, t.layoutDescriptorOff, !0), e.setUint32(m.command_ring_off, t.commandRingOff, !0), e.setUint32(m.action_ring_off, t.actionRingOff, !0), e.setUint32(m.entity_index_off, t.entityIndexOff, !0), e.setUint32(m.event_ring_off, t.eventRingOff, !0), e.setUint32(m.region_table_off, t.regionTableOff, !0), e.setUint32(m.region_table_count, t.regionTableCount, !0), e.setUint32(m.bindings_off, t.bindingsOff, !0);
80
80
  }
81
- function Pn(e) {
81
+ function $n(e) {
82
82
  return {
83
83
  magic: e.getUint32(m.magic, !0),
84
84
  simAbiVersion: e.getUint32(m.sim_abi_version, !0),
@@ -123,7 +123,7 @@ const E = {
123
123
  f32: E.f32,
124
124
  f64: E.f64
125
125
  };
126
- function ht(e, t, n) {
126
+ function _t(e, t, n) {
127
127
  e.setUint16(t + O.component_id, n.componentId, !0), e.setUint16(t + O.field_id, n.fieldId, !0), e.setUint8(t + O.type_tag, n.typeTag), e.setUint32(t + O.byte_off, n.byteOff, !0), e.setUint16(t + O.stride, n.stride, !0);
128
128
  }
129
129
  function mt(e, t) {
@@ -150,7 +150,7 @@ function gt(e, t, n) {
150
150
  e.setUint32(t + N.row_count, n.rowCount, !0), e.setUint32(t + N.row_capacity, n.rowCapacity, !0), e.setUint32(t + N.column_count, n.columns.length, !0), e.setUint32(t + N.enabled_count, n.enabledCount, !0);
151
151
  let r = t + ge;
152
152
  for (let s = 0; s < n.columns.length; s++)
153
- ht(e, r, n.columns[s]), r += me;
153
+ _t(e, r, n.columns[s]), r += me;
154
154
  return r;
155
155
  }
156
156
  function Et(e, t) {
@@ -221,21 +221,21 @@ function At(e, t, n) {
221
221
  function It(e, t) {
222
222
  return e.getUint32(t + b.write_head, !0);
223
223
  }
224
- function wt(e, t) {
224
+ function St(e, t) {
225
225
  return e.getUint32(t + b.read_head, !0);
226
226
  }
227
- function St(e, t) {
227
+ function wt(e, t) {
228
228
  return e.getUint32(t + b.capacity_slots, !0);
229
229
  }
230
230
  function Nt(e, t, n) {
231
231
  if (n.byteLength !== M - 1)
232
232
  throw new U(
233
- `out_payload must be ${M - 1} bytes (got ${n.byteLength})`
233
+ `outPayload must be ${M - 1} bytes (got ${n.byteLength})`
234
234
  );
235
- const r = It(e, t), s = wt(e, t);
235
+ const r = It(e, t), s = St(e, t);
236
236
  if (r === s) return Ee;
237
- const o = St(e, t), i = s & o - 1, c = t + Ve + i * M, a = e.getUint8(c), l = new Uint8Array(e.buffer, c + 1, M - 1);
238
- return n.set(l), e.setUint32(t + b.read_head, s + 1 >>> 0, !0), a;
237
+ const o = wt(e, t), i = s & o - 1, a = t + Ve + i * M, c = e.getUint8(a), l = new Uint8Array(e.buffer, a + 1, M - 1);
238
+ return n.set(l), e.setUint32(t + b.read_head, s + 1 >>> 0, !0), c;
239
239
  }
240
240
  function Dt(e, t, n) {
241
241
  let r = 0;
@@ -253,8 +253,8 @@ const re = 16, D = 12, ee = {
253
253
  }, v = 1 << 20;
254
254
  function Re(e) {
255
255
  if (e < 0 || !Number.isInteger(e))
256
- throw new Ge(
257
- `entity_index capacity must be a non-negative integer (got ${e})`
256
+ throw new He(
257
+ `entity index capacity must be a non-negative integer (got ${e})`
258
258
  );
259
259
  return re + e * D;
260
260
  }
@@ -267,15 +267,15 @@ function Ot(e, t) {
267
267
  function bt(e, t) {
268
268
  return e + re + t * 8;
269
269
  }
270
- class Ge extends Error {
270
+ class He extends Error {
271
271
  constructor(t) {
272
272
  super(t), this.name = "EntityIndexError";
273
273
  }
274
274
  }
275
275
  function Ct(e, t, n) {
276
276
  if (n < 0 || !Number.isInteger(n))
277
- throw new Ge(
278
- `entity_index capacity must be a non-negative integer (got ${n})`
277
+ throw new He(
278
+ `entity index capacity must be a non-negative integer (got ${n})`
279
279
  );
280
280
  e.setUint32(t + ee.length, 0, !0), e.setUint32(t + ee.capacity, n, !0);
281
281
  }
@@ -303,14 +303,14 @@ class Mt extends Error {
303
303
  super(t), this.name = "EventRingError";
304
304
  }
305
305
  }
306
- function $t(e, t, n) {
306
+ function Pt(e, t, n) {
307
307
  if (!Lt(n))
308
308
  throw new Mt(
309
309
  `event ring capacity_slots must be a positive power of two (got ${n})`
310
310
  );
311
311
  e.setUint32(t + Y.write_head, 0, !0), e.setUint32(t + Y.read_head, 0, !0), e.setUint32(t + Y.capacity_slots, n, !0), e.setUint32(t + Y.overflow_flag, 0, !0);
312
312
  }
313
- const Pt = 16, xt = 16, Gn = 256, V = {
313
+ const $t = 16, xt = 16, Hn = 256, V = {
314
314
  write_head: 0,
315
315
  read_head: 4,
316
316
  capacity_slots: 8,
@@ -320,9 +320,9 @@ function Vt(e, t) {
320
320
  return new Int32Array(e.buffer, e.byteOffset + t, 4);
321
321
  }
322
322
  function be(e) {
323
- return Pt + e * xt;
323
+ return $t + e * xt;
324
324
  }
325
- function Gt(e) {
325
+ function Ht(e) {
326
326
  return e > 0 && (e & e - 1) === 0;
327
327
  }
328
328
  class Ce extends Error {
@@ -330,14 +330,14 @@ class Ce extends Error {
330
330
  super(t), this.name = "ActionRingError";
331
331
  }
332
332
  }
333
- function Ht(e, t, n) {
334
- if (!Gt(n))
333
+ function Gt(e, t, n) {
334
+ if (!Ht(n))
335
335
  throw new Ce(
336
336
  `action ring capacity_slots must be a positive power of two (got ${n})`
337
337
  );
338
338
  if ((e.byteOffset + t) % 4 !== 0)
339
339
  throw new Ce(
340
- `action ring header must be 4-byte aligned for Atomics (view.byteOffset ${e.byteOffset} + ring_off ${t} is not a multiple of 4)`
340
+ `action ring header must be 4-byte aligned for Atomics (view.byteOffset ${e.byteOffset} + ringOff ${t} is not a multiple of 4)`
341
341
  );
342
342
  const r = Vt(e, t);
343
343
  Atomics.store(r, Bt, 0), Atomics.store(r, Ft, 0), Atomics.store(r, Yt, n), Atomics.store(r, kt, 0);
@@ -370,7 +370,7 @@ const j = [
370
370
  name: "event_ring",
371
371
  headerOff: "event_ring_off",
372
372
  sizeFromOptions: (e) => e.eventRingCapacitySlots !== void 0 ? Oe(e.eventRingCapacitySlots) : 0,
373
- init: (e, t, n) => $t(e, t, n.eventRingCapacitySlots),
373
+ init: (e, t, n) => Pt(e, t, n.eventRingCapacitySlots),
374
374
  regionBytes: (e, t) => Oe(e.getUint32(t + Y.capacity_slots, !0)),
375
375
  readOptions: (e, t, n) => {
376
376
  n.eventRingCapacitySlots = e.getUint32(
@@ -383,7 +383,7 @@ const j = [
383
383
  name: "action_ring",
384
384
  headerOff: "action_ring_off",
385
385
  sizeFromOptions: (e) => e.actionRingCapacitySlots !== void 0 ? be(e.actionRingCapacitySlots) : 0,
386
- init: (e, t, n) => Ht(e, t, n.actionRingCapacitySlots),
386
+ init: (e, t, n) => Gt(e, t, n.actionRingCapacitySlots),
387
387
  regionBytes: (e, t) => be(e.getUint32(t + V.capacity_slots, !0)),
388
388
  readOptions: (e, t, n) => {
389
389
  n.actionRingCapacitySlots = e.getUint32(
@@ -398,12 +398,12 @@ class Z extends Error {
398
398
  super(t), this.name = "RegionRegistryError";
399
399
  }
400
400
  }
401
- function He(e) {
401
+ function Ge(e) {
402
402
  return e * q;
403
403
  }
404
404
  function pe(e, t) {
405
405
  const n = e.getUint32(m.region_table_count, !0);
406
- if (t + He(n) > e.byteLength)
406
+ if (t + Ge(n) > e.byteLength)
407
407
  throw new Z(
408
408
  `region table of ${n} entries at byte ${t} overruns the buffer (${e.byteLength} bytes)`
409
409
  );
@@ -447,7 +447,7 @@ function qt(e, t, n) {
447
447
  r[s] = Xe(e, t + s * q);
448
448
  return r;
449
449
  }
450
- function Hn(e) {
450
+ function Gn(e) {
451
451
  const t = e.getUint32(m.region_table_off, !0);
452
452
  if (t === 0) return [];
453
453
  const n = pe(e, t);
@@ -481,7 +481,7 @@ const ye = 2 ** 31;
481
481
  class We extends Error {
482
482
  constructor(t) {
483
483
  super(
484
- `SAB column layout offset ${t} reaches or exceeds the 2³¹ (${ye}-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 (#382).`
484
+ `SAB column layout offset ${t} reaches or exceeds the 2³¹ (${ye}-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.`
485
485
  ), this.name = "StoreLayoutOverflowError";
486
486
  }
487
487
  }
@@ -512,41 +512,41 @@ function jt(e, t, n, r) {
512
512
  }
513
513
  function Qt(e, t, n = 0) {
514
514
  const s = yt(
515
- e.map((c) => ({
516
- archetypeId: c.archetypeId,
517
- componentMask: c.componentMask,
515
+ e.map((a) => ({
516
+ archetypeId: a.archetypeId,
517
+ componentMask: a.componentMask,
518
518
  rowCount: 0,
519
519
  enabledCount: 0,
520
- rowCapacity: c.rowCapacity,
521
- columns: c.columns.map((a) => ({
522
- componentId: a.componentId,
523
- fieldId: a.fieldId,
524
- typeTag: a.typeTag,
520
+ rowCapacity: a.rowCapacity,
521
+ columns: a.columns.map((c) => ({
522
+ componentId: c.componentId,
523
+ fieldId: c.fieldId,
524
+ typeTag: c.typeTag,
525
525
  byteOff: 0,
526
- stride: Ne[a.typeTag]
526
+ stride: Ne[c.typeTag]
527
527
  }))
528
528
  }))
529
529
  ) + n;
530
530
  let o = t + s;
531
531
  const i = new Array(e.length);
532
- for (let c = 0; c < e.length; c++) {
533
- const a = e[c], l = new Array(a.columns.length);
534
- for (let d = 0; d < a.columns.length; d++) {
535
- const f = a.columns[d], _ = Ne[f.typeTag];
536
- o = ze(o, _), l[d] = {
532
+ for (let a = 0; a < e.length; a++) {
533
+ const c = e[a], l = new Array(c.columns.length);
534
+ for (let d = 0; d < c.columns.length; d++) {
535
+ const f = c.columns[d], h = Ne[f.typeTag];
536
+ o = ze(o, h), l[d] = {
537
537
  componentId: f.componentId,
538
538
  fieldId: f.fieldId,
539
539
  typeTag: f.typeTag,
540
540
  byteOff: o,
541
- stride: _
542
- }, o += _ * a.rowCapacity;
541
+ stride: h
542
+ }, o += h * c.rowCapacity;
543
543
  }
544
- i[c] = {
545
- archetypeId: a.archetypeId,
546
- componentMask: a.componentMask,
544
+ i[a] = {
545
+ archetypeId: c.archetypeId,
546
+ componentMask: c.componentMask,
547
547
  rowCount: 0,
548
548
  enabledCount: 0,
549
- rowCapacity: a.rowCapacity,
549
+ rowCapacity: c.rowCapacity,
550
550
  columns: l
551
551
  };
552
552
  }
@@ -562,25 +562,25 @@ function qn(e, t = nt, n = {}) {
562
562
  const r = {};
563
563
  let s = ft;
564
564
  for (let A = 0; A < j.length; A++) {
565
- const C = j[A], H = C.sizeFromOptions(n);
566
- r[C.headerOff] = H === 0 ? 0 : s, s += H;
565
+ const C = j[A], G = C.sizeFromOptions(n);
566
+ r[C.headerOff] = G === 0 ? 0 : s, s += G;
567
567
  }
568
568
  const o = n.regions ?? [];
569
569
  Xt(o);
570
- const i = o.length, c = i > 0 ? s : 0;
571
- s += He(i);
572
- const a = new Array(i);
570
+ const i = o.length, a = i > 0 ? s : 0;
571
+ s += Ge(i);
572
+ const c = new Array(i);
573
573
  for (let A = 0; A < o.length; A++) {
574
574
  const C = o[A];
575
- a[A] = { regionId: C.id, byteOffset: s, byteLength: C.bytes }, s += C.bytes;
575
+ c[A] = { regionId: C.id, byteOffset: s, byteLength: C.bytes }, s += C.bytes;
576
576
  }
577
577
  const l = n.bindingsRegionBytes ?? 0, d = l === 0 ? 0 : s;
578
578
  s += l;
579
- const f = s, { descriptors: _, totalBytes: g, regionBytes: y } = Qt(
579
+ const f = s, { descriptors: h, totalBytes: g, regionBytes: p } = Qt(
580
580
  e,
581
581
  f,
582
582
  n.reservedDescriptorBytes ?? 0
583
- ), u = t(g), h = new DataView(u), T = {
583
+ ), u = t(g), _ = new DataView(u), T = {
584
584
  magic: lt,
585
585
  simAbiVersion: ut,
586
586
  viewStamp: 0,
@@ -588,7 +588,7 @@ function qn(e, t = nt, n = {}) {
588
588
  archetypeCount: e.length,
589
589
  layoutDescriptorOff: f,
590
590
  bindingsOff: d,
591
- regionTableOff: c,
591
+ regionTableOff: a,
592
592
  regionTableCount: i,
593
593
  // `regionOffsets` stays keyed by the snake ABI field names (it also indexes
594
594
  // `STORE_HEADER_OFFSETS`); map its 4 entries onto the camelCase header fields.
@@ -597,25 +597,25 @@ function qn(e, t = nt, n = {}) {
597
597
  eventRingOff: r.event_ring_off,
598
598
  actionRingOff: r.action_ring_off
599
599
  };
600
- _t(h, T), l > 0 && new Uint8Array(u, d, l).fill(0);
600
+ ht(_, T), l > 0 && new Uint8Array(u, d, l).fill(0);
601
601
  for (let A = 0; A < j.length; A++) {
602
- const C = j[A], H = r[C.headerOff];
603
- H !== 0 && C.init(h, H, n);
602
+ const C = j[A], G = r[C.headerOff];
603
+ G !== 0 && C.init(_, G, n);
604
604
  }
605
- c !== 0 && zt(h, c, a);
605
+ a !== 0 && zt(_, a, c);
606
606
  for (let A = 0; A < o.length; A++)
607
- o[A].init(h, a[A].byteOffset);
608
- pt(h, f, _);
609
- const x = Zt(u, _);
607
+ o[A].init(_, c[A].byteOffset);
608
+ pt(_, f, h);
609
+ const x = Zt(u, h);
610
610
  return {
611
611
  buffer: u,
612
- view: h,
612
+ view: _,
613
613
  header: T,
614
614
  archetypes: x,
615
- _regionBytes: y,
615
+ _regionBytes: p,
616
616
  _allocator: t,
617
617
  // Carry the headroom policy with the store so the realloc slow path
618
- // (`optionsFromOld`) can re-reserve the same margin (#541).
618
+ // (`optionsFromOld`) can re-reserve the same margin.
619
619
  _reservedDescriptorBytes: n.reservedDescriptorBytes ?? 0
620
620
  };
621
621
  }
@@ -623,16 +623,16 @@ function Zt(e, t) {
623
623
  const n = /* @__PURE__ */ new Map();
624
624
  for (let r = 0; r < t.length; r++) {
625
625
  const s = t[r], o = new Array(s.columns.length), i = /* @__PURE__ */ new Map();
626
- for (let c = 0; c < s.columns.length; c++) {
627
- const a = s.columns[c], l = {
628
- componentId: a.componentId,
629
- fieldId: a.fieldId,
630
- typeTag: a.typeTag,
631
- byteOff: a.byteOff,
632
- stride: a.stride,
633
- view: jt(e, a.typeTag, a.byteOff, s.rowCapacity)
626
+ for (let a = 0; a < s.columns.length; a++) {
627
+ const c = s.columns[a], l = {
628
+ componentId: c.componentId,
629
+ fieldId: c.fieldId,
630
+ typeTag: c.typeTag,
631
+ byteOff: c.byteOff,
632
+ stride: c.stride,
633
+ view: jt(e, c.typeTag, c.byteOff, s.rowCapacity)
634
634
  };
635
- o[c] = l, i.set(Kt(a.componentId, a.fieldId), l);
635
+ o[a] = l, i.set(Kt(c.componentId, c.fieldId), l);
636
636
  }
637
637
  n.set(s.archetypeId, {
638
638
  archetypeId: s.archetypeId,
@@ -669,13 +669,13 @@ class jn {
669
669
  }
670
670
  /** Live entity indices that hold this component (dense, iteration order is
671
671
  * SparseMap insertion/swap order — NOT canonical). Used by the hot query
672
- * integration path (#469); for the determinism surface use
672
+ * integration path; for the determinism surface use
673
673
  * `canonicalIndices` instead. */
674
674
  get indices() {
675
675
  return this._data.keys;
676
676
  }
677
677
  /** Live entity indices in **canonical** (ascending) order — the determinism
678
- * ordering for `stateHash` + snapshot/restore (ADR-0011, #470). The native
678
+ * ordering for `stateHash` + snapshot/restore. The native
679
679
  * `indices` getter is insertion/swap order and would make two worlds with
680
680
  * identical contents reached by different add/remove histories diverge, so
681
681
  * the cold determinism paths sort here. Allocates a sorted copy each call;
@@ -729,12 +729,12 @@ class jn {
729
729
  return s === void 0 ? !1 : (s[n] = r, !0);
730
730
  }
731
731
  }
732
- class p extends Error {
732
+ class y extends Error {
733
733
  constructor(t) {
734
734
  super(t), this.name = "SparseRestoreError";
735
735
  }
736
736
  }
737
- const Te = 12, Ae = 4, G = 8;
737
+ const Te = 12, Ae = 4, H = 8;
738
738
  function Ie(e, t) {
739
739
  let n = Jt;
740
740
  const r = (s) => {
@@ -747,21 +747,21 @@ function Ie(e, t) {
747
747
  function Qn(e) {
748
748
  let t = 4;
749
749
  for (let o = 0; o < e.length; o++) {
750
- const i = e[o], c = i.fieldNames.length;
751
- t += Te + i.size * (Ae + c * G);
750
+ const i = e[o], a = i.fieldNames.length;
751
+ t += Te + i.size * (Ae + a * H);
752
752
  }
753
753
  const n = new Uint8Array(t), r = new DataView(n.buffer);
754
754
  let s = 0;
755
755
  r.setUint32(s, e.length, !0), s += 4;
756
756
  for (let o = 0; o < e.length; o++) {
757
- const i = e[o], c = i.fieldNames.length, a = i.canonicalIndices();
758
- r.setUint32(s, c, !0), s += 4, r.setUint32(s, Ie(i.fieldNames, i.fieldTypes), !0), s += 4, r.setUint32(s, a.length, !0), s += 4;
759
- for (let l = 0; l < a.length; l++) {
760
- const d = a[l];
757
+ const i = e[o], a = i.fieldNames.length, c = i.canonicalIndices();
758
+ r.setUint32(s, a, !0), s += 4, r.setUint32(s, Ie(i.fieldNames, i.fieldTypes), !0), s += 4, r.setUint32(s, c.length, !0), s += 4;
759
+ for (let l = 0; l < c.length; l++) {
760
+ const d = c[l];
761
761
  r.setUint32(s, d, !0), s += 4;
762
762
  const f = i.getRow(d);
763
- for (let _ = 0; _ < c; _++)
764
- r.setFloat64(s, f[_], !0), s += G;
763
+ for (let h = 0; h < a; h++)
764
+ r.setFloat64(s, f[h], !0), s += H;
765
765
  }
766
766
  }
767
767
  return n;
@@ -769,98 +769,98 @@ function Qn(e) {
769
769
  function Zn(e, t) {
770
770
  const n = new DataView(t.buffer, t.byteOffset, t.byteLength), r = t.byteLength;
771
771
  let s = 0;
772
- const o = (c) => {
773
- if (s + c > r)
774
- throw new p(
775
- `sparse snapshot truncated: need ${c} more bytes at offset ${s}, have ${r - s}`
772
+ const o = (a) => {
773
+ if (s + a > r)
774
+ throw new y(
775
+ `sparse snapshot truncated: need ${a} more bytes at offset ${s}, have ${r - s}`
776
776
  );
777
777
  };
778
778
  o(4);
779
779
  const i = n.getUint32(s, !0);
780
780
  if (s += 4, i !== e.length)
781
- throw new p(
781
+ throw new y(
782
782
  `sparse store count mismatch: snapshot=${i}, registered=${e.length}`
783
783
  );
784
- for (let c = 0; c < e.length; c++) {
785
- const a = e[c];
784
+ for (let a = 0; a < e.length; a++) {
785
+ const c = e[a];
786
786
  o(Te);
787
787
  const l = n.getUint32(s, !0);
788
788
  s += 4;
789
789
  const d = n.getUint32(s, !0);
790
790
  s += 4;
791
791
  const f = n.getUint32(s, !0);
792
- if (s += 4, l !== a.fieldNames.length)
793
- throw new p(
794
- `sparse store ${c} field-count mismatch: snapshot=${l}, registered=${a.fieldNames.length}`
792
+ if (s += 4, l !== c.fieldNames.length)
793
+ throw new y(
794
+ `sparse store ${a} field-count mismatch: snapshot=${l}, registered=${c.fieldNames.length}`
795
795
  );
796
- const _ = Ie(a.fieldNames, a.fieldTypes);
797
- if (d !== _)
798
- throw new p(
799
- `sparse store ${c} schema identity mismatch: snapshot hash=${d}, registered=${_} (same field count, different field names/types — likely a registration-order divergence between the snapshot and restore worlds)`
796
+ const h = Ie(c.fieldNames, c.fieldTypes);
797
+ if (d !== h)
798
+ throw new y(
799
+ `sparse store ${a} schema identity mismatch: snapshot hash=${d}, registered=${h} (same field count, different field names/types — likely a registration-order divergence between the snapshot and restore worlds)`
800
800
  );
801
- a.clear();
801
+ c.clear();
802
802
  for (let g = 0; g < f; g++) {
803
- o(Ae + l * G);
804
- const y = n.getUint32(s, !0);
805
- if (s += 4, y > P)
806
- throw new p(
807
- `sparse store ${c} member ${g} entity index ${y} exceeds MAX_INDEX (${P})`
803
+ o(Ae + l * H);
804
+ const p = n.getUint32(s, !0);
805
+ if (s += 4, p > $)
806
+ throw new y(
807
+ `sparse store ${a} member ${g} entity index ${p} exceeds MAX_INDEX (${$})`
808
808
  );
809
809
  const u = new Array(l);
810
- for (let h = 0; h < l; h++)
811
- u[h] = n.getFloat64(s, !0), s += G;
812
- a.setRawRow(y, u);
810
+ for (let _ = 0; _ < l; _++)
811
+ u[_] = n.getFloat64(s, !0), s += H;
812
+ c.setRawRow(p, u);
813
813
  }
814
814
  }
815
815
  if (s !== r)
816
- throw new p(
816
+ throw new y(
817
817
  `sparse snapshot has ${r - s} trailing bytes after the last store (not a canonical encoding)`
818
818
  );
819
819
  }
820
820
  function Jn(e, t) {
821
821
  const n = new DataView(t.buffer, t.byteOffset, t.byteLength), r = t.byteLength;
822
822
  let s = 0;
823
- const o = (c) => {
824
- if (s + c > r)
825
- throw new p(
826
- `sparse snapshot truncated: need ${c} more bytes at offset ${s}, have ${r - s}`
823
+ const o = (a) => {
824
+ if (s + a > r)
825
+ throw new y(
826
+ `sparse snapshot truncated: need ${a} more bytes at offset ${s}, have ${r - s}`
827
827
  );
828
828
  };
829
829
  o(4);
830
830
  const i = n.getUint32(s, !0);
831
831
  if (s += 4, i !== e.length)
832
- throw new p(
832
+ throw new y(
833
833
  `sparse store count mismatch: snapshot=${i}, registered=${e.length}`
834
834
  );
835
- for (let c = 0; c < e.length; c++) {
836
- const a = e[c];
835
+ for (let a = 0; a < e.length; a++) {
836
+ const c = e[a];
837
837
  o(Te);
838
838
  const l = n.getUint32(s, !0);
839
839
  s += 4;
840
840
  const d = n.getUint32(s, !0);
841
841
  s += 4;
842
842
  const f = n.getUint32(s, !0);
843
- if (s += 4, l !== a.fieldNames.length)
844
- throw new p(
845
- `sparse store ${c} field-count mismatch: snapshot=${l}, registered=${a.fieldNames.length}`
843
+ if (s += 4, l !== c.fieldNames.length)
844
+ throw new y(
845
+ `sparse store ${a} field-count mismatch: snapshot=${l}, registered=${c.fieldNames.length}`
846
846
  );
847
- const _ = Ie(a.fieldNames, a.fieldTypes);
848
- if (d !== _)
849
- throw new p(
850
- `sparse store ${c} schema identity mismatch: snapshot hash=${d}, registered=${_} (same field count, different field names/types — likely a registration-order divergence between the snapshot and restore worlds)`
847
+ const h = Ie(c.fieldNames, c.fieldTypes);
848
+ if (d !== h)
849
+ throw new y(
850
+ `sparse store ${a} schema identity mismatch: snapshot hash=${d}, registered=${h} (same field count, different field names/types — likely a registration-order divergence between the snapshot and restore worlds)`
851
851
  );
852
852
  for (let g = 0; g < f; g++) {
853
- o(Ae + l * G);
854
- const y = n.getUint32(s, !0);
855
- if (s += 4, y > P)
856
- throw new p(
857
- `sparse store ${c} member ${g} entity index ${y} exceeds MAX_INDEX (${P})`
853
+ o(Ae + l * H);
854
+ const p = n.getUint32(s, !0);
855
+ if (s += 4, p > $)
856
+ throw new y(
857
+ `sparse store ${a} member ${g} entity index ${p} exceeds MAX_INDEX (${$})`
858
858
  );
859
- s += l * G;
859
+ s += l * H;
860
860
  }
861
861
  }
862
862
  if (s !== r)
863
- throw new p(
863
+ throw new y(
864
864
  `sparse snapshot has ${r - s} trailing bytes after the last store (not a canonical encoding)`
865
865
  );
866
866
  }
@@ -875,12 +875,12 @@ class Ke {
875
875
  * multi. Carries membership (and the target, when exclusive). */
876
876
  sparse;
877
877
  /** Cleanup policy applied to this relation's sources when a target is
878
- * destroyed (#473). `orphan` (the default) is a no-op — the link dangles
878
+ * destroyed. `orphan` (the default) is a no-op — the link dangles
879
879
  * safely. `Store` reads this at destroy-flush off `sourcesOf`. */
880
880
  onDeleteTarget;
881
881
  /** The backing sparse store instance. Owned for registration/liveness by
882
882
  * `Store`, but the relation drives the forward/membership rows on it directly
883
- * — that is the cardinality interaction this class now encapsulates (#498). */
883
+ * — that is the cardinality interaction this class now encapsulates. */
884
884
  _store;
885
885
  /** target `EntityID` → set of source `EntityID`s. Keyed by the full id, not
886
886
  * the index, so a recycled target slot can't alias a dead target's sources.
@@ -903,7 +903,7 @@ class Ke {
903
903
  r !== void 0 && (r.delete(n), r.size === 0 && this._reverse.delete(t));
904
904
  }
905
905
  /** Drop every reverse-index entry whose **target** is no longer alive,
906
- * returning the count dropped (#491). The `orphan` policy intentionally
906
+ * returning the count dropped. The `orphan` policy intentionally
907
907
  * leaves a destroyed target's reverse entry intact (the link dangles
908
908
  * safely), so a long-lived source that orphan-points at a stream of
909
909
  * short-lived targets and never re-targets/dies accumulates dead-target keys
@@ -999,7 +999,7 @@ class nn extends Ke {
999
999
  }
1000
1000
  }
1001
1001
  restoreAddTarget() {
1002
- throw new p(
1002
+ throw new y(
1003
1003
  "exclusive relation has no multi forward sources to restore (snapshot header should have guarded this)"
1004
1004
  );
1005
1005
  }
@@ -1077,26 +1077,26 @@ function ns(e) {
1077
1077
  let n = 4;
1078
1078
  for (let i = 0; i < e.length; i++) {
1079
1079
  n += je;
1080
- const c = e[i];
1081
- if (c.exclusive) {
1080
+ const a = e[i];
1081
+ if (a.exclusive) {
1082
1082
  t[i] = null;
1083
1083
  continue;
1084
1084
  }
1085
- const a = [];
1086
- c.forEachCanonicalTargetSet((l, d) => a.push([l, d])), t[i] = a, n += Qe;
1087
- for (let l = 0; l < a.length; l++)
1088
- n += Ze + a[l][1].length * te;
1085
+ const c = [];
1086
+ a.forEachCanonicalTargetSet((l, d) => c.push([l, d])), t[i] = c, n += Qe;
1087
+ for (let l = 0; l < c.length; l++)
1088
+ n += Ze + c[l][1].length * te;
1089
1089
  }
1090
1090
  const r = new Uint8Array(n), s = new DataView(r.buffer);
1091
1091
  let o = 0;
1092
1092
  s.setUint32(o, e.length, !0), o += 4;
1093
1093
  for (let i = 0; i < e.length; i++) {
1094
1094
  s.setUint32(o, e[i].exclusive ? 0 : 1, !0), o += 4;
1095
- const c = t[i];
1096
- if (c !== null) {
1097
- s.setUint32(o, c.length, !0), o += 4;
1098
- for (let a = 0; a < c.length; a++) {
1099
- const l = c[a][0], d = c[a][1];
1095
+ const a = t[i];
1096
+ if (a !== null) {
1097
+ s.setUint32(o, a.length, !0), o += 4;
1098
+ for (let c = 0; c < a.length; c++) {
1099
+ const l = a[c][0], d = a[c][1];
1100
1100
  s.setUint32(o, l, !0), o += 4, s.setUint32(o, d.length, !0), o += 4;
1101
1101
  for (let f = 0; f < d.length; f++)
1102
1102
  s.setFloat64(o, d[f], !0), o += te;
@@ -1108,109 +1108,109 @@ function ns(e) {
1108
1108
  function ss(e, t, n) {
1109
1109
  const r = new DataView(t.buffer, t.byteOffset, t.byteLength), s = t.byteLength;
1110
1110
  let o = 0;
1111
- const i = (a) => {
1112
- if (o + a > s)
1113
- throw new p(
1114
- `relation snapshot truncated: need ${a} more bytes at offset ${o}, have ${s - o}`
1111
+ const i = (c) => {
1112
+ if (o + c > s)
1113
+ throw new y(
1114
+ `relation snapshot truncated: need ${c} more bytes at offset ${o}, have ${s - o}`
1115
1115
  );
1116
1116
  };
1117
- for (let a = 0; a < e.length; a++) e[a].resetIndices();
1117
+ for (let c = 0; c < e.length; c++) e[c].resetIndices();
1118
1118
  i(4);
1119
- const c = r.getUint32(o, !0);
1120
- if (o += 4, c !== e.length)
1121
- throw new p(
1122
- `relation count mismatch: snapshot=${c}, registered=${e.length}`
1119
+ const a = r.getUint32(o, !0);
1120
+ if (o += 4, a !== e.length)
1121
+ throw new y(
1122
+ `relation count mismatch: snapshot=${a}, registered=${e.length}`
1123
1123
  );
1124
- for (let a = 0; a < e.length; a++) {
1125
- const l = e[a];
1124
+ for (let c = 0; c < e.length; c++) {
1125
+ const l = e[c];
1126
1126
  i(je);
1127
1127
  const d = r.getUint32(o, !0);
1128
1128
  if (o += 4, d === 1 === l.exclusive)
1129
- throw new p(
1130
- `relation ${a} cardinality mismatch: snapshot ${d ? "multi" : "exclusive"}, registered ${l.exclusive ? "exclusive" : "multi"}`
1129
+ throw new y(
1130
+ `relation ${c} cardinality mismatch: snapshot ${d ? "multi" : "exclusive"}, registered ${l.exclusive ? "exclusive" : "multi"}`
1131
1131
  );
1132
1132
  if (l.exclusive) continue;
1133
1133
  i(Qe);
1134
1134
  const f = r.getUint32(o, !0);
1135
1135
  o += 4;
1136
- for (let _ = 0; _ < f; _++) {
1136
+ for (let h = 0; h < f; h++) {
1137
1137
  i(Ze);
1138
1138
  const g = r.getUint32(o, !0);
1139
1139
  o += 4;
1140
- const y = r.getUint32(o, !0);
1141
- if (o += 4, g > P)
1142
- throw new p(
1143
- `relation ${a} source index ${g} exceeds MAX_INDEX (${P})`
1140
+ const p = r.getUint32(o, !0);
1141
+ if (o += 4, g > $)
1142
+ throw new y(
1143
+ `relation ${c} source index ${g} exceeds MAX_INDEX (${$})`
1144
1144
  );
1145
- i(y * te);
1145
+ i(p * te);
1146
1146
  const u = n(g);
1147
- for (let h = 0; h < y; h++) {
1147
+ for (let _ = 0; _ < p; _++) {
1148
1148
  const T = r.getFloat64(o, !0);
1149
1149
  o += te;
1150
1150
  const x = T;
1151
- if (!Number.isInteger(x) || x < 0 || x > Se)
1152
- throw new p(
1153
- `relation ${a} target ${x} is not a well-formed packed EntityID (expected an integer in [0, ${Se}])`
1151
+ if (!Number.isInteger(x) || x < 0 || x > we)
1152
+ throw new y(
1153
+ `relation ${c} target ${x} is not a well-formed packed EntityID (expected an integer in [0, ${we}])`
1154
1154
  );
1155
1155
  l.restoreAddTarget(g, T, u);
1156
1156
  }
1157
1157
  }
1158
1158
  }
1159
1159
  if (o !== s)
1160
- throw new p(
1160
+ throw new y(
1161
1161
  `relation snapshot has ${s - o} trailing bytes after the last relation (not a canonical encoding)`
1162
1162
  );
1163
1163
  }
1164
1164
  const ve = /* @__PURE__ */ new WeakMap();
1165
1165
  function rn(e) {
1166
- const t = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Set(), o = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set(), c = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Set(), l = /* @__PURE__ */ new Set(), d = /* @__PURE__ */ new Set();
1166
+ const t = /* @__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(), l = /* @__PURE__ */ new Set(), d = /* @__PURE__ */ new Set();
1167
1167
  for (let u = 0; u < e.writes.length; u++) {
1168
- const h = e.writes[u].id;
1169
- n.add(h), t.add(h), r.add(h);
1168
+ const _ = e.writes[u].id;
1169
+ n.add(_), t.add(_), r.add(_);
1170
1170
  }
1171
1171
  for (let u = 0; u < e.reads.length; u++)
1172
1172
  t.add(e.reads[u].id);
1173
1173
  for (let u = 0; u < e.spawns.length; u++) {
1174
- const h = e.spawns[u];
1175
- for (let T = 0; T < h.length; T++)
1176
- r.add(h[T].id);
1174
+ const _ = e.spawns[u];
1175
+ for (let T = 0; T < _.length; T++)
1176
+ r.add(_[T].id);
1177
1177
  }
1178
1178
  for (let u = 0; u < e.transitions.length; u++) {
1179
- const h = e.transitions[u];
1180
- if (h.add)
1181
- for (let T = 0; T < h.add.length; T++)
1182
- r.add(h.add[T].id);
1183
- if (h.remove)
1184
- for (let T = 0; T < h.remove.length; T++)
1185
- s.add(h.remove[T].id);
1179
+ const _ = e.transitions[u];
1180
+ if (_.add)
1181
+ for (let T = 0; T < _.add.length; T++)
1182
+ r.add(_.add[T].id);
1183
+ if (_.remove)
1184
+ for (let T = 0; T < _.remove.length; T++)
1185
+ s.add(_.remove[T].id);
1186
1186
  }
1187
1187
  for (let u = 0; u < e.despawns.length; u++)
1188
1188
  s.add(e.despawns[u].id);
1189
1189
  for (let u = 0; u < e.resourceReads.length; u++)
1190
1190
  o.add(e.resourceReads[u]);
1191
1191
  for (let u = 0; u < e.resourceWrites.length; u++) {
1192
- const h = e.resourceWrites[u];
1193
- i.add(h), o.add(h);
1192
+ const _ = e.resourceWrites[u];
1193
+ i.add(_), o.add(_);
1194
1194
  }
1195
1195
  const f = e.sparseWrites;
1196
1196
  if (f !== void 0)
1197
1197
  for (let u = 0; u < f.length; u++) {
1198
- const h = f[u];
1199
- a.add(h), c.add(h);
1198
+ const _ = f[u];
1199
+ c.add(_), a.add(_);
1200
1200
  }
1201
- const _ = e.sparseReads;
1202
- if (_ !== void 0)
1203
- for (let u = 0; u < _.length; u++) c.add(_[u]);
1201
+ const h = e.sparseReads;
1202
+ if (h !== void 0)
1203
+ for (let u = 0; u < h.length; u++) a.add(h[u]);
1204
1204
  const g = e.relationWrites;
1205
1205
  if (g !== void 0)
1206
1206
  for (let u = 0; u < g.length; u++) {
1207
- const h = g[u];
1208
- d.add(h), l.add(h);
1207
+ const _ = g[u];
1208
+ d.add(_), l.add(_);
1209
1209
  }
1210
- const y = e.relationReads;
1211
- if (y !== void 0)
1212
- for (let u = 0; u < y.length; u++)
1213
- l.add(y[u]);
1210
+ const p = e.relationReads;
1211
+ if (p !== void 0)
1212
+ for (let u = 0; u < p.length; u++)
1213
+ l.add(p[u]);
1214
1214
  return {
1215
1215
  reads: t,
1216
1216
  writes: n,
@@ -1219,8 +1219,8 @@ function rn(e) {
1219
1219
  hasDespawns: e.despawns.length > 0,
1220
1220
  resourceReads: o,
1221
1221
  resourceWrites: i,
1222
- sparseReads: c,
1223
- sparseWrites: a,
1222
+ sparseReads: a,
1223
+ sparseWrites: c,
1224
1224
  relationReads: l,
1225
1225
  relationWrites: d
1226
1226
  };
@@ -1263,17 +1263,17 @@ class dn {
1263
1263
  active = null;
1264
1264
  sets = null;
1265
1265
  // The label used in violation messages. Tracks `active` for a system span,
1266
- // but a run-condition span (#576) has no descriptor — only this name — so the
1266
+ // but a run-condition span has no descriptor — only this name — so the
1267
1267
  // failure helpers read the label here rather than off `active`.
1268
1268
  activeName = null;
1269
- // An `exclusive` system (#681) has full world access: every check_* below
1269
+ // An `exclusive` system has full world access: every check_* below
1270
1270
  // passes for the whole span. Kept as an explicit flag (rather than leaving
1271
1271
  // `sets` null) so `isActive()` stays truthful inside the span.
1272
1272
  exclusive = !1;
1273
1273
  enter(t) {
1274
1274
  this.active = t, this.activeName = t.name ?? `system_${t.id}`, this.exclusive = t.exclusive === !0, this.sets = this.exclusive ? null : on(t);
1275
1275
  }
1276
- /** Open a reads-only span for a run condition (#576). No descriptor — a
1276
+ /** Open a reads-only span for a run condition. No descriptor — a
1277
1277
  * condition can gate a whole SystemSet, so it isn't attributable to one
1278
1278
  * system — just its declared reads/resource_reads and a name for diagnostics.
1279
1279
  * Paired with `leave()`. */
@@ -1305,8 +1305,8 @@ class dn {
1305
1305
  checkDestroy() {
1306
1306
  if (this.sets === null || this.sets.hasDespawns) return;
1307
1307
  const t = this.activeName;
1308
- throw new S(
1309
- w.ACCESS_UNDECLARED,
1308
+ throw new w(
1309
+ S.ACCESS_UNDECLARED,
1310
1310
  `system '${t}' called despawn but didn't declare any despawns — declare the components this system removes via despawn in its 'despawns'`,
1311
1311
  { system: t, op: "despawn" }
1312
1312
  );
@@ -1321,7 +1321,7 @@ class dn {
1321
1321
  const n = t;
1322
1322
  this.sets.resourceWrites.has(n) || this.failResource("write", t, "resourceWrites");
1323
1323
  }
1324
- // --- Sparse component / relation checks (#496) ---
1324
+ // --- Sparse component / relation checks ---
1325
1325
  // Keyed against the dedicated sparse/relation sets, NOT the dense
1326
1326
  // `reads`/`writes` sets — the id spaces are disjoint by construction (see
1327
1327
  // file header). `def as unknown as number` recovers the SparseComponentID /
@@ -1346,7 +1346,7 @@ class dn {
1346
1346
  const n = t;
1347
1347
  this.sets.relationWrites.has(n) || this.failRelation("write", n, "relationWrites");
1348
1348
  }
1349
- /** A `(*, T)` wildcard (`Query.forEachRelatedTo`, #579) reads every
1349
+ /** A `(*, T)` wildcard (`Query.forEachRelatedTo`) reads every
1350
1350
  * relation's reverse index, so it can't name a specific relation — it is
1351
1351
  * authorised by the `ANY_RELATION` sentinel in `relationReads`. Honoured here
1352
1352
  * exactly like a per-relation read, just keyed on the reserved sentinel id
@@ -1358,7 +1358,7 @@ class dn {
1358
1358
  "relationReads (as ANY_RELATION)"
1359
1359
  ));
1360
1360
  }
1361
- // --- Optional query-term scope (#592) ---
1361
+ // --- Optional query-term scope ---
1362
1362
  // `Query.forEach` and `ChangedQuery.forEach` push the iterating query's
1363
1363
  // `_optional` term list for the span of the callback;
1364
1364
  // `Archetype.getOptionalColumnRead` then verifies the fetched component was
@@ -1372,7 +1372,7 @@ class dn {
1372
1372
  // `query.archetypes` walk can't be attributed to an optional declaration, so it
1373
1373
  // isn't checked — mirroring the unchecked outside-of-system calls in the header.
1374
1374
  //
1375
- // CAVEAT (#594 Task 3): the gate always attributes to the INNERMOST active
1375
+ // CAVEAT: the gate always attributes to the INNERMOST active
1376
1376
  // `forEach`. If you nest `forEach` and call `getOptionalColumnRead` on an
1377
1377
  // OUTER query's archetype inside the inner loop, it is checked against the inner
1378
1378
  // query's terms (a false throw or false pass). Per-query attribution isn't worth
@@ -1391,46 +1391,46 @@ class dn {
1391
1391
  const r = this.optionalScopes[n - 1], s = t.id;
1392
1392
  for (let o = 0; o < r.length; o++)
1393
1393
  if (r[o] === s) return;
1394
- throw new S(
1395
- w.OPTIONAL_TERM_NOT_DECLARED,
1394
+ throw new w(
1395
+ S.OPTIONAL_TERM_NOT_DECLARED,
1396
1396
  `getOptionalColumnRead fetched optional component ${s} but the iterating query didn't declare it — add .optional(component) to the query before fetching it`
1397
1397
  );
1398
1398
  }
1399
1399
  failComponent(t, n, r) {
1400
1400
  const s = this.activeName, o = dt(n);
1401
- throw new S(
1402
- w.ACCESS_UNDECLARED,
1401
+ throw new w(
1402
+ S.ACCESS_UNDECLARED,
1403
1403
  `system '${s}' performed ${t} on ${o} but didn't declare it — add it to '${r}' (see docs/api/systems.md)`,
1404
1404
  { system: s, op: t, component: n.id }
1405
1405
  );
1406
1406
  }
1407
1407
  failSparse(t, n, r) {
1408
1408
  const s = this.activeName;
1409
- throw new S(
1410
- w.ACCESS_UNDECLARED,
1409
+ throw new w(
1410
+ S.ACCESS_UNDECLARED,
1411
1411
  `system '${s}' performed ${t} on sparse component ${n} but didn't declare it — add it to '${r}' (see docs/api/systems.md)`,
1412
1412
  { system: s, op: t, sparse: n }
1413
1413
  );
1414
1414
  }
1415
1415
  failRelation(t, n, r) {
1416
1416
  const s = this.activeName;
1417
- throw new S(
1418
- w.ACCESS_UNDECLARED,
1417
+ throw new w(
1418
+ S.ACCESS_UNDECLARED,
1419
1419
  `system '${s}' performed ${t} on relation ${n} but didn't declare it — add it to '${r}' (see docs/api/systems.md)`,
1420
1420
  { system: s, op: t, relation: n }
1421
1421
  );
1422
1422
  }
1423
1423
  failResource(t, n, r) {
1424
1424
  const s = this.activeName, o = n.description ?? "<unnamed>";
1425
- throw new S(
1426
- w.ACCESS_UNDECLARED,
1425
+ throw new w(
1426
+ S.ACCESS_UNDECLARED,
1427
1427
  `system '${s}' performed resource ${t} on '${o}' but didn't declare it — add the resource key to '${r}' (see docs/api/systems.md)`,
1428
1428
  { system: s, op: t, resource: o }
1429
1429
  );
1430
1430
  }
1431
1431
  }
1432
1432
  const rs = new dn();
1433
- var $ = /* @__PURE__ */ ((e) => (e.PRE_STARTUP = "PRE_STARTUP", e.STARTUP = "STARTUP", e.POST_STARTUP = "POST_STARTUP", e.FIXED_UPDATE = "FIXED_UPDATE", e.PRE_UPDATE = "PRE_UPDATE", e.UPDATE = "UPDATE", e.POST_UPDATE = "POST_UPDATE", e))($ || {});
1433
+ var P = /* @__PURE__ */ ((e) => (e.PRE_STARTUP = "PRE_STARTUP", e.STARTUP = "STARTUP", e.POST_STARTUP = "POST_STARTUP", e.FIXED_UPDATE = "FIXED_UPDATE", e.PRE_UPDATE = "PRE_UPDATE", e.UPDATE = "UPDATE", e.POST_UPDATE = "POST_UPDATE", e))(P || {});
1434
1434
  const ce = [
1435
1435
  "PRE_STARTUP",
1436
1436
  "STARTUP",
@@ -1454,50 +1454,86 @@ function le(e) {
1454
1454
  }
1455
1455
  class is {
1456
1456
  labelSystems = /* @__PURE__ */ new Map();
1457
+ // Sorted descriptors for a phase, paired with the `systemLastRun` slot of each
1458
+ // — cached together so `runLabel` resolves both with the one `Map.get` it
1459
+ // already paid, and the per-system lookup inside the loop is array indexing.
1457
1460
  sortedCache = /* @__PURE__ */ new Map();
1458
1461
  systemIndex = /* @__PURE__ */ new Map();
1459
- systemLastRun = /* @__PURE__ */ new Map();
1460
- // Only systems carrying a run condition or set membership (#576). The hot
1462
+ // Previous-run tick per scheduled system — a packed array, NOT a `Map` keyed
1463
+ // on the descriptor. `runLabel` reads it and writes it back once per system
1464
+ // per phase. A profile of a dispatch-bound schedule shows that those two `Map`
1465
+ // operations, and not the system bodies, are where most of the phase loop goes
1466
+ // — they hash an object identity twice for each system in each frame.
1467
+ //
1468
+ // Indexed by a SCHEDULE-LOCAL slot, not by `SystemDescriptor.id`. Ids come
1469
+ // from a per-world counter, so two descriptors registered with two different
1470
+ // worlds both get id 0 — scheduling them into a third world would alias them
1471
+ // onto one slot and let the system that runs more often overwrite the other's
1472
+ // last-run tick (silently widening its `changed()` window). Slots are handed
1473
+ // out per Schedule, so identity comes from this schedule's own numbering.
1474
+ systemLastRun = [];
1475
+ // Descriptor → its `systemLastRun` slot. Consulted only by `addSystems` /
1476
+ // `removeSystem`; the run loop never touches it (the slot travels in the
1477
+ // phase plan).
1478
+ //
1479
+ // `removeSystem` MUST delete from this map. It is the only strong reference
1480
+ // the Schedule keeps to a descriptor once its node is gone, and a descriptor
1481
+ // closes over whatever its `fn` captured — leaving the entry behind pins that
1482
+ // for the world's lifetime. (The `Map` this replaced was deleted on remove;
1483
+ // forgetting to do the same here leaked every descriptor ever scheduled.)
1484
+ lastRunSlots = /* @__PURE__ */ new Map();
1485
+ // Slots freed by `removeSystem`, handed back out by `_assignLastRunSlot`.
1486
+ // Without reuse the array would grow by one per `addSystems` call — unbounded
1487
+ // under a workload that toggles systems on and off each frame.
1488
+ freeLastRunSlots = [];
1489
+ // Nesting depth of a drive (`runStartup` / `runUpdate` / `runFixedUpdate`).
1490
+ // Non-zero means a phase plan is live and `runLabel`'s loop may still write
1491
+ // `systemLastRun` through the `slots` array it captured, which is what makes
1492
+ // recycling a freed slot unsafe right now — see `_assignLastRunSlot`.
1493
+ _driveDepth = 0;
1494
+ // Only systems carrying a run condition or set membership. The hot
1461
1495
  // loop skips the per-system gate probe entirely when this is empty, so a
1462
- // schedule that uses no conditions runs byte-for-byte the pre-#576 path.
1496
+ // schedule that uses no conditions runs byte-for-byte the original path.
1463
1497
  gatedSystems = /* @__PURE__ */ new Map();
1464
1498
  // Live set configuration, read at sort time (ordering) and run time
1465
1499
  // (conditions) so `configureSet` is order-independent w.r.t. `addSystems`.
1466
1500
  setConditions = /* @__PURE__ */ new Map();
1467
1501
  setOrdering = /* @__PURE__ */ new Map();
1468
1502
  nextInsertionOrder = 0;
1469
- // The opt-in compute backend (#622), or null (the default — pure-TS). When
1503
+ // The opt-in compute backend, or null (the default — pure-TS). When
1470
1504
  // set, a scheduled system carrying a `backendHandle` runs `backend.run(...)`
1471
- // instead of its `fn`. `null` is the byte-for-byte pre-#622 path: `runLabel`
1505
+ // instead of its `fn`. `null` is the byte-for-byte no-backend path: `runLabel`
1472
1506
  // hoists this to a local and only reads `desc.backendHandle` when non-null,
1473
1507
  // so a no-backend ECS never touches the routing field.
1474
1508
  _backend = null;
1475
1509
  /** Dev-diagnostic sink (`ECSOptions.onWarn`); defaults to `console.warn`.
1476
1510
  * The only schedule diagnostic today is `warnDroppedEdge`. */
1477
1511
  onWarn;
1512
+ /** The `FIXED_UPDATE` node list, held directly for `hasFixedSystems`. */
1513
+ _fixedNodes = [];
1478
1514
  constructor(t) {
1479
1515
  this.onWarn = t ?? ((n) => console.warn(n));
1480
1516
  for (let n = 0; n < ce.length; n++)
1481
1517
  this.labelSystems.set(ce[n], []);
1482
- this.labelSystems.set("FIXED_UPDATE", []);
1518
+ this.labelSystems.set("FIXED_UPDATE", this._fixedNodes);
1483
1519
  for (let n = 0; n < de.length; n++)
1484
1520
  this.labelSystems.set(de[n], []);
1485
1521
  }
1486
1522
  addSystems(t, ...n) {
1487
1523
  for (const r of n) {
1488
- const s = "system" in r, o = s ? r.system : r, i = s ? r.ordering : void 0, c = s ? le(r.runIf) : W, a = s ? le(r.set) : W, l = {
1524
+ const s = "system" in r, o = s ? r.system : r, i = s ? r.ordering : void 0, a = s ? le(r.runIf) : W, c = s ? le(r.set) : W, l = {
1489
1525
  descriptor: o,
1490
1526
  insertionOrder: this.nextInsertionOrder++,
1491
1527
  before: new Set(i?.before ?? []),
1492
1528
  after: new Set(i?.after ?? []),
1493
- conditions: c,
1494
- sets: a
1529
+ conditions: a,
1530
+ sets: c
1495
1531
  };
1496
- this.labelSystems.get(t).push(l), this.systemIndex.set(o, t), this.systemLastRun.set(o, 0), (c.length > 0 || a.length > 0) && this.gatedSystems.set(o, l), this.sortedCache.delete(t);
1532
+ this.labelSystems.get(t).push(l), this.systemIndex.set(o, t), this._assignLastRunSlot(o), (a.length > 0 || c.length > 0) && this.gatedSystems.set(o, l), this.sortedCache.delete(t);
1497
1533
  }
1498
1534
  }
1499
1535
  /**
1500
- * Configure a `SystemSet` (#576) — its shared run condition(s) and/or
1536
+ * Configure a `SystemSet` — its shared run condition(s) and/or
1501
1537
  * ordering, inherited by every member. Additive and order-independent w.r.t.
1502
1538
  * `addSystems`: conditions accumulate (ANDed), ordering targets union, and
1503
1539
  * a member added before or after this call picks the configuration up.
@@ -1519,37 +1555,64 @@ class is {
1519
1555
  removeSystem(t) {
1520
1556
  const n = this.systemIndex.get(t);
1521
1557
  if (n === void 0) return;
1522
- const r = this.labelSystems.get(n), s = r.findIndex((o) => o.descriptor === t);
1558
+ const r = this.labelSystems.get(n), s = r.findIndex((i) => i.descriptor === t);
1523
1559
  if (s !== -1) {
1524
- const o = r.length - 1;
1525
- s !== o && (r[s] = r[o]), r.pop();
1526
- for (const i of r)
1527
- i.before.delete(t), i.after.delete(t);
1560
+ const i = r.length - 1;
1561
+ s !== i && (r[s] = r[i]), r.pop();
1562
+ for (const a of r)
1563
+ a.before.delete(t), a.after.delete(t);
1528
1564
  }
1529
- this.systemIndex.delete(t), this.systemLastRun.delete(t), this.gatedSystems.delete(t), this.sortedCache.delete(n);
1565
+ this.systemIndex.delete(t);
1566
+ const o = this.lastRunSlots.get(t);
1567
+ o !== void 0 && (this.systemLastRun[o] = 0, this.lastRunSlots.delete(t), this.freeLastRunSlots.push(o)), this.gatedSystems.delete(t), this.sortedCache.clear();
1530
1568
  }
1531
- /** Attach (or, with `null`, detach) the opt-in compute backend (#622). Driven
1569
+ /** Attach (or, with `null`, detach) the opt-in compute backend. Driven
1532
1570
  * by `ECS.attachBackend`; routes any scheduled system carrying a
1533
1571
  * `backendHandle` to `backend.run(handle)` in place of its `fn`. */
1534
1572
  setBackend(t) {
1535
1573
  this._backend = t;
1536
1574
  }
1575
+ // The three drive entry points each bracket their phases with `_driveDepth`,
1576
+ // so `_assignLastRunSlot` will not recycle a `systemLastRun` slot that a phase
1577
+ // plan captured by `runLabel`'s loop may still write to — see the guard there
1578
+ // for the hazard it closes.
1579
+ //
1580
+ // Held across the WHOLE drive, not per phase: one `try`/`finally` per frame
1581
+ // instead of one per phase (three, for an update). The difference is
1582
+ // measurable on a dispatch-bound schedule, where the system bodies do almost
1583
+ // no work. The wider window is also the more
1584
+ // conservative one, and slots still recycle freely between frames — the only
1585
+ // property `freeLastRunSlots` needs to stay bounded. Written out at each of
1586
+ // the three sites rather than wrapped in a helper taking a callback, which
1587
+ // would put a closure allocation and an indirect call on the per-frame path.
1537
1588
  runStartup(t, n) {
1538
- for (const r of ce)
1539
- this.runLabel(r, t, at, n);
1589
+ this._driveDepth++;
1590
+ try {
1591
+ for (const r of ce)
1592
+ this.runLabel(r, t, at, n);
1593
+ } finally {
1594
+ this._driveDepth--;
1595
+ }
1540
1596
  }
1541
1597
  runUpdate(t, n, r) {
1542
- for (const s of de)
1543
- this.runLabel(s, t, n, r);
1598
+ this._driveDepth++;
1599
+ try {
1600
+ for (const s of de)
1601
+ this.runLabel(s, t, n, r);
1602
+ } finally {
1603
+ this._driveDepth--;
1604
+ }
1544
1605
  }
1545
1606
  runFixedUpdate(t, n, r) {
1546
- this.runLabel("FIXED_UPDATE", t, n, r);
1607
+ this._driveDepth++;
1608
+ try {
1609
+ this.runLabel("FIXED_UPDATE", t, n, r);
1610
+ } finally {
1611
+ this._driveDepth--;
1612
+ }
1547
1613
  }
1548
1614
  hasFixedSystems() {
1549
- return this.labelSystems.get(
1550
- "FIXED_UPDATE"
1551
- /* FIXED_UPDATE */
1552
- ).length > 0;
1615
+ return this._fixedNodes.length > 0;
1553
1616
  }
1554
1617
  getAllSystems() {
1555
1618
  const t = [];
@@ -1561,26 +1624,41 @@ class is {
1561
1624
  hasSystem(t) {
1562
1625
  return this.systemIndex.has(t);
1563
1626
  }
1627
+ /** Hand `descriptor` its `systemLastRun` slot, keeping the array packed (no
1628
+ * holes ⇒ no undefined-check on the read in `runLabel`, which is the whole
1629
+ * point of it not being a `Map`). Idempotent for a descriptor already in this
1630
+ * schedule — `getSorted` re-asks for every system it sorts. A descriptor that
1631
+ * was removed and re-added gets a *fresh* slot starting at tick 0, which is
1632
+ * what the previous `Map`-based bookkeeping did (`delete` on remove, `set(…, 0)`
1633
+ * on re-add). */
1634
+ _assignLastRunSlot(t) {
1635
+ let n = this.lastRunSlots.get(t);
1636
+ if (n === void 0) {
1637
+ const r = this._driveDepth === 0 ? this.freeLastRunSlots.pop() : void 0;
1638
+ r !== void 0 ? (n = r, this.systemLastRun[n] = 0) : (n = this.systemLastRun.length, this.systemLastRun.push(0)), this.lastRunSlots.set(t, n);
1639
+ }
1640
+ return n;
1641
+ }
1564
1642
  clear() {
1565
1643
  for (const t of this.labelSystems.values())
1566
1644
  t.length = 0;
1567
- this.sortedCache.clear(), this.systemIndex.clear(), this.systemLastRun.clear(), this.gatedSystems.clear(), this.setConditions.clear(), this.setOrdering.clear();
1645
+ 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();
1568
1646
  }
1569
1647
  runLabel(t, n, r, s) {
1570
- const o = this.getSorted(t), i = this.gatedSystems.size > 0, c = this._backend, a = i ? /* @__PURE__ */ new Map() : void 0;
1571
- for (let l = 0; l < o.length; l++) {
1572
- const d = o[l];
1573
- if (i) {
1574
- const _ = this.gatedSystems.get(d);
1575
- if (_ !== void 0 && !this.shouldRun(_, n, a)) continue;
1648
+ const o = this.getSorted(t), i = o.sorted, a = o.slots, c = this.gatedSystems.size > 0, l = this._backend, d = c ? /* @__PURE__ */ new Map() : void 0;
1649
+ for (let f = 0; f < i.length; f++) {
1650
+ const h = i[f];
1651
+ if (c) {
1652
+ const p = this.gatedSystems.get(h);
1653
+ if (p !== void 0 && !this.shouldRun(p, n, d)) continue;
1576
1654
  }
1577
- n.lastRunTick = this.systemLastRun.get(d) ?? 0;
1578
- const f = c !== null ? d.backendHandle : void 0;
1655
+ n.lastRunTick = this.systemLastRun[a[f]];
1656
+ const g = l !== null ? h.backendHandle : void 0;
1579
1657
  try {
1580
- f !== void 0 ? c.run(f) : d.fn?.(n, r);
1658
+ g !== void 0 ? l.run(g) : h.fn?.(n, r);
1581
1659
  } finally {
1582
1660
  }
1583
- this.systemLastRun.set(d, s);
1661
+ this.systemLastRun[a[f]] = s;
1584
1662
  }
1585
1663
  n.flush();
1586
1664
  }
@@ -1592,7 +1670,7 @@ class is {
1592
1670
  * memo lives only for a single `runLabel` pass. Short-circuits on the first
1593
1671
  * `false`. The system's own conditions evaluate per system, in canonical order.
1594
1672
  *
1595
- * #731 SEMANTIC NOTE: this evaluates a set's conditions once-per-set-per-phase
1673
+ * SEMANTIC NOTE: this evaluates a set's conditions once-per-set-per-phase
1596
1674
  * rather than once-per-member. Equivalent for pure RunConditions; observably
1597
1675
  * different only if a set condition reads state mutated earlier in the SAME
1598
1676
  * phase (resources write immediately). That is intentional — the set gates as a
@@ -1605,8 +1683,8 @@ class is {
1605
1683
  const o = t.sets[s];
1606
1684
  let i = r.get(o);
1607
1685
  if (i === void 0) {
1608
- const c = this.setConditions.get(o);
1609
- i = c === void 0 || c.length === 0 ? !0 : this.evalConditions(c, n), r.set(o, i);
1686
+ const a = this.setConditions.get(o);
1687
+ i = a === void 0 || a.length === 0 ? !0 : this.evalConditions(a, n), r.set(o, i);
1610
1688
  }
1611
1689
  if (!i) return !1;
1612
1690
  }
@@ -1630,8 +1708,10 @@ class is {
1630
1708
  getSorted(t) {
1631
1709
  const n = this.sortedCache.get(t);
1632
1710
  if (n !== void 0) return n;
1633
- const r = this.labelSystems.get(t), s = this.sortSystems(r, t);
1634
- return this.sortedCache.set(t, s), s;
1711
+ const r = this.labelSystems.get(t), s = this.sortSystems(r, t), o = new Int32Array(s.length);
1712
+ for (let a = 0; a < s.length; a++) o[a] = this._assignLastRunSlot(s[a]);
1713
+ const i = { sorted: s, slots: o };
1714
+ return this.sortedCache.set(t, i), i;
1635
1715
  }
1636
1716
  /**
1637
1717
  * Delegates to the shared topologicalSort utility.
@@ -1644,14 +1724,14 @@ class is {
1644
1724
  for (const d of t) {
1645
1725
  r.push(d.descriptor), s.set(d.descriptor, d.insertionOrder), o.add(d.descriptor);
1646
1726
  for (let f = 0; f < d.sets.length; f++) {
1647
- const _ = d.sets[f];
1648
- let g = i.get(_);
1649
- g === void 0 && (g = [], i.set(_, g)), g.push(d.descriptor);
1727
+ const h = d.sets[f];
1728
+ let g = i.get(h);
1729
+ g === void 0 && (g = [], i.set(h, g)), g.push(d.descriptor);
1650
1730
  }
1651
1731
  }
1652
- const c = /* @__PURE__ */ new Map();
1732
+ const a = /* @__PURE__ */ new Map();
1653
1733
  for (const d of t)
1654
- c.set(d.descriptor, []);
1734
+ a.set(d.descriptor, []);
1655
1735
  for (const d of t) {
1656
1736
  this.resolveEdges(
1657
1737
  d.descriptor,
@@ -1659,42 +1739,42 @@ class is {
1659
1739
  "before",
1660
1740
  o,
1661
1741
  i,
1662
- c,
1742
+ a,
1663
1743
  n
1664
- ), this.resolveEdges(d.descriptor, d.after, "after", o, i, c, n);
1744
+ ), this.resolveEdges(d.descriptor, d.after, "after", o, i, a, n);
1665
1745
  for (let f = 0; f < d.sets.length; f++) {
1666
- const _ = this.setOrdering.get(d.sets[f]);
1667
- _ !== void 0 && (this.resolveEdges(
1746
+ const h = this.setOrdering.get(d.sets[f]);
1747
+ h !== void 0 && (this.resolveEdges(
1668
1748
  d.descriptor,
1669
- _.before,
1749
+ h.before,
1670
1750
  "before",
1671
1751
  o,
1672
1752
  i,
1673
- c,
1753
+ a,
1674
1754
  n
1675
1755
  ), this.resolveEdges(
1676
1756
  d.descriptor,
1677
- _.after,
1757
+ h.after,
1678
1758
  "after",
1679
1759
  o,
1680
1760
  i,
1681
- c,
1761
+ a,
1682
1762
  n
1683
1763
  ));
1684
1764
  }
1685
1765
  }
1686
- const a = (d, f) => s.get(d) - s.get(f), l = (d) => d.name ?? `system_${d.id}`;
1766
+ const c = (d, f) => s.get(d) - s.get(f), l = (d) => d.name ?? `system_${d.id}`;
1687
1767
  try {
1688
- return tt(r, c, a, l);
1768
+ return tt(r, a, c, l);
1689
1769
  } catch (d) {
1690
- throw d instanceof TypeError ? new S(
1691
- w.CIRCULAR_SYSTEM_DEPENDENCY,
1770
+ throw d instanceof TypeError ? new w(
1771
+ S.CIRCULAR_SYSTEM_DEPENDENCY,
1692
1772
  `Circular system dependency detected in ${n}: ${d.message}`
1693
1773
  ) : d;
1694
1774
  }
1695
1775
  }
1696
1776
  /**
1697
- * Add the topo edges for one ordering list (#576). For `"before"` the source
1777
+ * Add the topo edges for one ordering list. For `"before"` the source
1698
1778
  * runs before each target (edge source→target); for `"after"` it runs after
1699
1779
  * each target (edge target→source). A `SystemSet` target expands to every
1700
1780
  * member within this phase (self-edges skipped, so a member ordered against
@@ -1702,10 +1782,10 @@ class is {
1702
1782
  * dropped — with a dev warning only for a concrete system, since a set
1703
1783
  * legitimately expands to nothing when its members live in another phase.
1704
1784
  */
1705
- resolveEdges(t, n, r, s, o, i, c) {
1706
- for (const a of n) {
1707
- if (ln(a)) {
1708
- const l = o.get(a);
1785
+ resolveEdges(t, n, r, s, o, i, a) {
1786
+ for (const c of n) {
1787
+ if (ln(c)) {
1788
+ const l = o.get(c);
1709
1789
  if (l === void 0) continue;
1710
1790
  for (let d = 0; d < l.length; d++) {
1711
1791
  const f = l[d];
@@ -1713,7 +1793,7 @@ class is {
1713
1793
  }
1714
1794
  continue;
1715
1795
  }
1716
- s.has(a) && this.addDirectedEdge(t, a, r, i);
1796
+ s.has(c) && this.addDirectedEdge(t, c, r, i);
1717
1797
  }
1718
1798
  }
1719
1799
  /** Push one directed edge into the adjacency map. Both endpoints are known to
@@ -1740,11 +1820,11 @@ class is {
1740
1820
  );
1741
1821
  }
1742
1822
  }
1743
- const ne = 1024, se = 1024 * ne, Me = 64 * ne, X = 256 * se, $e = 3, un = 64, fn = 8, Pe = 4 * se, xe = (e) => 2 ** Math.ceil(Math.log2(Math.max(1, e))), Q = (e) => 2 ** Math.floor(Math.log2(Math.max(1, e))), F = (e, t, n) => Math.min(n, Math.max(t, e)), I = (e) => e >= se ? `${(e / se).toFixed(1)} MiB` : e >= ne ? `${(e / ne).toFixed(0)} KiB` : `${e} B`;
1823
+ const ne = 1024, se = 1024 * ne, Me = 64 * ne, X = 256 * se, Pe = 3, un = 64, fn = 8, $e = 4 * se, xe = (e) => 2 ** Math.ceil(Math.log2(Math.max(1, e))), Q = (e) => 2 ** Math.floor(Math.log2(Math.max(1, e))), F = (e, t, n) => Math.min(n, Math.max(t, e)), I = (e) => e >= se ? `${(e / se).toFixed(1)} MiB` : e >= ne ? `${(e / ne).toFixed(0)} KiB` : `${e} B`;
1744
1824
  function R(e, t) {
1745
1825
  if (!Number.isInteger(t) || t <= 0)
1746
- throw new S(
1747
- w.INVALID_MEMORY_OPTIONS,
1826
+ throw new w(
1827
+ S.INVALID_MEMORY_OPTIONS,
1748
1828
  `memory.${e} must be a positive integer (got ${t})`
1749
1829
  );
1750
1830
  }
@@ -1753,35 +1833,35 @@ function as(e) {
1753
1833
  (s) => e !== void 0 && e[s] !== void 0
1754
1834
  );
1755
1835
  if (t.length > 1)
1756
- throw new S(
1757
- w.INVALID_MEMORY_OPTIONS,
1836
+ throw new w(
1837
+ S.INVALID_MEMORY_OPTIONS,
1758
1838
  `memory takes at most one of budget | maxBytes | wasm | allocator | heap | shared (got: ${t.join(", ")})`
1759
1839
  );
1760
1840
  const n = e?.columnCapacity;
1761
- if (n !== void 0 && R("column_capacity", n), e?.budget !== void 0) {
1841
+ if (n !== void 0 && R("columnCapacity", n), e?.budget !== void 0) {
1762
1842
  const { entities: s } = e.budget, o = e.budget.archetypes ?? fn, i = e.budget.bytesPerEntity ?? un;
1763
- if (R("budget.entities", s), R("budget.archetypes", o), R("budget.bytes_per_entity", i), s > 1 << 20)
1764
- throw new S(
1765
- w.INVALID_MEMORY_OPTIONS,
1843
+ if (R("budget.entities", s), R("budget.archetypes", o), R("budget.bytesPerEntity", i), s > 1 << 20)
1844
+ throw new w(
1845
+ S.INVALID_MEMORY_OPTIONS,
1766
1846
  `memory.budget.entities=${s} exceeds the EntityID index space (1<<20 = ${1 << 20})`
1767
1847
  );
1768
- const c = n ?? F(xe(Math.ceil(s / o)), 64, 1 << 20), a = F(xe(s * 2), 4096, 1 << 20), l = a * D, d = s * i * $e, f = ze(
1769
- Math.max(l + d, Pe),
1848
+ const a = n ?? F(xe(Math.ceil(s / o)), 64, 1 << 20), c = F(xe(s * 2), 4096, 1 << 20), l = c * D, d = s * i * Pe, f = ze(
1849
+ Math.max(l + d, $e),
1770
1850
  Me
1771
1851
  );
1772
1852
  return {
1773
1853
  source: "budget",
1774
1854
  allocator: K(f),
1775
- columnCapacity: c,
1776
- entityIndexCapacity: a,
1855
+ columnCapacity: a,
1856
+ entityIndexCapacity: c,
1777
1857
  capBytes: f,
1778
1858
  intentLabel: `budget of ${s} entities`,
1779
1859
  budgetEntities: s,
1780
1860
  derivation: [
1781
- `column_capacity = ${n !== void 0 ? `${c} (pinned)` : `pow2(${s}/${o} per archetype) = ${c}`}`,
1782
- `entity_index = pow2(2 × ${s}) = ${a} slots × ${D} B = ${I(l)}`,
1783
- `columns = ${s} × ${i} B × ${$e} (double+holes headroom) = ${I(d)}`,
1784
- `cap = align64K(max(index + columns, ${I(Pe)} floor)) = ${I(f)}`
1861
+ `columnCapacity = ${n !== void 0 ? `${a} (pinned)` : `pow2(${s}/${o} per archetype) = ${a}`}`,
1862
+ `entityIndex = pow2(2 × ${s}) = ${c} slots × ${D} B = ${I(l)}`,
1863
+ `columns = ${s} × ${i} B × ${Pe} (double+holes headroom) = ${I(d)}`,
1864
+ `cap = align64K(max(index + columns, ${I($e)} floor)) = ${I(f)}`
1785
1865
  ],
1786
1866
  wasmMemory: null
1787
1867
  };
@@ -1794,7 +1874,7 @@ function as(e) {
1794
1874
  v
1795
1875
  );
1796
1876
  return {
1797
- source: "max_bytes",
1877
+ source: "maxBytes",
1798
1878
  allocator: K(e.maxBytes),
1799
1879
  columnCapacity: s,
1800
1880
  entityIndexCapacity: o,
@@ -1803,8 +1883,8 @@ function as(e) {
1803
1883
  budgetEntities: null,
1804
1884
  derivation: [
1805
1885
  `cap = ${I(e.maxBytes)} (caller-declared)`,
1806
- `column_capacity = ${s} (${n !== void 0 ? "pinned" : "default"})`,
1807
- `entity_index = floor_pow2(cap/4 ÷ ${D} B) = ${o} slots`
1886
+ `columnCapacity = ${s} (${n !== void 0 ? "pinned" : "default"})`,
1887
+ `entityIndex = floor_pow2(cap/4 ÷ ${D} B) = ${o} slots`
1808
1888
  ],
1809
1889
  wasmMemory: null
1810
1890
  };
@@ -1813,13 +1893,13 @@ function as(e) {
1813
1893
  const s = e.wasm, o = n ?? B;
1814
1894
  if (s.memory !== void 0) {
1815
1895
  if (!(s.memory.buffer instanceof SharedArrayBuffer))
1816
- throw new S(
1817
- w.INVALID_MEMORY_OPTIONS,
1818
- "memory.wasm.memory must be constructed with `shared: true` — the SAB substrate requires a SharedArrayBuffer-backed WebAssembly.Memory (ADR-0004 / ADR-0018)"
1896
+ throw new w(
1897
+ S.INVALID_MEMORY_OPTIONS,
1898
+ "memory.wasm.memory must be constructed with `shared: true` — the SAB substrate requires a SharedArrayBuffer-backed WebAssembly.Memory"
1819
1899
  );
1820
1900
  return {
1821
1901
  source: "wasm",
1822
- allocator: we(s.memory),
1902
+ allocator: Se(s.memory),
1823
1903
  columnCapacity: o,
1824
1904
  entityIndexCapacity: v,
1825
1905
  // The JS API hides a Memory's `maximum`; the caller declared it.
@@ -1829,52 +1909,52 @@ function as(e) {
1829
1909
  derivation: [
1830
1910
  "backing = wasm_memory_allocator(memory) — zero-copy with the sim (is_in_place ✓)",
1831
1911
  "cap = the Memory's own `maximum` (declared by the caller; not readable from JS)",
1832
- `column_capacity = ${o} (${n !== void 0 ? "pinned" : "default"})`
1912
+ `columnCapacity = ${o} (${n !== void 0 ? "pinned" : "default"})`
1833
1913
  ],
1834
1914
  wasmMemory: s.memory
1835
1915
  };
1836
1916
  }
1837
- R("wasm.maximum_pages", s.maximumPages);
1917
+ R("wasm.maximumPages", s.maximumPages);
1838
1918
  const i = s.initialPages ?? Math.min(32, s.maximumPages);
1839
- if (R("wasm.initial_pages", i), i > s.maximumPages)
1840
- throw new S(
1841
- w.INVALID_MEMORY_OPTIONS,
1842
- `memory.wasm.initial_pages (${i}) exceeds maximum_pages (${s.maximumPages})`
1919
+ if (R("wasm.initialPages", i), i > s.maximumPages)
1920
+ throw new w(
1921
+ S.INVALID_MEMORY_OPTIONS,
1922
+ `memory.wasm.initialPages (${i}) exceeds maximumPages (${s.maximumPages})`
1843
1923
  );
1844
- const c = new WebAssembly.Memory({
1924
+ const a = new WebAssembly.Memory({
1845
1925
  initial: i,
1846
1926
  maximum: s.maximumPages,
1847
1927
  shared: !0
1848
- }), a = s.maximumPages * Me, l = F(
1849
- Q(a / 4 / D),
1928
+ }), c = s.maximumPages * Me, l = F(
1929
+ Q(c / 4 / D),
1850
1930
  4096,
1851
1931
  v
1852
1932
  );
1853
1933
  return {
1854
1934
  source: "wasm",
1855
- allocator: we(c),
1935
+ allocator: Se(a),
1856
1936
  columnCapacity: o,
1857
1937
  entityIndexCapacity: l,
1858
- capBytes: a,
1938
+ capBytes: c,
1859
1939
  intentLabel: `engine-constructed WebAssembly.Memory (max ${s.maximumPages} pages)`,
1860
1940
  budgetEntities: null,
1861
1941
  derivation: [
1862
- `cap = ${s.maximumPages} pages × 64 KiB = ${I(a)} (Memory maximum)`,
1942
+ `cap = ${s.maximumPages} pages × 64 KiB = ${I(c)} (Memory maximum)`,
1863
1943
  `initial = ${i} pages (${s.initialPages !== void 0 ? "declared" : "default"})`,
1864
- `entity_index = floor_pow2(cap/4 ÷ ${D} B) = ${l} slots`,
1865
- `column_capacity = ${o} (${n !== void 0 ? "pinned" : "default"})`
1944
+ `entityIndex = floor_pow2(cap/4 ÷ ${D} B) = ${l} slots`,
1945
+ `columnCapacity = ${o} (${n !== void 0 ? "pinned" : "default"})`
1866
1946
  ],
1867
- wasmMemory: c
1947
+ wasmMemory: a
1868
1948
  };
1869
1949
  }
1870
1950
  if (e?.allocator !== void 0) {
1871
1951
  if (e.allocator.isInPlace !== !0)
1872
- throw new S(
1873
- w.INVALID_MEMORY_OPTIONS,
1874
- "memory.allocator must declare `is_in_place: true` (ADR-0008): 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 growable_sab_allocator / wasm_memory_allocator; non-in-place allocators are snapshot/test sizing only."
1952
+ throw new w(
1953
+ S.INVALID_MEMORY_OPTIONS,
1954
+ "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."
1875
1955
  );
1876
1956
  const s = n ?? B, o = e.capBytesHint;
1877
- return o !== void 0 && R("cap_bytes_hint", o), {
1957
+ return o !== void 0 && R("capBytesHint", o), {
1878
1958
  source: "allocator",
1879
1959
  allocator: e.allocator,
1880
1960
  columnCapacity: s,
@@ -1885,7 +1965,7 @@ function as(e) {
1885
1965
  derivation: [
1886
1966
  "backing = caller allocator (is_in_place ✓ checked at construction)",
1887
1967
  o !== void 0 ? `cap = ${I(o)} (caller hint — diagnostics only; the allocator owns the real cap)` : "cap = allocator-owned (no hint)",
1888
- `column_capacity = ${s} (${n !== void 0 ? "pinned" : "default"})`
1968
+ `columnCapacity = ${s} (${n !== void 0 ? "pinned" : "default"})`
1889
1969
  ],
1890
1970
  wasmMemory: null
1891
1971
  };
@@ -1906,10 +1986,10 @@ function as(e) {
1906
1986
  intentLabel: `pure-TS heap backing (${I(s)} growable cap, no SharedArrayBuffer)`,
1907
1987
  budgetEntities: null,
1908
1988
  derivation: [
1909
- `backing = heap_arraybuffer_allocator(${I(s)}) — resizable ArrayBuffer, no SAB / no COOP+COEP (is_in_place ✓)`,
1989
+ `backing = heap_arraybuffer_allocator(${I(s)}) — fixed ArrayBuffer reserved at the cap, no SAB / no COOP+COEP (is_in_place ✓)`,
1910
1990
  "trade-off: no worker offload / no WASM backend (both need a transferable SharedArrayBuffer)",
1911
- `column_capacity = ${o} (${n !== void 0 ? "pinned" : "default"})`,
1912
- `entity_index = floor_pow2(cap/4 ÷ ${D} B) = ${i} slots`
1991
+ `columnCapacity = ${o} (${n !== void 0 ? "pinned" : "default"})`,
1992
+ `entityIndex = floor_pow2(cap/4 ÷ ${D} B) = ${i} slots`
1913
1993
  ],
1914
1994
  wasmMemory: null
1915
1995
  };
@@ -1932,8 +2012,8 @@ function as(e) {
1932
2012
  derivation: [
1933
2013
  `backing = growable_sab_allocator(${I(s)}) — growable SharedArrayBuffer (is_in_place ✓); needs cross-origin isolation`,
1934
2014
  "enables worker offload + a WASM compute backend (transferable SharedArrayBuffer)",
1935
- `column_capacity = ${o} (${n !== void 0 ? "pinned" : "default"})`,
1936
- `entity_index = floor_pow2(cap/4 ÷ ${D} B) = ${i} slots`
2015
+ `columnCapacity = ${o} (${n !== void 0 ? "pinned" : "default"})`,
2016
+ `entityIndex = floor_pow2(cap/4 ÷ ${D} B) = ${i} slots`
1937
2017
  ],
1938
2018
  wasmMemory: null
1939
2019
  };
@@ -1949,8 +2029,8 @@ function as(e) {
1949
2029
  budgetEntities: null,
1950
2030
  derivation: [
1951
2031
  `cap = ${I(X)} (heap_arraybuffer_allocator default)`,
1952
- `column_capacity = ${r} (${n !== void 0 ? "pinned" : "DEFAULT_COLUMN_CAPACITY"})`,
1953
- `entity_index = ${v} slots (full EntityID space, ~12 MiB virtual)`
2032
+ `columnCapacity = ${r} (${n !== void 0 ? "pinned" : "DEFAULT_COLUMN_CAPACITY"})`,
2033
+ `entityIndex = ${v} slots (full EntityID space, ~12 MiB virtual)`
1954
2034
  ],
1955
2035
  wasmMemory: null
1956
2036
  };
@@ -1988,7 +2068,7 @@ function ue(e, t) {
1988
2068
  return ot(t, "HostCommand kind");
1989
2069
  }
1990
2070
  }
1991
- class _n {
2071
+ class hn {
1992
2072
  queued = [];
1993
2073
  spawn(t, n) {
1994
2074
  return this.queued.push({ kind: "spawn", components: t, onSpawned: n }), this;
@@ -2035,7 +2115,7 @@ class _n {
2035
2115
  get pending() {
2036
2116
  return this.queued.length;
2037
2117
  }
2038
- /** Drop every buffered command without applying it (M15) — e.g. abandoning
2118
+ /** Drop every buffered command without applying it — e.g. abandoning
2039
2119
  * queued edits on a scene unload. Returns how many were dropped. Does not
2040
2120
  * touch commands already drained into the world. */
2041
2121
  clear() {
@@ -2050,7 +2130,7 @@ class _n {
2050
2130
  * `tap`, when present, is invoked with each command in apply order just before
2051
2131
  * it is applied — the record/replay hook ({@link HostCommandRecorder}). It is
2052
2132
  * an OPT-IN observer: the tap-free path keeps the original tight loop, so an
2053
- * un-recorded drain pays nothing (#702).
2133
+ * un-recorded drain pays nothing.
2054
2134
  */
2055
2135
  drain(t, n) {
2056
2136
  const r = this.queued.length;
@@ -2066,13 +2146,13 @@ class _n {
2066
2146
  }
2067
2147
  }
2068
2148
  const Je = M - 1;
2069
- function hn(e) {
2149
+ function _n(e) {
2070
2150
  if (e === Ee)
2071
2151
  throw new U(
2072
- "cannot bind op_code 0 (reserved as the command-ring empty-slot marker)"
2152
+ "cannot bind opCode 0 (reserved as the command-ring empty-slot marker)"
2073
2153
  );
2074
2154
  if (e < 0 || e > 255 || !Number.isInteger(e))
2075
- throw new U(`command op_code must be a u8 in [1, 255] (got ${e})`);
2155
+ throw new U(`command opCode must be a u8 in [1, 255] (got ${e})`);
2076
2156
  }
2077
2157
  function oe(e) {
2078
2158
  const t = new Uint8Array(Je);
@@ -2110,7 +2190,7 @@ function ls() {
2110
2190
  encode(e) {
2111
2191
  if (e.kind !== "despawn")
2112
2192
  throw new U(
2113
- `ring_despawn_codec encodes a "despawn" command (got "${e.kind}")`
2193
+ `ringDespawnCodec encodes a "despawn" command (got "${e.kind}")`
2114
2194
  );
2115
2195
  return oe(e.eid);
2116
2196
  },
@@ -2122,7 +2202,7 @@ function us() {
2122
2202
  encode(e) {
2123
2203
  if (e.kind !== "disable")
2124
2204
  throw new U(
2125
- `ring_disable_codec encodes a "disable" command (got "${e.kind}")`
2205
+ `ringDisableCodec encodes a "disable" command (got "${e.kind}")`
2126
2206
  );
2127
2207
  return oe(e.eid);
2128
2208
  },
@@ -2134,14 +2214,14 @@ function fs() {
2134
2214
  encode(e) {
2135
2215
  if (e.kind !== "enable")
2136
2216
  throw new U(
2137
- `ring_enable_codec encodes an "enable" command (got "${e.kind}")`
2217
+ `ringEnableCodec encodes an "enable" command (got "${e.kind}")`
2138
2218
  );
2139
2219
  return oe(e.eid);
2140
2220
  },
2141
2221
  decode: (e) => ({ kind: "enable", eid: ie(e) })
2142
2222
  };
2143
2223
  }
2144
- function _s(e) {
2224
+ function hs(e) {
2145
2225
  return {
2146
2226
  encode(t) {
2147
2227
  if (t.kind !== "remove_component")
@@ -2153,20 +2233,20 @@ function _s(e) {
2153
2233
  decode: (t) => ({ kind: "remove_component", eid: ie(t), def: e })
2154
2234
  };
2155
2235
  }
2156
- class hs {
2236
+ class _s {
2157
2237
  appliers = /* @__PURE__ */ new Map();
2158
2238
  /** Bind a raw ctx-aware applier to `opCode`. Re-binding replaces. */
2159
2239
  on(t, n) {
2160
- return hn(t), this.appliers.set(t, n), this;
2240
+ return _n(t), this.appliers.set(t, n), this;
2161
2241
  }
2162
- /** Unbind `opCode` (M15). Returns whether a binding was removed; subsequent
2242
+ /** Unbind `opCode`. Returns whether a binding was removed; subsequent
2163
2243
  * slots carrying it hit the unknown-opcode path. */
2164
2244
  off(t) {
2165
2245
  return this.appliers.delete(t);
2166
2246
  }
2167
2247
  /** Bind a `HostCommand` codec to `opCode`: each matching slot is decoded and
2168
2248
  * run through `applyHostCommand` — the SAME dispatch the typed queue uses.
2169
- * A drain-time `tap` (record/replay, #702) sees the decoded command before it
2249
+ * A drain-time `tap` (record/replay) sees the decoded command before it
2170
2250
  * applies, so ring-sourced commands share one log with the typed transport. */
2171
2251
  onCommand(t, n) {
2172
2252
  return this.on(t, (r, s, o) => {
@@ -2177,19 +2257,19 @@ class hs {
2177
2257
  /** Drain every pending slot, dispatching each to its bound applier. Unbound
2178
2258
  * opcodes are skipped (the read head still advances — matching
2179
2259
  * `drainCommandRing` / `CommandDispatcher`). Returns slots drained. `tap`,
2180
- * when present, is forwarded to each applier as the record/replay hook (#702);
2260
+ * when present, is forwarded to each applier as the record/replay hook;
2181
2261
  * only `onCommand`-bound (generic `HostCommand`) opcodes surface to it. */
2182
2262
  drain(t, n, r, s) {
2183
2263
  return Dt(n, r, (o, i) => {
2184
- const c = this.appliers.get(o);
2185
- c !== void 0 && c(t, i, s);
2264
+ const a = this.appliers.get(o);
2265
+ a !== void 0 && a(t, i, s);
2186
2266
  });
2187
2267
  }
2188
2268
  }
2189
2269
  const mn = /* @__PURE__ */ new Set([
2190
- $.PRE_STARTUP,
2191
- $.STARTUP,
2192
- $.POST_STARTUP
2270
+ P.PRE_STARTUP,
2271
+ P.STARTUP,
2272
+ P.POST_STARTUP
2193
2273
  ]), fe = /* @__PURE__ */ new WeakMap();
2194
2274
  function ms(e, t) {
2195
2275
  const n = fe.get(t);
@@ -2198,15 +2278,15 @@ function ms(e, t) {
2198
2278
  return fe.delete(t), t.clear(), !0;
2199
2279
  }
2200
2280
  function gs(e, t) {
2201
- const n = new _n(), r = [];
2281
+ const n = new hn(), r = [];
2202
2282
  fe.set(n, r);
2203
- const s = t?.name ?? "host_command_apply", o = t?.ring, i = t?.recorder, c = i?.record, a = t?.schedules ?? [$.PRE_STARTUP, $.PRE_UPDATE];
2204
- if (i !== void 0 && a.includes($.FIXED_UPDATE))
2205
- throw new S(
2206
- w.INVALID_RECORDER_SCHEDULE,
2283
+ const s = t?.name ?? "host_command_apply", o = t?.ring, i = t?.recorder, a = i?.record, c = t?.schedules ?? [P.PRE_STARTUP, P.PRE_UPDATE];
2284
+ if (i !== void 0 && c.includes(P.FIXED_UPDATE))
2285
+ throw new w(
2286
+ S.INVALID_RECORDER_SCHEDULE,
2207
2287
  "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)."
2208
2288
  );
2209
- for (const l of a) {
2289
+ for (const l of c) {
2210
2290
  const d = !mn.has(l), f = e.registerSystem({
2211
2291
  name: `${s}:${l}`,
2212
2292
  // `reads`/`writes` are required by `SystemConfig` but empty here: the
@@ -2217,10 +2297,10 @@ function gs(e, t) {
2217
2297
  reads: [],
2218
2298
  writes: [],
2219
2299
  exclusive: !0,
2220
- fn: (_, g) => {
2221
- if (i !== void 0 && d && i.openTick(_.ecsTick, g), n.drain(_, c), o !== void 0) {
2222
- const y = e.columnStore, u = y.header.commandRingOff;
2223
- u !== 0 && o.drain(_, y.view, u, c);
2300
+ fn: (h, g) => {
2301
+ if (i !== void 0 && d && i.openTick(h.ecsTick, g), n.drain(h, a), o !== void 0) {
2302
+ const p = e.columnStore, u = p.header.commandRingOff;
2303
+ u !== 0 && o.drain(h, p.view, u, a);
2224
2304
  }
2225
2305
  }
2226
2306
  });
@@ -2231,25 +2311,25 @@ function gs(e, t) {
2231
2311
  export {
2232
2312
  ee as $,
2233
2313
  Kt as A,
2234
- $e as B,
2235
- $n as C,
2314
+ Pe as B,
2315
+ Pn as C,
2236
2316
  X as D,
2237
- S as E,
2317
+ w as E,
2238
2318
  es as F,
2239
2319
  en as G,
2240
- hs as H,
2320
+ _s as H,
2241
2321
  ts as I,
2242
2322
  Rn as J,
2243
2323
  qn as K,
2244
2324
  ze as L,
2245
- P as M,
2246
- wn as N,
2325
+ $ as M,
2326
+ Sn as N,
2247
2327
  ye as O,
2248
2328
  We as P,
2249
2329
  j as Q,
2250
2330
  Cn as R,
2251
2331
  m as S,
2252
- Hn as T,
2332
+ Gn as T,
2253
2333
  In as U,
2254
2334
  zn as V,
2255
2335
  Xn as W,
@@ -2260,7 +2340,7 @@ export {
2260
2340
  un as a,
2261
2341
  Qn as a0,
2262
2342
  ns as a1,
2263
- p as a2,
2343
+ y as a2,
2264
2344
  Zn as a3,
2265
2345
  ss as a4,
2266
2346
  Jn as a5,
@@ -2268,7 +2348,7 @@ export {
2268
2348
  J as a7,
2269
2349
  v as a8,
2270
2350
  kn as a9,
2271
- _n as aA,
2351
+ hn as aA,
2272
2352
  cs as aB,
2273
2353
  Ue as aC,
2274
2354
  An as aD,
@@ -2279,13 +2359,13 @@ export {
2279
2359
  Kn as ae,
2280
2360
  Jt as af,
2281
2361
  qe as ag,
2282
- Sn as ah,
2362
+ wn as ah,
2283
2363
  Ye as ai,
2284
2364
  Bn as aj,
2285
2365
  Mn as ak,
2286
2366
  jn as al,
2287
2367
  z as am,
2288
- Gn as an,
2368
+ Hn as an,
2289
2369
  Yn as ao,
2290
2370
  Vn as ap,
2291
2371
  is as aq,
@@ -2293,7 +2373,7 @@ export {
2293
2373
  bn as as,
2294
2374
  Nn as at,
2295
2375
  Dn as au,
2296
- $ as av,
2376
+ P as av,
2297
2377
  os as aw,
2298
2378
  gs as ax,
2299
2379
  ms as ay,
@@ -2304,23 +2384,23 @@ export {
2304
2384
  ls as e,
2305
2385
  us as f,
2306
2386
  fs as g,
2307
- _s as h,
2387
+ hs as h,
2308
2388
  Je as i,
2309
2389
  vn as j,
2310
2390
  Ln as k,
2311
- _e as l,
2391
+ he as l,
2312
2392
  Un as m,
2313
- Se as n,
2393
+ we as n,
2314
2394
  ft as o,
2315
2395
  lt as p,
2316
2396
  ut as q,
2317
2397
  as as r,
2318
- Pn as s,
2398
+ $n as s,
2319
2399
  Fn as t,
2320
2400
  Zt as u,
2321
2401
  yn as v,
2322
2402
  Tn as w,
2323
- w as x,
2403
+ S as x,
2324
2404
  B as y,
2325
2405
  k as z
2326
2406
  };