@vworlds/vecs 1.0.15 → 1.0.16

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 (181) hide show
  1. package/README.md +249 -119
  2. package/dist/component.d.ts +52 -76
  3. package/dist/component.js +60 -45
  4. package/dist/component.js.map +1 -1
  5. package/dist/component_meta.d.ts +98 -0
  6. package/dist/component_meta.js +65 -0
  7. package/dist/component_meta.js.map +1 -0
  8. package/dist/dsl.d.ts +46 -34
  9. package/dist/dsl.js +459 -61
  10. package/dist/dsl.js.map +1 -1
  11. package/dist/entity/entity.base.d.ts +57 -0
  12. package/dist/entity/entity.base.js +81 -0
  13. package/dist/entity/entity.base.js.map +1 -0
  14. package/dist/entity/entity.components.d.ts +117 -0
  15. package/dist/entity/entity.components.js +244 -0
  16. package/dist/entity/entity.components.js.map +1 -0
  17. package/dist/entity/entity.d.ts +35 -0
  18. package/dist/entity/entity.identity.d.ts +8 -0
  19. package/dist/entity/entity.identity.js +15 -0
  20. package/dist/entity/entity.identity.js.map +1 -0
  21. package/dist/entity/entity.js +33 -0
  22. package/dist/entity/entity.js.map +1 -0
  23. package/dist/entity/entity.lifecycle.d.ts +12 -0
  24. package/dist/entity/entity.lifecycle.js +111 -0
  25. package/dist/entity/entity.lifecycle.js.map +1 -0
  26. package/dist/entity/entity.queries.d.ts +3 -0
  27. package/dist/entity/entity.queries.js +33 -0
  28. package/dist/entity/entity.queries.js.map +1 -0
  29. package/dist/entity/entity.relationships.d.ts +9 -0
  30. package/dist/entity/entity.relationships.js +74 -0
  31. package/dist/entity/entity.relationships.js.map +1 -0
  32. package/dist/entity/index.d.ts +2 -0
  33. package/dist/entity/index.js +3 -0
  34. package/dist/entity/index.js.map +1 -0
  35. package/dist/filter.d.ts +27 -8
  36. package/dist/filter.js +33 -18
  37. package/dist/filter.js.map +1 -1
  38. package/dist/index.d.ts +13 -5
  39. package/dist/index.js +12 -2
  40. package/dist/index.js.map +1 -1
  41. package/dist/inject.d.ts +80 -0
  42. package/dist/inject.js +270 -0
  43. package/dist/inject.js.map +1 -0
  44. package/dist/module.d.ts +23 -0
  45. package/dist/module.js +17 -0
  46. package/dist/module.js.map +1 -0
  47. package/dist/modules/identity.d.ts +15 -0
  48. package/dist/modules/identity.js +41 -0
  49. package/dist/modules/identity.js.map +1 -0
  50. package/dist/modules/singleton.d.ts +26 -0
  51. package/dist/modules/singleton.js +41 -0
  52. package/dist/modules/singleton.js.map +1 -0
  53. package/dist/package.json +12 -1
  54. package/dist/phase.d.ts +2 -2
  55. package/dist/query/index.d.ts +6 -0
  56. package/dist/query/index.js +5 -0
  57. package/dist/query/index.js.map +1 -0
  58. package/dist/query/query.00.base.d.ts +23 -0
  59. package/dist/query/query.00.base.js +77 -0
  60. package/dist/query/query.00.base.js.map +1 -0
  61. package/dist/query/query.01.reactive.d.ts +7 -0
  62. package/dist/query/query.01.reactive.js +58 -0
  63. package/dist/query/query.01.reactive.js.map +1 -0
  64. package/dist/query/query.02.lifecycle.d.ts +6 -0
  65. package/dist/query/query.02.lifecycle.js +63 -0
  66. package/dist/query/query.02.lifecycle.js.map +1 -0
  67. package/dist/query/query.03.tracking.d.ts +15 -0
  68. package/dist/query/query.03.tracking.js +31 -0
  69. package/dist/query/query.03.tracking.js.map +1 -0
  70. package/dist/query/query.04.callbacks.d.ts +14 -0
  71. package/dist/query/query.04.callbacks.js +65 -0
  72. package/dist/query/query.04.callbacks.js.map +1 -0
  73. package/dist/query/query.05.updates.d.ts +14 -0
  74. package/dist/query/query.05.updates.js +81 -0
  75. package/dist/query/query.05.updates.js.map +1 -0
  76. package/dist/query/query.06.predicate.d.ts +13 -0
  77. package/dist/query/query.06.predicate.js +40 -0
  78. package/dist/query/query.06.predicate.js.map +1 -0
  79. package/dist/query/query.07.groups.d.ts +41 -0
  80. package/dist/query/query.07.groups.js +110 -0
  81. package/dist/query/query.07.groups.js.map +1 -0
  82. package/dist/query/query.d.ts +53 -0
  83. package/dist/query/query.js +138 -0
  84. package/dist/query/query.js.map +1 -0
  85. package/dist/relationship.d.ts +19 -0
  86. package/dist/relationship.js +18 -0
  87. package/dist/relationship.js.map +1 -0
  88. package/dist/system.d.ts +37 -23
  89. package/dist/system.js +80 -64
  90. package/dist/system.js.map +1 -1
  91. package/dist/terms/all_term.d.ts +32 -0
  92. package/dist/terms/all_term.js +41 -0
  93. package/dist/terms/all_term.js.map +1 -0
  94. package/dist/terms/any_term.d.ts +33 -0
  95. package/dist/terms/any_term.js +42 -0
  96. package/dist/terms/any_term.js.map +1 -0
  97. package/dist/terms/build.d.ts +62 -0
  98. package/dist/terms/build.js +382 -0
  99. package/dist/terms/build.js.map +1 -0
  100. package/dist/terms/component_term.d.ts +37 -0
  101. package/dist/terms/component_term.js +49 -0
  102. package/dist/terms/component_term.js.map +1 -0
  103. package/dist/terms/empty_term.d.ts +6 -0
  104. package/dist/terms/empty_term.js +12 -0
  105. package/dist/terms/empty_term.js.map +1 -0
  106. package/dist/terms/index.d.ts +11 -0
  107. package/dist/terms/index.js +12 -0
  108. package/dist/terms/index.js.map +1 -0
  109. package/dist/terms/not_term.d.ts +35 -0
  110. package/dist/terms/not_term.js +47 -0
  111. package/dist/terms/not_term.js.map +1 -0
  112. package/dist/terms/only_term.d.ts +47 -0
  113. package/dist/terms/only_term.js +79 -0
  114. package/dist/terms/only_term.js.map +1 -0
  115. package/dist/terms/predicate_term.d.ts +80 -0
  116. package/dist/terms/predicate_term.js +109 -0
  117. package/dist/terms/predicate_term.js.map +1 -0
  118. package/dist/terms/target_term.d.ts +43 -0
  119. package/dist/terms/target_term.js +87 -0
  120. package/dist/terms/target_term.js.map +1 -0
  121. package/dist/terms/term.d.ts +94 -0
  122. package/dist/terms/term.js +202 -0
  123. package/dist/terms/term.js.map +1 -0
  124. package/dist/terms/world_term.d.ts +68 -0
  125. package/dist/terms/world_term.js +99 -0
  126. package/dist/terms/world_term.js.map +1 -0
  127. package/dist/timer.js +2 -2
  128. package/dist/timer.js.map +1 -1
  129. package/dist/util/array_map.js +12 -0
  130. package/dist/util/array_map.js.map +1 -1
  131. package/dist/util/bitset.js +107 -22
  132. package/dist/util/bitset.js.map +1 -1
  133. package/dist/util/dense_set.d.ts +1 -0
  134. package/dist/util/dense_set.js +90 -0
  135. package/dist/util/dense_set.js.map +1 -0
  136. package/dist/util/id_pool.d.ts +23 -0
  137. package/dist/util/id_pool.js +194 -0
  138. package/dist/util/id_pool.js.map +1 -0
  139. package/dist/world/index.d.ts +3 -0
  140. package/dist/world/index.js +3 -0
  141. package/dist/world/index.js.map +1 -0
  142. package/dist/world/world.base.d.ts +6 -0
  143. package/dist/world/world.base.js +21 -0
  144. package/dist/world/world.base.js.map +1 -0
  145. package/dist/world/world.components.d.ts +67 -0
  146. package/dist/world/world.components.js +93 -0
  147. package/dist/world/world.components.js.map +1 -0
  148. package/dist/world/world.d.ts +29 -0
  149. package/dist/world/world.deferred.d.ts +13 -0
  150. package/dist/world/world.deferred.js +93 -0
  151. package/dist/world/world.deferred.js.map +1 -0
  152. package/dist/world/world.entities.d.ts +18 -0
  153. package/dist/world/world.entities.js +97 -0
  154. package/dist/world/world.entities.js.map +1 -0
  155. package/dist/world/world.js +39 -0
  156. package/dist/world/world.js.map +1 -0
  157. package/dist/world/world.modules.d.ts +12 -0
  158. package/dist/world/world.modules.js +21 -0
  159. package/dist/world/world.modules.js.map +1 -0
  160. package/dist/world/world.pipeline.d.ts +21 -0
  161. package/dist/world/world.pipeline.js +105 -0
  162. package/dist/world/world.pipeline.js.map +1 -0
  163. package/dist/world/world.pools.d.ts +9 -0
  164. package/dist/world/world.pools.js +59 -0
  165. package/dist/world/world.pools.js.map +1 -0
  166. package/dist/world/world.queries.d.ts +18 -0
  167. package/dist/world/world.queries.js +101 -0
  168. package/dist/world/world.queries.js.map +1 -0
  169. package/dist/world/world.storage.d.ts +7 -0
  170. package/dist/world/world.storage.js +26 -0
  171. package/dist/world/world.storage.js.map +1 -0
  172. package/package.json +12 -1
  173. package/dist/entity.d.ts +0 -215
  174. package/dist/entity.js +0 -457
  175. package/dist/entity.js.map +0 -1
  176. package/dist/query.d.ts +0 -251
  177. package/dist/query.js +0 -353
  178. package/dist/query.js.map +0 -1
  179. package/dist/world.d.ts +0 -389
  180. package/dist/world.js +0 -631
  181. package/dist/world.js.map +0 -1
