@oasys/oecs 0.1.2 → 0.2.1

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 (41) hide show
  1. package/README.md +172 -164
  2. package/dist/archetype.d.ts +50 -13
  3. package/dist/archetype.d.ts.map +1 -1
  4. package/dist/component.d.ts +27 -10
  5. package/dist/component.d.ts.map +1 -1
  6. package/dist/ecs.d.ts +104 -0
  7. package/dist/ecs.d.ts.map +1 -0
  8. package/dist/entity.d.ts.map +1 -1
  9. package/dist/event.d.ts +2 -2
  10. package/dist/event.d.ts.map +1 -1
  11. package/dist/index.cjs +1 -1
  12. package/dist/index.d.ts +8 -7
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +673 -321
  15. package/dist/query.d.ts +28 -31
  16. package/dist/query.d.ts.map +1 -1
  17. package/dist/ref.d.ts +19 -0
  18. package/dist/ref.d.ts.map +1 -0
  19. package/dist/resource.d.ts +23 -0
  20. package/dist/resource.d.ts.map +1 -0
  21. package/dist/schedule.d.ts +3 -3
  22. package/dist/schedule.d.ts.map +1 -1
  23. package/dist/store.d.ts +48 -29
  24. package/dist/store.d.ts.map +1 -1
  25. package/dist/system.d.ts +2 -2
  26. package/dist/system.d.ts.map +1 -1
  27. package/dist/type_primitives/assertions.d.ts +1 -0
  28. package/dist/type_primitives/assertions.d.ts.map +1 -1
  29. package/dist/type_primitives/bitset/bitset.d.ts +2 -2
  30. package/dist/type_primitives/bitset/bitset.d.ts.map +1 -1
  31. package/dist/type_primitives/sparse_map/sparse_map.d.ts.map +1 -1
  32. package/dist/type_primitives/sparse_set/sparse_set.d.ts.map +1 -1
  33. package/dist/type_primitives/typed_arrays/typed_arrays.d.ts +9 -0
  34. package/dist/type_primitives/typed_arrays/typed_arrays.d.ts.map +1 -1
  35. package/dist/utils/constants.d.ts +20 -0
  36. package/dist/utils/constants.d.ts.map +1 -0
  37. package/dist/utils/error.d.ts +2 -9
  38. package/dist/utils/error.d.ts.map +1 -1
  39. package/package.json +3 -2
  40. package/dist/world.d.ts +0 -73
  41. package/dist/world.d.ts.map +0 -1
