@vworlds/vecs 1.0.45 → 1.0.47

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 -60
  3. package/dist/component.js +24 -17
  4. package/dist/component.js.map +1 -1
  5. package/dist/component_meta.d.ts +67 -79
  6. package/dist/component_meta.js +331 -37
  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 -41
  13. package/dist/entity/entity.components.js +249 -82
  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 -50
  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 -6
  39. package/dist/modules/relationship_types.js +70 -6
  40. package/dist/modules/relationship_types.js.map +1 -1
  41. package/dist/modules/relationships.d.ts +31 -9
  42. package/dist/modules/relationships.js +120 -44
  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 +90 -53
  123. package/docs/concepts.md +21 -17
  124. package/docs/design-guide.md +125 -94
  125. package/docs/entities.md +62 -76
  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 +245 -124
  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
@@ -25,6 +25,8 @@ export class Term {
25
25
  this._entities = new Set();
26
26
  this._destroyed = false;
27
27
  this._childUnsubscribes = [];
28
+ /** Consumers that may act on a refresh while no membership event is in flight. */
29
+ this._quiescentRefreshConsumers = 0;
28
30
  }
29
31
  get count() {
30
32
  return this._entities.size;
@@ -72,13 +74,19 @@ export class Term {
72
74
  throw new Error(`Cannot subscribe to destroyed ${this.kind} term`);
73
75
  }
74
76
  this._consumers.add(consumer);
77
+ const refreshesWhileQuiescent = consumer.onTermRefresh !== undefined && consumer._refreshesOnlyInFlight !== true;
78
+ if (refreshesWhileQuiescent) {
79
+ this._quiescentRefreshConsumers++;
80
+ }
75
81
  let active = true;
76
82
  return () => {
77
83
  if (!active) {
78
84
  return;
79
85
  }
80
86
  active = false;
81
- this._consumers.delete(consumer);
87
+ if (this._consumers.delete(consumer) && refreshesWhileQuiescent) {
88
+ this._quiescentRefreshConsumers--;
89
+ }
82
90
  if (!this._pinned && this._consumers.size === 0) {
83
91
  this.destroy();
84
92
  }
@@ -98,29 +106,57 @@ export class Term {
98
106
  }
99
107
  this._destroyed = true;
100
108
  this._consumers.clear();
109
+ this._quiescentRefreshConsumers = 0;
101
110
  while (this._childUnsubscribes.length > 0) {
102
111
  this._childUnsubscribes.pop()();
103
112
  }
104
113
  this._entities.clear();
105
114
  this._onDestroy(this);
106
115
  }
107
- /** @internal Emit an enter event and add entity; no-op if already present. */
116
+ /**
117
+ * @internal Emit an enter event and add entity; no-op if already present.
118
+ *
119
+ * The world's `_termEmitDepth` counts the delivery as in flight from the
120
+ * membership change until every consumer has seen it.
121
+ */
108
122
  _add(entity) {
109
123
  if (this._entities.has(entity)) {
110
124
  return;
111
125
  }
112
- this._entities.add(entity);
113
- this._emit(0 /* TermEventKind.Enter */, entity);
126
+ const world = this.world;
127
+ world._termEmitDepth++;
128
+ try {
129
+ this._entities.add(entity);
130
+ this._emit(0 /* TermEventKind.Enter */, entity);
131
+ }
132
+ finally {
133
+ world._termEmitDepth--;
134
+ }
114
135
  }
115
- /** @internal Emit an exit event and remove entity; no-op if not present. */
136
+ /** @internal Emit an exit event and remove entity; no-op if not present. Counted like {@link _add}. */
116
137
  _delete(entity) {
117
- if (!this._entities.delete(entity)) {
118
- return;
138
+ const world = this.world;
139
+ world._termEmitDepth++;
140
+ try {
141
+ if (this._entities.delete(entity)) {
142
+ this._emit(1 /* TermEventKind.Exit */, entity);
143
+ }
144
+ }
145
+ finally {
146
+ world._termEmitDepth--;
119
147
  }
120
- this._emit(1 /* TermEventKind.Exit */, entity);
121
148
  }
122
- /** @internal Propagate a refresh hint to all consumers (both channels). */
149
+ /**
150
+ * @internal Propagate a refresh hint to all consumers (both channels).
151
+ *
152
+ * Skipped when no membership event is in flight and every consumer either
153
+ * has no `onTermRefresh` or only acts on one while an event is in flight: no
154
+ * consumer would do anything.
155
+ */
123
156
  _emitRefresh(entity) {
157
+ if (this._quiescentRefreshConsumers === 0 && this.world._termEmitDepth === 0) {
158
+ return;
159
+ }
124
160
  this._consumers.forEach((consumer) => consumer.onTermRefresh?.(entity));
125
161
  }
126
162
  /** @internal Register an additional cleanup callback run during `destroy`. */
@@ -153,13 +189,24 @@ export class Term {
153
189
  */
154
190
  _setChildren(children) {
155
191
  this._children.push(...children);
192
+ const refreshesOnlyInFlight = this._childRefreshesOnlyInFlight();
156
193
  children.forEach((child) => {
157
194
  this._childUnsubscribes.push(child.subscribe({
158
195
  onTermEvent: (kind, entity) => this._onChildEvent(kind, entity, child),
159
196
  onTermRefresh: (entity) => this._onChildRefresh(entity, child),
197
+ _refreshesOnlyInFlight: refreshesOnlyInFlight,
160
198
  }));
161
199
  });
162
200
  }
201
+ /**
202
+ * @internal Whether {@link _onChildRefresh} only acts while a membership
203
+ * event is in flight. Terms whose membership depends on child membership
204
+ * alone (`all`, `any`, `not`) return `true`, which lets a child skip
205
+ * delivering refreshes to them while the world is quiescent.
206
+ */
207
+ _childRefreshesOnlyInFlight() {
208
+ return false;
209
+ }
163
210
  /**
164
211
  * @internal Default child membership-event handler: forward to
165
212
  * `onTermEvent`. Composite terms (e.g. `TargetTerm`) override this to
@@ -174,7 +221,9 @@ export class Term {
174
221
  * Most composites delegate to `onTermRefresh` which defaults to `_sync`.
175
222
  * Subclasses that only want to react to *specific* child kinds (e.g.
176
223
  * `PredicateTerm` reacting only to component-kind children) override this
177
- * to filter before calling `_sync`.
224
+ * to filter before calling `_sync`. `AllTerm` and `AnyTerm`, whose membership
225
+ * depends only on their children's membership, ignore refreshes unless a
226
+ * membership event is still in flight.
178
227
  */
179
228
  _onChildRefresh(entity, _child) {
180
229
  this.onTermRefresh(entity);
@@ -1 +1 @@
1
- {"version":3,"file":"term.js","sourceRoot":"","sources":["../../src/terms/term.ts"],"names":[],"mappings":"AAoDA;;;;;;;;;;;GAWG;AACH,MAAM,OAAgB,IAAI;IAUxB,YACkB,KAAY,EACZ,GAAW,EACX,IAAc,EACb,OAAgB,EAChB,UAAgC;QAJjC,UAAK,GAAL,KAAK,CAAO;QACZ,QAAG,GAAH,GAAG,CAAQ;QACX,SAAI,GAAJ,IAAI,CAAU;QACb,YAAO,GAAP,OAAO,CAAS;QAChB,eAAU,GAAV,UAAU,CAAsB;QAdnD,gBAAgB;QACG,cAAS,GAAW,EAAE,CAAC;QAC1C,gBAAgB;QACG,eAAU,GAAG,IAAI,GAAG,EAAgB,CAAC;QACxD,gBAAgB;QACG,cAAS,GAAG,IAAI,GAAG,EAAU,CAAC;QACzC,eAAU,GAAG,KAAK,CAAC;QACV,uBAAkB,GAAmB,EAAE,CAAC;IAQtD,CAAC;IAEJ,IAAW,KAAK;QACd,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;IAC7B,CAAC;IAEM,CAAC,MAAM,CAAC,QAAQ,CAAC;QACtB,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;IAC3C,CAAC;IAEM,QAAQ;QACb,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAEM,GAAG,CAAC,MAAc;QACvB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IAED;;;;OAIG;IACI,WAAW,CAAC,KAAoB,EAAE,MAAc;QACrD,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACrB,CAAC;IAED;;;;;;;OAOG;IACI,aAAa,CAAC,MAAc;QACjC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACrB,CAAC;IAED;;;;;;;;;OASG;IACI,SAAS,CAAC,QAAsB;QACrC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,iCAAiC,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC;QACrE,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC9B,IAAI,MAAM,GAAG,IAAI,CAAC;QAClB,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,OAAO;YACT,CAAC;YACD,MAAM,GAAG,KAAK,CAAC;YACf,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACjC,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBAChD,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,CAAC;QACH,CAAC,CAAC;IACJ,CAAC;IAED;;;;;;;OAOG;IACI,OAAO;QACZ,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACpC,OAAO;QACT,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1C,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAG,EAAE,CAAC;QACnC,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QACvB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,8EAA8E;IACpE,IAAI,CAAC,MAAc;QAC3B,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YAC/B,OAAO;QACT,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC3B,IAAI,CAAC,KAAK,8BAAsB,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED,4EAA4E;IAClE,OAAO,CAAC,MAAc;QAC9B,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YACnC,OAAO;QACT,CAAC;QACD,IAAI,CAAC,KAAK,6BAAqB,MAAM,CAAC,CAAC;IACzC,CAAC;IAED,2EAA2E;IACjE,YAAY,CAAC,MAAc;QACnC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAC1E,CAAC;IAED,8EAA8E;IACpE,gBAAgB,CAAC,OAAmB;QAC5C,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC;IAED;;;;;;OAMG;IACO,oBAAoB;QAC5B,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;YACrC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC1B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;OASG;IACO,YAAY,CAAC,QAAyB;QAC9C,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;QACjC,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACzB,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAC1B,KAAK,CAAC,SAAS,CAAC;gBACd,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC;gBACtE,aAAa,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,KAAK,CAAC;aAC/D,CAAC,CACH,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACO,aAAa,CAAC,IAAmB,EAAE,MAAc,EAAE,MAAY;QACvE,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACjC,CAAC;IAED;;;;;;;OAOG;IACO,eAAe,CAAC,MAAc,EAAE,MAAY;QACpD,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;IAKD;;;;;;;OAOG;IACO,KAAK,CAAC,MAAc;QAC5B,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,IAAmB,EAAE,MAAc;QAC/C,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5E,CAAC;CACF"}
1
+ {"version":3,"file":"term.js","sourceRoot":"","sources":["../../src/terms/term.ts"],"names":[],"mappings":"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"}
@@ -47,21 +47,37 @@ export declare class ArrayMap<T> {
47
47
  * An iterable `Map<number, T>` substitute backed by dense entries plus sparse indexes.
48
48
  *
49
49
  * Use this when callers need fast `forEach` or `values` over present entries.
50
- * Random access resolves `key -> dense index` through {@link ArrayMap}, then
51
- * indexes into `_items`; iteration walks the dense `_items` array directly.
50
+ * Random access reads the entry's dense position from a sparse slot array
51
+ * indexed by key, then reads the value from the dense value array; iteration
52
+ * walks the dense key and value arrays directly.
52
53
  *
53
- * Deletes keep `_items` dense by moving the last value into the removed slot
54
- * and updating the moved value's stored index.
54
+ * Deletes keep the dense arrays dense by moving the last entry into the removed
55
+ * position and updating the moved entry's slot.
55
56
  *
56
- * Compared with {@link ArrayMap}, this costs extra memory for tuple storage and
57
- * an index map, and `delete`/new `set` do more bookkeeping. In return, iteration
58
- * is dense and does not scan sparse holes.
57
+ * Compared with {@link ArrayMap}, this costs extra memory for the dense arrays,
58
+ * and `delete`/new `set` do more bookkeeping. In return, iteration is dense and
59
+ * does not scan sparse holes.
60
+ *
61
+ * Trade-off: the dense arrays grow by `push`, so V8 cannot pretenure the entries
62
+ * the way it pretenured the per-entry `[key, value]` literals of the previous
63
+ * layout. A fresh process that creates tens of thousands of long-lived entities
64
+ * in bulk and then destroys them is slower for it: 3–17% to create and 19–35%
65
+ * to destroy 65,536 two-component entities. The gap comes from allocation-site
66
+ * pretenuring, not extra work, and it reverses under
67
+ * `node --no-allocation-site-pretenuring`. Lookups take two loads instead of
68
+ * four, and the layout took about 9% off the steady-state tick of
69
+ * `bench/sector-tick.ts`; `bench/README.md` has the measurements.
59
70
  *
60
71
  * @typeParam T - Value type stored in the map.
61
72
  */
62
73
  export declare class IterableArrayMap<T> {
63
- private readonly _indices;
64
- private readonly _items;
74
+ /**
75
+ * Key -> dense position + 1. Holes and `0` mean "absent", so the array only
76
+ * ever holds small integers and lookups stay on V8's fast SMI elements path.
77
+ */
78
+ private readonly _slots;
79
+ private readonly _keys;
80
+ private readonly _values;
65
81
  /** The number of entries currently in the map. */
66
82
  get size(): number;
67
83
  /**
@@ -95,12 +111,27 @@ export declare class IterableArrayMap<T> {
95
111
  * @param callback - Invoked with `(value, key, map)` for each entry.
96
112
  */
97
113
  forEach(callback: (value: T, key: number, map: IterableArrayMap<T>) => void): void;
114
+ /**
115
+ * Visit every present entry tolerating deletion of the **current** entry
116
+ * from inside the callback.
117
+ *
118
+ * `delete` swaps the last entry into the vacated slot, which the plain
119
+ * {@link IterableArrayMap.forEach} would skip. This variant re-visits the
120
+ * slot after the callback returns when a new entry has been swapped in, so
121
+ * the swapped-in entry is visited next. Deleting the last entry (no swap,
122
+ * slot just pops out of bounds) is detected via a length check.
123
+ *
124
+ * Only deletion of the current entry is safe. A callback that deletes a
125
+ * *different* (lower-indexed) entry will still cause that swapped-in entry
126
+ * to be skipped — callers that mutate other slots must keep using a
127
+ * snapshot.
128
+ */
129
+ forEachSafe(callback: (value: T, key: number, map: IterableArrayMap<T>) => void): void;
98
130
  /**
99
131
  * Return an iterator over `[key, value]` entries in dense item order.
100
132
  *
101
- * Entries are backed by the map's internal storage for speed. Treat them as
102
- * immutable; mutating them through casts or plain JavaScript can corrupt the
103
- * map's key index.
133
+ * Each entry is a fresh pair read from the map's current contents as the
134
+ * iterator advances.
104
135
  */
105
136
  entries(): IterableIterator<readonly [number, T]>;
106
137
  /** Return an iterator over `[key, value]` entries in dense item order. */
@@ -70,26 +70,42 @@ export class ArrayMap {
70
70
  * An iterable `Map<number, T>` substitute backed by dense entries plus sparse indexes.
71
71
  *
72
72
  * Use this when callers need fast `forEach` or `values` over present entries.
73
- * Random access resolves `key -> dense index` through {@link ArrayMap}, then
74
- * indexes into `_items`; iteration walks the dense `_items` array directly.
73
+ * Random access reads the entry's dense position from a sparse slot array
74
+ * indexed by key, then reads the value from the dense value array; iteration
75
+ * walks the dense key and value arrays directly.
75
76
  *
76
- * Deletes keep `_items` dense by moving the last value into the removed slot
77
- * and updating the moved value's stored index.
77
+ * Deletes keep the dense arrays dense by moving the last entry into the removed
78
+ * position and updating the moved entry's slot.
78
79
  *
79
- * Compared with {@link ArrayMap}, this costs extra memory for tuple storage and
80
- * an index map, and `delete`/new `set` do more bookkeeping. In return, iteration
81
- * is dense and does not scan sparse holes.
80
+ * Compared with {@link ArrayMap}, this costs extra memory for the dense arrays,
81
+ * and `delete`/new `set` do more bookkeeping. In return, iteration is dense and
82
+ * does not scan sparse holes.
83
+ *
84
+ * Trade-off: the dense arrays grow by `push`, so V8 cannot pretenure the entries
85
+ * the way it pretenured the per-entry `[key, value]` literals of the previous
86
+ * layout. A fresh process that creates tens of thousands of long-lived entities
87
+ * in bulk and then destroys them is slower for it: 3–17% to create and 19–35%
88
+ * to destroy 65,536 two-component entities. The gap comes from allocation-site
89
+ * pretenuring, not extra work, and it reverses under
90
+ * `node --no-allocation-site-pretenuring`. Lookups take two loads instead of
91
+ * four, and the layout took about 9% off the steady-state tick of
92
+ * `bench/sector-tick.ts`; `bench/README.md` has the measurements.
82
93
  *
83
94
  * @typeParam T - Value type stored in the map.
84
95
  */
85
96
  export class IterableArrayMap {
86
97
  constructor() {
87
- this._indices = new ArrayMap();
88
- this._items = [];
98
+ /**
99
+ * Key -> dense position + 1. Holes and `0` mean "absent", so the array only
100
+ * ever holds small integers and lookups stay on V8's fast SMI elements path.
101
+ */
102
+ this._slots = [];
103
+ this._keys = [];
104
+ this._values = [];
89
105
  }
90
106
  /** The number of entries currently in the map. */
91
107
  get size() {
92
- return this._items.length;
108
+ return this._keys.length;
93
109
  }
94
110
  /**
95
111
  * Insert or replace the value at `key`.
@@ -98,14 +114,14 @@ export class IterableArrayMap {
98
114
  * @param value - Value to store.
99
115
  */
100
116
  set(key, value) {
101
- const existingIndex = this._indices.get(key);
102
- if (existingIndex !== undefined) {
103
- this._items[existingIndex] = [key, value];
117
+ const slot = this._slots[key];
118
+ if (slot > 0) {
119
+ this._values[slot - 1] = value;
104
120
  return;
105
121
  }
106
- const index = this._items.length;
107
- this._indices.set(key, index);
108
- this._items.push([key, value]);
122
+ this._keys.push(key);
123
+ this._values.push(value);
124
+ this._slots[key] = this._keys.length;
109
125
  }
110
126
  /**
111
127
  * Retrieve the value stored at `key`, or `undefined` if no entry exists.
@@ -113,8 +129,8 @@ export class IterableArrayMap {
113
129
  * @param key - Non-negative integer key.
114
130
  */
115
131
  get(key) {
116
- const index = this._indices.get(key);
117
- return index === undefined ? undefined : this._items[index][1];
132
+ const slot = this._slots[key];
133
+ return slot > 0 ? this._values[slot - 1] : undefined;
118
134
  }
119
135
  /**
120
136
  * Return `true` when an entry exists at `key`.
@@ -122,7 +138,7 @@ export class IterableArrayMap {
122
138
  * @param key - Non-negative integer key.
123
139
  */
124
140
  has(key) {
125
- return this._indices.has(key);
141
+ return this._slots[key] > 0;
126
142
  }
127
143
  /**
128
144
  * Remove the entry at `key`. Does nothing if no entry exists there.
@@ -130,19 +146,22 @@ export class IterableArrayMap {
130
146
  * @param key - Non-negative integer key.
131
147
  */
132
148
  delete(key) {
133
- const index = this._indices.get(key);
134
- if (index === undefined) {
149
+ const slot = this._slots[key];
150
+ if (!(slot > 0)) {
135
151
  return;
136
152
  }
137
- const lastIndex = this._items.length - 1;
138
- if (index !== lastIndex) {
139
- const lastItem = this._items[lastIndex];
140
- this._items[index] = lastItem;
141
- const lastKey = lastItem[0];
142
- this._indices.set(lastKey, index);
153
+ const keys = this._keys;
154
+ const values = this._values;
155
+ const lastIndex = keys.length - 1;
156
+ if (slot - 1 !== lastIndex) {
157
+ const lastKey = keys[lastIndex];
158
+ keys[slot - 1] = lastKey;
159
+ values[slot - 1] = values[lastIndex];
160
+ this._slots[lastKey] = slot;
143
161
  }
144
- this._items.pop();
145
- this._indices.delete(key);
162
+ keys.pop();
163
+ values.pop();
164
+ this._slots[key] = 0;
146
165
  }
147
166
  /**
148
167
  * Visit every present entry in dense item order.
@@ -150,21 +169,50 @@ export class IterableArrayMap {
150
169
  * @param callback - Invoked with `(value, key, map)` for each entry.
151
170
  */
152
171
  forEach(callback) {
153
- const items = this._items;
154
- for (let i = 0; i < items.length; i++) {
155
- const [key, value] = items[i];
156
- callback(value, key, this);
172
+ const keys = this._keys;
173
+ const values = this._values;
174
+ for (let i = 0; i < keys.length; i++) {
175
+ callback(values[i], keys[i], this);
176
+ }
177
+ }
178
+ /**
179
+ * Visit every present entry tolerating deletion of the **current** entry
180
+ * from inside the callback.
181
+ *
182
+ * `delete` swaps the last entry into the vacated slot, which the plain
183
+ * {@link IterableArrayMap.forEach} would skip. This variant re-visits the
184
+ * slot after the callback returns when a new entry has been swapped in, so
185
+ * the swapped-in entry is visited next. Deleting the last entry (no swap,
186
+ * slot just pops out of bounds) is detected via a length check.
187
+ *
188
+ * Only deletion of the current entry is safe. A callback that deletes a
189
+ * *different* (lower-indexed) entry will still cause that swapped-in entry
190
+ * to be skipped — callers that mutate other slots must keep using a
191
+ * snapshot.
192
+ */
193
+ forEachSafe(callback) {
194
+ const keys = this._keys;
195
+ const values = this._values;
196
+ for (let i = 0; i < keys.length; i++) {
197
+ const key = keys[i];
198
+ callback(values[i], key, this);
199
+ if (i < keys.length && keys[i] !== key) {
200
+ i--;
201
+ }
157
202
  }
158
203
  }
159
204
  /**
160
205
  * Return an iterator over `[key, value]` entries in dense item order.
161
206
  *
162
- * Entries are backed by the map's internal storage for speed. Treat them as
163
- * immutable; mutating them through casts or plain JavaScript can corrupt the
164
- * map's key index.
207
+ * Each entry is a fresh pair read from the map's current contents as the
208
+ * iterator advances.
165
209
  */
166
- entries() {
167
- return this._items.values();
210
+ *entries() {
211
+ const keys = this._keys;
212
+ const values = this._values;
213
+ for (let i = 0; i < keys.length; i++) {
214
+ yield [keys[i], values[i]];
215
+ }
168
216
  }
169
217
  /** Return an iterator over `[key, value]` entries in dense item order. */
170
218
  [Symbol.iterator]() {
@@ -172,12 +220,13 @@ export class IterableArrayMap {
172
220
  }
173
221
  /** Return every present value in dense item order. */
174
222
  values() {
175
- return this._items.map(([, value]) => value);
223
+ return this._values.slice();
176
224
  }
177
225
  /** Remove all entries and reset {@link size} to zero. */
178
226
  clear() {
179
- this._indices.clear();
180
- this._items.length = 0;
227
+ this._slots.length = 0;
228
+ this._keys.length = 0;
229
+ this._values.length = 0;
181
230
  }
182
231
  }
183
232
  //# sourceMappingURL=array_map.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"array_map.js","sourceRoot":"","sources":["../../src/util/array_map.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"array_map.js","sourceRoot":"","sources":["../../src/util/array_map.ts"],"names":[],"mappings":"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"}
@@ -68,6 +68,32 @@ export class DenseSet {
68
68
  callbackfn.call(thisArg, items[i], items[i], this);
69
69
  }
70
70
  }
71
+ /**
72
+ * Visit each element (current order) tolerating deletion of the **current**
73
+ * element from inside the callback.
74
+ *
75
+ * `delete` swaps the last element into the vacated slot, which the plain
76
+ * {@link DenseSet.forEach} would skip. This variant holds the index after
77
+ * the callback returns when a new element has been swapped in, so the
78
+ * swapped-in value is visited next. Deleting the last element (no swap,
79
+ * slot just pops out of bounds) is detected via a length check so the
80
+ * previous slot is never re-processed.
81
+ *
82
+ * Only deletion of the current element is safe. A callback that deletes a
83
+ * *different* (lower-indexed) member will still cause that swapped-in
84
+ * element to be skipped — callers that mutate other slots must keep using
85
+ * a snapshot.
86
+ */
87
+ forEachSafe(callbackfn, thisArg) {
88
+ const items = this._items;
89
+ for (let i = 0; i < items.length; i++) {
90
+ const cur = items[i];
91
+ callbackfn.call(thisArg, cur, cur, this);
92
+ if (i < items.length && items[i] !== cur) {
93
+ i--;
94
+ }
95
+ }
96
+ }
71
97
  /** Iterator over elements in current order. */
72
98
  [Symbol.iterator]() {
73
99
  return this._items[Symbol.iterator]();
@@ -1 +1 @@
1
- {"version":3,"file":"dense_set.js","sourceRoot":"","sources":["../../src/util/dense_set.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,QAAQ;IAArB;QACmB,WAAM,GAAQ,EAAE,CAAC;QACjB,UAAK,GAAG,IAAI,GAAG,EAAa,CAAC;IA+EhD,CAAC;IA7EC,2CAA2C;IAC3C,IAAW,IAAI;QACb,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IAC5B,CAAC;IAED,mEAAmE;IACnE,IAAW,CAAC,MAAM,CAAC,WAAW,CAAC;QAC7B,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,6CAA6C;IACtC,GAAG,CAAC,KAAQ;QACjB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC1C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,8CAA8C;IACvC,GAAG,CAAC,KAAQ;QACjB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,KAAQ;QACpB,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;YACpB,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,EAAG,CAAC;QAChC,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;YACnB,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;YACtB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAC1B,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,4BAA4B;IACrB,KAAK;QACV,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QACvB,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED,yEAAyE;IAClE,OAAO,CAAC,UAAsD,EAAE,OAAiB;QACtF,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED,+CAA+C;IACxC,CAAC,MAAM,CAAC,QAAQ,CAAC;QACtB,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;IACxC,CAAC;IAED,gDAAgD;IACzC,CAAC,OAAO;QACb,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAC/B,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAED,+CAA+C;IACxC,IAAI;QACT,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;IACxC,CAAC;IAED,+CAA+C;IACxC,MAAM;QACX,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;IACxC,CAAC;CACF"}
1
+ {"version":3,"file":"dense_set.js","sourceRoot":"","sources":["../../src/util/dense_set.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,18 @@ export class Base {
16
16
  * removals, and destroy cleanup can delete stale entries safely.
17
17
  */
18
18
  this._identityIndexedNames = new WeakMap();
19
+ /**
20
+ * @internal Entity of the system currently running, or `undefined` outside a
21
+ * system. Stamped onto every command at enqueue time so the originating
22
+ * system survives until the command is routed (see {@link System._run}).
23
+ */
24
+ this._currentSource = undefined;
25
+ /**
26
+ * @internal Source entity of the command currently being applied. Read by
27
+ * {@link Query._notifyModified} to silence updates from ignored sources;
28
+ * cleared once the command queue drains.
29
+ */
30
+ this._routingSource = undefined;
19
31
  }
20
32
  }
21
33
  //# sourceMappingURL=world.base.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"world.base.js","sourceRoot":"","sources":["../../src/world/world.base.ts"],"names":[],"mappings":"AAOA,MAAM,OAAO,IAAI;IAAjB;QACE;;;;WAIG;QACa,mBAAc,GAAG,IAAI,GAAG,EAAkB,CAAC;QAE3D;;;WAGG;QACa,uBAAkB,GAAG,IAAI,GAAG,EAAkB,CAAC;QAE/D;;;WAGG;QACa,0BAAqB,GAAG,IAAI,OAAO,EAAkB,CAAC;IAexE,CAAC;CAAA"}
1
+ {"version":3,"file":"world.base.js","sourceRoot":"","sources":["../../src/world/world.base.ts"],"names":[],"mappings":"AAOA,MAAM,OAAO,IAAI;IAAjB;QACE;;;;WAIG;QACa,mBAAc,GAAG,IAAI,GAAG,EAAkB,CAAC;QAE3D;;;WAGG;QACa,uBAAkB,GAAG,IAAI,GAAG,EAAkB,CAAC;QAE/D;;;WAGG;QACa,0BAAqB,GAAG,IAAI,OAAO,EAAkB,CAAC;QAEtE;;;;WAIG;QACI,mBAAc,GAAuB,SAAS,CAAC;QAEtD;;;;WAIG;QACI,mBAAc,GAAuB,SAAS,CAAC;IACxD,CAAC;CAAA"}
@@ -20,6 +20,13 @@ import { type WorldOptions } from "./world.base.js";
20
20
  * deferred scope; user code can wrap arbitrary blocks with
21
21
  * {@link beginDefer} / {@link endDefer} or {@link defer}. {@link flush}
22
22
  * drains the queue at top level.
23
+ *
24
+ * ## Cross-world transfer
25
+ *
26
+ * {@link snapshotSubtree}, {@link restoreSubtree}, and {@link moveSubtree}
27
+ * capture and recreate an entity forest in a second world. They reject calls
28
+ * while either world is deferred, because cross-world scheduling is the
29
+ * application's job.
23
30
  */
24
31
  export declare class World extends Pipeline {
25
32
  constructor(options?: WorldOptions);
@@ -8,6 +8,17 @@ export class Deferred extends Queries {
8
8
  this._deferredDepth = 0;
9
9
  /** @internal `true` while {@link _processCommandQueue} is iterating, to avoid re-entrant drains. */
10
10
  this._draining = false;
11
+ /**
12
+ * @internal Buffered cleanup actions scheduled by `Entity._cleanupIncoming`.
13
+ *
14
+ * `undefined` outside an active `_destroy` cascade. The outermost `_destroy`
15
+ * call lazily allocates the scope, recursive `_destroy` calls append to the
16
+ * same scope, and the outermost call drains it to empty before returning.
17
+ * Set back to `undefined` during each flush pass so recursive destroys
18
+ * triggered by the flush buffer into a fresh scope and are drained by the
19
+ * outer `while` loop.
20
+ */
21
+ this._deletionScope = undefined;
11
22
  }
12
23
  /** `true` while the world is in deferred mode. */
13
24
  get deferred() {
@@ -69,6 +80,12 @@ export class Deferred extends Queries {
69
80
  case 5 /* CommandKind.Attach */:
70
81
  cmd.entity._attach(cmd.meta, cmd.component);
71
82
  return;
83
+ case 6 /* CommandKind.AddTarget */:
84
+ cmd.entity._addTarget(cmd.meta, cmd.target);
85
+ return;
86
+ case 7 /* CommandKind.RemoveTarget */:
87
+ cmd.entity._removeTarget(cmd.meta, cmd.target);
88
+ return;
72
89
  }
73
90
  }
74
91
  /** @internal Drain the top-level command queue in arrival order. */
@@ -1 +1 @@
1
- {"version":3,"file":"world.deferred.js","sourceRoot":"","sources":["../../src/world/world.deferred.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"world.deferred.js","sourceRoot":"","sources":["../../src/world/world.deferred.ts"],"names":[],"mappings":"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"}
@@ -12,13 +12,24 @@ export declare class Entities extends Deferred {
12
12
  * deferred scope return that same pending entity.
13
13
  */
14
14
  getOrCreateEntity(this: World, eid: EID, onCreateCallback?: (e: Entity) => void): Entity;
15
- /** Look up an entity by component ref or identity name. */
15
+ /**
16
+ * Look up an entity by component ref or identity name.
17
+ *
18
+ * A foreign `Entity` (one whose `world` is not this world) throws: passing an
19
+ * entity from another world is a programming error, not a miss. An `Entity`
20
+ * whose world matches but whose eid is unknown (e.g. after destruction)
21
+ * returns `undefined`.
22
+ */
16
23
  getEntity(this: World, ref: ComponentRef | string): Entity | undefined;
17
24
  /** Create a new entity with an auto-assigned id. */
18
25
  entity(this: World): Entity;
19
26
  /** Look up an existing entity by identity name, creating it if absent. */
20
27
  entity(this: World, ref: string): Entity;
21
- /** Look up an existing entity by component ref. */
28
+ /**
29
+ * Look up an existing entity by component ref.
30
+ *
31
+ * A foreign `Entity` ref throws (see {@link getEntity}).
32
+ */
22
33
  entity(this: World, ref: ComponentRef): Entity;
23
34
  /** Destroy every entity currently tracked by the world. */
24
35
  clearAllEntities(): void;