@@ -0,0 +1,111 @@
1
+ import { CleanupPolicy } from "../component_meta.js";
2
+ import { Components } from "./entity.components.js";
3
+ export class Lifecycle extends Components {
4
+ /**
5
+ * @internal Apply a `Destroy` command: fire `_exit` on every query, then
6
+ * `onRemove` on every component, emit the `destroy` event, unregister from
7
+ * the world, and apply incoming relationship cleanup policies.
8
+ */
9
+ _destroy() {
10
+ if (this._destroyed) {
11
+ return;
12
+ }
13
+ const ownMeta = this._ownMeta;
14
+ // Mark destroyed up front so a carrier cleanup that re-enters this entity's
15
+ // `_destroy` (possible with exotic relationship topologies under Delete)
16
+ // hits the guard above instead of tearing down twice.
17
+ this._destroyed = true;
18
+ if (ownMeta) {
19
+ const selfCarry = this._components.has(ownMeta.eid) ? 1 : 0;
20
+ if (ownMeta.usageCount > selfCarry) {
21
+ if (ownMeta.onDelete === CleanupPolicy.Throw) {
22
+ // The public `destroy()` already throws when an in-use component is
23
+ // destroyed; reaching here means usage grew between that check and
24
+ // this deferred apply. Abort instead of throwing so a mid-drain
25
+ // `_processCommandQueue` is not left half-applied, and revive the
26
+ // entity since nothing has been torn down yet.
27
+ this._destroyed = false;
28
+ return;
29
+ }
30
+ this._applyOnDelete(ownMeta, selfCarry);
31
+ }
32
+ }
33
+ const entity = this;
34
+ this.world._notifyEntityDestroyed(entity);
35
+ this._components.forEach((c, eid) => {
36
+ const meta = this.world.entity(eid).ownMeta;
37
+ if (meta.isRelationship) {
38
+ this._removeIncoming(c.target, eid);
39
+ }
40
+ this.componentBitmask.deleteBit(meta.bitPtr);
41
+ this.world._notifyComponentRemoved(eid, entity);
42
+ meta._decrementUsage();
43
+ const removeHandlers = meta._onRemoveHandlers;
44
+ if (removeHandlers) {
45
+ removeHandlers.forEach((handler) => handler(entity, c));
46
+ }
47
+ });
48
+ this._dirtyComponentBitmask.clear();
49
+ this._queries.clear();
50
+ if (this._events) {
51
+ this._events.emit("destroy");
52
+ this._events.removeAllListeners("destroy");
53
+ }
54
+ if (ownMeta && ownMeta.usageCount === 0 && ownMeta.Class !== Object) {
55
+ this.world._classRegistry.delete(ownMeta.Class);
56
+ }
57
+ this.world._unregisterEntity(entity);
58
+ this._cleanupIncoming();
59
+ }
60
+ /**
61
+ * Destroy this entity.
62
+ *
63
+ * Each component fires its `onRemove` hook, the `"destroy"` event is emitted
64
+ * just before teardown, and the entity is unregistered from the world.
65
+ * After destruction the entity must not be used.
66
+ */
67
+ destroy() {
68
+ const ownMeta = this._ownMeta;
69
+ if (ownMeta &&
70
+ ownMeta.onDelete === CleanupPolicy.Throw &&
71
+ ownMeta.usageCount > (this._components.has(ownMeta.eid) ? 1 : 0)) {
72
+ throw new Error(`Cannot destroy entity ${this.eid}; component eid is still in use`);
73
+ }
74
+ if (this.world.deferred) {
75
+ this.world._enqueue({ kind: 4 /* CommandKind.Destroy */, entity: this });
76
+ }
77
+ else {
78
+ this._destroy();
79
+ }
80
+ }
81
+ // Collect carriers first, then act: the scan must not mutate `world.entities`
82
+ // while iterating, and `_destroy` idempotency makes overlapping Delete
83
+ // cascades safe. Carriers are cleaned via the internal `_remove`/`_destroy`
84
+ // (not the deferred-aware public methods) so `usageCount` drops synchronously
85
+ // and the `usageCount === 0` classRegistry cleanup in `_destroy` stays correct.
86
+ // Edge: if a Delete carrier is itself an in-use component key with
87
+ // `onDelete = Throw`, its `_destroy` safe-aborts and it survives still holding
88
+ // this now-destroyed component eid. This is the same exotic policy-interaction
89
+ // class flagged in `_cleanupIncoming`; left for the relationship/query rework.
90
+ _applyOnDelete(ownMeta, selfCarry) {
91
+ const ceid = ownMeta.eid;
92
+ const carriers = [];
93
+ let remaining = ownMeta.usageCount - selfCarry;
94
+ this.world.entities.forEach((e) => {
95
+ if (remaining > 0 && e !== this && e._get(ceid) !== undefined) {
96
+ carriers.push(e);
97
+ remaining--;
98
+ }
99
+ });
100
+ const shouldDelete = ownMeta.onDelete === CleanupPolicy.Delete;
101
+ for (const carrier of carriers) {
102
+ if (shouldDelete) {
103
+ carrier._destroy();
104
+ }
105
+ else {
106
+ carrier._remove(ownMeta);
107
+ }
108
+ }
109
+ }
110
+ }
111
+ //# sourceMappingURL=entity.lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity.lifecycle.js","sourceRoot":"","sources":["../../src/entity/entity.lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Base } from "./entity.base.js";
2
+ export declare class Queries extends Base {
3
+ }
@@ -0,0 +1,33 @@
1
+ import { Base } from "./entity.base.js";
2
+ export class Queries extends Base {
3
+ /**
4
+ * @internal Record that this entity is now tracked by `q`. Called by
5
+ * `Query._enter`.
6
+ */
7
+ _addQueryMembership(q) {
8
+ if (q._watchesUpdates()) {
9
+ this._queries.add(q);
10
+ }
11
+ }
12
+ /**
13
+ * @internal Return `true` when this entity is currently tracked by `q`.
14
+ */
15
+ _isInQuery(q) {
16
+ return this._queries.has(q);
17
+ }
18
+ /**
19
+ * @internal Forget query `q` without firing exit callbacks. Called by
20
+ * {@link World} when a {@link Query.destroy} sweeps every entity.
21
+ */
22
+ _purgeQuery(q) {
23
+ this._queries.delete(q);
24
+ }
25
+ /**
26
+ * @internal Record that this entity is no longer tracked by `q`. Called by
27
+ * `Query._exit`.
28
+ */
29
+ _removeQueryMembership(q) {
30
+ this._queries.delete(q);
31
+ }
32
+ }
33
+ //# sourceMappingURL=entity.queries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity.queries.js","sourceRoot":"","sources":["../../src/entity/entity.queries.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,MAAM,OAAO,OAAQ,SAAQ,IAAI;IAC/B;;;OAGG;IACI,mBAAmB,CAAC,CAAQ;QACjC,IAAI,CAAC,CAAC,eAAe,EAAE,EAAE,CAAC;YACxB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED;;OAEG;IACI,UAAU,CAAC,CAAQ;QACxB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC9B,CAAC;IAED;;;OAGG;IACI,WAAW,CAAC,CAAQ;QACzB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IAED;;;OAGG;IACI,sBAAsB,CAAC,CAAQ;QACpC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;CACF"}
@@ -0,0 +1,9 @@
1
+ import { type ComponentRef } from "../component_meta.js";
2
+ import type { Entity } from "./entity.js";
3
+ import { Queries } from "./entity.queries.js";
4
+ export declare class Relationships extends Queries {
5
+ /** Return this entity's target through relationship `ref`, if present. */
6
+ parent(ref: ComponentRef): Entity | undefined;
7
+ /** Return entities targeting this one through relationship `ref`. */
8
+ children(ref: ComponentRef): ReadonlySet<Entity>;
9
+ }
@@ -0,0 +1,74 @@
1
+ import { CleanupPolicy } from "../component_meta.js";
2
+ import { ArrayMap } from "../util/array_map.js";
3
+ import { DenseSet } from "../util/dense_set.js";
4
+ import { Queries } from "./entity.queries.js";
5
+ export class Relationships extends Queries {
6
+ /** Return this entity's target through relationship `ref`, if present. */
7
+ parent(ref) {
8
+ return this._components.get(this.world.entity(ref).eid)?.target;
9
+ }
10
+ /** Return entities targeting this one through relationship `ref`. */
11
+ children(ref) {
12
+ return this._incoming?.get(this.world.entity(ref).eid) ?? Relationships._emptyIncoming;
13
+ }
14
+ /**
15
+ * @internal Fast child set lookup by relationship eid — skips ref -> eid
16
+ * resolution. Used by the `source` predicate and fan-out invoker.
17
+ */
18
+ _childrenByEid(relEid) {
19
+ return this._incoming?.get(relEid);
20
+ }
21
+ /** @internal */
22
+ _addIncoming(target, relEid) {
23
+ if (!target || target._destroyed) {
24
+ return;
25
+ }
26
+ let sources = target._incoming?.get(relEid);
27
+ if (!sources) {
28
+ sources = new DenseSet();
29
+ (target._incoming ?? (target._incoming = new ArrayMap())).set(relEid, sources);
30
+ }
31
+ sources.add(this);
32
+ }
33
+ /** @internal */
34
+ _cleanupIncoming() {
35
+ this._incoming?.forEach((sources, relEid) => {
36
+ const relEntity = this.world.getEntity(relEid);
37
+ if (!relEntity) {
38
+ return;
39
+ }
40
+ const policy = relEntity.ownMeta.onDeleteTarget;
41
+ for (const source of [...sources]) {
42
+ if (policy === CleanupPolicy.Delete) {
43
+ // If source is also an in-use component entity with onDelete Throw,
44
+ // this exotic cascade can still throw; revisit with the relationship rework.
45
+ source.destroy();
46
+ }
47
+ else {
48
+ source.remove(relEid);
49
+ }
50
+ }
51
+ });
52
+ this._incoming = undefined;
53
+ }
54
+ /** @internal */
55
+ _removeIncoming(target, relEid) {
56
+ const sources = target?._incoming?.get(relEid);
57
+ if (!sources) {
58
+ return;
59
+ }
60
+ sources.delete(this);
61
+ if (sources.size === 0) {
62
+ target._incoming.delete(relEid);
63
+ }
64
+ }
65
+ /** @internal */
66
+ _updateIncoming(meta, oldTarget, newTarget) {
67
+ if (!meta.isRelationship || oldTarget === newTarget) {
68
+ return;
69
+ }
70
+ this._removeIncoming(oldTarget, meta.eid);
71
+ this._addIncoming(newTarget, meta.eid);
72
+ }
73
+ }
74
+ //# sourceMappingURL=entity.relationships.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity.relationships.js","sourceRoot":"","sources":["../../src/entity/entity.relationships.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAyC,MAAM,sBAAsB,CAAC;AAE5F,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAE9C,MAAM,OAAO,aAAc,SAAQ,OAAO;IACxC,0EAA0E;IACnE,MAAM,CAAC,GAAiB;QAC7B,OAAQ,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAA8B,EAAE,MAAM,CAAC;IAChG,CAAC;IAED,qEAAqE;IAC9D,QAAQ,CAAC,GAAiB;QAC/B,OAAO,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,aAAa,CAAC,cAAc,CAAC;IACzF,CAAC;IAED;;;OAGG;IACI,cAAc,CAAC,MAAc;QAClC,OAAO,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;IAED,gBAAgB;IACN,YAAY,CAAC,MAA0B,EAAE,MAAc;QAC/D,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACjC,OAAO;QACT,CAAC;QACD,IAAI,OAAO,GAAG,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,GAAG,IAAI,QAAQ,EAAU,CAAC;YACjC,CAAC,MAAM,CAAC,SAAS,KAAhB,MAAM,CAAC,SAAS,GAAK,IAAI,QAAQ,EAAE,EAAC,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC7D,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,IAAyB,CAAC,CAAC;IACzC,CAAC;IAED,gBAAgB;IACN,gBAAgB;QACxB,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAC/C,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,OAAO;YACT,CAAC;YACD,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,cAAc,CAAC;YAChD,KAAK,MAAM,MAAM,IAAI,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC;gBAClC,IAAI,MAAM,KAAK,aAAa,CAAC,MAAM,EAAE,CAAC;oBACpC,oEAAoE;oBACpE,6EAA6E;oBAC7E,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBACxB,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED,gBAAgB;IACN,eAAe,CAAC,MAA0B,EAAE,MAAc;QAClE,MAAM,OAAO,GAAG,MAAM,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAC/C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;QACT,CAAC;QACD,OAAO,CAAC,MAAM,CAAC,IAAyB,CAAC,CAAC;QAC1C,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACvB,MAAO,CAAC,SAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED,gBAAgB;IACN,eAAe,CACvB,IAAmB,EACnB,SAA6B,EAC7B,SAA6B;QAE7B,IAAI,CAAC,IAAI,CAAC,cAAc,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YACpD,OAAO;QACT,CAAC;QACD,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1C,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;IACzC,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ export { Entity, type EntityClass } from "./entity.js";
2
+ export { Identity } from "./entity.identity.js";
@@ -0,0 +1,3 @@
1
+ export { Entity } from "./entity.js";
2
+ export { Identity } from "./entity.identity.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/entity/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAoB,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC"}
package/dist/filter.d.ts CHANGED
@@ -1,7 +1,9 @@
1
- import { type ComponentClass } from "./component.js";
2
- import type { Entity } from "./entity.js";
3
- import type { World } from "./world.js";
4
- import { type MaybeRequired, type QueryDSL } from "./dsl.js";
1
+ import { type ComponentType } from "./component.js";
2
+ import { Entity } from "./entity/index.js";
3
+ import type { World } from "./world/index.js";
4
+ import { type QueryDSL } from "./dsl.js";
5
+ import type { Term } from "./terms/term.js";
6
+ import { Iter, type FanInjectTuple, type MaybeResolvedInjectTuple } from "./inject.js";
5
7
  /**
6
8
  * A non-reactive, one-shot entity filter.
7
9
  *
@@ -35,13 +37,15 @@ import { type MaybeRequired, type QueryDSL } from "./dsl.js";
35
37
  * manually via the `_guaranteed` argument. Components in `R` are non-nullable
36
38
  * in `forEach` callback tuples.
37
39
  */
