@vworlds/vecs 1.0.44 → 1.0.46

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 (136) hide show
  1. package/README.md +7 -1
  2. package/dist/component.d.ts +57 -51
  3. package/dist/component.js +25 -9
  4. package/dist/component.js.map +1 -1
  5. package/dist/component_meta.d.ts +71 -66
  6. package/dist/component_meta.js +331 -34
  7. package/dist/component_meta.js.map +1 -1
  8. package/dist/dsl.js +1 -1
  9. package/dist/dsl.js.map +1 -1
  10. package/dist/entity/entity.base.js +4 -0
  11. package/dist/entity/entity.base.js.map +1 -1
  12. package/dist/entity/entity.components.d.ts +39 -27
  13. package/dist/entity/entity.components.js +258 -74
  14. package/dist/entity/entity.components.js.map +1 -1
  15. package/dist/entity/entity.d.ts +1 -2
  16. package/dist/entity/entity.js +2 -3
  17. package/dist/entity/entity.js.map +1 -1
  18. package/dist/entity/entity.lifecycle.d.ts +7 -1
  19. package/dist/entity/entity.lifecycle.js +40 -53
  20. package/dist/entity/entity.lifecycle.js.map +1 -1
  21. package/dist/entity/entity.queries.js +30 -0
  22. package/dist/entity/entity.queries.js.map +1 -1
  23. package/dist/entity/entity.relationships.d.ts +4 -0
  24. package/dist/entity/entity.relationships.js +18 -10
  25. package/dist/entity/entity.relationships.js.map +1 -1
  26. package/dist/index.d.ts +7 -4
  27. package/dist/index.js +4 -2
  28. package/dist/index.js.map +1 -1
  29. package/dist/inject.d.ts +63 -14
  30. package/dist/inject.js +165 -89
  31. package/dist/inject.js.map +1 -1
  32. package/dist/modules/identity.js +2 -2
  33. package/dist/modules/identity.js.map +1 -1
  34. package/dist/modules/implements.js +2 -2
  35. package/dist/modules/implements.js.map +1 -1
  36. package/dist/modules/pipeline.js +5 -5
  37. package/dist/modules/pipeline.js.map +1 -1
  38. package/dist/modules/relationship_types.d.ts +70 -3
  39. package/dist/modules/relationship_types.js +70 -3
  40. package/dist/modules/relationship_types.js.map +1 -1
  41. package/dist/modules/relationships.d.ts +31 -8
  42. package/dist/modules/relationships.js +120 -30
  43. package/dist/modules/relationships.js.map +1 -1
  44. package/dist/modules/singleton.js +2 -2
  45. package/dist/modules/singleton.js.map +1 -1
  46. package/dist/modules/snapshot.d.ts +26 -0
  47. package/dist/modules/snapshot.js +45 -0
  48. package/dist/modules/snapshot.js.map +1 -0
  49. package/dist/modules/snapshot_types.d.ts +85 -0
  50. package/dist/modules/snapshot_types.js +130 -0
  51. package/dist/modules/snapshot_types.js.map +1 -0
  52. package/dist/package.json +2 -2
  53. package/dist/query/callbacks.d.ts +9 -7
  54. package/dist/query/callbacks.js +27 -41
  55. package/dist/query/callbacks.js.map +1 -1
  56. package/dist/query/grouped_query.js +7 -7
  57. package/dist/query/grouped_query.js.map +1 -1
  58. package/dist/query/grouping.d.ts +6 -2
  59. package/dist/query/grouping.js +84 -15
  60. package/dist/query/grouping.js.map +1 -1
  61. package/dist/query/query.d.ts +4 -4
  62. package/dist/query/query.js +37 -14
  63. package/dist/query/query.js.map +1 -1
  64. package/dist/snapshot/capture.d.ts +1 -0
  65. package/dist/snapshot/capture.js +212 -0
  66. package/dist/snapshot/capture.js.map +1 -0
  67. package/dist/snapshot/clone.d.ts +1 -0
  68. package/dist/snapshot/clone.js +107 -0
  69. package/dist/snapshot/clone.js.map +1 -0
  70. package/dist/snapshot/index.d.ts +5 -0
  71. package/dist/snapshot/index.js +21 -0
  72. package/dist/snapshot/index.js.map +1 -0
  73. package/dist/snapshot/preflight.d.ts +1 -0
  74. package/dist/snapshot/preflight.js +40 -0
  75. package/dist/snapshot/preflight.js.map +1 -0
  76. package/dist/snapshot/restore.d.ts +1 -0
  77. package/dist/snapshot/restore.js +111 -0
  78. package/dist/snapshot/restore.js.map +1 -0
  79. package/dist/snapshot/types.d.ts +135 -0
  80. package/dist/snapshot/types.js +26 -0
  81. package/dist/snapshot/types.js.map +1 -0
  82. package/dist/system.d.ts +3 -1
  83. package/dist/system.js +33 -23
  84. package/dist/system.js.map +1 -1
  85. package/dist/terms/all_term.js +19 -0
  86. package/dist/terms/all_term.js.map +1 -1
  87. package/dist/terms/any_term.js +19 -0
  88. package/dist/terms/any_term.js.map +1 -1
  89. package/dist/terms/not_term.js +4 -0
  90. package/dist/terms/not_term.js.map +1 -1
  91. package/dist/terms/target_term.d.ts +1 -2
  92. package/dist/terms/target_term.js +2 -4
  93. package/dist/terms/target_term.js.map +1 -1
  94. package/dist/terms/term.d.ts +2 -0
  95. package/dist/terms/term.js +59 -10
  96. package/dist/terms/term.js.map +1 -1
  97. package/dist/util/array_map.d.ts +43 -12
  98. package/dist/util/array_map.js +90 -41
  99. package/dist/util/array_map.js.map +1 -1
  100. package/dist/util/dense_set.js +26 -0
  101. package/dist/util/dense_set.js.map +1 -1
  102. package/dist/world/world.base.js +12 -0
  103. package/dist/world/world.base.js.map +1 -1
  104. package/dist/world/world.d.ts +7 -0
  105. package/dist/world/world.deferred.js +17 -0
  106. package/dist/world/world.deferred.js.map +1 -1
  107. package/dist/world/world.entities.d.ts +13 -2
  108. package/dist/world/world.entities.js +16 -2
  109. package/dist/world/world.entities.js.map +1 -1
  110. package/dist/world/world.js +15 -3
  111. package/dist/world/world.js.map +1 -1
  112. package/dist/world/world.pipeline.d.ts +2 -2
  113. package/dist/world/world.pipeline.js +4 -2
  114. package/dist/world/world.pipeline.js.map +1 -1
  115. package/dist/world/world.queries.d.ts +7 -0
  116. package/dist/world/world.queries.js +52 -0
  117. package/dist/world/world.queries.js.map +1 -1
  118. package/dist/world/world.transfers.d.ts +137 -0
  119. package/dist/world/world.transfers.js +188 -0
  120. package/dist/world/world.transfers.js.map +1 -0
  121. package/docs/README.md +18 -6
  122. package/docs/components.md +91 -48
  123. package/docs/concepts.md +21 -17
  124. package/docs/design-guide.md +125 -89
  125. package/docs/entities.md +62 -72
  126. package/docs/execution-model.md +26 -10
  127. package/docs/getting-started.md +6 -6
  128. package/docs/glossary.md +19 -10
  129. package/docs/modules.md +8 -8
  130. package/docs/queries-and-filters.md +15 -10
  131. package/docs/relationships.md +250 -115
  132. package/docs/snapshots.md +181 -0
  133. package/docs/systems.md +64 -21
  134. package/docs/utilities.md +10 -6
  135. package/package.json +2 -2
  136. package/skills/vecs/SKILL.md +5 -4