package/dist/index.js CHANGED
@@ -1,34 +1,34 @@
1
- class R extends Error {
1
+ class H extends Error {
2
2
  constructor(t, e, s) {
3
3
  super(t), this.is_operational = e, this.context = s, this.name = this.constructor.name, Error.captureStackTrace(this, this.constructor);
4
4
  }
5
5
  }
6
- var q = /* @__PURE__ */ ((a) => (a.EID_MAX_INDEX_OVERFLOW = "EID_MAX_INDEX_OVERFLOW", a.EID_MAX_GEN_OVERFLOW = "EID_MAX_GEN_OVERFLOW", a.COMPONENT_NOT_REGISTERED = "COMPONENT_NOT_REGISTERED", a.ENTITY_NOT_ALIVE = "ENTITY_NOT_ALIVE", a.CIRCULAR_SYSTEM_DEPENDENCY = "CIRCULAR_SYSTEM_DEPENDENCY", a.DUPLICATE_SYSTEM = "DUPLICATE_SYSTEM", a.ARCHETYPE_NOT_FOUND = "ARCHETYPE_NOT_FOUND", a))(q || {});
7
- class Y extends R {
6
+ var z = /* @__PURE__ */ ((l) => (l.EID_MAX_INDEX_OVERFLOW = "EID_MAX_INDEX_OVERFLOW", l.EID_MAX_GEN_OVERFLOW = "EID_MAX_GEN_OVERFLOW", l.COMPONENT_NOT_REGISTERED = "COMPONENT_NOT_REGISTERED", l.ENTITY_NOT_ALIVE = "ENTITY_NOT_ALIVE", l.CIRCULAR_SYSTEM_DEPENDENCY = "CIRCULAR_SYSTEM_DEPENDENCY", l.DUPLICATE_SYSTEM = "DUPLICATE_SYSTEM", l.ARCHETYPE_NOT_FOUND = "ARCHETYPE_NOT_FOUND", l.RESOURCE_NOT_REGISTERED = "RESOURCE_NOT_REGISTERED", l))(z || {});
7
+ class Q extends H {
8
8
  constructor(t, e, s) {
9
9
  super(e ?? t, !0, s), this.category = t;
10
10
  }
11
11
  }
12
- function b(a, t, e) {
13
- return a;
12
+ function N(l, t, e) {
13
+ return l;
14
14
  }
15
- const X = 4;
16
- class v {
15
+ const v = -1, y = -1, D = Object.freeze(/* @__PURE__ */ Object.create(null)), k = 5, I = 31, J = 2166136261, Z = 16777619, tt = 2654435769, et = 1367130551, b = 16, C = 2, V = 1024, R = 0, j = 0, st = 31, nt = 1 / 60, rt = 4, it = 0, ot = 4;
16
+ class x {
17
17
  _words;
18
18
  constructor(t) {
19
- this._words = t ?? new Array(X).fill(0);
19
+ this._words = t ?? new Array(ot).fill(0);
20
20
  }
21
21
  has(t) {
22
- const e = t >>> 5;
23
- return e >= this._words.length ? !1 : (this._words[e] & 1 << (t & 31)) !== 0;
22
+ const e = t >>> k;
23
+ return e >= this._words.length ? !1 : (this._words[e] & 1 << (t & I)) !== 0;
24
24
  }
25
25
  set(t) {
26
- const e = t >>> 5;
27
- e >= this._words.length && this.grow(e + 1), this._words[e] |= 1 << (t & 31);
26
+ const e = t >>> k;
27
+ e >= this._words.length && this.grow(e + 1), this._words[e] |= 1 << (t & I);
28
28
  }
29
29
  clear(t) {
30
- const e = t >>> 5;
31
- e >= this._words.length || (this._words[e] &= ~(1 << (t & 31)));
30
+ const e = t >>> k;
31
+ e >= this._words.length || (this._words[e] &= ~(1 << (t & I)));
32
32
  }
33
33
  /** True if any bit is set in both this and other (non-empty intersection). */
34
34
  overlaps(t) {
@@ -56,25 +56,25 @@ class v {
56
56
  return !0;
57
57
  }
58
58
  copy() {
59
- return new v(this._words.slice());
59
+ return new x(this._words.slice());
60
60
  }
61
61
  copy_with_set(t) {
62
- const e = t >>> 5, s = e + 1, n = this._words.length > s ? this._words.length : s, r = new Array(n).fill(0);
62
+ const e = t >>> k, s = e + 1, n = this._words.length > s ? this._words.length : s, r = new Array(n).fill(0);
63
63
  for (let i = 0; i < this._words.length; i++) r[i] = this._words[i];
64
- return r[e] |= 1 << (t & 31), new v(r);
64
+ return r[e] |= 1 << (t & I), new x(r);
65
65
  }
66
66
  copy_with_clear(t) {
67
- const e = this._words.slice(), s = t >>> 5;
68
- return s < e.length && (e[s] &= ~(1 << (t & 31))), new v(e);
67
+ const e = this._words.slice(), s = t >>> k;
68
+ return s < e.length && (e[s] &= ~(1 << (t & I))), new x(e);
69
69
  }
70
70
  /** FNV-1a hash. Skips trailing zero words so differently-sized arrays with the same bits hash equally. */
71
71
  hash() {
72
- let t = 2166136261;
72
+ let t = J;
73
73
  const e = this._words;
74
74
  let s = e.length - 1;
75
75
  for (; s >= 0 && e[s] === 0; ) s--;
76
76
  for (let n = 0; n <= s; n++)
77
- t ^= e[n], t = Math.imul(t, 16777619);
77
+ t ^= e[n], t = Math.imul(t, Z);
78
78
  return t;
79
79
  }
80
80
  /** Iterate all set bits via lowest-set-bit extraction. */
@@ -83,9 +83,9 @@ class v {
83
83
  for (let s = 0; s < e.length; s++) {
84
84
  let n = e[s];
85
85
  if (n === 0) continue;
86
- const r = s << 5;
86
+ const r = s << k;
87
87
  for (; n !== 0; ) {
88
- const i = n & -n >>> 0, _ = 31 - Math.clz32(i);
88
+ const i = n & -n >>> 0, _ = I - Math.clz32(i);
89
89
  t(r + _), n ^= i;
90
90
  }
91
91
  }
@@ -98,14 +98,144 @@ class v {
98
98
  this._words = s;
99
99
  }
100
100
  }
101
- const A = 20, P = (1 << A) - 1, L = 31 - A, U = (1 << L) - 1, F = (a, t) => t << A | a, f = (a) => a & P, M = (a) => a >> A, z = (a) => b(
102
- a
103
- ), V = (a) => b(
104
- a
101
+ class A {
102
+ constructor(t, e = b) {
103
+ this._ctor = t, this._buf = new t(e);
104
+ }
105
+ _buf;
106
+ _len = 0;
107
+ get length() {
108
+ return this._len;
109
+ }
110
+ push(t) {
111
+ this._len >= this._buf.length && this._grow(), this._buf[this._len++] = t;
112
+ }
113
+ pop() {
114
+ return this._buf[--this._len];
115
+ }
116
+ get(t) {
117
+ return this._buf[t];
118
+ }
119
+ set_at(t, e) {
120
+ this._buf[t] = e;
121
+ }
122
+ /**
123
+ * Move the last element into slot i, decrement length.
124
+ * Returns the value that was removed from slot i.
125
+ */
126
+ swap_remove(t) {
127
+ const e = this._buf[t];
128
+ return this._buf[t] = this._buf[--this._len], e;
129
+ }
130
+ clear() {
131
+ this._len = 0;
132
+ }
133
+ /**
134
+ * Raw backing buffer. Valid data: indices 0..length-1.
135
+ * This reference is stable until the next push() that triggers a grow —
136
+ * do not cache across entity additions.
137
+ */
138
+ get buf() {
139
+ return this._buf;
140
+ }
141
+ /**
142
+ * Zero-copy subarray view of valid data (0..length-1).
143
+ * Shares the backing buffer — invalidated if a subsequent push() grows.
144
+ */
145
+ view() {
146
+ return this._buf.subarray(0, this._len);
147
+ }
148
+ [Symbol.iterator]() {
149
+ let t = 0;
150
+ const e = this._buf, s = this._len;
151
+ return {
152
+ next() {
153
+ return t < s ? { value: e[t++], done: !1 } : { value: 0, done: !0 };
154
+ }
155
+ };
156
+ }
157
+ /** Ensure the backing buffer can hold at least `capacity` elements without growing. */
158
+ ensure_capacity(t) {
159
+ if (t <= this._buf.length) return;
160
+ let e = this._buf.length || 1;
161
+ for (; e < t; ) e *= C;
162
+ const s = new this._ctor(e);
163
+ s.set(this._buf.subarray(0, this._len)), this._buf = s;
164
+ }
165
+ /**
166
+ * Append `count` elements from `src` starting at `src_offset`.
167
+ * Grows if needed. Equivalent to push() in a loop but uses TypedArray.set().
168
+ */
169
+ bulk_append(t, e, s) {
170
+ this.ensure_capacity(this._len + s), this._buf.set(t.subarray(e, e + s), this._len), this._len += s;
171
+ }
172
+ /** Append `count` zeroes. Grows if needed. */
173
+ bulk_append_zeroes(t) {
174
+ this.ensure_capacity(this._len + t), this._buf.fill(0, this._len, this._len + t), this._len += t;
175
+ }
176
+ _grow() {
177
+ const t = new this._ctor(this._buf.length * C);
178
+ t.set(this._buf), this._buf = t;
179
+ }
180
+ }
181
+ class _t extends A {
182
+ constructor(t = b) {
183
+ super(Float32Array, t);
184
+ }
185
+ }
186
+ class ct extends A {
187
+ constructor(t = b) {
188
+ super(Float64Array, t);
189
+ }
190
+ }
191
+ class ht extends A {
192
+ constructor(t = b) {
193
+ super(Int8Array, t);
194
+ }
195
+ }
196
+ class lt extends A {
197
+ constructor(t = b) {
198
+ super(Int16Array, t);
199
+ }
200
+ }
201
+ class at extends A {
202
+ constructor(t = b) {
203
+ super(Int32Array, t);
204
+ }
205
+ }
206
+ class dt extends A {
207
+ constructor(t = b) {
208
+ super(Uint8Array, t);
209
+ }
210
+ }
211
+ class ut extends A {
212
+ constructor(t = b) {
213
+ super(Uint16Array, t);
214
+ }
215
+ }
216
+ class B extends A {
217
+ constructor(t = b) {
218
+ super(Uint32Array, t);
219
+ }
220
+ }
221
+ const ft = {
222
+ f32: _t,
223
+ f64: ct,
224
+ i8: ht,
225
+ i16: lt,
226
+ i32: at,
227
+ u8: dt,
228
+ u16: ut,
229
+ u32: B
230
+ }, P = 20, F = (1 << P) - 1, gt = st - P, X = (1 << gt) - 1, mt = (l, t) => t << P | l, m = (l) => l & F, Y = (l) => l >> P, yt = (l) => N(
231
+ l
232
+ ), pt = (l) => N(
233
+ l
105
234
  );
106
- class C {
235
+ class wt {
107
236
  field_names;
108
237
  columns;
238
+ // any: type-erased storage — channel is stored in Map<number, EventChannel>, F is lost
109
239
  reader;
110
240
  constructor(t) {
111
241
  this.field_names = t, this.columns = [];
@@ -133,44 +263,92 @@ class C {
133
263
  t[e].length = 0;
134
264
  }
135
265
  }
136
- const G = (a) => b(
137
- a
266
+ const vt = (l) => N(
267
+ l
138
268
  );
139
- class W {
269
+ class xt {
270
+ field_names;
271
+ field_index;
272
+ columns;
273
+ // any: type-erased storage — channel is stored in Map<number, ResourceChannel>, F is lost
274
+ reader;
275
+ constructor(t, e) {
276
+ this.field_names = t, this.field_index = /* @__PURE__ */ Object.create(null), this.columns = [];
277
+ for (let r = 0; r < t.length; r++)
278
+ this.field_index[t[r]] = r, this.columns.push([e[t[r]] ?? 0]);
279
+ const s = /* @__PURE__ */ Object.create(null), n = this.columns;
280
+ for (let r = 0; r < t.length; r++) {
281
+ const i = n[r];
282
+ Object.defineProperty(s, t[r], {
283
+ get() {
284
+ return i[R];
285
+ },
286
+ enumerable: !0
287
+ });
288
+ }
289
+ this.reader = s;
290
+ }
291
+ write(t) {
292
+ const e = this.field_names, s = this.columns;
293
+ for (let n = 0; n < e.length; n++)
294
+ e[n] in t && (s[n][R] = t[e[n]]);
295
+ }
296
+ read_field(t) {
297
+ return this.columns[t][R];
298
+ }
299
+ write_field(t, e) {
300
+ this.columns[t][R] = e;
301
+ }
302
+ }
303
+ const bt = (l) => N(
304
+ l
305
+ );
306
+ class Tt {
140
307
  id;
141
308
  mask;
142
309
  has_columns;
143
- entity_ids = [];
310
+ _entity_ids;
144
311
  length = 0;
145
312
  edges = [];
146
- // Sparse array indexed by ComponentID — undefined for absent components.
147
- // Allows O(1) column group lookup by component.
313
+ // --- Flat column storage ---
314
+ // Dense array of ALL columns across all components in this archetype.
315
+ _flat_columns = [];
316
+ // Sparse by ComponentID → starting index into _flat_columns.
317
+ _col_offset = [];
318
+ // Sparse by ComponentID → number of fields for that component.
319
+ _field_count = [];
320
+ // Sparse by ComponentID → field_index record (field name → offset within component).
321
+ _field_index = [];
322
+ // Sparse by ComponentID → field_names array.
323
+ _field_names = [];
324
+ // Sparse array indexed by ComponentID — kept for create_ref compatibility.
148
325
  column_groups = [];
149
- // Dense list of ComponentIDs that have columns — used to iterate only
150
- // data-bearing components in copy/add/remove operations.
326
+ // Dense list of ComponentIDs that have columns — used for copy_shared_from.
151
327
  _column_ids = [];
152
- constructor(t, e, s) {
153
- if (this.id = t, this.mask = e, s)
154
- for (let n = 0; n < s.length; n++) {
155
- const r = s[n], i = new Array(r.field_names.length);
156
- for (let h = 0; h < r.field_names.length; h++)
157
- i[h] = [];
158
- const _ = /* @__PURE__ */ Object.create(null);
159
- for (let h = 0; h < r.field_names.length; h++)
160
- _[r.field_names[h]] = i[h];
161
- this.column_groups[r.component_id] = {
162
- layout: r,
163
- columns: i,
164
- record: _
165
- }, this._column_ids.push(r.component_id);
328
+ constructor(t, e, s, n = V) {
329
+ if (this.id = t, this.mask = e, this._entity_ids = new B(n), s) {
330
+ let r = 0;
331
+ for (let i = 0; i < s.length; i++) {
332
+ const _ = s[i], c = _.component_id, o = new Array(_.field_names.length);
333
+ this._col_offset[c] = r, this._field_count[c] = _.field_names.length, this._field_index[c] = _.field_index, this._field_names[c] = _.field_names;
334
+ for (let h = 0; h < _.field_names.length; h++) {
335
+ const a = new ft[_.field_types[h]](n);
336
+ o[h] = a, this._flat_columns[r++] = a;
337
+ }
338
+ this.column_groups[c] = { layout: _, columns: o }, this._column_ids.push(c);
166
339
  }
340
+ }
167
341
  this.has_columns = this._column_ids.length > 0;
168
342
  }
169
343
  get entity_count() {
170
344
  return this.length;
171
345
  }
346
+ /** Raw entity ID buffer. Valid data at indices 0..entity_count-1. */
347
+ get entity_ids() {
348
+ return this._entity_ids.buf;
349
+ }
172
350
  get entity_list() {
173
- return this.entity_ids;
351
+ return this._entity_ids.view();
174
352
  }
175
353
  has_component(t) {
176
354
  return this.mask.has(t);
@@ -180,36 +358,39 @@ class W {
180
358
  }
181
359
  /** Get a single field's column. Valid data: indices 0..entity_count-1. */
182
360
  get_column(t, e) {
183
- const s = this.column_groups[t], n = s.layout.field_index[e];
184
- return s.columns[n];
185
- }
186
- /** Get all columns for a component as { fieldName: number[] }. */
187
- get_column_group(t) {
188
- const e = this.column_groups[t];
189
- return e ? e.record : {};
361
+ const s = t, n = this._field_index[s][e];
362
+ return this._flat_columns[this._col_offset[s] + n].buf;
190
363
  }
191
364
  write_fields(t, e, s) {
192
- const n = this.column_groups[e];
193
- if (!n) return;
194
- const { field_names: r } = n.layout;
195
- for (let i = 0; i < r.length; i++)
196
- n.columns[i][t] = s[r[i]];
365
+ const n = e, r = this._col_offset[n];
366
+ if (r === void 0) return;
367
+ const i = this._field_names[n], _ = this._flat_columns;
368
+ for (let c = 0; c < i.length; c++)
369
+ _[r + c].buf[t] = s[i[c]];
370
+ }
371
+ /** Fast positional write: values[i] → field[i] in declaration order. No string lookup. */
372
+ write_fields_positional(t, e, s) {
373
+ const n = e, r = this._col_offset[n];
374
+ if (r === void 0) return;
375
+ const i = this._flat_columns;
376
+ for (let _ = 0; _ < s.length; _++)
377
+ i[r + _].buf[t] = s[_];
197
378
  }
198
379
  read_field(t, e, s) {
199
- const n = this.column_groups[e];
200
- if (!n) return NaN;
201
- const r = n.layout.field_index[s];
202
- return r === void 0 ? NaN : n.columns[r][t] ?? NaN;
380
+ const n = e, r = this._col_offset[n];
381
+ if (r === void 0) return NaN;
382
+ const i = this._field_index[n][s];
383
+ return i === void 0 ? NaN : this._flat_columns[r + i].buf[t];
203
384
  }
204
385
  /** Copy all shared component columns from source archetype at src_row into dst_row. */
205
386
  copy_shared_from(t, e, s) {
206
- const n = t.column_groups, r = this._column_ids;
207
- for (let i = 0; i < r.length; i++) {
208
- const _ = r[i], h = n[_];
209
- if (!h) continue;
210
- const o = this.column_groups[_];
211
- for (let c = 0; c < o.columns.length; c++)
212
- o.columns[c][s] = h.columns[c][e];
387
+ const n = t._col_offset, r = t._field_count, i = t._flat_columns, _ = this._flat_columns, c = this._column_ids;
388
+ for (let o = 0; o < c.length; o++) {
389
+ const h = c[o], a = n[h];
390
+ if (a === void 0) continue;
391
+ const u = this._col_offset[h], d = r[h];
392
+ for (let g = 0; g < d; g++)
393
+ _[u + g].buf[s] = i[a + g].buf[e];
213
394
  }
214
395
  }
215
396
  /**
@@ -218,49 +399,88 @@ class W {
218
399
  */
219
400
  add_entity(t) {
220
401
  const e = this.length;
221
- this.entity_ids.push(t);
222
- const s = this._column_ids;
223
- for (let n = 0; n < s.length; n++) {
224
- const r = this.column_groups[s[n]];
225
- for (let i = 0; i < r.columns.length; i++)
226
- r.columns[i].push(0);
227
- }
402
+ this._entity_ids.push(t);
403
+ const s = this._flat_columns;
404
+ for (let n = 0; n < s.length; n++)
405
+ s[n].push(0);
228
406
  return this.length++, e;
229
407
  }
230
408
  /**
231
409
  * Remove entity at row via swap-and-pop. Swaps the last entity into the
232
410
  * vacated row to keep data dense. Returns the entity_index of the swapped
233
- * entity (so Store can update its row), or -1 if no swap was needed.
411
+ * entity (so Store can update its row), or NO_SWAP if no swap was needed.
234
412
  */
235
413
  remove_entity(t) {
236
414
  const e = this.length - 1;
237
- let s = -1;
238
- const n = this._column_ids;
415
+ let s = y;
416
+ const n = this._flat_columns, r = this._entity_ids.buf;
239
417
  if (t !== e) {
240
- this.entity_ids[t] = this.entity_ids[e], s = f(this.entity_ids[t]);
241
- for (let r = 0; r < n.length; r++) {
242
- const i = this.column_groups[n[r]];
243
- for (let _ = 0; _ < i.columns.length; _++)
244
- i.columns[_][t] = i.columns[_][e], i.columns[_].pop();
245
- }
418
+ r[t] = r[e], s = m(r[t]);
419
+ for (let i = 0; i < n.length; i++)
420
+ n[i].swap_remove(t);
246
421
  } else
247
- for (let r = 0; r < n.length; r++) {
248
- const i = this.column_groups[n[r]];
249
- for (let _ = 0; _ < i.columns.length; _++)
250
- i.columns[_].pop();
251
- }
252
- return this.entity_ids.pop(), this.length--, s;
422
+ for (let i = 0; i < n.length; i++)
423
+ n[i].pop();
424
+ return this._entity_ids.pop(), this.length--, s;
253
425
  }
254
426
  /** Tag-optimized add: skip column push entirely (no data to store). */
255
427
  add_entity_tag(t) {
256
428
  const e = this.length;
257
- return this.entity_ids.push(t), this.length++, e;
429
+ return this._entity_ids.push(t), this.length++, e;
258
430
  }
259
431
  /** Tag-optimized remove via swap-and-pop: skip column swap/pop entirely. */
260
432
  remove_entity_tag(t) {
261
433
  const e = this.length - 1;
262
- let s = -1;
263
- return t !== e && (this.entity_ids[t] = this.entity_ids[e], s = f(this.entity_ids[t])), this.entity_ids.pop(), this.length--, s;
434
+ let s = y;
435
+ const n = this._entity_ids.buf;
436
+ return t !== e && (n[t] = n[e], s = m(n[t])), this._entity_ids.pop(), this.length--, s;
437
+ }
438
+ /**
439
+ * Move an entity from src archetype into this archetype in a single pass.
440
+ * Combines add_entity + copy_shared_from + remove_entity(src).
441
+ * Uses a pre-computed transition map for branchless column copy.
442
+ * Writes dst_row to _move_result[0], swapped entity index to _move_result[1].
443
+ */
444
+ move_entity_from(t, e, s, n) {
445
+ const r = this.length;
446
+ this._entity_ids.push(s);
447
+ const i = this._flat_columns, _ = t._flat_columns;
448
+ for (let o = 0; o < i.length; o++) {
449
+ const h = n[o];
450
+ i[o].push(h >= 0 ? _[h].buf[e] : 0);
451
+ }
452
+ this.length++;
453
+ const c = t.has_columns ? t.remove_entity(e) : t.remove_entity_tag(e);
454
+ f[0] = r, f[1] = c;
455
+ }
456
+ /**
457
+ * Move an entity from src into this archetype (tag-only: no columns to copy).
458
+ * Writes dst_row to _move_result[0], swapped entity index to _move_result[1].
459
+ */
460
+ move_entity_from_tag(t, e, s) {
461
+ const n = this.length;
462
+ this._entity_ids.push(s), this.length++;
463
+ const r = t.remove_entity_tag(e);
464
+ f[0] = n, f[1] = r;
465
+ }
466
+ /**
467
+ * Bulk-move ALL entities from src into this archetype using TypedArray.set().
468
+ * Much faster than per-entity move_entity_from when the entire source is moving.
469
+ * After this call, src is empty. Returns the starting dst_row for the batch.
470
+ */
471
+ bulk_move_all_from(t, e) {
472
+ const s = t.length;
473
+ if (s === 0) return this.length;
474
+ const n = this.length, r = this._flat_columns, i = t._flat_columns;
475
+ this._entity_ids.bulk_append(t._entity_ids.buf, 0, s);
476
+ for (let _ = 0; _ < r.length; _++) {
477
+ const c = e[_];
478
+ c >= 0 ? r[_].bulk_append(i[c].buf, 0, s) : r[_].bulk_append_zeroes(s);
479
+ }
480
+ this.length += s, t.length = 0, t._entity_ids.clear();
481
+ for (let _ = 0; _ < i.length; _++)
482
+ i[_].clear();
483
+ return n;
264
484
  }
265
485
  get_edge(t) {
266
486
  return this.edges[t];
@@ -269,12 +489,25 @@ class W {
269
489
  this.edges[t] = e;
270
490
  }
271
491
  }
272
- function j(a, t, e) {
273
- const s = a.get(t);
274
- s !== void 0 ? s.push(e) : a.set(t, [e]);
492
+ const f = [0, y];
493
+ function M(l, t) {
494
+ const e = t._flat_columns, s = new Int16Array(e.length), n = t._column_ids, r = l._col_offset, i = t._col_offset, _ = t._field_count;
495
+ for (let c = 0; c < n.length; c++) {
496
+ const o = n[c], h = i[o], a = _[o], u = r[o];
497
+ if (u !== void 0)
498
+ for (let d = 0; d < a; d++)
499
+ s[h + d] = u + d;
500
+ else
501
+ for (let d = 0; d < a; d++)
502
+ s[h + d] = -1;
503
+ }
504
+ return s;
505
+ }
506
+ function K(l, t, e) {
507
+ const s = l.get(t);
508
+ s !== void 0 ? s.push(e) : l.set(t, [e]);
275
509
  }
276
- const y = -1, S = Object.freeze(/* @__PURE__ */ Object.create(null));
277
- class $ {
510
+ class At {
278
511
  // --- Entity ID management ---
279
512
  // Generational slot allocator: entity_generations[index] holds the current
280
513
  // generation for that slot. Free indices are recycled via a stack.
@@ -283,7 +516,7 @@ class $ {
283
516
  entity_free_indices = [];
284
517
  entity_alive_count = 0;
285
518
  // --- Component metadata ---
286
- // Parallel array indexed by ComponentID: field_names and field_index
519
+ // Parallel array indexed by ComponentID: field_names, field_index, and field_types
287
520
  // for building archetype column layouts.
288
521
  component_metas = [];
289
522
  component_count = 0;
@@ -291,6 +524,10 @@ class $ {
291
524
  // Parallel array indexed by EventID: each channel holds SoA columns + reader.
292
525
  event_channels = [];
293
526
  event_count = 0;
527
+ // --- Resource channels ---
528
+ // Parallel array indexed by ResourceID: each channel holds a single row of SoA columns.
529
+ resource_channels = [];
530
+ resource_count = 0;
294
531
  // --- Archetype management ---
295
532
  archetypes = [];
296
533
  // Hash-bucketed lookup: BitSet.hash() → ArchetypeID[] for deduplication
@@ -316,8 +553,9 @@ class $ {
316
553
  pending_add_values = [];
317
554
  pending_remove_ids = [];
318
555
  pending_remove_defs = [];
319
- constructor() {
320
- this.empty_archetype_id = this.arch_get_or_create_from_mask(new v());
556
+ initial_capacity;
557
+ constructor(t) {
558
+ this.initial_capacity = t ?? V, this.empty_archetype_id = this.arch_get_or_create_from_mask(new x());
321
559
  }
322
560
  // =======================================================
323
561
  // Archetype graph
@@ -332,28 +570,29 @@ class $ {
332
570
  arch_get_or_create_from_mask(t) {
333
571
  const e = t.hash(), s = this.archetype_map.get(e);
334
572
  if (s !== void 0) {
335
- for (let h = 0; h < s.length; h++)
336
- if (this.archetypes[s[h]].mask.equals(t))
337
- return s[h];
573
+ for (let c = 0; c < s.length; c++)
574
+ if (this.archetypes[s[c]].mask.equals(t))
575
+ return s[c];
338
576
  }
339
- const n = G(this.next_archetype_id++), r = [];
340
- t.for_each((h) => {
341
- const o = h, c = this.component_metas[o];
342
- c && c.field_names.length > 0 && r.push({
577
+ const n = bt(this.next_archetype_id++), r = [];
578
+ t.for_each((c) => {
579
+ const o = c, h = this.component_metas[o];
580
+ h && h.field_names.length > 0 && r.push({
343
581
  component_id: o,
344
- field_names: c.field_names,
345
- field_index: c.field_index
582
+ field_names: h.field_names,
583
+ field_index: h.field_index,
584
+ field_types: h.field_types
346
585
  });
347
586
  });
348
- const i = new W(n, t, r);
349
- this.archetypes.push(i), j(this.archetype_map, e, n), t.for_each((h) => {
350
- const o = h;
351
- let c = this.component_index.get(o);
352
- c || (c = /* @__PURE__ */ new Set(), this.component_index.set(o, c)), c.add(n);
587
+ const i = new Tt(n, t, r, this.initial_capacity);
588
+ this.archetypes.push(i), K(this.archetype_map, e, n), t.for_each((c) => {
589
+ const o = c;
590
+ let h = this.component_index.get(o);
591
+ h || (h = /* @__PURE__ */ new Set(), this.component_index.set(o, h)), h.add(n);
353
592
  });
354
593
  const _ = this.registered_queries;
355
- for (let h = 0; h < _.length; h++) {
356
- const o = _[h];
594
+ for (let c = 0; c < _.length; c++) {
595
+ const o = _[c];
357
596
  i.matches(o.include_mask) && (!o.exclude_mask || !i.mask.overlaps(o.exclude_mask)) && (!o.any_of_mask || i.mask.overlaps(o.any_of_mask)) && o.result.push(i);
358
597
  }
359
598
  return n;
@@ -384,37 +623,44 @@ class $ {
384
623
  arch_cache_edge(t, e, s) {
385
624
  const n = t.get_edge(s) ?? {
386
625
  add: null,
387
- remove: null
626
+ remove: null,
627
+ add_map: null,
628
+ remove_map: null
388
629
  };
389
- n.add = e.id, t.set_edge(s, n);
390
- const r = e.get_edge(s) ?? { add: null, remove: null };
391
- r.remove = t.id, e.set_edge(s, r);
630
+ n.add = e.id, n.add_map = M(t, e), t.set_edge(s, n);
631
+ const r = e.get_edge(s) ?? {
632
+ add: null,
633
+ remove: null,
634
+ add_map: null,
635
+ remove_map: null
636
+ };
637
+ r.remove = t.id, r.remove_map = M(e, t), e.set_edge(s, r);
392
638
  }
393
639
  // =======================================================
394
640
  // Entity lifecycle
395
641
  // =======================================================
396
642
  create_entity() {
397
643
  let t, e;
398
- this.entity_free_indices.length > 0 ? (t = this.entity_free_indices.pop(), e = this.entity_generations[t]) : (t = this.entity_high_water++, this.entity_generations[t] = 0, e = 0), this.entity_alive_count++;
399
- const s = F(t, e);
400
- return this.entity_archetype[t] = this.empty_archetype_id, this.entity_row[t] = y, s;
644
+ this.entity_free_indices.length > 0 ? (t = this.entity_free_indices.pop(), e = this.entity_generations[t]) : (t = this.entity_high_water++, this.entity_generations[t] = j, e = j), this.entity_alive_count++;
645
+ const s = mt(t, e);
646
+ return this.entity_archetype[t] = this.empty_archetype_id, this.entity_row[t] = v, s;
401
647
  }
402
648
  /** Immediately destroy an entity, removing it from its archetype. */
403
649
  destroy_entity(t) {
404
650
  if (!this.is_alive(t))
405
651
  return;
406
- const e = f(t), s = this.entity_row[e];
407
- if (s !== y) {
652
+ const e = m(t), s = this.entity_row[e];
653
+ if (s !== v) {
408
654
  const i = this.arch_get(this.entity_archetype[e]).remove_entity(s);
409
- i !== -1 && (this.entity_row[i] = s);
655
+ i !== y && (this.entity_row[i] = s);
410
656
  }
411
- this.entity_archetype[e] = y, this.entity_row[e] = y;
412
- const n = M(t);
413
- this.entity_generations[e] = n + 1 & U, this.entity_free_indices.push(e), this.entity_alive_count--;
657
+ this.entity_archetype[e] = v, this.entity_row[e] = v;
658
+ const n = Y(t);
659
+ this.entity_generations[e] = n + 1 & X, this.entity_free_indices.push(e), this.entity_alive_count--;
414
660
  }
415
661
  is_alive(t) {
416
- const e = f(t);
417
- return e < this.entity_high_water && this.entity_generations[e] === M(t);
662
+ const e = m(t);
663
+ return e < this.entity_high_water && this.entity_generations[e] === Y(t);
418
664
  }
419
665
  get entity_count() {
420
666
  return this.entity_alive_count;
@@ -431,14 +677,14 @@ class $ {
431
677
  if (t.length === 0) return;
432
678
  const e = this.entity_archetype, s = this.entity_row, n = this.entity_generations, r = this.archetypes, i = this.entity_high_water;
433
679
  for (let _ = 0; _ < t.length; _++) {
434
- const h = t[_], o = h & P, c = h >> A;
435
- if (o >= i || n[o] !== c) continue;
436
- const l = s[o];
437
- if (l !== y) {
438
- const u = r[e[o]], d = u.has_columns ? u.remove_entity(l) : u.remove_entity_tag(l);
439
- d !== -1 && (s[d] = l);
680
+ const c = t[_], o = c & F, h = c >> P;
681
+ if (o >= i || n[o] !== h) continue;
682
+ const a = s[o];
683
+ if (a !== v) {
684
+ const u = r[e[o]], d = u.has_columns ? u.remove_entity(a) : u.remove_entity_tag(a);
685
+ d !== y && (s[d] = a);
440
686
  }
441
- e[o] = y, s[o] = y, n[o] = c + 1 & U, this.entity_free_indices.push(o), this.entity_alive_count--;
687
+ e[o] = v, s[o] = v, n[o] = h + 1 & X, this.entity_free_indices.push(o), this.entity_alive_count--;
442
688
  }
443
689
  t.length = 0;
444
690
  }
@@ -446,7 +692,7 @@ class $ {
446
692
  return this.pending_destroy.length;
447
693
  }
448
694
  add_component_deferred(t, e, s) {
449
- this.pending_add_ids.push(t), this.pending_add_defs.push(e), this.pending_add_values.push(s ?? S);
695
+ this.pending_add_ids.push(t), this.pending_add_defs.push(e), this.pending_add_values.push(s ?? D);
450
696
  }
451
697
  remove_component_deferred(t, e) {
452
698
  this.pending_remove_ids.push(t), this.pending_remove_defs.push(e);
@@ -456,37 +702,47 @@ class $ {
456
702
  }
457
703
  /** Batch-apply all deferred component additions. */
458
704
  _flush_adds() {
459
- const t = this.pending_add_ids, e = this.pending_add_defs, s = this.pending_add_values, n = t.length, r = this.entity_archetype, i = this.entity_row, _ = this.entity_generations, h = this.archetypes, o = this.component_metas, c = this.entity_high_water;
460
- for (let l = 0; l < n; l++) {
461
- const u = t[l], d = u & P, p = u >> A;
462
- if (d >= c || _[d] !== p) continue;
463
- const x = r[d], m = e[l], g = h[x];
464
- if (g.mask.has(m)) {
465
- o[m].field_names.length > 0 && g.write_fields(i[d], m, s[l]);
705
+ const t = this.pending_add_ids, e = this.pending_add_defs, s = this.pending_add_values, n = t.length, r = this.entity_archetype, i = this.entity_row, _ = this.entity_generations, c = this.archetypes, o = this.component_metas, h = this.entity_high_water;
706
+ for (let a = 0; a < n; a++) {
707
+ const u = t[a], d = u & F, g = u >> P;
708
+ if (d >= h || _[d] !== g) continue;
709
+ const T = r[d], p = e[a], w = c[T];
710
+ if (w.mask.has(p)) {
711
+ o[p].field_names.length > 0 && w.write_fields(i[d], p, s[a]);
466
712
  continue;
467
713
  }
468
- const E = this.arch_resolve_add(x, m), w = h[E], T = i[d], k = !w.has_columns && !g.has_columns, N = k ? w.add_entity_tag(u) : w.add_entity(u);
469
- if (T !== y) {
470
- k || w.copy_shared_from(g, T, N);
471
- const I = k ? g.remove_entity_tag(T) : g.remove_entity(T);
472
- I !== -1 && (i[I] = T);
473
- }
474
- o[m].field_names.length > 0 && w.write_fields(N, m, s[l]), r[d] = E, i[d] = N;
714
+ const S = this.arch_resolve_add(T, p), E = c[S], O = i[d], L = !E.has_columns && !w.has_columns;
715
+ let U;
716
+ if (O !== v) {
717
+ if (L)
718
+ E.move_entity_from_tag(w, O, u);
719
+ else {
720
+ const $ = w.get_edge(p);
721
+ E.move_entity_from(w, O, u, $.add_map);
722
+ }
723
+ U = f[0], f[1] !== y && (i[f[1]] = O);
724
+ } else
725
+ U = L ? E.add_entity_tag(u) : E.add_entity(u);
726
+ o[p].field_names.length > 0 && E.write_fields(U, p, s[a]), r[d] = S, i[d] = U;
475
727
  }
476
728
  t.length = 0, e.length = 0, s.length = 0;
477
729
  }
478
730
  /** Batch-apply all deferred component removals. */
479
731
  _flush_removes() {
480
- const t = this.pending_remove_ids, e = this.pending_remove_defs, s = t.length, n = this.entity_archetype, r = this.entity_row, i = this.entity_generations, _ = this.archetypes, h = this.entity_high_water;
732
+ const t = this.pending_remove_ids, e = this.pending_remove_defs, s = t.length, n = this.entity_archetype, r = this.entity_row, i = this.entity_generations, _ = this.archetypes, c = this.entity_high_water;
481
733
  for (let o = 0; o < s; o++) {
482
- const c = t[o], l = c & P, u = c >> A;
483
- if (l >= h || i[l] !== u) continue;
484
- const d = n[l], p = e[o], x = _[d];
485
- if (!x.mask.has(p)) continue;
486
- const m = this.arch_resolve_remove(d, p), g = _[m], E = r[l], w = !g.has_columns && !x.has_columns, T = w ? g.add_entity_tag(c) : g.add_entity(c);
487
- w || g.copy_shared_from(x, E, T);
488
- const k = w ? x.remove_entity_tag(E) : x.remove_entity(E);
489
- k !== -1 && (r[k] = E), n[l] = m, r[l] = T;
734
+ const h = t[o], a = h & F, u = h >> P;
735
+ if (a >= c || i[a] !== u) continue;
736
+ const d = n[a], g = e[o], T = _[d];
737
+ if (!T.mask.has(g)) continue;
738
+ const p = this.arch_resolve_remove(d, g), w = _[p], S = r[a];
739
+ if (!w.has_columns && !T.has_columns)
740
+ w.move_entity_from_tag(T, S, h);
741
+ else {
742
+ const O = T.get_edge(g);
743
+ w.move_entity_from(T, S, h, O.remove_map);
744
+ }
745
+ f[1] !== y && (r[f[1]] = S), n[a] = p, r[a] = f[0];
490
746
  }
491
747
  t.length = 0, e.length = 0;
492
748
  }
@@ -497,15 +753,15 @@ class $ {
497
753
  // Component registration
498
754
  // =======================================================
499
755
  register_component(t) {
500
- const e = z(this.component_count++), s = t, n = /* @__PURE__ */ Object.create(null);
501
- for (let r = 0; r < s.length; r++)
502
- n[s[r]] = r;
503
- return this.component_metas.push({ field_names: s, field_index: n }), e;
756
+ const e = yt(this.component_count++), s = Object.keys(t), n = new Array(s.length), r = /* @__PURE__ */ Object.create(null);
757
+ for (let i = 0; i < s.length; i++)
758
+ r[s[i]] = i, n[i] = t[s[i]];
759
+ return this.component_metas.push({ field_names: s, field_index: r, field_types: n }), e;
504
760
  }
505
761
  add_component(t, e, s) {
506
762
  if (!this.is_alive(t))
507
763
  return;
508
- const n = f(t), r = this.entity_archetype[n], i = this.arch_get(r);
764
+ const n = m(t), r = this.entity_archetype[n], i = this.arch_get(r);
509
765
  if (i.has_component(e)) {
510
766
  i.write_fields(
511
767
  this.entity_row[n],
@@ -517,23 +773,24 @@ class $ {
517
773
  const _ = this.arch_resolve_add(
518
774
  r,
519
775
  e
520
- ), h = this.arch_get(_), o = this.entity_row[n], c = h.add_entity(t);
521
- if (o !== y) {
522
- h.copy_shared_from(i, o, c);
523
- const l = i.remove_entity(o);
524
- l !== -1 && (this.entity_row[l] = o);
525
- }
526
- h.write_fields(
527
- c,
776
+ ), c = this.arch_get(_), o = this.entity_row[n];
777
+ let h;
778
+ if (o !== v) {
779
+ const a = i.get_edge(e);
780
+ !c.has_columns && !i.has_columns ? c.move_entity_from_tag(i, o, t) : c.move_entity_from(i, o, t, a.add_map), h = f[0], f[1] !== y && (this.entity_row[f[1]] = o);
781
+ } else
782
+ h = c.has_columns ? c.add_entity(t) : c.add_entity_tag(t);
783
+ c.write_fields(
784
+ h,
528
785
  e,
529
786
  s
530
- ), this.entity_archetype[n] = _, this.entity_row[n] = c;
787
+ ), this.entity_archetype[n] = _, this.entity_row[n] = h;
531
788
  }
532
789
  /** Add multiple components in one transition (resolves final archetype, then moves once). */
533
790
  add_components(t, e) {
534
791
  if (!this.is_alive(t))
535
792
  return;
536
- const s = f(t), n = this.entity_archetype[s];
793
+ const s = m(t), n = this.entity_archetype[s];
537
794
  let r = n;
538
795
  for (let i = 0; i < e.length; i++)
539
796
  r = this.arch_resolve_add(
@@ -541,77 +798,107 @@ class $ {
541
798
  e[i].def
542
799
  );
543
800
  if (r !== n) {
544
- const i = this.arch_get(n), _ = this.arch_get(r), h = this.entity_row[s], o = _.add_entity(t);
545
- if (h !== y) {
546
- _.copy_shared_from(i, h, o);
547
- const c = i.remove_entity(h);
548
- c !== -1 && (this.entity_row[c] = h);
549
- }
550
- for (let c = 0; c < e.length; c++)
801
+ const i = this.arch_get(n), _ = this.arch_get(r), c = this.entity_row[s];
802
+ let o;
803
+ if (c !== v) {
804
+ const h = M(i, _);
805
+ _.move_entity_from(i, c, t, h), o = f[0], f[1] !== y && (this.entity_row[f[1]] = c);
806
+ } else
807
+ o = _.add_entity(t);
808
+ for (let h = 0; h < e.length; h++)
551
809
  _.write_fields(
552
810
  o,
553
- e[c].def,
554
- e[c].values ?? S
811
+ e[h].def,
812
+ e[h].values ?? D
555
813
  );
556
814
  this.entity_archetype[s] = r, this.entity_row[s] = o;
557
815
  } else {
558
816
  const i = this.arch_get(n), _ = this.entity_row[s];
559
- for (let h = 0; h < e.length; h++)
817
+ for (let c = 0; c < e.length; c++)
560
818
  i.write_fields(
561
819
  _,
562
- e[h].def,
563
- e[h].values ?? S
820
+ e[c].def,
821
+ e[c].values ?? D
564
822
  );
565
823
  }
566
824
  }
567
825
  remove_component(t, e) {
568
826
  if (!this.is_alive(t))
569
827
  return;
570
- const s = f(t), n = this.entity_archetype[s], r = this.arch_get(n);
828
+ const s = m(t), n = this.entity_archetype[s], r = this.arch_get(n);
571
829
  if (!r.has_component(e)) return;
572
830
  const i = this.arch_resolve_remove(
573
831
  n,
574
832
  e
575
- ), _ = this.arch_get(i), h = this.entity_row[s], o = _.add_entity(t);
576
- _.copy_shared_from(r, h, o);
577
- const c = r.remove_entity(h);
578
- c !== -1 && (this.entity_row[c] = h), this.entity_archetype[s] = i, this.entity_row[s] = o;
833
+ ), _ = this.arch_get(i), c = this.entity_row[s], o = r.get_edge(e);
834
+ !_.has_columns && !r.has_columns ? _.move_entity_from_tag(r, c, t) : _.move_entity_from(r, c, t, o.remove_map), f[1] !== y && (this.entity_row[f[1]] = c), this.entity_archetype[s] = i, this.entity_row[s] = f[0];
579
835
  }
580
836
  /** Remove multiple components in one transition (resolves final archetype, then moves once). */
581
837
  remove_components(t, e) {
582
838
  if (!this.is_alive(t))
583
839
  return;
584
- const s = f(t), n = this.entity_archetype[s];
840
+ const s = m(t), n = this.entity_archetype[s];
585
841
  let r = n;
586
- for (let l = 0; l < e.length; l++)
842
+ for (let h = 0; h < e.length; h++)
587
843
  r = this.arch_resolve_remove(
588
844
  r,
589
- e[l]
845
+ e[h]
590
846
  );
591
847
  if (r === n) return;
592
- const i = this.arch_get(n), _ = this.arch_get(r), h = this.entity_row[s], o = _.add_entity(t);
593
- _.copy_shared_from(i, h, o);
594
- const c = i.remove_entity(h);
595
- c !== -1 && (this.entity_row[c] = h), this.entity_archetype[s] = r, this.entity_row[s] = o;
848
+ const i = this.arch_get(n), _ = this.arch_get(r), c = this.entity_row[s], o = M(i, _);
849
+ _.move_entity_from(i, c, t, o), f[1] !== y && (this.entity_row[f[1]] = c), this.entity_archetype[s] = r, this.entity_row[s] = f[0];
596
850
  }
597
851
  has_component(t, e) {
598
852
  if (!this.is_alive(t))
599
853
  return !1;
600
- const s = f(t);
854
+ const s = m(t);
601
855
  return this.arch_get(
602
856
  this.entity_archetype[s]
603
857
  ).has_component(e);
604
858
  }
859
+ /**
860
+ * Bulk add a component to ALL entities in the given archetype.
861
+ * Uses TypedArray.set() for O(columns) instead of O(N×columns).
862
+ * The archetype must not already contain this component.
863
+ */
864
+ batch_add_component(t, e, s) {
865
+ if (t.length === 0) return;
866
+ const n = e;
867
+ if (t.mask.has(n)) return;
868
+ const r = this.arch_resolve_add(t.id, n), i = this.arch_get(r), _ = t.get_edge(n), c = t.length, o = this.entity_archetype, h = this.entity_row, a = i.bulk_move_all_from(t, _.add_map);
869
+ for (let d = 0; d < c; d++) {
870
+ const g = m(i.entity_ids[a + d]);
871
+ o[g] = r, h[g] = a + d;
872
+ }
873
+ if (this.component_metas[n].field_names.length > 0 && s)
874
+ for (let d = 0; d < c; d++)
875
+ i.write_fields(a + d, n, s);
876
+ }
877
+ /**
878
+ * Bulk remove a component from ALL entities in the given archetype.
879
+ * Uses TypedArray.set() for O(columns) instead of O(N×columns).
880
+ * The archetype must contain this component.
881
+ */
882
+ batch_remove_component(t, e) {
883
+ if (t.length === 0) return;
884
+ const s = e;
885
+ if (!t.mask.has(s)) return;
886
+ const n = this.arch_resolve_remove(t.id, s), r = this.arch_get(n), i = t.get_edge(s), _ = t.length, c = r.bulk_move_all_from(t, i.remove_map), o = this.entity_archetype, h = this.entity_row;
887
+ for (let a = 0; a < _; a++) {
888
+ const u = m(r.entity_ids[c + a]);
889
+ o[u] = n, h[u] = c + a;
890
+ }
891
+ }
605
892
  // =======================================================
606
893
  // Direct data access (used by SystemContext)
607
894
  // =======================================================
608
895
  get_entity_archetype(t) {
609
896
  return this.arch_get(
610
- this.entity_archetype[f(t)]
897
+ this.entity_archetype[m(t)]
611
898
  );
612
899
  }
613
900
  get_entity_row(t) {
614
- return this.entity_row[f(t)];
901
+ return this.entity_row[m(t)];
615
902
  }
616
903
  // =======================================================
617
904
  // Query support
@@ -635,28 +922,28 @@ class $ {
635
922
  );
636
923
  let i, _ = !1;
637
924
  for (let o = 0; o < n.length; o++) {
638
- let c = n[o];
639
- if (c === 0) continue;
640
- const l = o << 5;
641
- for (; c !== 0; ) {
642
- const u = c & -c >>> 0, d = l + (31 - Math.clz32(u));
643
- c ^= u;
644
- const p = this.component_index.get(d);
645
- if (!p || p.size === 0) {
925
+ let h = n[o];
926
+ if (h === 0) continue;
927
+ const a = o << k;
928
+ for (; h !== 0; ) {
929
+ const u = h & -h >>> 0, d = a + (I - Math.clz32(u));
930
+ h ^= u;
931
+ const g = this.component_index.get(d);
932
+ if (!g || g.size === 0) {
646
933
  _ = !0;
647
934
  break;
648
935
  }
649
- (!i || p.size < i.size) && (i = p);
936
+ (!i || g.size < i.size) && (i = g);
650
937
  }
651
938
  if (_) break;
652
939
  }
653
940
  if (_ || !i) return [];
654
- const h = [];
941
+ const c = [];
655
942
  for (const o of i) {
656
- const c = this.arch_get(o);
657
- c.matches(t) && (!e || !c.mask.overlaps(e)) && (!s || c.mask.overlaps(s)) && h.push(c);
943
+ const h = this.arch_get(o);
944
+ h.matches(t) && (!e || !h.mask.overlaps(e)) && (!s || h.mask.overlaps(s)) && c.push(h);
658
945
  }
659
- return h;
946
+ return c;
660
947
  }
661
948
  /**
662
949
  * Register a live query. Returns a mutable Archetype[] that this Store will
@@ -682,7 +969,7 @@ class $ {
682
969
  // Event channels
683
970
  // =======================================================
684
971
  register_event(t) {
685
- const e = V(this.event_count++), s = new C(t);
972
+ const e = pt(this.event_count++), s = new wt(t);
686
973
  return this.event_channels.push(s), e;
687
974
  }
688
975
  emit_event(t, e) {
@@ -699,30 +986,43 @@ class $ {
699
986
  for (let e = 0; e < t.length; e++)
700
987
  t[e].clear();
701
988
  }
989
+ // =======================================================
990
+ // Resource channels
991
+ // =======================================================
992
+ register_resource(t, e) {
993
+ const s = vt(this.resource_count++), n = new xt(t, e);
994
+ return this.resource_channels.push(n), s;
995
+ }
996
+ get_resource_reader(t) {
997
+ return this.resource_channels[t].reader;
998
+ }
999
+ get_resource_channel(t) {
1000
+ return this.resource_channels[t];
1001
+ }
702
1002
  }
703
- var B = /* @__PURE__ */ ((a) => (a.PRE_STARTUP = "PRE_STARTUP", a.STARTUP = "STARTUP", a.POST_STARTUP = "POST_STARTUP", a.FIXED_UPDATE = "FIXED_UPDATE", a.PRE_UPDATE = "PRE_UPDATE", a.UPDATE = "UPDATE", a.POST_UPDATE = "POST_UPDATE", a))(B || {});
704
- const D = [
1003
+ var Et = /* @__PURE__ */ ((l) => (l.PRE_STARTUP = "PRE_STARTUP", l.STARTUP = "STARTUP", l.POST_STARTUP = "POST_STARTUP", l.FIXED_UPDATE = "FIXED_UPDATE", l.PRE_UPDATE = "PRE_UPDATE", l.UPDATE = "UPDATE", l.POST_UPDATE = "POST_UPDATE", l))(Et || {});
1004
+ const q = [
705
1005
  "PRE_STARTUP",
706
1006
  "STARTUP",
707
1007
  "POST_STARTUP"
708
1008
  /* POST_STARTUP */
709
- ], O = [
1009
+ ], G = [
710
1010
  "PRE_UPDATE",
711
1011
  "UPDATE",
712
1012
  "POST_UPDATE"
713
1013
  /* POST_UPDATE */
714
1014
  ];
715
- class Q {
1015
+ class kt {
716
1016
  label_systems = /* @__PURE__ */ new Map();
717
1017
  sorted_cache = /* @__PURE__ */ new Map();
718
1018
  system_index = /* @__PURE__ */ new Map();
719
1019
  next_insertion_order = 0;
720
1020
  constructor() {
721
- for (let t = 0; t < D.length; t++)
722
- this.label_systems.set(D[t], []);
1021
+ for (let t = 0; t < q.length; t++)
1022
+ this.label_systems.set(q[t], []);
723
1023
  this.label_systems.set("FIXED_UPDATE", []);
724
- for (let t = 0; t < O.length; t++)
725
- this.label_systems.set(O[t], []);
1024
+ for (let t = 0; t < G.length; t++)
1025
+ this.label_systems.set(G[t], []);
726
1026
  }
727
1027
  add_systems(t, ...e) {
728
1028
  for (const s of e) {
@@ -748,11 +1048,11 @@ class Q {
748
1048
  this.system_index.delete(t), this.sorted_cache.delete(e);
749
1049
  }
750
1050
  run_startup(t) {
751
- for (const e of D)
752
- this.run_label(e, t, 0);
1051
+ for (const e of q)
1052
+ this.run_label(e, t, it);
753
1053
  }
754
1054
  run_update(t, e) {
755
- for (const s of O)
1055
+ for (const s of G)
756
1056
  this.run_label(s, t, e);
757
1057
  }
758
1058
  run_fixed_update(t, e) {
@@ -801,51 +1101,72 @@ class Q {
801
1101
  for (const o of t)
802
1102
  s.set(o.descriptor, /* @__PURE__ */ new Set()), n.set(o.descriptor, 0), r.set(o.descriptor, o.insertion_order), i.add(o.descriptor);
803
1103
  for (const o of t) {
804
- for (const c of o.before)
805
- i.has(c) && (s.get(o.descriptor).add(c), n.set(c, n.get(c) + 1));
806
- for (const c of o.after)
807
- i.has(c) && (s.get(c).add(o.descriptor), n.set(o.descriptor, n.get(o.descriptor) + 1));
1104
+ for (const h of o.before)
1105
+ i.has(h) && (s.get(o.descriptor).add(h), n.set(h, n.get(h) + 1));
1106
+ for (const h of o.after)
1107
+ i.has(h) && (s.get(h).add(o.descriptor), n.set(o.descriptor, n.get(o.descriptor) + 1));
808
1108
  }
809
1109
  let _ = [];
810
1110
  for (const o of t)
811
1111
  n.get(o.descriptor) === 0 && _.push(o.descriptor);
812
- _.sort((o, c) => r.get(c) - r.get(o));
813
- const h = [];
1112
+ _.sort((o, h) => r.get(h) - r.get(o));
1113
+ const c = [];
814
1114
  for (; _.length > 0; ) {
815
1115
  const o = _.pop();
816
- h.push(o);
817
- for (const c of s.get(o)) {
818
- const l = n.get(c) - 1;
819
- n.set(c, l), l === 0 && _.push(c);
1116
+ c.push(o);
1117
+ for (const h of s.get(o)) {
1118
+ const a = n.get(h) - 1;
1119
+ n.set(h, a), a === 0 && _.push(h);
820
1120
  }
821
- _.sort((c, l) => r.get(l) - r.get(c));
1121
+ _.sort((h, a) => r.get(a) - r.get(h));
822
1122
  }
823
- if (h.length !== t.length) {
824
- const o = new Set(h), c = t.filter((l) => !o.has(l.descriptor)).map((l) => `system_${l.descriptor.id}`);
825
- throw new Y(
826
- q.CIRCULAR_SYSTEM_DEPENDENCY,
827
- `Circular system dependency detected in ${e}: [${c.join(", ")}]`
1123
+ if (c.length !== t.length) {
1124
+ const o = new Set(c), h = t.filter((a) => !o.has(a.descriptor)).map((a) => a.descriptor.name ?? `system_${a.descriptor.id}`);
1125
+ throw new Q(
1126
+ z.CIRCULAR_SYSTEM_DEPENDENCY,
1127
+ `Circular system dependency detected in ${e}: [${h.join(", ")}]`
828
1128
  );
829
1129
  }
830
- return h;
1130
+ return c;
831
1131
  }
832
1132
  }
833
- const K = Object.freeze(/* @__PURE__ */ Object.create(null));
834
- class J {
1133
+ const W = /* @__PURE__ */ new WeakMap();
1134
+ function It(l, t) {
1135
+ let e = W.get(l);
1136
+ if (!e) {
1137
+ e = /* @__PURE__ */ Object.create(null);
1138
+ const { field_names: r } = l.layout;
1139
+ for (let i = 0; i < r.length; i++) {
1140
+ const _ = i;
1141
+ Object.defineProperty(e, r[i], {
1142
+ get() {
1143
+ return this._columns[_][this._row];
1144
+ },
1145
+ set(c) {
1146
+ this._columns[_][this._row] = c;
1147
+ },
1148
+ enumerable: !0,
1149
+ configurable: !1
1150
+ });
1151
+ }
1152
+ W.set(l, e);
1153
+ }
1154
+ const s = Object.create(e), n = new Array(l.columns.length);
1155
+ for (let r = 0; r < l.columns.length; r++) n[r] = l.columns[r].buf;
1156
+ return s._columns = n, s._row = t, s;
1157
+ }
1158
+ class Pt {
835
1159
  _archetypes;
836
1160
  _defs;
837
1161
  _resolver;
838
1162
  _include;
839
1163
  _exclude;
840
1164
  _any_of;
841
- // Pre-allocated args buffer for each() — avoids allocating a new array per
842
- // archetype. Holds [columnGroup0, columnGroup1, ..., entityCount].
843
- _args_buf;
844
1165
  constructor(t, e, s, n, r, i) {
845
- this._archetypes = t, this._defs = e, this._resolver = s, this._include = n, this._exclude = r, this._any_of = i, this._args_buf = new Array(e.length + 1);
1166
+ this._archetypes = t, this._defs = e, this._resolver = s, this._include = n, this._exclude = r, this._any_of = i;
846
1167
  }
847
1168
  /** Number of matching archetypes (including empty ones). */
848
- get length() {
1169
+ get archetype_count() {
849
1170
  return this._archetypes.length;
850
1171
  }
851
1172
  /** Total entity count across all matching archetypes. */
@@ -864,22 +1185,6 @@ class J {
864
1185
  for (let e = 0; e < t.length; e++)
865
1186
  t[e].entity_count > 0 && (yield t[e]);
866
1187
  }
867
- /**
868
- * Typed per-archetype iteration. Calls fn once per non-empty archetype
869
- * with column groups for each queried component, plus the entity count.
870
- * The system is responsible for the inner loop over entities.
871
- */
872
- each(t) {
873
- const e = this._archetypes, s = this._defs, n = this._args_buf;
874
- for (let r = 0; r < e.length; r++) {
875
- const i = e[r], _ = i.entity_count;
876
- if (_ !== 0) {
877
- for (let h = 0; h < s.length; h++)
878
- n[h] = i.get_column_group(s[h]);
879
- n[s.length] = _, t.apply(null, n);
880
- }
881
- }
882
- }
883
1188
  /** Extend required component set. Returns a new (cached) Query. */
884
1189
  and(...t) {
885
1190
  const e = this._include.copy(), s = this._defs.slice();
@@ -894,7 +1199,7 @@ class J {
894
1199
  }
895
1200
  /** Exclude archetypes that have any of these components. */
896
1201
  not(...t) {
897
- const e = this._exclude ? this._exclude.copy() : new v();
1202
+ const e = this._exclude ? this._exclude.copy() : new x();
898
1203
  for (let s = 0; s < t.length; s++) e.set(t[s]);
899
1204
  return this._resolver._resolve_query(
900
1205
  this._include,
@@ -904,8 +1209,8 @@ class J {
904
1209
  );
905
1210
  }
906
1211
  /** Require at least one of these components. */
907
- or(...t) {
908
- const e = this._any_of ? this._any_of.copy() : new v();
1212
+ any_of(...t) {
1213
+ const e = this._any_of ? this._any_of.copy() : new x();
909
1214
  for (let s = 0; s < t.length; s++) e.set(t[s]);
910
1215
  return this._resolver._resolve_query(
911
1216
  this._include,
@@ -915,17 +1220,17 @@ class J {
915
1220
  );
916
1221
  }
917
1222
  }
918
- class Z {
1223
+ class St {
919
1224
  constructor(t) {
920
1225
  this._resolver = t;
921
1226
  }
922
1227
  every(...t) {
923
- const e = new v();
1228
+ const e = new x();
924
1229
  for (let s = 0; s < t.length; s++) e.set(t[s]);
925
1230
  return this._resolver._resolve_query(e, null, null, t);
926
1231
  }
927
1232
  }
928
- class H {
1233
+ class Ot {
929
1234
  store;
930
1235
  constructor(t) {
931
1236
  this.store = t;
@@ -934,22 +1239,24 @@ class H {
934
1239
  return this.store.create_entity();
935
1240
  }
936
1241
  get_field(t, e, s) {
937
- const n = this.store.get_entity_archetype(e), r = this.store.get_entity_row(e);
938
- return n.read_field(r, t, s);
1242
+ const n = this.store.get_entity_archetype(t), r = this.store.get_entity_row(t);
1243
+ return n.read_field(r, e, s);
939
1244
  }
940
1245
  set_field(t, e, s, n) {
941
- const r = this.store.get_entity_archetype(e), i = this.store.get_entity_row(e), _ = r.get_column(t, s);
1246
+ const r = this.store.get_entity_archetype(t), i = this.store.get_entity_row(t), _ = r.get_column(e, s);
942
1247
  _[i] = n;
943
1248
  }
1249
+ /** Create a cached component reference for a single entity. See ref.ts. */
1250
+ ref(t, e) {
1251
+ const s = this.store.get_entity_archetype(e), n = this.store.get_entity_row(e);
1252
+ return It(s.column_groups[t], n);
1253
+ }
944
1254
  /** Buffer an entity for deferred destruction (applied at phase flush). */
945
1255
  destroy_entity(t) {
946
1256
  return this.store.destroy_entity_deferred(t), this;
947
1257
  }
948
- flush_destroyed() {
949
- this.store.flush_destroyed();
950
- }
951
1258
  add_component(t, e, s) {
952
- return this.store.add_component_deferred(t, e, s ?? K), this;
1259
+ return this.store.add_component_deferred(t, e, s ?? D), this;
953
1260
  }
954
1261
  remove_component(t, e) {
955
1262
  return this.store.remove_component_deferred(t, e), this;
@@ -964,11 +1271,20 @@ class H {
964
1271
  read(t) {
965
1272
  return this.store.get_event_reader(t);
966
1273
  }
1274
+ // =======================================================
1275
+ // Resources
1276
+ // =======================================================
1277
+ resource(t) {
1278
+ return this.store.get_resource_reader(t);
1279
+ }
1280
+ set_resource(t, e) {
1281
+ this.store.get_resource_channel(t).write(e);
1282
+ }
967
1283
  }
968
- const tt = (a) => b(
969
- a
970
- ), et = Object.freeze(/* @__PURE__ */ Object.create(null));
971
- class st {
1284
+ const Dt = (l) => N(
1285
+ l
1286
+ );
1287
+ class Nt {
972
1288
  store;
973
1289
  schedule;
974
1290
  ctx;
@@ -982,9 +1298,9 @@ class st {
982
1298
  // Multiple queries can share the same hash (collision), so each bucket is an array.
983
1299
  query_cache = /* @__PURE__ */ new Map();
984
1300
  // Reusable BitSet for building query masks — avoids allocation per query() call
985
- scratch_mask = new v();
1301
+ scratch_mask = new x();
986
1302
  constructor(t) {
987
- this.store = new $(), this.schedule = new Q(), this.ctx = new H(this.store), this._fixed_timestep = t?.fixed_timestep ?? 1 / 60, this._max_fixed_steps = t?.max_fixed_steps ?? 4;
1303
+ this.store = new At(t?.initial_capacity), this.schedule = new kt(), this.ctx = new Ot(this.store), this._fixed_timestep = t?.fixed_timestep ?? nt, this._max_fixed_steps = t?.max_fixed_steps ?? rt;
988
1304
  }
989
1305
  get fixed_timestep() {
990
1306
  return this._fixed_timestep;
@@ -995,11 +1311,17 @@ class st {
995
1311
  get fixed_alpha() {
996
1312
  return this._accumulator / this._fixed_timestep;
997
1313
  }
998
- register_component(t) {
1314
+ // Implementation
1315
+ register_component(t, e) {
1316
+ if (Array.isArray(t)) {
1317
+ const s = e ?? "f64", n = /* @__PURE__ */ Object.create(null);
1318
+ for (const r of t) n[r] = s;
1319
+ return this.store.register_component(n);
1320
+ }
999
1321
  return this.store.register_component(t);
1000
1322
  }
1001
1323
  register_tag() {
1002
- return this.store.register_component([]);
1324
+ return this.store.register_component({});
1003
1325
  }
1004
1326
  register_event(t) {
1005
1327
  return this.store.register_event(t);
@@ -1007,10 +1329,22 @@ class st {
1007
1329
  register_signal() {
1008
1330
  return this.store.register_event([]);
1009
1331
  }
1332
+ register_resource(t, e) {
1333
+ return this.store.register_resource(
1334
+ t,
1335
+ e
1336
+ );
1337
+ }
1338
+ resource(t) {
1339
+ return this.store.get_resource_reader(t);
1340
+ }
1341
+ set_resource(t, e) {
1342
+ this.store.get_resource_channel(t).write(e);
1343
+ }
1010
1344
  create_entity() {
1011
1345
  return this.store.create_entity();
1012
1346
  }
1013
- destroy_entity(t) {
1347
+ destroy_entity_deferred(t) {
1014
1348
  this.store.destroy_entity_deferred(t);
1015
1349
  }
1016
1350
  is_alive(t) {
@@ -1020,7 +1354,7 @@ class st {
1020
1354
  return this.store.entity_count;
1021
1355
  }
1022
1356
  add_component(t, e, s) {
1023
- this.store.add_component(t, e, s ?? et);
1357
+ return this.store.add_component(t, e, s ?? D), this;
1024
1358
  }
1025
1359
  add_components(t, e) {
1026
1360
  this.store.add_components(t, e);
@@ -1034,9 +1368,23 @@ class st {
1034
1368
  has_component(t, e) {
1035
1369
  return this.store.has_component(t, e);
1036
1370
  }
1371
+ batch_add_component(t, e, s) {
1372
+ this.store.batch_add_component(t, e, s);
1373
+ }
1374
+ /**
1375
+ * Bulk remove a component from ALL entities in the given archetype.
1376
+ * O(columns) via TypedArray.set() instead of O(N×columns).
1377
+ */
1378
+ batch_remove_component(t, e) {
1379
+ this.store.batch_remove_component(t, e);
1380
+ }
1037
1381
  get_field(t, e, s) {
1038
- const n = this.store.get_entity_archetype(e), r = this.store.get_entity_row(e);
1039
- return n.read_field(r, t, s);
1382
+ const n = this.store.get_entity_archetype(t), r = this.store.get_entity_row(t);
1383
+ return n.read_field(r, e, s);
1384
+ }
1385
+ set_field(t, e, s, n) {
1386
+ const r = this.store.get_entity_archetype(t), i = this.store.get_entity_row(t), _ = r.get_column(e, s);
1387
+ _[i] = n;
1040
1388
  }
1041
1389
  emit(t, e) {
1042
1390
  e === void 0 ? this.store.emit_signal(t) : this.store.emit_event(t, e);
@@ -1050,26 +1398,26 @@ class st {
1050
1398
  }
1051
1399
  /** QueryResolver implementation — creates or retrieves a cached Query. */
1052
1400
  _resolve_query(t, e, s, n) {
1053
- const r = t.hash(), i = e ? e.hash() : 0, _ = s ? s.hash() : 0, h = r ^ Math.imul(i, 2654435769) ^ Math.imul(_, 1367130551) | 0, o = this._find_cached(h, t, e, s);
1401
+ const r = t.hash(), i = e ? e.hash() : 0, _ = s ? s.hash() : 0, c = r ^ Math.imul(i, tt) ^ Math.imul(_, et) | 0, o = this._find_cached(c, t, e, s);
1054
1402
  if (o !== void 0) return o.query;
1055
- const c = this.store.register_query(
1403
+ const h = this.store.register_query(
1056
1404
  t,
1057
1405
  e ?? void 0,
1058
1406
  s ?? void 0
1059
- ), l = new J(
1060
- c,
1407
+ ), a = new Pt(
1408
+ h,
1061
1409
  n,
1062
1410
  this,
1063
1411
  t.copy(),
1064
1412
  e?.copy() ?? null,
1065
1413
  s?.copy() ?? null
1066
1414
  );
1067
- return j(this.query_cache, h, {
1415
+ return K(this.query_cache, c, {
1068
1416
  include_mask: t.copy(),
1069
1417
  exclude_mask: e?.copy() ?? null,
1070
1418
  any_of_mask: s?.copy() ?? null,
1071
- query: l
1072
- }), l;
1419
+ query: a
1420
+ }), a;
1073
1421
  }
1074
1422
  _find_cached(t, e, s, n) {
1075
1423
  const r = this.query_cache.get(t);
@@ -1080,14 +1428,18 @@ class st {
1080
1428
  return _;
1081
1429
  }
1082
1430
  }
1431
+ // any: overload implementation must unify bare fn, (fn, query_fn), and SystemConfig
1083
1432
  register_system(t, e) {
1084
1433
  let s;
1085
- if (typeof t == "function") {
1086
- const i = e(new Z(this)), _ = this.ctx;
1087
- s = { fn: (h, o) => t(i, _, o) };
1088
- } else
1434
+ if (typeof t == "function")
1435
+ if (e !== void 0) {
1436
+ const i = e(new St(this)), _ = this.ctx, c = t;
1437
+ s = { fn: (o, h) => c(i, _, h) };
1438
+ } else
1439
+ s = { fn: t };
1440
+ else
1089
1441
  s = t;
1090
- const n = tt(this.next_system_id++), r = Object.freeze(
1442
+ const n = Dt(this.next_system_id++), r = Object.freeze(
1091
1443
  Object.assign({ id: n }, s)
1092
1444
  );
1093
1445
  return this.systems.add(r), r;
@@ -1103,17 +1455,17 @@ class st {
1103
1455
  }
1104
1456
  startup() {
1105
1457
  for (const t of this.systems.values())
1106
- t.on_added?.(this.store);
1458
+ t.on_added?.(this.ctx);
1107
1459
  this.schedule.run_startup(this.ctx);
1108
1460
  }
1109
1461
  update(t) {
1110
- if (this.store.clear_events(), this.schedule.has_fixed_systems()) {
1462
+ if (this.schedule.has_fixed_systems()) {
1111
1463
  this._accumulator += t;
1112
1464
  const e = this._max_fixed_steps * this._fixed_timestep;
1113
1465
  for (this._accumulator > e && (this._accumulator = e); this._accumulator >= this._fixed_timestep; )
1114
1466
  this.schedule.run_fixed_update(this.ctx, this._fixed_timestep), this._accumulator -= this._fixed_timestep;
1115
1467
  }
1116
- this.schedule.run_update(this.ctx, t);
1468
+ this.schedule.run_update(this.ctx, t), this.store.clear_events();
1117
1469
  }
1118
1470
  flush() {
1119
1471
  this.ctx.flush();
@@ -1125,9 +1477,9 @@ class st {
1125
1477
  }
1126
1478
  }
1127
1479
  export {
1128
- J as Query,
1129
- Z as QueryBuilder,
1130
- B as SCHEDULE,
1131
- H as SystemContext,
1132
- st as World
1480
+ Nt as ECS,
1481
+ Pt as Query,
1482
+ St as QueryBuilder,
1483
+ Et as SCHEDULE,
1484
+ Ot as SystemContext
1133
1485
  };