38
- export declare class Filter<R extends ComponentClass[] = []> {
40
+ export declare class Filter<R extends ComponentType[] = []> {
39
41
  /** World this filter reads entities from. */
40
42
  readonly world: World;
41
43
  private readonly _belongs;
44
+ private readonly _dsl;
42
45
  constructor(
43
46
  /** World this filter reads entities from. */
44
47
  world: World, dsl: QueryDSL);
48
+ get rootTerm(): Term | undefined;
45
49
  /**
46
50
  * Walk all current world entities and call `callback` for each one that
47
51
  * satisfies the filter's DSL.
@@ -57,11 +61,26 @@ export declare class Filter<R extends ComponentClass[] = []> {
57
61
  * non-nullable in the resolved tuple; any other component class may be
58
62
  * `undefined` if the entity does not have it.
59
63
  *
64
+ * The resolved tuple is reused for every matching entity. Read or
65
+ * destructure it inside the callback; do not retain the tuple array.
66
+ *
60
67
  * @param components - Component classes to resolve from each matching entity.
61
68
  * @param callback - Receives the entity and a tuple of resolved component
62
69
  * instances.
63
70
  */
64
- forEach<J extends ComponentClass[]>(components: readonly [...J], callback: (e: Entity, resolved: {
65
- [K in keyof J]: MaybeRequired<J[K], R>;
66
- }) => void): void;
71
+ forEach<J extends FanInjectTuple>(components: readonly [...J], callback: (e: Entity, resolved: MaybeResolvedInjectTuple<J, R>) => void): void;
72
+ /**
73
+ * As above, but pass `Entity` first to make the entity-first signature
74
+ * explicit. Identical behavior to the no-marker form.
75
+ */
76
+ forEach<J extends FanInjectTuple>(cursor: typeof Entity, components: readonly [...J], callback: (e: Entity, resolved: MaybeResolvedInjectTuple<J, R>) => void): void;
77
+ /**
78
+ * As above, but pass `Iter` first to receive a reused {@link Iter}
79
+ * cursor instead of the bare entity. The cursor exposes the visited entity
80
+ * (`it.entity`) and, in `it.src`, the source entity each resolved component
81
+ * was read from (the visited entity for direct components, the relationship
82
+ * target for `up`-injected ones).
83
+ */
84
+ forEach<J extends FanInjectTuple>(cursor: typeof Iter, components: readonly [...J], callback: (it: Iter, resolved: MaybeResolvedInjectTuple<J, R>) => void): void;
85
+ private _forEachMatch;
67
86
  }
package/dist/filter.js CHANGED
@@ -1,4 +1,5 @@
1
- import { _buildEntityTest } from "./dsl.js";
1
+ import { _compile } from "./dsl.js";
2
+ import { isCursorMarker, makeInjectedInvoker, wantsIter, } from "./inject.js";
2
3
  /**
3
4
  * A non-reactive, one-shot entity filter.
4
5
  *
@@ -37,26 +38,40 @@ export class Filter {
37
38
  /** World this filter reads entities from. */
38
39
  world, dsl) {
39
40
  this.world = world;
40
- this._belongs = _buildEntityTest(world, dsl);
41
+ this._dsl = dsl;
42
+ this._belongs = _compile(world, dsl);
41
43
  }