@@ -16,7 +16,7 @@ import { IdentityEntity } from "./entity.identity.js";
16
16
  * ## Deferred semantics
17
17
  *
18
18
  * Inside a system body or `forEach` iteration the world is in **deferred
19
- * mode**: `add` / `attach` / `set` / `ensure` / `ensureTarget` / `modified` / `remove` /
19
+ * mode**: `add` / `attach` / `set` / `ensure` / `modified` / `remove` /
20
20
  * `destroy` only enqueue commands. The data layer (the components map and
21
21
  * `componentBitmask`) is mutated when the world drains its queue. Concretely,
22
22
  * while deferred:
@@ -25,7 +25,6 @@ import { IdentityEntity } from "./entity.identity.js";
25
25
  * - `entity.get(C)` / `entity.getMut(C)` returns `undefined` after `entity.attach(instance)` if C was absent.
26
26
  * - `entity.get(C)` / `entity.getMut(C)` returns the previous value after `entity.set(C, props)`.
27
27
  * - `entity.ensure(C)` returns a mutable component immediately, but `entity.get(C)` does not see it until the queue drains.
28
- * - `entity.ensureTarget(R)` returns its pending target immediately, but `entity.target(R)` does not see it until the queue drains.
29
28
  * - `entity.get(C)` / `entity.getMut(C)` still returns the component after `entity.remove(C)`.
30
29
  *
31
30
  * Outside deferred mode the same calls execute inline and mutations are
