@oasys/oecs 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/README.md +196 -267
  2. package/dist/array-CxbPyiHO.cjs +1 -0
  3. package/dist/array-uFR7Q8fU.js +132 -0
  4. package/dist/core/ecs/access_check.d.ts +77 -0
  5. package/dist/core/ecs/access_check.d.ts.map +1 -0
  6. package/dist/core/ecs/archetype.d.ts +474 -0
  7. package/dist/core/ecs/archetype.d.ts.map +1 -0
  8. package/dist/core/ecs/builtin_relations.d.ts +43 -0
  9. package/dist/core/ecs/builtin_relations.d.ts.map +1 -0
  10. package/dist/core/ecs/command_log.d.ts +113 -0
  11. package/dist/core/ecs/command_log.d.ts.map +1 -0
  12. package/dist/core/ecs/component.d.ts +106 -0
  13. package/dist/core/ecs/component.d.ts.map +1 -0
  14. package/dist/core/ecs/compute_backend.d.ts +37 -0
  15. package/dist/core/ecs/compute_backend.d.ts.map +1 -0
  16. package/dist/core/ecs/dispatch_trace.d.ts +93 -0
  17. package/dist/core/ecs/dispatch_trace.d.ts.map +1 -0
  18. package/dist/core/ecs/ecs.d.ts +533 -0
  19. package/dist/core/ecs/ecs.d.ts.map +1 -0
  20. package/dist/core/ecs/ecs_memory.d.ts +179 -0
  21. package/dist/core/ecs/ecs_memory.d.ts.map +1 -0
  22. package/dist/core/ecs/entity.d.ts +28 -0
  23. package/dist/core/ecs/entity.d.ts.map +1 -0
  24. package/dist/core/ecs/event.d.ts +54 -0
  25. package/dist/core/ecs/event.d.ts.map +1 -0
  26. package/dist/core/ecs/frame_trace.d.ts +133 -0
  27. package/dist/core/ecs/frame_trace.d.ts.map +1 -0
  28. package/dist/core/ecs/host_commands.d.ts +252 -0
  29. package/dist/core/ecs/host_commands.d.ts.map +1 -0
  30. package/dist/core/ecs/index.d.ts +41 -0
  31. package/dist/core/ecs/index.d.ts.map +1 -0
  32. package/dist/core/ecs/observer.d.ts +142 -0
  33. package/dist/core/ecs/observer.d.ts.map +1 -0
  34. package/dist/core/ecs/query.d.ts +557 -0
  35. package/dist/core/ecs/query.d.ts.map +1 -0
  36. package/dist/core/ecs/ref.d.ts +31 -0
  37. package/dist/core/ecs/ref.d.ts.map +1 -0
  38. package/dist/core/ecs/relation.d.ts +231 -0
  39. package/dist/core/ecs/relation.d.ts.map +1 -0
  40. package/dist/core/ecs/resource.d.ts +33 -0
  41. package/dist/core/ecs/resource.d.ts.map +1 -0
  42. package/dist/core/ecs/resume.d.ts +85 -0
  43. package/dist/core/ecs/resume.d.ts.map +1 -0
  44. package/dist/core/ecs/run_condition.d.ts +75 -0
  45. package/dist/core/ecs/run_condition.d.ts.map +1 -0
  46. package/dist/core/ecs/schedule.d.ts +133 -0
  47. package/dist/core/ecs/schedule.d.ts.map +1 -0
  48. package/dist/core/ecs/sparse_store.d.ts +107 -0
  49. package/dist/core/ecs/sparse_store.d.ts.map +1 -0
  50. package/dist/core/ecs/store.d.ts +1149 -0
  51. package/dist/core/ecs/store.d.ts.map +1 -0
  52. package/dist/core/ecs/store_layout_listener.d.ts +23 -0
  53. package/dist/core/ecs/store_layout_listener.d.ts.map +1 -0
  54. package/dist/core/ecs/system.d.ts +134 -0
  55. package/dist/core/ecs/system.d.ts.map +1 -0
  56. package/dist/core/ecs/utils/arrays.d.ts +7 -0
  57. package/dist/core/ecs/utils/arrays.d.ts.map +1 -0
  58. package/dist/core/ecs/utils/constants.d.ts +12 -0
  59. package/dist/core/ecs/utils/constants.d.ts.map +1 -0
  60. package/dist/core/ecs/utils/error.d.ts +51 -0
  61. package/dist/core/ecs/utils/error.d.ts.map +1 -0
  62. package/dist/core/reactive/array.d.ts +24 -0
  63. package/dist/core/reactive/array.d.ts.map +1 -0
  64. package/dist/core/reactive/index.cjs +1 -0
  65. package/dist/core/reactive/index.d.ts +10 -0
  66. package/dist/core/reactive/index.d.ts.map +1 -0
  67. package/dist/core/reactive/index.js +17 -0
  68. package/dist/core/reactive/interop.d.ts +19 -0
  69. package/dist/core/reactive/interop.d.ts.map +1 -0
  70. package/dist/core/reactive/kernel.d.ts +71 -0
  71. package/dist/core/reactive/kernel.d.ts.map +1 -0
  72. package/dist/core/reactive/map.d.ts +16 -0
  73. package/dist/core/reactive/map.d.ts.map +1 -0
  74. package/dist/core/reactive/struct.d.ts +10 -0
  75. package/dist/core/reactive/struct.d.ts.map +1 -0
  76. package/dist/core/store/__generated__/abi.d.ts +43 -0
  77. package/dist/core/store/__generated__/abi.d.ts.map +1 -0
  78. package/dist/core/store/action_ring.d.ts +136 -0
  79. package/dist/core/store/action_ring.d.ts.map +1 -0
  80. package/dist/core/store/allocator.d.ts +238 -0
  81. package/dist/core/store/allocator.d.ts.map +1 -0
  82. package/dist/core/store/buffer_backed_column.d.ts +69 -0
  83. package/dist/core/store/buffer_backed_column.d.ts.map +1 -0
  84. package/dist/core/store/column_store.d.ts +265 -0
  85. package/dist/core/store/column_store.d.ts.map +1 -0
  86. package/dist/core/store/command_dispatch.d.ts +52 -0
  87. package/dist/core/store/command_dispatch.d.ts.map +1 -0
  88. package/dist/core/store/command_ring.d.ts +107 -0
  89. package/dist/core/store/command_ring.d.ts.map +1 -0
  90. package/dist/core/store/descriptor.d.ts +80 -0
  91. package/dist/core/store/descriptor.d.ts.map +1 -0
  92. package/dist/core/store/entity_index.d.ts +108 -0
  93. package/dist/core/store/entity_index.d.ts.map +1 -0
  94. package/dist/core/store/event_ring.d.ts +95 -0
  95. package/dist/core/store/event_ring.d.ts.map +1 -0
  96. package/dist/core/store/extend.d.ts +109 -0
  97. package/dist/core/store/extend.d.ts.map +1 -0
  98. package/dist/core/store/grow.d.ts +39 -0
  99. package/dist/core/store/grow.d.ts.map +1 -0
  100. package/dist/core/store/header.d.ts +64 -0
  101. package/dist/core/store/header.d.ts.map +1 -0
  102. package/dist/core/store/index.d.ts +16 -0
  103. package/dist/core/store/index.d.ts.map +1 -0
  104. package/dist/core/store/region_table.d.ts +74 -0
  105. package/dist/core/store/region_table.d.ts.map +1 -0
  106. package/dist/core/store/snapshot.d.ts +43 -0
  107. package/dist/core/store/snapshot.d.ts.map +1 -0
  108. package/dist/core/store/state_hash.d.ts +38 -0
  109. package/dist/core/store/state_hash.d.ts.map +1 -0
  110. package/dist/core/store/store_regions.d.ts +38 -0
  111. package/dist/core/store/store_regions.d.ts.map +1 -0
  112. package/dist/extensions/editor/editor.d.ts +149 -0
  113. package/dist/extensions/editor/editor.d.ts.map +1 -0
  114. package/dist/extensions/editor/field_handle.d.ts +35 -0
  115. package/dist/extensions/editor/field_handle.d.ts.map +1 -0
  116. package/dist/extensions/editor/index.cjs +1 -0
  117. package/dist/extensions/editor/index.d.ts +21 -0
  118. package/dist/extensions/editor/index.d.ts.map +1 -0
  119. package/dist/extensions/editor/index.js +209 -0
  120. package/dist/extensions/reactive/ecs_sync.d.ts +210 -0
  121. package/dist/extensions/reactive/ecs_sync.d.ts.map +1 -0
  122. package/dist/extensions/reactive/index.cjs +1 -0
  123. package/dist/extensions/reactive/index.d.ts +23 -0
  124. package/dist/extensions/reactive/index.d.ts.map +1 -0
  125. package/dist/extensions/reactive/index.js +225 -0
  126. package/dist/extensions/solid/index.cjs +1 -0
  127. package/dist/extensions/solid/index.d.ts +6 -0
  128. package/dist/extensions/solid/index.d.ts.map +1 -0
  129. package/dist/extensions/solid/index.js +32 -0
  130. package/dist/extensions/solid/kernel_solid.d.ts +42 -0
  131. package/dist/extensions/solid/kernel_solid.d.ts.map +1 -0
  132. package/dist/index.cjs +2 -1
  133. package/dist/index.d.ts +16 -12
  134. package/dist/index.d.ts.map +1 -1
  135. package/dist/index.js +8565 -1310
  136. package/dist/interop-CT-REx0W.cjs +1 -0
  137. package/dist/interop-CcY6ASQc.js +18 -0
  138. package/dist/kernel-DgyrLFjW.js +227 -0
  139. package/dist/kernel-yWV3XnAb.cjs +1 -0
  140. package/dist/log/console_sink.d.ts +4 -0
  141. package/dist/log/console_sink.d.ts.map +1 -0
  142. package/dist/log/index.d.ts +3 -0
  143. package/dist/log/index.d.ts.map +1 -0
  144. package/dist/log/logger.d.ts +27 -0
  145. package/dist/log/logger.d.ts.map +1 -0
  146. package/dist/primitives.cjs +1 -0
  147. package/dist/primitives.d.ts +18 -0
  148. package/dist/primitives.d.ts.map +1 -0
  149. package/dist/primitives.js +44 -0
  150. package/dist/shared-BXSZnxx4.cjs +1 -0
  151. package/dist/shared-C678TAPY.js +99 -0
  152. package/dist/shared.cjs +1 -0
  153. package/dist/shared.d.ts +22 -0
  154. package/dist/shared.d.ts.map +1 -0
  155. package/dist/shared.js +7 -0
  156. package/dist/topological_sort-DlRpSrxu.js +391 -0
  157. package/dist/topological_sort-WAT-VHb-.cjs +1 -0
  158. package/dist/type_primitives/assertions.d.ts +12 -8
  159. package/dist/type_primitives/assertions.d.ts.map +1 -1
  160. package/dist/type_primitives/binary_heap/binary_heap.d.ts +6 -2
  161. package/dist/type_primitives/binary_heap/binary_heap.d.ts.map +1 -1
  162. package/dist/type_primitives/bitset/bitset.d.ts +16 -4
  163. package/dist/type_primitives/bitset/bitset.d.ts.map +1 -1
  164. package/dist/type_primitives/brand.d.ts +6 -1
  165. package/dist/type_primitives/brand.d.ts.map +1 -1
  166. package/dist/type_primitives/error.d.ts +4 -0
  167. package/dist/type_primitives/error.d.ts.map +1 -1
  168. package/dist/type_primitives/index.d.ts +3 -0
  169. package/dist/type_primitives/index.d.ts.map +1 -1
  170. package/dist/type_primitives/sparse_map/sparse_map.d.ts +7 -3
  171. package/dist/type_primitives/sparse_map/sparse_map.d.ts.map +1 -1
  172. package/dist/type_primitives/sparse_set/sparse_set.d.ts +4 -0
  173. package/dist/type_primitives/sparse_set/sparse_set.d.ts.map +1 -1
  174. package/dist/type_primitives/topological_sort/topological_sort.d.ts +7 -3
  175. package/dist/type_primitives/topological_sort/topological_sort.d.ts.map +1 -1
  176. package/dist/type_primitives/typed_arrays/typed_arrays.d.ts +53 -16
  177. package/dist/type_primitives/typed_arrays/typed_arrays.d.ts.map +1 -1
  178. package/dist/utils/arrays.d.ts +1 -1
  179. package/dist/utils/arrays.d.ts.map +1 -1
  180. package/dist/utils/error.d.ts +2 -20
  181. package/dist/utils/error.d.ts.map +1 -1
  182. package/package.json +36 -9
  183. package/dist/archetype.d.ts +0 -108
  184. package/dist/archetype.d.ts.map +0 -1
  185. package/dist/component.d.ts +0 -45
  186. package/dist/component.d.ts.map +0 -1
  187. package/dist/ecs.d.ts +0 -104
  188. package/dist/ecs.d.ts.map +0 -1
  189. package/dist/entity.d.ts +0 -11
  190. package/dist/entity.d.ts.map +0 -1
  191. package/dist/event.d.ts +0 -30
  192. package/dist/event.d.ts.map +0 -1
  193. package/dist/query.d.ts +0 -94
  194. package/dist/query.d.ts.map +0 -1
  195. package/dist/ref.d.ts +0 -23
  196. package/dist/ref.d.ts.map +0 -1
  197. package/dist/resource.d.ts +0 -23
  198. package/dist/resource.d.ts.map +0 -1
  199. package/dist/schedule.d.ts +0 -45
  200. package/dist/schedule.d.ts.map +0 -1
  201. package/dist/store.d.ts +0 -118
  202. package/dist/store.d.ts.map +0 -1
  203. package/dist/system.d.ts +0 -16
  204. package/dist/system.d.ts.map +0 -1