42
- forEach(componentsOrCallback, callback) {
44
+ get rootTerm() {
45
+ return this.world._getCachedTerm(this._dsl);
46
+ }
47
+ forEach(arg0, arg1, arg2) {
48
+ // Bare `forEach(callback)`: a function that is not a cursor marker.
49
+ if (typeof arg0 === "function" && !isCursorMarker(arg0)) {
50
+ const callback = arg0;
51
+ this.world.defer(() => {
52
+ this._forEachMatch(callback);
53
+ });
54
+ return;
55
+ }
56
+ const useIter = wantsIter(arg0);
57
+ const components = (isCursorMarker(arg0) ? arg1 : arg0);
58
+ const callback = (isCursorMarker(arg0) ? arg2 : arg1);
43
59
  this.world.defer(() => {
44
- if (typeof componentsOrCallback === "function") {
45
- this.world.entities.forEach((e) => {
46
- if (this._belongs(e)) {
47
- componentsOrCallback(e);
48
- }
49
- });
60
+ const invoke = makeInjectedInvoker(this.world, components, useIter, callback);
61
+ this._forEachMatch(invoke);
62
+ });
63
+ }
64
+ _forEachMatch(callback) {
65
+ const rootTerm = this.rootTerm;
66
+ if (rootTerm) {
67
+ for (const entity of rootTerm) {
68
+ callback(entity);
50
69
  }
51
- else {
52
- const types = componentsOrCallback.map((C) => this.world.getComponentType(C));
53
- this.world.entities.forEach((e) => {
54
- if (!this._belongs(e)) {
55
- return;
56
- }
57
- const resolved = types.map((t) => e.get(t));
58
- callback(e, resolved);
59
- });
70
+ return;
71
+ }
72
+ this.world.entities.forEach((e) => {
73
+ if (this._belongs(e)) {
74
+ callback(e);
60
75
  }
61
76
  });
62
77
  }
@@ -1 +1 @@
1
- {"version":3,"file":"filter.js","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAA0D,MAAM,UAAU,CAAC;AAEpG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,OAAO,MAAM;IAGjB;IACE,6CAA6C;IAC7B,KAAY,EAC5B,GAAa;QADG,UAAK,GAAL,KAAK,CAAO;QAG5B,IAAI,CAAC,QAAQ,GAAG,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC/C,CAAC;IA2BM,OAAO,CACZ,oBAA6D,EAC7D,QAAoF;QAEpF,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE;YACpB,IAAI,OAAO,oBAAoB,KAAK,UAAU,EAAE,CAAC;gBAC/C,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;oBAChC,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;wBACrB,oBAAoB,CAAC,CAAC,CAAC,CAAC;oBAC1B,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,MAAM,KAAK,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC9E,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;oBAChC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;wBACtB,OAAO;oBACT,CAAC;oBACD,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC5C,QAAS,CAAC,CAAC,EAAE,QAAe,CAAC,CAAC;gBAChC,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
1
+ {"version":3,"file":"filter.js","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAsC,MAAM,UAAU,CAAC;AAExE,OAAO,EACL,cAAc,EAEd,mBAAmB,EACnB,SAAS,GAIV,MAAM,aAAa,CAAC;AAErB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,OAAO,MAAM;IAIjB;IACE,6CAA6C;IAC7B,KAAY,EAC5B,GAAa;QADG,UAAK,GAAL,KAAK,CAAO;QAG5B,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;QAChB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACvC,CAAC;IAED,IAAW,QAAQ;QACjB,OAAO,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC;IAqDM,OAAO,CAAC,IAAa,EAAE,IAAc,EAAE,IAAc;QAC1D,oEAAoE;QACpE,IAAI,OAAO,IAAI,KAAK,UAAU,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;YACxD,MAAM,QAAQ,GAAG,IAA2B,CAAC;YAC7C,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE;gBACpB,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YAC/B,CAAC,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,UAAU,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAgC,CAAC;QACvF,MAAM,QAAQ,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAG3C,CAAC;QACV,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE;YACpB,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;YAC9E,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,aAAa,CAAC,QAA6B;QACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC/B,IAAI,QAAQ,EAAE,CAAC;YACb,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;gBAC9B,QAAQ,CAAC,MAAM,CAAC,CAAC;YACnB,CAAC;YACD,OAAO;QACT,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;YAChC,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrB,QAAQ,CAAC,CAAC,CAAC,CAAC;YACd,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
package/dist/index.d.ts CHANGED
@@ -1,9 +1,17 @@
1
- export { type System, type SystemQuery } from "./system.js";
2
- export { Query } from "./query.js";
3
- export { World } from "./world.js";
1
+ export { System, type SystemQuery } from "./system.js";
2
+ export { Query, GroupedQuery, Group, Iter, type EntityTestFunc, type MaybeRequired, type QueryDSL, type DownInject, type FanInjectElement, type FanInjectTuple, type InjectElement, type InjectTuple, type MaybeResolvedInjectTuple, type RequiredResolvedInjectTuple, type UpInject, } from "./query/index.js";
3
+ export { DEFAULT_POOLS, World, type WorldOptions } from "./world/index.js";
4
4
  export { Filter } from "./filter.js";
5
- export { type Component, type ComponentClass, type ComponentMeta } from "./component.js";
6
- export { type Entity } from "./entity.js";
5
+ export { ChildOf, Relationship, SilenceSource } from "./relationship.js";
6
+ export { CleanupPolicy, Component, type ComponentInstance, type ComponentClass, type ComponentMeta, type ComponentRef, } from "./component.js";
7
+ export { Entity, type EntityClass, Identity } from "./entity/index.js";
8
+ export { Module } from "./module.js";
9
+ export { IdentityModule } from "./modules/identity.js";
10
+ export { Singleton, SingletonModule } from "./modules/singleton.js";
7
11
  export { type IPhase } from "./phase.js";
12
+ export { getDSLKey } from "./dsl.js";
13
+ export { Term, TermEventKind, type TermConsumer } from "./terms/term.js";
8
14
  export { IntervalTickSource, RateTickSource, type ITickSource } from "./timer.js";
15
+ export { ArrayMap } from "./util/array_map.js";
9
16
  export { Bitset } from "./util/bitset.js";
17
+ export { type IdPoolConfig } from "./util/id_pool.js";
package/dist/index.js CHANGED
@@ -1,6 +1,16 @@
1
- export { Query } from "./query.js";
2
- export { World } from "./world.js";
1
+ export { System } from "./system.js";
2
+ export { Query, GroupedQuery, Group, Iter, } from "./query/index.js";
3
+ export { DEFAULT_POOLS, World } from "./world/index.js";
3
4
  export { Filter } from "./filter.js";
5
+ export { ChildOf, Relationship, SilenceSource } from "./relationship.js";
6
+ export { CleanupPolicy, Component, } from "./component.js";
7
+ export { Entity, Identity } from "./entity/index.js";
8
+ export { Module } from "./module.js";
9
+ export { IdentityModule } from "./modules/identity.js";
10
+ export { Singleton, SingletonModule } from "./modules/singleton.js";
11
+ export { getDSLKey } from "./dsl.js";
12
+ export { Term } from "./terms/term.js";
4
13
  export { IntervalTickSource, RateTickSource } from "./timer.js";
14
+ export { ArrayMap } from "./util/array_map.js";
5
15
  export { Bitset } from "./util/bitset.js";
6
16
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAIrC,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAoB,MAAM,YAAY,CAAC;AAClF,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAoB,MAAM,aAAa,CAAC;AACvD,OAAO,EACL,KAAK,EACL,YAAY,EACZ,KAAK,EACL,IAAI,GAYL,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,KAAK,EAAqB,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EACL,aAAa,EACb,SAAS,GAKV,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,MAAM,EAAoB,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEpE,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,IAAI,EAAoC,MAAM,iBAAiB,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAoB,MAAM,YAAY,CAAC;AAClF,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,80 @@
1
+ import { type ComponentInstance, type ComponentRef, type ComponentType } from "./component.js";
2
+ import { Entity } from "./entity/index.js";
3
+ import { type World } from "./world/index.js";
4
+ import { type MaybeRequired } from "./dsl.js";
5
+ export type UpInject<J extends readonly ComponentType[] = readonly ComponentType[]> = {
6
+ up: readonly [ComponentRef, readonly [...J]];
7
+ };
8
+ export type DownInject<J extends readonly ComponentType[] = readonly ComponentType[]> = {
9
+ down: readonly [ComponentRef, readonly [...J]];
10
+ };
11
+ export type InjectElement = ComponentType | UpInject;
12
+ export type InjectTuple = readonly InjectElement[];
13
+ export type FanInjectElement = InjectElement | DownInject;
14
+ export type FanInjectTuple = readonly FanInjectElement[];
15
+ export type ResolvedInjectTerm = number | {
16
+ up: readonly [number, readonly number[]];
17
+ } | {
18
+ down: readonly [number, readonly number[]];
19
+ };
20
+ /** Resolves the component instance type for one injected component class. */
21
+ type ResolvedComponentInstance<T> = T extends ComponentType ? InstanceType<T> : never;
22
+ type OptionalResolvedComponentInstances<J extends readonly ComponentType[]> = {
23
+ [K in keyof J]: InstanceType<J[K]> | undefined;
24
+ };
25
+ type MaybeResolvedInjectElement<T, R extends ComponentType[]> = T extends ComponentType ? [MaybeRequired<T, R>] : T extends UpInject<infer J> ? OptionalResolvedComponentInstances<J> : T extends DownInject<infer J> ? OptionalResolvedComponentInstances<J> : [];
26
+ type RequiredResolvedInjectElement<T> = T extends ComponentType ? [ResolvedComponentInstance<T>] : T extends UpInject<infer J> ? OptionalResolvedComponentInstances<J> : T extends DownInject<infer J> ? OptionalResolvedComponentInstances<J> : [];
27
+ export type MaybeResolvedInjectTuple<J extends FanInjectTuple, R extends ComponentType[]> = J extends readonly [infer First, ...infer Rest extends FanInjectTuple] ? [...MaybeResolvedInjectElement<First, R>, ...MaybeResolvedInjectTuple<Rest, R>] : [];
28
+ export type RequiredResolvedInjectTuple<J extends InjectTuple> = J extends readonly [
29
+ infer First,
30
+ ...infer Rest extends InjectTuple
31
+ ] ? [...RequiredResolvedInjectElement<First>, ...RequiredResolvedInjectTuple<Rest>] : [];
32
+ export declare function mapInject(world: World, inject: readonly FanInjectElement[]): ResolvedInjectTerm[];
33
+ export declare function injectArity(inject: readonly ResolvedInjectTerm[]): number;
34
+ export declare function getInjected(e: Entity, inject: readonly ResolvedInjectTerm[], requireDirectComponents: boolean, out: (ComponentInstance | undefined)[], exitSnapshot?: Map<number, ComponentInstance>): void;
35
+ export declare function getInjectedWithSrc(e: Entity, inject: readonly ResolvedInjectTerm[], out: (ComponentInstance | undefined)[], src: (Entity | undefined)[], requireDirectComponents?: boolean, exitSnapshot?: Map<number, ComponentInstance>): void;
36
+ export declare function directInjectEids(inject: readonly ResolvedInjectTerm[]): number[];
37
+ /**
38
+ * Per-iteration cursor passed to `each` / `forEach` / `enter` / `exit` /
39
+ * `update` / `sort` callbacks when the caller opts in by passing `Iter` as
40
+ * the first argument:
41
+ *
42
+ * ```ts
43
+ * system.each(Iter, [Body, { up: [ChildOf, [Position]] }], (it, [body, pos]) => {
44
+ * it.entity; // the visited entity
45
+ * it.src[0]; // entity `body` was read from (the visited entity)
46
+ * it.src[1]; // entity `pos` was read from (the ChildOf target), or undefined
47
+ * });
48
+ * ```
49
+ *
50
+ * A single instance is created when the iteration is set up and mutated before
51
+ * every callback, so it allocates nothing per entity. Read what you need inside
52
+ * the callback; do not retain the cursor or its {@link src} array across
53
+ * callbacks.
54
+ */
55
+ export declare class Iter {
56
+ /** The entity currently being visited. */
57
+ entity: Entity;
58
+ /**
59
+ * Source entity for each injected component, in the same order as the
60
+ * resolved tuple: the visited entity for a directly-injected component, or
61
+ * the relationship target for an `up`-injected one (`undefined` when the
62
+ * entity has no such relationship or target).
63
+ */
64
+ readonly src: (Entity | undefined)[];
65
+ constructor(arity: number);
66
+ }
67
+ export declare function isCursorMarker(x: unknown): x is typeof Entity | typeof Iter;
68
+ export declare function wantsIter(x: unknown): x is typeof Iter;
69
+ /**
70
+ * Iterate `entities`, resolving injected components per the `forEach` /
71
+ * `each` argument grammar (bare callback, `[components]`, `Entity`/`Iter`
72
+ * cursor markers). Runs inside a deferred scope so mutations made by the
73
+ * callback are buffered and applied after iteration finishes.
74
+ *
75
+ * Shared by {@link Query.forEach} and {@link Group.forEach} so both honour the
76
+ * same injection and deferral semantics.
77
+ */
78
+ export declare function forEachInjected(world: World, entities: Iterable<Entity>, arg0: unknown, arg1?: unknown, arg2?: unknown): void;
79
+ export declare function makeInjectedInvoker(world: World, components: readonly FanInjectElement[], useIter: boolean, callback: (eOrIt: unknown, resolved: unknown) => void): (e: Entity) => void;
80
+ export {};