@@ -34,7 +33,7 @@ import { IdentityEntity } from "./entity.identity.js";
34
33
  export class Entity extends IdentityEntity {
35
34
  /** Attach this entity to `parent` through the built-in `ChildOf` relationship. */
36
35
  childOf(parent) {
37
- return this.set(ChildOf, { target: parent });
36
+ return this.add(ChildOf, parent);
38
37
  }
39
38
  /** Get this entity's parent through the built-in `ChildOf` relationship, if present. */
40
39
  get parent() {
@@ -1 +1 @@
1
- {"version":3,"file":"entity.js","sourceRoot":"","sources":["../../src/entity/entity.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAE3D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAWtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,OAAO,MAAO,SAAQ,cAAc;IACxC,kFAAkF;IAC3E,OAAO,CAAC,MAAc;QAC3B,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,wFAAwF;IACxF,IAAW,MAAM;QACf,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED,4EAA4E;IAC5E,IAAW,MAAM,CAAC,MAA0B;QAC1C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACvB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,oEAAoE;IACpE,IAAW,SAAS;QAClB,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED,oDAAoD;IACpD,IAAW,KAAK;QACd,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC;IAC1B,CAAC;CACF"}
1
+ {"version":3,"file":"entity.js","sourceRoot":"","sources":["../../src/entity/entity.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAE3D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAWtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,OAAO,MAAO,SAAQ,cAAc;IACxC,kFAAkF;IAC3E,OAAO,CAAC,MAAc;QAC3B,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACnC,CAAC;IAED,wFAAwF;IACxF,IAAW,MAAM;QACf,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED,4EAA4E;IAC5E,IAAW,MAAM,CAAC,MAA0B;QAC1C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACvB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,oEAAoE;IACpE,IAAW,SAAS;QAClB,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED,oDAAoD;IACpD,IAAW,KAAK;QACd,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC;IAC1B,CAAC;CACF"}
@@ -1,4 +1,5 @@
1
1
  import { Components } from "./entity.components.js";
2
+ import type { Entity } from "./entity.js";
2
3
  export declare class Lifecycle extends Components {
3
4
  /**
4
5
  * Destroy this entity.
@@ -6,8 +7,13 @@ export declare class Lifecycle extends Components {
6
7
  * Each component fires its `onRemove` hook, the entity is unregistered from
7
8
  * the world, and incoming relationship cleanup policies are applied. After
8
9
  * destruction the entity must not be used.
10
+ *
11
+ * A synchronous throw (a `Throw`-policy component entity still in use)
12
+ * happens before any mutation, so the world stays usable. A throw during
13
+ * deferred application or a cleanup cascade propagates out of `progress()` /
14
+ * `flush()` and leaves the world partial — treat it as a programming error.
9
15
  */
10
- destroy(): void;
16
+ destroy(this: Entity): void;
11
17
  private _applyOnDelete;
12
18
  /**
13
19
  * Walk this entity's incoming relationships and buffer cleanup ops onto the
@@ -21,39 +21,30 @@ export class Lifecycle extends Components {
21
21
  }
22
22
  try {
23
23
  const entityMeta = this._meta;
24
- // Mark destroyed up front so a carrier cleanup that re-enters this entity's
25
- // `_destroy` (possible with exotic relationship topologies under Delete)
26
- // hits the guard above instead of tearing down twice.
27
- this._destroyed = true;
24
+ let selfCarry = 0;
28
25
  if (entityMeta) {
29
- const selfCarry = this._components.has(entityMeta.eid) ? 1 : 0;
30
- if (entityMeta.usageCount > selfCarry) {
31
- if (entityMeta.onDelete === CleanupPolicy.Throw) {
32
- // The public `destroy()` already throws when an in-use component is
33
- // destroyed; reaching here means usage grew between that check and
34
- // this deferred apply. Abort instead of throwing so a mid-drain
35
- // `_processCommandQueue` is not left half-applied, and revive the
36
- // entity since nothing has been torn down yet.
37
- this._destroyed = false;
38
- return;
39
- }
40
- this._applyOnDelete(entityMeta, selfCarry);
26
+ selfCarry = this._components.has(entityMeta.eid) ? 1 : 0;
27
+ if (entityMeta.usageCount > selfCarry && entityMeta.onDelete === CleanupPolicy.Throw) {
28
+ throw new Error(`Cannot destroy entity ${this.eid}; component eid is still in use`);
41
29
  }
42
30
  }
43
- const entity = this;
44
- this.world._notifyEntityDestroyed(entity);
45
- this._components.forEach((c, ceid) => {
31
+ // Mark destroyed before applying cleanup so a carrier cascade that
32
+ // re-enters this entity cannot tear it down twice.
33
+ this._destroyed = true;
34
+ if (entityMeta && entityMeta.usageCount > selfCarry) {
35
+ this._applyOnDelete(entityMeta, selfCarry);
36
+ }
37
+ this.world._notifyEntityDestroyed(this);
38
+ this._components.forEachSafe((c, ceid) => {
46
39
  const componentMeta = this.world.entity(ceid).meta;
47
40
  if (componentMeta.isRelationship) {
48
- this._removeIncoming(c.target, ceid);
41
+ this._detachRelationship(componentMeta, c);
42
+ return;
49
43
  }
50
44
  this.componentBitmask.deleteBit(componentMeta.bitPtr);
51
- this.world._notifyComponentRemoved(ceid, entity);
52
- componentMeta._decrementUsage();
53
- const removeHandlers = componentMeta._onRemoveHandlers;
54
- if (removeHandlers) {
55
- removeHandlers.forEach((handler) => handler(entity, c));
56
- }
45
+ this.world._notifyComponentRemoved(ceid, this);
46
+ componentMeta._detachCarrier(this);
47
+ componentMeta._onRemove?.(this, c);
57
48
  });
58
49
  this._dirtyComponentBitmask.clear();
59
50
  this._queries.clear();
@@ -61,7 +52,7 @@ export class Lifecycle extends Components {
61
52
  if (entityMeta && entityMeta.usageCount === 0 && entityMeta.Class !== Object) {
62
53
  this.world._classRegistry.delete(entityMeta.Class);
63
54
  }
64
- this.world._unregisterEntity(entity);
55
+ this.world._unregisterEntity(this);
65
56
  this._cleanupIncoming();
66
57
  }
67
58
  finally {
@@ -81,6 +72,11 @@ export class Lifecycle extends Components {
81
72
  * Each component fires its `onRemove` hook, the entity is unregistered from
82
73
  * the world, and incoming relationship cleanup policies are applied. After
83
74
  * destruction the entity must not be used.
75
+ *
76
+ * A synchronous throw (a `Throw`-policy component entity still in use)
77
+ * happens before any mutation, so the world stays usable. A throw during
78
+ * deferred application or a cleanup cascade propagates out of `progress()` /
79
+ * `flush()` and leaves the world partial — treat it as a programming error.
84
80
  */
85
81
  destroy() {
86
82
  const entityMeta = this._meta;
@@ -96,34 +92,28 @@ export class Lifecycle extends Components {
96
92
  this._destroy();
97
93
  }
98
94
  }
99
- // Collect carriers first, then act: the scan must not mutate `world.entities`
100
- // while iterating, and `_destroy` idempotency makes overlapping Delete
101
- // cascades safe. Carriers are cleaned via the internal `_remove`/`_destroy`
102
- // (not the deferred-aware public methods) so `usageCount` drops synchronously
103
- // and the `usageCount === 0` classRegistry cleanup in `_destroy` stays correct.
104
- // Edge: if a Delete carrier is itself an in-use component key with
105
- // `onDelete = Throw`, its `_destroy` safe-aborts and it survives still holding
106
- // this now-destroyed component eid. This is the same exotic policy-interaction
107
- // class flagged in `_cleanupIncoming`; left for the relationship/query rework.
108
95
  _applyOnDelete(entityMeta, selfCarry) {
109
- const ceid = entityMeta.eid;
110
- const carriers = [];
111
- let remaining = entityMeta.usageCount - selfCarry;
112
- this.world.entities.forEach((e) => {
113
- if (remaining > 0 && e !== this && e._get(ceid) !== undefined) {
114
- carriers.push(e);
115
- remaining--;
116
- }
117
- });
96
+ const carriers = entityMeta._carriers;
97
+ if (!carriers || carriers.size <= selfCarry) {
98
+ return;
99
+ }
118
100
  const shouldDelete = entityMeta.onDelete === CleanupPolicy.Delete;
119
- for (const carrier of carriers) {
101
+ // forEachSafe tolerates deletion of the current carrier mid-loop: each
102
+ // `_destroy`/`_remove` below detaches only its own carrier from this meta
103
+ // (via `_detachCarrier`), and any further cascade is buffered onto the
104
+ // world's deletion scope and drained after this scan completes — so no
105
+ // other slot of `carriers` is mutated while we are iterating it.
106
+ carriers.forEachSafe((carrier) => {
107
+ if (carrier === this) {
108
+ return;
109
+ }
120
110
  if (shouldDelete) {
121
111
  carrier._destroy();
122
112
  }
123
113
  else {
124
114
  carrier._remove(entityMeta);
125
115
  }
126
- }
116
+ });
127
117
  }
128
118
  /**
129
119
  * Walk this entity's incoming relationships and buffer cleanup ops onto the
@@ -154,14 +144,11 @@ export class Lifecycle extends Components {
154
144
  // `sources` is iterated read-only here; re-entrant _removeIncoming
155
145
  // mutates it during the scope flush (after this scan completes), not
156
146
  // during this forEach, so no snapshot is needed.
157
- const sourceEntity = source;
158
147
  if (policy === CleanupPolicy.Delete) {
159
- // If source is also an in-use component entity with onDelete Throw,
160
- // this exotic cascade can still throw; revisit with the relationship rework.
161
- scope.push([0 /* DeletionOpKind.Destroy */, sourceEntity]);
148
+ scope.push([0 /* DeletionOpKind.Destroy */, source]);
162
149
  }
163
150
  else {
164
- scope.push([1 /* DeletionOpKind.Remove */, sourceEntity, relEntity.meta]);
151
+ scope.push([1 /* DeletionOpKind.Remove */, source, relEntity.meta, this]);
165
152
  }
166
153
  }
167
154
  });