@@ -0,0 +1,557 @@
1
+ import { Store } from './store';
2
+ import { FrameTraceSink } from './frame_trace';
3
+ import { Archetype, ArchetypeView } from './archetype';
4
+ import { EntityID } from './entity';
5
+ import { ComponentDef, ComponentID, ComponentSchema, FieldValues, MutableColumnsForSchema, ColumnsForSchema, BundleOrDef } from './component';
6
+ import { SparseComponentDef, SparseComponentID } from './sparse_store';
7
+ import { RelationDef } from './relation';
8
+ import { ComponentRef, ReadonlyComponentRef } from './ref';
9
+ import { EventKey, EventReader, EventSchema, SignalKey } from './event';
10
+ import { ResourceKey } from './resource';
11
+ import { BitSet } from '../../type_primitives';
12
+ export interface QueryCacheEntry {
13
+ includeMask: BitSet;
14
+ excludeMask: BitSet | null;
15
+ anyOfMask: BitSet | null;
16
+ query: Query<any>;
17
+ }
18
+ export interface QueryResolver {
19
+ _resolveQuery(include: BitSet, exclude: BitSet | null, anyOf: BitSet | null, defs: readonly ComponentDef[]): Query<any>;
20
+ _getLastRunTick(): number;
21
+ /** Current ECS write tick — the tick `eachChunk` stamps via `cols.mut` (§eachChunk). */
22
+ _getCurrentTick(): number;
23
+ _getQueryDirtyEpoch(): number;
24
+ _nextQueryId(): number;
25
+ _andSingleCache: Map<number, Query<any>>;
26
+ _notSingleCache: Map<number, Query<any>>;
27
+ _anyOfSingleCache: Map<number, Query<any>>;
28
+ _changedSingleCache: Map<number, ChangedQuery<any>>;
29
+ _optionalSingleCache: Map<number, Query<any>>;
30
+ _withSparseSingleCache: Map<number, Query<any>>;
31
+ _withoutSparseSingleCache: Map<number, Query<any>>;
32
+ _withRelationSingleCache: Map<number, Query<any>>;
33
+ _withoutRelationSingleCache: Map<number, Query<any>>;
34
+ _includeDisabledSingleCache: Map<number, Query<any>>;
35
+ _hierarchySingleCache: Map<number, Query<any>>;
36
+ /** Second query-match path (#469 / ADR-0011): drive iteration by sparse
37
+ * membership rather than the archetype mask, yielding entities — sparse
38
+ * members are scattered across archetypes, so there is no archetype-column
39
+ * span to hand back. With a sparse require term, drive from the smallest
40
+ * required store and filter; with only sparse excludes, drive the dense
41
+ * archetype list and skip excluded rows; with neither, walk dense entities.
42
+ * Only entered via `Query.forEachEntity`, so dense `forEach` never pays.
43
+ * `includeDisabled` widens the per-archetype row scan from enabled rows to
44
+ * all rows (#577). */
45
+ _forEachSparseMatch(include: BitSet, exclude: BitSet | null, anyOf: BitSet | null, sparseInclude: readonly SparseComponentID[], sparseExclude: readonly SparseComponentID[], denseArchetypes: readonly Archetype[], cb: (entityId: EntityID) => void, includeDisabled: boolean): void;
46
+ /** Backing sparse id of a relation — resolves a `(R, *)` wildcard term
47
+ * (`withRelation`, #579) to the membership store the sparse-match path
48
+ * already drives. */
49
+ _relationBackingSparseId(def: RelationDef): SparseComponentID;
50
+ /** Third query-match path (#579): `(*, T)` — drive iteration from the union of
51
+ * every relation's `sourcesOf(target)` (dedup + canonical sort), intersected
52
+ * with the dense mask + sparse terms + the enabled-row filter. Only entered via
53
+ * `Query.forEachRelatedTo`. */
54
+ _forEachRelationTargetMatch(target: EntityID, include: BitSet, exclude: BitSet | null, anyOf: BitSet | null, sparseInclude: readonly SparseComponentID[], sparseExclude: readonly SparseComponentID[], includeDisabled: boolean, cb: (entityId: EntityID) => void): void;
55
+ /** Fourth query-match path (#581): yield the matched entities (dense mask +
56
+ * sparse terms + enabled-row filter, exactly the `_forEachSparseMatch`
57
+ * intersection) in canonical **hierarchy depth order** over exclusive relation
58
+ * `relation` — depth ascending (parents before children), entity index
59
+ * ascending within a depth band. Entities deeper than `maxDepth` are skipped
60
+ * (`HIERARCHY_UNBOUNDED` = no limit). Only entered via `Query.forEachEntity`
61
+ * on a query carrying a `.hierarchy(R)` term. */
62
+ _forEachHierarchyMatch(include: BitSet, exclude: BitSet | null, anyOf: BitSet | null, sparseInclude: readonly SparseComponentID[], sparseExclude: readonly SparseComponentID[], denseArchetypes: readonly Archetype[], relation: RelationDef, maxDepth: number, includeDisabled: boolean, cb: (entityId: EntityID) => void): void;
63
+ }
64
+ /** No depth limit on a `.hierarchy(R)` term (#581) — yield every matched entity
65
+ * regardless of its depth in the tree. The default `maxDepth`. */
66
+ export declare const HIERARCHY_UNBOUNDED: number;
67
+ /** A `.hierarchy(R)` depth-ordering term (#581). Records the exclusive relation
68
+ * whose tree defines the order and the (optional) max depth to yield. Stored on
69
+ * the Query and consumed by the `forEachEntity` hierarchy match path; absent
70
+ * (`null`) for the common case. */
71
+ export interface HierarchyTerm {
72
+ /** The exclusive relation whose chain/tree defines the depth ordering. */
73
+ readonly relation: RelationDef;
74
+ /** Inclusive max depth to yield (root = 0); entities deeper than this are
75
+ * skipped. `HIERARCHY_UNBOUNDED` for no limit (bitECS `Hierarchy()` depth arg). */
76
+ readonly maxDepth: number;
77
+ }
78
+ /**
79
+ * eachChunk cursor (§eachChunk). One instance is allocated per `eachChunk`
80
+ * pass and reused across every matched archetype in that pass — only `_arch`/
81
+ * `_tick` are re-pointed per archetype, so the inner loop allocates nothing.
82
+ * Per-call (not cached on the query) so a nested `eachChunk` on the same query
83
+ * gets its own cursor and can't re-point an outer pass's position. `.mut(def)` /
84
+ * `.read(def)` resolve a whole component's columns at once into a field-keyed
85
+ * object (a per-archetype-per-component cache refreshed in place), hiding the
86
+ * change tick. Destructure the group immediately; don't retain it across calls.
87
+ */
88
+ export declare class ChunkColumns {
89
+ /** @internal */ _arch: Archetype;
90
+ /** @internal */ _tick: number;
91
+ /** Mutable column group — `const { x, y } = cols.mut(Pos)`. Stamps the tick. */
92
+ mut<S extends ComponentSchema>(def: ComponentDef<S>): MutableColumnsForSchema<S>;
93
+ /** Read-only column group — `const { vx, vy } = cols.read(Vel)`. No tick bump. */
94
+ read<S extends ComponentSchema>(def: ComponentDef<S>): ColumnsForSchema<S>;
95
+ }
96
+ export declare class Query<Defs extends readonly ComponentDef[]> {
97
+ private readonly _archetypes;
98
+ readonly _defs: Defs;
99
+ private readonly _resolver;
100
+ readonly _include: BitSet;
101
+ private readonly _exclude;
102
+ private readonly _anyOf;
103
+ private _nonEmptyArchetypes;
104
+ private _lastSeenEpoch;
105
+ readonly _id: number;
106
+ readonly _sparseInclude: readonly SparseComponentID[];
107
+ readonly _sparseExclude: readonly SparseComponentID[];
108
+ readonly _optional: readonly ComponentID[];
109
+ readonly _includeDisabled: boolean;
110
+ readonly _relationIncludes: readonly RelationDef[];
111
+ readonly _relationExcludes: readonly RelationDef[];
112
+ readonly _hierarchy: HierarchyTerm | null;
113
+ constructor(archetypes: Archetype[], defs: Defs, resolver: QueryResolver, include: BitSet, exclude: BitSet | null, anyOf: BitSet | null, id: number, sparseInclude?: readonly SparseComponentID[], sparseExclude?: readonly SparseComponentID[], optional?: readonly ComponentID[], includeDisabled?: boolean, relationIncludes?: readonly RelationDef[], relationExcludes?: readonly RelationDef[], hierarchy?: HierarchyTerm | null);
114
+ /** Guard the dense-only methods (`count` / `forEach` / `archetype_count`)
115
+ * against a query carrying sparse terms. These walk the dense archetype
116
+ * list and never consult `_sparseInclude` / `_sparseExclude`, so on a
117
+ * sparse-derived query they'd **fail open** — returning the unfiltered dense
118
+ * result instead of the sparse-filtered one. Throw in `__DEV__` (compiled
119
+ * out of prod) steering the caller to `forEachEntity`, the only path that
120
+ * honors sparse membership (#469). Mirrors `ChangedQuery`'s dev-guard on its
121
+ * include-mask invariant. */
122
+ private _assertDenseOnly;
123
+ /** Number of matching archetypes (including empty ones). */
124
+ get archetypeCount(): number;
125
+ /** Total entity count across all matching archetypes — enabled rows only by
126
+ * default, or all rows when `includeDisabled()` (#577). Reads the partition
127
+ * fields directly (not the flag-dependent `entityCount` getter). */
128
+ count(): number;
129
+ get archetypes(): readonly ArchetypeView[];
130
+ /** Carry this query's non-dense terms — optional fetch-if-present (#575) and
131
+ * sparse membership (#469) — onto a freshly composed dense query. `and` /
132
+ * `not` / `anyOf` build the new dense mask via `_resolveQuery`, which is
133
+ * keyed on the mask alone and so hands back a query carrying NONE of these
134
+ * terms; before #592 that silently dropped them, making composition
135
+ * order-dependent (`q.optional(V).and(H)` lost `V`; `q.and(H).optional(V)`
136
+ * kept it). When this query carries no non-dense terms (the common case)
137
+ * `base` is already correct and returned as-is, preserving the mask-cached
138
+ * singleton with zero allocation. Otherwise re-derive on top of `base`'s dense
139
+ * state, threading the terms forward so composition is symmetric regardless of
140
+ * order. Reading `base`'s private fields is allowed — same-class instance. */
141
+ private _carryNondense;
142
+ /** Extend required component set. Returns a new (cached) Query. */
143
+ and<D extends ComponentDef[]>(...comps: D): Query<[...Defs, ...D]>;
144
+ /** @internal — cold cache-miss path for single-arg `and`, split out (#649) so
145
+ * the hot `and` body is just key-compute + cache hit. The miss path runs once
146
+ * per unique composition, then every repeat is a cache hit; keeping it out of
147
+ * line shrinks `and`'s inlined footprint when several composes share one hot
148
+ * function (the `query_compose` shape). Same rationale for `_notMiss` /
149
+ * `_anyOfMiss` / `_changedMiss`. */
150
+ private _andMiss;
151
+ /** Exclude archetypes that have any of these components. */
152
+ without(...comps: ComponentDef[]): Query<Defs>;
153
+ /** @internal — cold cache-miss path for single-arg `not` (#649); see `_andMiss`. */
154
+ private _notMiss;
155
+ /** Require a sparse component (#469): match only entities that hold it,
156
+ * across every archetype. A sparse term doesn't touch the dense mask, so
157
+ * the returned (cached) query reuses this one's live archetype list; it is
158
+ * iterated via `forEachEntity`, never `forEach` (sparse members are
159
+ * scattered within archetypes, so there is no SoA column span to yield). */
160
+ withSparse(...defs: SparseComponentDef[]): Query<Defs>;
161
+ /** One-id `withSparse` composition, cached on `(parent_id, sparseId)` in
162
+ * the resolver's shared single-term map. Both the single- and multi-arg public
163
+ * forms fold over this, so all sparse-require composition is deduplicated. */
164
+ private _withSparseOne;
165
+ /** Exclude a sparse component (#469): drop entities that hold it. Same
166
+ * dense-list reuse and `forEachEntity` iteration as `withSparse`. */
167
+ withoutSparse(...defs: SparseComponentDef[]): Query<Defs>;
168
+ /** One-id `withoutSparse` composition, cached on `(parent_id, sparseId)`. The
169
+ * multi-arg form folds over this (#497) — mirrors `_withSparseOne`. */
170
+ private _withoutSparseOne;
171
+ /** Build a derived query carrying new sparse terms. Reuses this query's
172
+ * dense state by reference — the masks are never mutated in place (`and` /
173
+ * `not` / `anyOf` copy before mutating), and `_archetypes` is the same
174
+ * live array the store appends to, so the derived query stays live too.
175
+ * Carries the existing `_optional` terms through unchanged (the two axes
176
+ * compose). */
177
+ private _deriveSparse;
178
+ /** Require the `(R, *)` wildcard (#579): match only sources that hold **any**
179
+ * target under relation `R`. "Has any `(R, *)` pair" is exactly membership in
180
+ * R's backing sparse store (exclusive `{target}` row / multi tag), so this is a
181
+ * relation-typed front door over `withSparse` — it pushes R's backing sparse
182
+ * id onto `_sparseInclude` and reuses the `forEachEntity` sparse-match path
183
+ * (insertion order; canonical sorting is reserved for `stateHash`/snapshot, and
184
+ * costs 4–5× here for no determinism benefit — see the §579 bench report).
185
+ * Membership semantics: each source once; fetch its targets with
186
+ * `ctx.targetsOf(e, R)`. Requires `relationReads: [R]` (checked at iteration).
187
+ * Cached per `(parent_id, relation_id)` like the sparse terms (#497). */
188
+ withRelation(...defs: RelationDef[]): Query<Defs>;
189
+ private _withRelationOne;
190
+ /** Exclude the `(R, *)` wildcard (#579): drop sources that hold any target
191
+ * under `R`. Mirror of `withRelation` on the exclude side (pushes R's
192
+ * backing sparse id onto `_sparseExclude`). */
193
+ withoutRelation(...defs: RelationDef[]): Query<Defs>;
194
+ private _withoutRelationOne;
195
+ /** Build a derived query carrying new relation-wildcard terms. Threads the
196
+ * backing-sparse ids (which the driver actually consumes) plus the relation
197
+ * ids (which only the `__DEV__` access check consumes), reusing the dense /
198
+ * optional / disabled state by reference — same rationale as `_deriveSparse`. */
199
+ private _deriveRelation;
200
+ /** Order this query's matched entities in **hierarchy depth order** over the
201
+ * exclusive relation `R` — parents before children — and (optionally) drop any
202
+ * deeper than `maxDepth` (#581; flecs `cascade` / bitECS `Hierarchy()`). The
203
+ * matched *set* is unchanged (still the dense mask + sparse + `(R, *)` + disabled
204
+ * terms); `.hierarchy(R)` only **reorders** + depth-limits it, so an entity with
205
+ * no `R`-parent is a root at depth 0 and still yielded (first). The canonical
206
+ * order is depth ascending, then **entity index ascending within each depth
207
+ * band** — a total, insertion-order-independent order (identical across lockstep
208
+ * peers), produced by an O(K) radix on the entity index, never a comparator sort.
209
+ *
210
+ * Iterate with `forEachEntity`: members scatter across archetypes, so there is
211
+ * no SoA column span — `forEach` / `count` reject a hierarchy query (like a
212
+ * sparse term). **Exclusive relations only** (matches the traversal constraint
213
+ * #474); a multi relation throws `RELATION_MODE_MISMATCH` at iteration, and a
214
+ * cycle is a loud `RELATION_CYCLE` in `__DEV__` (a safe break in production).
215
+ * Requires `relationReads: [R]` (checked at iteration). Carried through
216
+ * `and`/`not`/`anyOf` like the sparse terms (`_carryNondense`).
217
+ *
218
+ * `Defs` is unchanged — `R` is an ordering, not a required component (like
219
+ * `not` / `anyOf`). Returns a new query; the unbounded form is cached. */
220
+ hierarchy(relation: RelationDef, maxDepth?: number): Query<Defs>;
221
+ /** Build a derived query carrying a hierarchy ordering term. Reuses this
222
+ * query's dense / sparse / optional / disabled / relation-wildcard state by
223
+ * reference (the matched set is unchanged) — same rationale as `_deriveSparse`. */
224
+ private _deriveHierarchy;
225
+ /** Assert every `(R, *)` wildcard term on this query was declared in the
226
+ * system's `relationReads` (#579 / #496). Iteration-time (`forEachEntity` /
227
+ * `forEachRelatedTo`), not construction-time, so it is robust to queries
228
+ * built outside a system — same rationale as the data-op checks. `__DEV__` only;
229
+ * outside a system `checkRelationRead` is a no-op. */
230
+ private _checkRelationAccess;
231
+ /** Iterate every source related to `target` under **any** relation — the
232
+ * `(*, T)` wildcard (#579) — intersected with this query's dense + sparse +
233
+ * `(R, *)` + disabled predicate, each source yielded once in ascending-EntityID
234
+ * order (the `sourcesOf` / `sourcesOfAny` convention). `target` is supplied
235
+ * here rather than as a chained term because it is a runtime `EntityID`: baking
236
+ * it into a cached `Query` would key the cache on a recycled value and churn
237
+ * query-ids, and `(*, T)` is the rare/cold shape. Composes with
238
+ * `withRelation` / `withSparse` / dense terms on the receiver. Reads
239
+ * every relation's reverse index, so the system must declare
240
+ * `relationReads: [ANY_RELATION]` (plus `[R]` for any composed `withRelation`).
241
+ * Cold/structural — not a per-tick hot loop over many targets. */
242
+ forEachRelatedTo(target: EntityID, cb: (entityId: EntityID) => void): void;
243
+ /** Add optional fetch-if-present terms (#575). Does NOT narrow the matched
244
+ * set — the dense mask is untouched, so iteration still spans archetypes with
245
+ * and without each `T`. Read each column per archetype span via
246
+ * `arch.getOptionalColumnRead(T, field)` (column when present, `undefined`
247
+ * when absent). `.optional(T)` is the *declaration* that authorizes that fetch:
248
+ * inside `forEach`, `getOptionalColumnRead` throws in `__DEV__` if `T` was
249
+ * not declared here (#592) — the read-side analog of `reads:[T]`, which is also
250
+ * still required for access coverage (both checks fire, even on the absent
251
+ * span). The term is carried through `and`/`not`/`anyOf` (see
252
+ * `_carryNondense`), so it survives composition in any order. Returns a new
253
+ * (cached) Query.
254
+ *
255
+ * `Defs` is unchanged (the optional `T` is not a required component, like
256
+ * `not` / `anyOf`); column types come from the accessor's own generics. */
257
+ optional(...defs: ComponentDef[]): Query<Defs>;
258
+ /** One-id `optional` composition, cached on `(parent_id << 16) | cid` in the
259
+ * resolver's shared single-term map (dense cid <= 128, same packing as the
260
+ * `and` / `not` / `anyOf` caches). */
261
+ private _optionalOne;
262
+ /** Build a derived query carrying new optional terms. Reuses this query's
263
+ * dense state by reference (the matched set is unchanged) and carries the
264
+ * existing sparse terms through unchanged — same rationale as `_deriveSparse`. */
265
+ private _deriveOptional;
266
+ /** Opt this query back in to disabled entities (#577). By default a query
267
+ * excludes disabled entities (the iteration bound `arch.entityCount` is the
268
+ * enabled-row count). The returned (cached) query spans disabled rows too:
269
+ * `forEach` publishes the all-rows flag so the SoA loop's `arch.entityCount`
270
+ * reports `length`, and `count`/`forEachEntity` widen accordingly. Does NOT
271
+ * touch the dense mask, so it reuses this query's live archetype list and is
272
+ * carried through `and`/`not`/`anyOf` like the sparse/optional terms. */
273
+ includeDisabled(): Query<Defs>;
274
+ forEach(cb: (arch: ArchetypeView) => void): void;
275
+ /** @internal — cold `includeDisabled` wrapper for `forEach` (#577), split out
276
+ * (#649) so the all-rows flag dance (`_setIterAllRows` + try/finally) stays
277
+ * out of `forEach`'s inlined hot body. The default (enabled-only) query never
278
+ * reaches here, so V8 leaves this uninlined and `forEach` shrinks accordingly. */
279
+ private _forEachIncludeDisabled;
280
+ /**
281
+ * Per-archetype destructured column iteration (§eachChunk) — the flecs
282
+ * `run()` / koota `useStores` model, and the recommended hot-path default for
283
+ * mutating systems:
284
+ *
285
+ * q.eachChunk((cols, count) => {
286
+ * const { x, y } = cols.mut(Pos); // whole group, tick stamped inside
287
+ * const { vx, vy } = cols.read(Vel); // read-only group
288
+ * for (let i = 0; i < count; i++) { x[i] += vx[i] * dt; y[i] += vy[i] * dt; }
289
+ * });
290
+ *
291
+ * vs the raw path it replaces (per-field `getColumn` + manual `ecsTick`
292
+ * thread + `entityCount` loop). It folds away: per-field fetches (one call
293
+ * per component), the `getColumn`/`getColumnRead` choice (→ `.mut`/`.read`),
294
+ * the manual tick arg (hidden in `.mut`), and the `.length`-vs-`entityCount`
295
+ * corruption trap (`count` is `entityCount`). It is also the only mutable
296
+ * column accessor reachable through the iteration path — the read-only
297
+ * `ArchetypeView` from `forEach` deliberately omits the mutable `getColumn`.
298
+ * The SoA inner loop is byte-identical, and the per-archetype group objects
299
+ * are cached (zero per-archetype allocation). One `ChunkColumns` cursor is
300
+ * allocated per pass and reused across that pass's archetypes. Honours
301
+ * `includeDisabled()` exactly like `forEach` (the bound widens to the
302
+ * disabled tail); dense-only like `forEach` (sparse/relation/hierarchy terms
303
+ * throw in `__DEV__` — iterate those with `forEachEntity`).
304
+ */
305
+ eachChunk(cb: (cols: ChunkColumns, count: number) => void): void;
306
+ /** @internal — shared body for `eachChunk`'s default and `includeDisabled`
307
+ * paths. The `ChunkColumns` cursor is allocated per call (a 2-field object whose
308
+ * cost doesn't scale with the per-row work) rather than cached on the query, so
309
+ * a nested `eachChunk` on the SAME query gets its own cursor instead of
310
+ * re-pointing the outer pass's `_arch`/`_tick`. The per-(archetype, component)
311
+ * column-group caches that actually matter for allocation live on the
312
+ * `Archetype`, untouched. */
313
+ private _eachChunkInner;
314
+ /**
315
+ * Early-exit iteration: like `forEach`, but stops as soon as `cb` returns
316
+ * `true`, and returns whether any callback did. The predicate analog for
317
+ * "does any matching row satisfy X?" — without it, callers hand-rolled a
318
+ * `query.archetypes` walk (re-implementing the empty-archetype skip) just
319
+ * to be able to `return` mid-scan. Deliberately a separate method:
320
+ * honouring return values on `forEach`'s existing `=> void` callback
321
+ * would silently change behaviour for arrow-expression bodies that happen
322
+ * to return a truthy value.
323
+ */
324
+ forEachUntil(cb: (arch: ArchetypeView) => boolean): boolean;
325
+ /** @internal — shared body for `forEachUntil`'s default and
326
+ * `includeDisabled` paths. Same dev-mode optional-term scope as
327
+ * `forEach` (#592). */
328
+ private _forEachUntilInner;
329
+ /** @internal — the `includeDisabled` delegate for `forEach` (#577). The
330
+ * default (enabled-only) path inlines this body directly into `forEach`
331
+ * (#608) to dodge a megamorphic delegate hop; this copy survives only for the
332
+ * rare all-rows path, which needs the `_setIterAllRows` try/finally wrap. */
333
+ private _forEachInner;
334
+ /** Iterate the entities this query matches, yielding each `EntityID`
335
+ * (#469 — the sparse-membership match path). Use this whenever the query
336
+ * carries a `withSparse` / `withoutSparse` term: members are scattered
337
+ * across archetypes, so there is no SoA column span to hand back — read
338
+ * fields via `ctx.getField` (dense) or `ctx.getSparseField` (sparse) on
339
+ * the yielded entity. A dense-only query also works here (it walks its
340
+ * archetypes' entity ids), but prefer `forEach` for the SoA hot loop.
341
+ *
342
+ * Iteration is read-mostly: mutating the *driving* sparse component's
343
+ * membership mid-iteration is unsafe. The walk drives off the store's live
344
+ * key array, so **adding** the driving component (the store `push`es a new
345
+ * key, which the `i < length` loop then visits) and **removing** it (the
346
+ * store swap-pops, shifting the index list under the walk) both corrupt the
347
+ * traversal. This is sharper than for dense `forEach`: `ctx.addSparse` /
348
+ * `ctx.addRelation` apply *immediately* (no archetype transition to defer),
349
+ * so unlike a deferred dense `addComponent` the mutation lands in the live
350
+ * array at once. Buffer such edits and apply them after the walk. */
351
+ forEachEntity(cb: (entityId: EntityID) => void): void;
352
+ /** @internal — used by ChangedQuery. Rebuild non-empty archetype list if the
353
+ * Store has bumped its dirty epoch since our last rebuild, return cached result.
354
+ *
355
+ * Rebuild allocates a *fresh* array and swaps it in rather than truncating
356
+ * the cached one in place (#431). `forEach`/`count`/`ChangedQuery.forEach`
357
+ * bind the returned array once and walk it; an in-place `dst.length = 0` +
358
+ * re-push would corrupt that walk if the query is re-entrantly iterated —
359
+ * i.e. the callback runs an immediate-mode mutation that crosses a
360
+ * 0↔non-zero entity boundary on the *same* Query (bumping the epoch) and
361
+ * then re-enters here via a nested `forEach`/`count`. Building fresh hands
362
+ * the inner call its own array and leaves the outer iterator's snapshot
363
+ * intact, so each archetype is visited exactly once. Cost is one array
364
+ * allocation per epoch advance (rare — only on boundary crossings); the
365
+ * steady-state path returns the cached array with zero allocation. In-system
366
+ * iteration never triggers a rebuild mid-loop: deferred mutations settle the
367
+ * epoch during `flushStructural`, between systems. */
368
+ _nonEmpty(): Archetype[];
369
+ /** @internal — cold rebuild path for `_nonEmpty`, split out (#649) so the
370
+ * hot `_nonEmpty` body is just an epoch check + cached return. Keeping the
371
+ * filter loops here shrinks `_nonEmpty`'s inlined bytecode footprint, which
372
+ * matters when several composed queries iterate inside one hot function (the
373
+ * `query_compose` shape): the leaner `_nonEmpty` keeps `forEach` under V8's
374
+ * per-function cumulative inlining budget. */
375
+ private _rebuildNonEmpty;
376
+ /** Require at least one of these components. */
377
+ anyOf(...comps: ComponentDef[]): Query<Defs>;
378
+ /** @internal — cold cache-miss path for single-arg `anyOf` (#649); see `_andMiss`. */
379
+ private _anyOfMiss;
380
+ /** Create a ChangedQuery that filters archetypes by change tick.
381
+ *
382
+ * Granularity is **archetype**, not row: the `_changedTick[cid]` is
383
+ * bumped per archetype on any write into that component's column
384
+ * (`Archetype._changedTick` in archetype.ts). A 1-row write in a
385
+ * 1000-row archetype trips `forEach` on the whole archetype next tick.
386
+ * Use cases that need row-level granularity should compare per-row
387
+ * state explicitly inside the callback.
388
+ *
389
+ * The returned ChangedQuery is composable (M6): `and`/`without`/`anyOf`/
390
+ * `optional` refine it further, so `q.changed(Pos).without(Dead)` works — and
391
+ * is the same set as `q.without(Dead).changed(Pos)`. */
392
+ changed(...defs: ComponentDef[]): ChangedQuery<Defs>;
393
+ /** @internal — cold cache-miss path for single-arg `changed` (#649); see `_andMiss`. */
394
+ private _changedMiss;
395
+ /** @internal — reads lastRunTick from the resolver (ECS). */
396
+ _ctxLastRunTick(): number;
397
+ }
398
+ export declare class QueryBuilder {
399
+ private readonly _resolver;
400
+ constructor(_resolver: QueryResolver);
401
+ with<T extends ComponentDef[]>(...defs: T): Query<T>;
402
+ }
403
+ /**
404
+ * Deferred structural-command facade (§ctx.commands — Bevy `Commands`).
405
+ * Namespaces the deferred structural ops so the call site is self-documenting:
406
+ * `ctx.commands.add(e, …)` is *always* deferred (applied at the phase flush),
407
+ * ending the collision where `ecs.addComponent` (immediate) and the bare
408
+ * `ctx.addComponent` (deferred) share a name with opposite timing. Takes
409
+ * varargs callable bundles, so one shape — `commands.spawn(bundle(Pos,{x,y}), bundle(Vel,{vx:1}))`
410
+ * — serves spawn and add. The legacy `ctx.addComponent`/etc. stay for now;
411
+ * the intent is for `ctx.commands.*` to become the only deferred surface.
412
+ */
413
+ export declare class Commands {
414
+ private readonly store;
415
+ constructor(store: Store);
416
+ /** Spawn from bundles. Create is immediate (the id is returned now); the
417
+ * component attaches are deferred to the phase flush — so until that flush the
418
+ * entity exists in its empty/partial archetype and a query running later in
419
+ * the same phase can observe it half-built. (Same semantics as
420
+ * `ctx.createEntity` + `ctx.addComponent`; fully-deferred id-reservation
421
+ * spawn, à la Bevy, is a separate follow-up.) */
422
+ spawn(...items: BundleOrDef[]): EntityID;
423
+ /** Attach bundles to an existing entity (deferred). */
424
+ add(entityId: EntityID, ...items: BundleOrDef[]): this;
425
+ /** Remove a component (deferred). */
426
+ remove(entityId: EntityID, def: ComponentDef): this;
427
+ /** Destroy an entity (deferred). */
428
+ despawn(entityId: EntityID): this;
429
+ /** Disable an entity (deferred). */
430
+ disable(entityId: EntityID): this;
431
+ /** Re-enable an entity (deferred). */
432
+ enable(entityId: EntityID): this;
433
+ }
434
+ export declare class SystemContext {
435
+ private readonly store;
436
+ lastRunTick: number;
437
+ /** Deferred structural-command facade (§ctx.commands). */
438
+ readonly commands: Commands;
439
+ /** Current ECS tick. Use this for write ticks in getColumn. */
440
+ get ecsTick(): number;
441
+ /** The world's frame-trace sink (ADR-0030), or `null`. Lets the schedule
442
+ * fire `systemStart`/`flush*` without reaching into the private store.
443
+ * Read only under `if (__DEV__)`; the seam is dead-code-eliminated in prod. */
444
+ get _trace(): FrameTraceSink | null;
445
+ constructor(store: Store);
446
+ createEntity(): EntityID;
447
+ isAlive(entityId: EntityID): boolean;
448
+ hasComponent(entityId: EntityID, def: ComponentDef): boolean;
449
+ getField<S extends ComponentSchema>(entityId: EntityID, def: ComponentDef<S>, field: string & keyof S): number;
450
+ setField<S extends ComponentSchema>(entityId: EntityID, def: ComponentDef<S>, field: string & keyof S, value: number): void;
451
+ /** Read-modify-write one field: `updateField(e, Gold, "value", v => v - cost)`
452
+ * is the one-line form of the `getField` → compute → `setField` round trip.
453
+ * Returns the written value. Same access-check and observer semantics as the
454
+ * two calls it composes. */
455
+ updateField<S extends ComponentSchema>(entityId: EntityID, def: ComponentDef<S>, field: string & keyof S, fn: (current: number) => number): number;
456
+ /**
457
+ * Record an entity as changed for a component's per-entity `onSet` observer
458
+ * (#517 §1 / ADR-0013). The SoA write idiom — `const col = arch.getColumn(D,
459
+ * f, tick); col[i] = v` in a tight loop — bypasses the deferred buffer and the
460
+ * engine never sees the per-element writes, so a per-entity `onSet` consumer
461
+ * pushes the row here (the bench's winning `tick+list`: raw write + an int
462
+ * push, fired batched at the post-update detection point — never a per-element
463
+ * observable setter). No-op for components without a per-entity onSet observer.
464
+ * `setField` records automatically; this is for the hot `getColumn` loop.
465
+ */
466
+ markChanged(entityId: EntityID, def: ComponentDef): void;
467
+ /**
468
+ * Create a cached component reference for a single entity. Marks the
469
+ * component as changed (the mutable default — see `refRead` for the
470
+ * read-only variant to reach for when you are not mutating). See ref.ts.
471
+ */
472
+ ref<S extends ComponentSchema>(def: ComponentDef<S>, entityId: EntityID): ComponentRef<S>;
473
+ /**
474
+ * Create a cached read-only component reference for a single entity. Use
475
+ * this when you are not mutating. The returned `ReadonlyComponentRef<S>`
476
+ * is an *advisory* compile-time barrier (no `_changedTick` bump): the
477
+ * `readonly` typing blocks field writes at the type layer, but the
478
+ * underlying accessor shares its prototype with `ref()` and can still be
479
+ * written through a §10c-policed cast. See ref.ts.
480
+ */
481
+ refRead<S extends ComponentSchema>(def: ComponentDef<S>, entityId: EntityID): ReadonlyComponentRef<S>;
482
+ /** Buffer an entity for deferred destruction (applied at phase flush). */
483
+ destroyEntity(id: EntityID): this;
484
+ addComponent(entityId: EntityID, def: ComponentDef<Record<string, never>>): this;
485
+ addComponent<S extends ComponentSchema>(entityId: EntityID, def: ComponentDef<S>, values: FieldValues<S>): this;
486
+ removeComponent(entityId: EntityID, def: ComponentDef): this;
487
+ /** Buffer `entityId` to be disabled at the phase flush (idempotent). */
488
+ disable(entityId: EntityID): this;
489
+ /** Buffer `entityId` to be re-enabled at the phase flush (idempotent). */
490
+ enable(entityId: EntityID): this;
491
+ /** Whether `entityId` is currently disabled (immediate read). */
492
+ isDisabled(entityId: EntityID): boolean;
493
+ addSparse(entityId: EntityID, def: SparseComponentDef<Record<string, never>>): this;
494
+ addSparse<S extends ComponentSchema>(entityId: EntityID, def: SparseComponentDef<S>, values: FieldValues<S>): this;
495
+ removeSparse(entityId: EntityID, def: SparseComponentDef): this;
496
+ hasSparse(entityId: EntityID, def: SparseComponentDef): boolean;
497
+ getSparseField<S extends ComponentSchema>(entityId: EntityID, def: SparseComponentDef<S>, field: string & keyof S): number;
498
+ setSparseField<S extends ComponentSchema>(entityId: EntityID, def: SparseComponentDef<S>, field: string & keyof S, value: number): void;
499
+ /** Add a `(R, tgt)` pair to `src` (exclusive replaces, multi adds). */
500
+ addRelation(src: EntityID, def: RelationDef, tgt: EntityID): this;
501
+ /** Remove a `(R, tgt)` pair from `src`; for multi, omitting `tgt` removes all. */
502
+ removeRelation(src: EntityID, def: RelationDef, tgt?: EntityID): this;
503
+ /** The single target of `src` under an exclusive relation, or `undefined`. */
504
+ targetOf(src: EntityID, def: RelationDef): EntityID | undefined;
505
+ /** All targets of `src` under `R`, ascending by id. */
506
+ targetsOf(src: EntityID, def: RelationDef): EntityID[];
507
+ /** Sources pointing at `tgt` under `R` (the reverse index), ascending by id. */
508
+ sourcesOf(def: RelationDef, tgt: EntityID): EntityID[];
509
+ /** Whether `src` holds any pair under `R`. */
510
+ hasRelation(src: EntityID, def: RelationDef): boolean;
511
+ /** Flush all deferred changes: structural (add/remove) first, then
512
+ * destructions. Republishes archetype row counts into the SAB
513
+ * descriptor at the end so any WASM scan running in the next phase
514
+ * sees fresh `row_count` fields. This is one of two publish sites —
515
+ * `ECS.update()` also republishes once at tick start (see PATTERNS.md
516
+ * §60), covering host-side mutations between updates. The publish walks
517
+ * descriptors only — it doesn't touch column data — and benches at
518
+ * sub-microsecond per archetype, so paying it once per phase boundary
519
+ * is materially cheaper than the pre-#306 pattern of paying it per
520
+ * WASM-using system per tick. After #336 the descriptor walk is gated
521
+ * on a dirty flag, so read-only phases skip the walk entirely. */
522
+ flush(): void;
523
+ emit(key: SignalKey): void;
524
+ emit<S extends EventSchema>(key: EventKey<S>, values: S): void;
525
+ read<S extends EventSchema>(key: EventKey<S>): EventReader<S>;
526
+ resource<T>(key: ResourceKey<T>): T;
527
+ setResource<T>(key: ResourceKey<T>, value: T): void;
528
+ /** Drop a resource mid-tick (#798). A lifecycle mutation, so it is access-
529
+ * checked as a *write* — the system must declare the key in `resourceWrites`,
530
+ * which serialises it against readers/writers of the same resource. Fails
531
+ * closed on a missing key. */
532
+ removeResource<T>(key: ResourceKey<T>): void;
533
+ hasResource<T>(key: ResourceKey<T>): boolean;
534
+ }
535
+ export declare class ChangedQuery<Defs extends readonly ComponentDef[]> {
536
+ private readonly _query;
537
+ private readonly _changedIds;
538
+ constructor(query: Query<Defs>, changedIds: number[]);
539
+ /** Also require these components (mirrors `Query.and`). */
540
+ and<D extends ComponentDef[]>(...comps: D): ChangedQuery<[...Defs, ...D]>;
541
+ /** Exclude archetypes holding any of these (mirrors `Query.without`). */
542
+ without(...comps: ComponentDef[]): ChangedQuery<Defs>;
543
+ /** Require at least one of these (mirrors `Query.anyOf`). */
544
+ anyOf(...comps: ComponentDef[]): ChangedQuery<Defs>;
545
+ /** Permit optional-component data access in the loop (mirrors `Query.optional`). */
546
+ optional(...defs: ComponentDef[]): ChangedQuery<Defs>;
547
+ forEach(cb: (arch: ArchetypeView) => void): void;
548
+ /** @internal — cold `includeDisabled` wrapper (#577), split out of `forEach`
549
+ * (#649) so the all-rows flag dance stays out of the inlined hot body. */
550
+ private _forEachIncludeDisabled;
551
+ /** @internal — the `includeDisabled` delegate for `forEach` (#577). The
552
+ * default path inlines this body directly into `forEach` (#608) to dodge a
553
+ * megamorphic delegate hop; this copy survives only for the rare all-rows
554
+ * path, which needs the `_setIterAllRows` try/finally wrap. */
555
+ private _forEachInner;
556
+ }
557
+ //# sourceMappingURL=query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../src/core/ecs/query.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import { ComponentSchema } from './component';
2
+ import { ArchetypeColumnLayout } from './archetype';
3
+ import { AnyTypedArray, ColumnBacking } from '../../type_primitives';
4
+ /** Maps component schema to scalar get/set properties: { x: number, y: number }. */
5
+ export type ComponentRef<S extends ComponentSchema> = {
6
+ -readonly [K in keyof S]: number;
7
+ };
8
+ /**
9
+ * Read-only view of a component reference. This is an **advisory** barrier,
10
+ * not a runtime safety boundary: the `readonly` properties block field writes
11
+ * at the type layer, but `createRef` installs working get/set on the shared
12
+ * prototype for both `ref()` and `refRead()`, so a §10c-policed cast can
13
+ * still write through (and would skip the change-tick bump `ref()` performs).
14
+ * Treat it as "I promise I am only reading," enforced by the escape-hatch lint
15
+ * (`bun run lint:escape-hatches`), not by the runtime.
16
+ */
17
+ export type ReadonlyComponentRef<S extends ComponentSchema> = {
18
+ readonly [K in keyof S]: number;
19
+ };
20
+ /** Minimal column group shape needed by createRef. */
21
+ export interface RefColumnGroup {
22
+ readonly layout: ArchetypeColumnLayout;
23
+ readonly columns: ColumnBacking<AnyTypedArray>[];
24
+ }
25
+ /**
26
+ * Create a ComponentRef bound to a specific row in a column group.
27
+ * The prototype is built once per column group and cached; subsequent
28
+ * calls for the same group only allocate the lightweight ref object.
29
+ */
30
+ export declare function createRef<S extends ComponentSchema>(group: RefColumnGroup, row: number): ComponentRef<S>;
31
+ //# sourceMappingURL=ref.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ref.d.ts","sourceRoot":"","sources":["../../../src/core/ecs/ref.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;KA2BK;AAEL,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE1E,oFAAoF;AACpF,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,eAAe,IAAI;IACrD,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM;CAChC,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,oBAAoB,CAAC,CAAC,SAAS,eAAe,IAAI;IAC7D,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM;CAC/B,CAAC;AAMF,sDAAsD;AACtD,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,MAAM,EAAE,qBAAqB,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,aAAa,CAAC,EAAE,CAAC;CACjD;AAWD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,eAAe,EAClD,KAAK,EAAE,cAAc,EACrB,GAAG,EAAE,MAAM,GACT,YAAY,CAAC,CAAC,CAAC,CAwBjB"}