@@ -183,7 +170,7 @@ export class Lifecycle extends Components {
183
170
  op[1]._destroy();
184
171
  }
185
172
  else {
186
- op[1]._remove(op[2]);
173
+ op[1]._removeTarget(op[2], op[3]);
187
174
  }
188
175
  }
189
176
  }
@@ -1 +1 @@
1
- {"version":3,"file":"entity.lifecycle.js","sourceRoot":"","sources":["../../src/entity/entity.lifecycle.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"entity.lifecycle.js","sourceRoot":"","sources":["../../src/entity/entity.lifecycle.ts"],"names":[],"mappings":"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"}
@@ -33,5 +33,35 @@ export class Queries extends Base {
33
33
  _isMemberOf(q) {
34
34
  return this._queries.has(q);
35
35
  }
36
+ /**
37
+ * @internal Route a `modified` event for component `ceid` to the queries this
38
+ * entity belongs to. Queries that do not watch `ceid` ignore it, so only the
39
+ * watchers matter.
40
+ *
41
+ * When every query watching `ceid` is a system, delivery only queues inbox
42
+ * events and the order across queries is unobservable, so the shorter of the
43
+ * world's watcher list and this entity's membership set is walked. Otherwise
44
+ * the membership set is walked in insertion order exactly as before: a plain
45
+ * query's `update` callback runs synchronously and may change that set
46
+ * mid-walk.
47
+ */
48
+ _routeModified(ceid, component) {
49
+ const watchers = this.world._updateWatchers[ceid];
50
+ if (watchers === undefined) {
51
+ return;
52
+ }
53
+ const queries = this._queries;
54
+ const list = watchers.queries;
55
+ if (watchers.synchronous === 0 && list.length < queries.size) {
56
+ for (let i = 0; i < list.length; i++) {
57
+ const q = list[i];
58
+ if (queries.has(q)) {
59
+ q._notifyModified(this, ceid, component);
60
+ }
61
+ }
62
+ return;
63
+ }
64
+ queries.forEach((q) => q._notifyModified(this, ceid, component));
65
+ }
36
66
  }
37
67
  //# sourceMappingURL=entity.queries.js.map
@@ -1 +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;;;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;IAED;;;;;;OAMG;IACI,WAAW,CAAC,CAAQ;QACzB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC9B,CAAC;CACF"}
1
+ {"version":3,"file":"entity.queries.js","sourceRoot":"","sources":["../../src/entity/entity.queries.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAGxC,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;;;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;IAED;;;;;;OAMG;IACI,WAAW,CAAC,CAAQ;QACzB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC9B,CAAC;IAED;;;;;;;;;;;OAWG;IACI,cAAc,CAAe,IAAS,EAAE,SAA4B;QACzE,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9B,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC;QAC9B,IAAI,QAAQ,CAAC,WAAW,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;YAC7D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACrC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;gBAClB,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;oBACnB,CAAC,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;gBAC3C,CAAC;YACH,CAAC;YACD,OAAO;QACT,CAAC;QACD,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;IACnE,CAAC;CACF"}
@@ -4,6 +4,10 @@ import { Queries } from "./entity.queries.js";
4
4
  export declare class Relationships extends Queries {
5
5
  /** Return this entity's target through relationship `ref`, if present. */
6
6
  target(rel: ComponentRef): Entity | undefined;
7
+ /** Return a safe readonly snapshot of all targets through relationship `ref`. */
8
+ targets(rel: ComponentRef): readonly Entity[];
9
+ /** Return whether this entity targets `target` through relationship `ref`. */
10
+ hasTarget(rel: ComponentRef, target: Entity): boolean;
7
11
  /** Return entities targeting this one through relationship `ref`. */
8
12
  children(ref: ComponentRef): ReadonlySet<Entity>;
9
13
  }
@@ -5,7 +5,21 @@ export class Relationships extends Queries {
5
5
  /** Return this entity's target through relationship `ref`, if present. */
6
6
  target(rel) {
7
7
  const relEid = typeof rel === "number" ? rel : this.world.entity(rel).eid;
8
- return this._components.get(relEid)?.target;
8
+ return this._components.get(relEid)?._target();
9
+ }
10
+ /** Return a safe readonly snapshot of all targets through relationship `ref`. */
11
+ targets(rel) {
12
+ const relEid = typeof rel === "number" ? rel : this.world.entity(rel).eid;
13
+ return this._components.get(relEid)?._targetArray() ?? [];
14
+ }
15
+ /** Return whether this entity targets `target` through relationship `ref`. */
16
+ hasTarget(rel, target) {
17
+ const relEid = typeof rel === "number" ? rel : this.world.entity(rel).eid;
18
+ return this._components.get(relEid)?._hasTarget(target) ?? false;
19
+ }
20
+ /** @internal Test targets by relationship eid without allocating a snapshot. */
21
+ _someTargetByEid(relEid, predicate) {
22
+ return (this._components.get(relEid)?._someTarget(predicate) ?? false);
9
23
  }
10
24
  /** Return entities targeting this one through relationship `ref`. */
11
25
  children(ref) {
@@ -43,15 +57,9 @@ export class Relationships extends Queries {
43
57
  }
44
58
  }
45
59
  /** @internal */
46
- _updateIncoming(meta, oldTarget, newTarget) {
47
- if (!meta.isRelationship || oldTarget === newTarget) {
48
- return;
49
- }
50
- this._removeIncoming(oldTarget, meta.eid);
51
- this._addIncoming(newTarget, meta.eid);
52
- if (oldTarget && newTarget) {
53
- meta._onRetargetHandlers?.forEach((handler) => handler(this, oldTarget, newTarget));
54
- }
60
+ _notifyRelationshipChanged(meta, relationship) {
61
+ this.world._notifyComponentChanged(meta.eid, this);
62
+ this._routeModified(meta.eid, relationship);
55
63
  }
56
64
  }
57
65
  //# sourceMappingURL=entity.relationships.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"entity.relationships.js","sourceRoot":"","sources":["../../src/entity/entity.relationships.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,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,MAAM,MAAM,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC;QAC1E,OAAQ,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAA8B,EAAE,MAAM,CAAC;IAC5E,CAAC;IAED,qEAAqE;IAC9D,QAAQ,CAAC,GAAiB;QAC/B,MAAM,MAAM,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC;QAC1E,OAAO,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,aAAa,CAAC,cAAc,CAAC;IACrE,CAAC;IAED;;;OAGG;IACI,cAAc,CAAC,MAAW;QAC/B,OAAO,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;IAED,gBAAgB;IACN,YAAY,CAAC,MAA0B,EAAE,MAAW;QAC5D,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,gBAAgB,EAAE,EAAC,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACrE,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,IAAyB,CAAC,CAAC;IACzC,CAAC;IAED,gBAAgB;IACN,eAAe,CAAC,MAA0B,EAAE,MAAW;QAC/D,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;QACvC,IAAI,SAAS,IAAI,SAAS,EAAE,CAAC;YAC3B,IAAI,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAC5C,OAAO,CAAC,IAAyB,EAAE,SAAS,EAAE,SAAS,CAAC,CACzD,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"entity.relationships.js","sourceRoot":"","sources":["../../src/entity/entity.relationships.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -2,17 +2,20 @@ export { System, type SystemQuery } from "./system.js";
2
2
  export { Query, GroupedQuery, Group } from "./query/index.js";
3
3
  export type { EntityTestFunc, MaybeRequired, QueryDSL } from "./dsl.js";
4
4
  export { Iter } from "./inject.js";
5
- export type { DownInject, FanInjectElement, FanInjectTuple, InjectElement, InjectTuple, MaybeResolvedInjectTuple, RequiredResolvedInjectTuple, TargetInject, } from "./inject.js";
5
+ export type { DownInject, FanInjectElement, FanInjectTuple, InjectElement, InjectTuple, MaybeResolvedInjectTuple, RequiredResolvedInjectTuple, ResolvedTargets, ResolvedTargetsRow, TargetInject, TargetInjectProjection, TargetsInject, } from "./inject.js";
6
6
  export { DEFAULT_POOLS, World, type WorldOptions } from "./world/index.js";
7
7
  export { Filter } from "./filter.js";
8
- export { ChildOf, DependsOn, OwnedTarget, SilenceSource } from "./modules/relationships.js";
9
- export { CleanupPolicy, Component, Implements, Relationship, type ComponentInstance, type ComponentClass, type ComponentMeta, type ComponentRef, type RetargetHandler, } from "./component.js";
8
+ export { ChildOf, DependsOn, Exclusive, OneOf, OwnedTarget, SilenceSource, } from "./modules/relationships.js";
9
+ export { CleanupPolicy, Component, Implements, Relationship, type ComponentInstance, type ComponentClass, type ComponentMeta, type ComponentRef, type CustomSnapshotOptions, type HookEvent, type HookEventMap, type HookHandler, type TargetHandler, } from "./component.js";
10
10
  export { Entity, type EID, type EntityClass, Identity } from "./entity/index.js";
11
11
  export { Module, type ModuleConfig } from "./module.js";
12
+ export { MoveSubtreeError } from "./world/world.transfers.js";
12
13
  export { IdentityModule } from "./modules/identity.js";
13
14
  export { ImplementsModule } from "./modules/implements.js";
14
15
  export { Singleton, SingletonModule } from "./modules/singleton.js";
15
- export { Traversable, RelationshipsModule } from "./modules/relationships.js";
16
+ export { Traversable, With, RelationshipsModule } from "./modules/relationships.js";
17
+ export { type SnapshotCapture, type SnapshotMaterialize, ClonePublic, CustomSnapshot, DontSnapshot, OnSnapshot, SnapshotModule, } from "./modules/snapshot.js";
18
+ export { type ComponentSnapshot, type EntitySubtreeSnapshot, type ExternalTargetPolicy, type MoveSubtreeResult, type RelationshipSnapshot, type RelationshipType, type RestoreSubtreeResult, type SubtreeEntitySnapshot, type SubtreeSnapshotOptions, } from "./snapshot/types.js";
16
19
  export { BUILTIN_PIPELINE_PHASES, insertPhaseAfter, ON_LOAD, ON_STORE, ON_UPDATE, ON_VALIDATE, POST_LOAD, POST_UPDATE, PRE_STORE, PRE_UPDATE, Phase, PipelineModule, } from "./modules/pipeline.js";
17
20
  export { getDSLKey } from "./dsl.js";
18
21
  export { Term, TermEventKind, type TermConsumer } from "./terms/term.js";
package/dist/index.js CHANGED
@@ -3,14 +3,16 @@ export { Query, GroupedQuery, Group } from "./query/index.js";
3
3
  export { Iter } from "./inject.js";
4
4
  export { DEFAULT_POOLS, World } from "./world/index.js";
5
5
  export { Filter } from "./filter.js";
6
- export { ChildOf, DependsOn, OwnedTarget, SilenceSource } from "./modules/relationships.js";
6
+ export { ChildOf, DependsOn, Exclusive, OneOf, OwnedTarget, SilenceSource, } from "./modules/relationships.js";
7
7
  export { CleanupPolicy, Component, Implements, Relationship, } from "./component.js";
8
8
  export { Entity, Identity } from "./entity/index.js";
9
9
  export { Module } from "./module.js";
10
+ export { MoveSubtreeError } from "./world/world.transfers.js";
10
11
  export { IdentityModule } from "./modules/identity.js";
11
12
  export { ImplementsModule } from "./modules/implements.js";
12
13
  export { Singleton, SingletonModule } from "./modules/singleton.js";
13
- export { Traversable, RelationshipsModule } from "./modules/relationships.js";
14
+ export { Traversable, With, RelationshipsModule } from "./modules/relationships.js";
15
+ export { ClonePublic, CustomSnapshot, DontSnapshot, OnSnapshot, SnapshotModule, } from "./modules/snapshot.js";
14
16
  export { BUILTIN_PIPELINE_PHASES, insertPhaseAfter, ON_LOAD, ON_STORE, ON_UPDATE, ON_VALIDATE, POST_LOAD, POST_UPDATE, PRE_STORE, PRE_UPDATE, Phase, PipelineModule, } from "./modules/pipeline.js";
15
17
  export { getDSLKey } from "./dsl.js";
16
18
  export { Term } from "./terms/term.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAoB,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAE9D,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAWnC,OAAO,EAAE,aAAa,EAAE,KAAK,EAAqB,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC5F,OAAO,EACL,aAAa,EACb,SAAS,EACT,UAAU,EACV,YAAY,GAMb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,MAAM,EAA8B,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAAE,MAAM,EAAqB,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAC9E,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EAChB,OAAO,EACP,QAAQ,EACR,SAAS,EACT,WAAW,EACX,SAAS,EACT,WAAW,EACX,SAAS,EACT,UAAU,EACV,KAAK,EACL,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,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,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAuC,MAAM,kBAAkB,CAAC;AAC/E,OAAO,EAAE,4BAA4B,EAAqB,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAoB,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAE9D,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAenC,OAAO,EAAE,aAAa,EAAE,KAAK,EAAqB,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EACL,OAAO,EACP,SAAS,EACT,SAAS,EACT,KAAK,EACL,WAAW,EACX,aAAa,GACd,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,aAAa,EACb,SAAS,EACT,UAAU,EACV,YAAY,GAUb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,MAAM,EAA8B,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAAE,MAAM,EAAqB,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACpF,OAAO,EAGL,WAAW,EACX,cAAc,EACd,YAAY,EACZ,UAAU,EACV,cAAc,GACf,MAAM,uBAAuB,CAAC;AAY/B,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EAChB,OAAO,EACP,QAAQ,EACR,SAAS,EACT,WAAW,EACX,SAAS,EACT,WAAW,EACX,SAAS,EACT,UAAU,EACV,KAAK,EACL,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,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,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAuC,MAAM,kBAAkB,CAAC;AAC/E,OAAO,EAAE,4BAA4B,EAAqB,MAAM,mBAAmB,CAAC"}
package/dist/inject.d.ts CHANGED
@@ -2,30 +2,70 @@ import { type ComponentInstance, type ComponentRef, type ComponentType } from ".
2
2
  import { Entity, type EID } from "./entity/index.js";
3
3
  import { type World } from "./world/index.js";
4
4
  import { type MaybeRequired } from "./dsl.js";
5
- export type TargetInject<J extends readonly ComponentType[] = readonly ComponentType[]> = {
6
- target: readonly [ComponentRef, readonly [...J]];
5
+ export type TargetInjectProjection = ComponentType | typeof Entity;
6
+ /**
7
+ * Follows a relationship and injects values from its target into a callback tuple.
8
+ *
9
+ * Pass one component class or {@link Entity} directly for a single slot, or pass
10
+ * a tuple to project several slots in order:
11
+ *
12
+ * ```ts
13
+ * { target: [FriendOf, Position] } // Position | undefined
14
+ * { target: [FriendOf, Entity] } // Entity | undefined
15
+ * { target: [FriendOf, [Entity, Position]] } // Entity | undefined, Position | undefined
16
+ * ```
17
+ *
18
+ * Every projected slot is optional because the relationship or target-side
19
+ * component may be absent when the callback runs.
20
+ */
21
+ export type TargetInject<P extends TargetInjectProjection | readonly TargetInjectProjection[] = TargetInjectProjection | readonly TargetInjectProjection[]> = {
22
+ target: readonly [ComponentRef, P];
23
+ };
24
+ /**
25
+ * Follows every target of a relationship and injects one array-valued tuple slot.
26
+ * Each array entry is a projected tuple for one target, in relationship order.
27
+ */
28
+ export type TargetsInject<P extends TargetInjectProjection | readonly TargetInjectProjection[] = TargetInjectProjection | readonly TargetInjectProjection[]> = {
29
+ targets: readonly [ComponentRef, P];
7
30
  };
8
31
  export type DownInject<J extends readonly ComponentType[] = readonly ComponentType[]> = {
9
32
  down: readonly [ComponentRef, readonly [...J]];
10
33
  };
11
- export type InjectElement = ComponentType | TargetInject;
34
+ export type InjectElement = ComponentType | TargetInject | TargetsInject;
12
35
  export type InjectTuple = readonly InjectElement[];
13
36
  export type FanInjectElement = InjectElement | DownInject;
14
37
  export type FanInjectTuple = readonly FanInjectElement[];
15
38
  export type ResolvedInjectTerm = EID | {
16
39
  target: readonly [EID, readonly EID[]];
40
+ } | {
41
+ targets: readonly [EID, readonly EID[]];
17
42
  } | {
18
43
  down: readonly [EID, readonly EID[]];
19
44
  };
20
- export type InjectSnapshot = readonly (ComponentInstance | undefined)[];
21
- export type InjectSnapshotTypes = readonly (EID | undefined)[];
22
45
  /** Resolves the component instance type for one injected component class. */
23
46
  type ResolvedComponentInstance<T> = T extends ComponentType ? InstanceType<T> : never;
24
47
  type OptionalResolvedComponentInstances<J extends readonly ComponentType[]> = {
25
48
  [K in keyof J]: InstanceType<J[K]> | undefined;
26
49
  };
27
- type MaybeResolvedInjectElement<T, R extends ComponentType[]> = T extends ComponentType ? [MaybeRequired<T, R>] : T extends TargetInject<infer J> ? OptionalResolvedComponentInstances<J> : T extends DownInject<infer J> ? OptionalResolvedComponentInstances<J> : [];
28
- type RequiredResolvedInjectElement<T> = T extends ComponentType ? [ResolvedComponentInstance<T>] : T extends TargetInject<infer J> ? OptionalResolvedComponentInstances<J> : T extends DownInject<infer J> ? OptionalResolvedComponentInstances<J> : [];
50
+ type OptionalResolvedTargetProjection<P> = P extends typeof Entity ? Entity | undefined : P extends ComponentType ? InstanceType<P> | undefined : never;
51
+ type OptionalResolvedTargetProjections<P> = P extends readonly TargetInjectProjection[] ? {
52
+ [K in keyof P]: OptionalResolvedTargetProjection<P[K]>;
53
+ } : [OptionalResolvedTargetProjection<P>];
54
+ type ResolvedTargetsProjection<P> = P extends typeof Entity ? Entity : P extends ComponentType ? InstanceType<P> | undefined : never;
55
+ /** One projected row produced by a {@link TargetsInject}. */
56
+ export type ResolvedTargetsRow<P> = P extends readonly TargetInjectProjection[] ? {
57
+ readonly [K in keyof P]: ResolvedTargetsProjection<P[K]>;
58
+ } : readonly [ResolvedTargetsProjection<P>];
59
+ /** The single array-valued callback slot produced by a {@link TargetsInject}. */
60
+ export type ResolvedTargets<P> = ReadonlyArray<ResolvedTargetsRow<P>>;
61
+ export type InjectedValue = ComponentInstance | Entity | ReadonlyArray<readonly (ComponentInstance | Entity | undefined)[]> | undefined;
62
+ export type InjectSource = Entity | readonly Entity[] | undefined;
63
+ export type InjectSnapshot = {
64
+ readonly values: readonly InjectedValue[];
65
+ readonly src: readonly InjectSource[];
66
+ };
67
+ type MaybeResolvedInjectElement<T, R extends ComponentType[]> = T extends ComponentType ? [MaybeRequired<T, R>] : T extends TargetInject<infer P> ? OptionalResolvedTargetProjections<P> : T extends TargetsInject<infer P> ? [ResolvedTargets<P>] : T extends DownInject<infer J> ? OptionalResolvedComponentInstances<J> : [];
68
+ type RequiredResolvedInjectElement<T> = T extends ComponentType ? [ResolvedComponentInstance<T>] : T extends TargetInject<infer P> ? OptionalResolvedTargetProjections<P> : T extends TargetsInject<infer P> ? [ResolvedTargets<P>] : T extends DownInject<infer J> ? OptionalResolvedComponentInstances<J> : [];
29
69
  export type MaybeResolvedInjectTuple<J extends FanInjectTuple, R extends ComponentType[]> = J extends readonly [infer First, ...infer Rest extends FanInjectTuple] ? [...MaybeResolvedInjectElement<First, R>, ...MaybeResolvedInjectTuple<Rest, R>] : [];
30
70
  export type RequiredResolvedInjectTuple<J extends InjectTuple> = J extends readonly [
31
71
  infer First,
@@ -33,10 +73,18 @@ export type RequiredResolvedInjectTuple<J extends InjectTuple> = J extends reado
33
73
  ] ? [...RequiredResolvedInjectElement<First>, ...RequiredResolvedInjectTuple<Rest>] : [];
34
74
  export declare function mapInject(world: World, inject: readonly FanInjectElement[]): ResolvedInjectTerm[];
35
75
  export declare function injectArity(inject: readonly ResolvedInjectTerm[]): number;
36
- export declare function getInjected(e: Entity, inject: readonly ResolvedInjectTerm[], requireDirectComponents: boolean, out: (ComponentInstance | undefined)[], snapshot?: InjectSnapshot): void;
37
- export declare function getInjectedWithSrc(e: Entity, inject: readonly ResolvedInjectTerm[], out: (ComponentInstance | undefined)[], src: (Entity | undefined)[], requireDirectComponents?: boolean, exitSnapshot?: InjectSnapshot): void;
38
- export declare function directInjectEids(inject: readonly ResolvedInjectTerm[]): EID[];
39
- export declare function directInjectSnapshotTypes(inject: readonly ResolvedInjectTerm[]): InjectSnapshotTypes | undefined;
76
+ export declare function getInjected(e: Entity, inject: readonly ResolvedInjectTerm[], requireDirectComponents: boolean, out: InjectedValue[]): void;
77
+ export declare function getInjectedWithSrc(e: Entity, inject: readonly ResolvedInjectTerm[], out: InjectedValue[], src: InjectSource[], requireDirectComponents?: boolean): void;
78
+ /** Capture a detached injection tuple and its source tuple for deferred callback replay. */
79
+ export declare function snapshotInjected(e: Entity, inject: readonly ResolvedInjectTerm[], arity: number): InjectSnapshot;
80
+ export declare function replayInjectedSnapshot(inject: readonly ResolvedInjectTerm[], snapshot: InjectSnapshot, requireDirectComponents: boolean, out: InjectedValue[]): void;
81
+ export declare function replayInjectedSnapshotWithSrc(inject: readonly ResolvedInjectTerm[], snapshot: InjectSnapshot, requireDirectComponents: boolean, out: InjectedValue[], src: InjectSource[]): void;
82
+ /**
83
+ * Component eids whose changes can alter a resolved tuple: directly injected
84
+ * component eids plus the relationship eid of every `target` / `targets` term.
85
+ * Callers watch these to re-sort or re-key when a tuple input changes.
86
+ */
87
+ export declare function injectWatchEids(inject: readonly ResolvedInjectTerm[]): EID[];
40
88
  /**
41
89
  * Per-iteration cursor passed to `each` / `forEach` / `enter` / `exit` /
42
90
  * `update` / `orderBy` callbacks when the caller opts in by passing `Iter` as
@@ -61,11 +109,12 @@ export declare class Iter {
61
109
  /**
62
110
  * Source entity for each injected component, in the same order as the
63
111
  * resolved tuple: the visited entity for a directly-injected component, the
64
- * relationship target for a `target`-injected one, or the specific child for
112
+ * relationship target for a `target`-injected one, the target array for a
113
+ * `targets`-injected one, or the specific child for
65
114
  * a `down`-injected one (`undefined` when the entity has no such relationship,
66
115
  * target, or — for `down` — when the slot is unfilled).
67
116
  */
68
- readonly src: (Entity | undefined)[];
117
+ readonly src: InjectSource[];
69
118
  constructor(arity: number);
70
119
  }
71
120
  export declare function wantsIter(x: unknown): x is typeof Iter;
@@ -74,7 +123,7 @@ export type FanInjectCallbackOptions<J extends FanInjectTuple = FanInjectTuple>
74
123
  inject: readonly [...J];
75
124
  };
76
125
  export type FanInjectCallbackArg<J extends FanInjectTuple = FanInjectTuple> = readonly [...J] | FanInjectCallbackOptions<J>;
77
- export type InjectedCallback = (eOrIt: Entity | Iter, resolved: readonly (ComponentInstance | undefined)[]) => void;
126
+ export type InjectedCallback = (eOrIt: Entity | Iter, resolved: readonly InjectedValue[]) => void;
78
127
  /**
79
128
  * Iterate `entities`, resolving injected components per the `forEach` /
80
129
  * `each` argument grammar (bare callback, `[components]`, or