aiecsjs 0.5.6 → 0.5.7

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 (63) hide show
  1. package/README.md +21 -12
  2. package/README_ZHTW.md +21 -12
  3. package/api.json +23 -0
  4. package/dist/chunk-22ICWJ5O.js +2 -0
  5. package/dist/chunk-22ICWJ5O.js.map +1 -0
  6. package/dist/chunk-2KCN5RVK.js +2 -0
  7. package/dist/chunk-2KCN5RVK.js.map +1 -0
  8. package/dist/chunk-5QWEV4VJ.cjs +2 -0
  9. package/dist/chunk-5QWEV4VJ.cjs.map +1 -0
  10. package/dist/chunk-AGWUE6JB.js +2 -0
  11. package/dist/chunk-AGWUE6JB.js.map +1 -0
  12. package/dist/chunk-P5GW7GKY.cjs +2 -0
  13. package/dist/chunk-P5GW7GKY.cjs.map +1 -0
  14. package/dist/chunk-SRX2MZPX.cjs +2 -0
  15. package/dist/chunk-SRX2MZPX.cjs.map +1 -0
  16. package/dist/commands.cjs +1 -1
  17. package/dist/commands.cjs.map +1 -1
  18. package/dist/commands.d.cts +1 -1
  19. package/dist/commands.d.ts +1 -1
  20. package/dist/commands.js +1 -1
  21. package/dist/commands.js.map +1 -1
  22. package/dist/index.cjs +1 -1
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +49 -4
  25. package/dist/index.d.ts +49 -4
  26. package/dist/index.js +1 -1
  27. package/dist/index.js.map +1 -1
  28. package/dist/observers.cjs +1 -1
  29. package/dist/observers.d.cts +1 -1
  30. package/dist/observers.d.ts +1 -1
  31. package/dist/observers.js +1 -1
  32. package/dist/observers.js.map +1 -1
  33. package/dist/relations.cjs +1 -1
  34. package/dist/relations.d.cts +1 -1
  35. package/dist/relations.d.ts +1 -1
  36. package/dist/relations.js +1 -1
  37. package/dist/relations.js.map +1 -1
  38. package/dist/serialize.cjs +1 -1
  39. package/dist/serialize.d.cts +1 -1
  40. package/dist/serialize.d.ts +1 -1
  41. package/dist/serialize.js +1 -1
  42. package/dist/{types-BGEeHad-.d.cts → types-BeVLA7xG.d.cts} +11 -1
  43. package/dist/{types-BGEeHad-.d.ts → types-BeVLA7xG.d.ts} +11 -1
  44. package/dist/worker.cjs +1 -1
  45. package/dist/worker.cjs.map +1 -1
  46. package/dist/worker.d.cts +2 -2
  47. package/dist/worker.d.ts +2 -2
  48. package/dist/worker.js +1 -1
  49. package/dist/worker.js.map +1 -1
  50. package/llms-full.txt +50 -12
  51. package/package.json +7 -2
  52. package/dist/chunk-FZ5DSL4K.cjs +0 -2
  53. package/dist/chunk-FZ5DSL4K.cjs.map +0 -1
  54. package/dist/chunk-H3E365XN.cjs +0 -2
  55. package/dist/chunk-H3E365XN.cjs.map +0 -1
  56. package/dist/chunk-IFA7MVBB.js +0 -2
  57. package/dist/chunk-IFA7MVBB.js.map +0 -1
  58. package/dist/chunk-L3H4HVUJ.cjs +0 -2
  59. package/dist/chunk-L3H4HVUJ.cjs.map +0 -1
  60. package/dist/chunk-R67UJPKI.js +0 -2
  61. package/dist/chunk-R67UJPKI.js.map +0 -1
  62. package/dist/chunk-TKDLUVJR.js +0 -2
  63. package/dist/chunk-TKDLUVJR.js.map +0 -1
package/README.md CHANGED
@@ -31,7 +31,7 @@ pipe(movement)(world, 1/60)
31
31
 
32
32
  > **Use `forEachEntityIndexed` for column iteration.** Its callback is `(e, i, ...cols)`: `e` is the packed `EntityId` (use it directly for `destroyEntity`, `hasComponent`, `getComponent`, command buffers), and `i` is the **safe column subscript** — index every SoA column with it (`pos.x[i]`). The packed `e` is **not** a column index: it only equals the index until a slot is recycled (generation 0); after any `destroyEntity` recycles a slot, `e !== i` and indexing a column with `e` reads the wrong slot (out of bounds → `undefined`/`NaN`). `forEachEntityIndexed` hands you the correct `i` so this footgun is closed in code. Use `forEachEntity` when you only need the `EntityId` (and index columns via `getEntityIndex(e)` if you must).
33
33
 
34
- > **Status: experimental (v0.5.x).** The API surface in `STABILITY.md` is committed for the 0.x line, but expect adjustments. A stable 1.0 freeze is targeted after community feedback.
34
+ > **Status: 0.5.7 — experimental (0.5.x line).** The API surface in `STABILITY.md` is committed for the 0.x line, but expect adjustments. A stable 1.0 freeze is targeted after community feedback.
35
35
 
36
36
  ## Table of contents
37
37
 
@@ -56,7 +56,7 @@ pipe(movement)(world, 1/60)
56
56
  ## Why aiecsjs?
57
57
 
58
58
  - **Archetype-first storage** — entities sharing the same component set live in one contiguous table; queries walk straight `for` loops over parallel TypedArrays. Iteration is cache-friendly by construction.
59
- - **Zero-config TypeScript inference** — `defineQuery([Position, Velocity])` returns an iterator that yields `(eid, posCols, velCols)` with the correct TypedArray types. No manual generics.
59
+ - **First-class TypeScript** — typed `EntityId`, components, worlds, and queries with no manual generics. Iteration helpers pass the SoA column views positionally (`forEachEntityIndexed(w, q, (e, i, pos, vel) => …)`); the **column arguments are `any`-typed** today — statically tuple-typed columns are future work — while `e` (`EntityId`) and `i` (`number`) are fully typed.
60
60
  - **AI-first documentation contract** — every public export has a stability tag and a `since` version. Ships `llms.txt`, `llms-full.txt`, and `api.json` so LLM tools can read the API surface directly.
61
61
 
62
62
  ### Comparison
@@ -65,7 +65,7 @@ pipe(movement)(world, 1/60)
65
65
  |---|---|---|---|---|
66
66
  | Storage | Archetype + SoA columns | SparseSet + bitmask + SoA/AoS | Archetype + JS objects | Configurable (packed/sparse/compact) + ArrayBuffer |
67
67
  | API style | Functional + `pipe` | Functional + `pipe` | Chainable OO | Decorator classes |
68
- | TS inference on query | Tuple-aware columns | Manual | Predicate inference | Class-based |
68
+ | TS inference on query | Typed `e`/`i`; columns `any` | Manual | Predicate inference | Class-based |
69
69
  | Multi-thread | SAB snapshot transport (0.x); true shared cols planned 0.3+ | SAB-ready, scheduling DIY | Single-thread | Roadmap (not shipped) |
70
70
  | AI docs | `llms.txt` + `llms-full.txt` + `api.json` | No | No | No |
71
71
  | Maintenance | Active (new) | Active | Slowed (~3y since npm release) | Active |
@@ -337,7 +337,7 @@ Observers fire synchronously inside the mutation call. Use them for side effects
337
337
 
338
338
  ### Command buffers — when and why
339
339
 
340
- The golden rule: **do not add or remove components on entities you're currently iterating over.** Doing so can skip or double-process entities because the archetype membership changes mid-walk. Use a command buffer to defer:
340
+ The golden rule: **add or remove components via a command buffer while iterating** — never mutate an iterated entity's component set inline. Adding or removing a component changes archetype membership mid-walk, which can skip or double-process entities. In-loop `destroyEntity` **is** safe (the iteration re-reads the live row count each step, so the callback never sees the reserved eid 0 and never a destroyed entity), but with two caveats: a surviving entity swapped into a freed row is **deferred to the next pass** (not visited again this pass), and iteration order after a destroy is not guaranteed. Use a command buffer to defer component mutations:
341
341
 
342
342
  ```ts
343
343
  import { withCommandBuffer } from 'aiecsjs/commands'
@@ -402,11 +402,13 @@ type WorldOptions = {
402
402
  maxEntities?: number // default 1_000_000
403
403
  indexBits?: 20 | 24 // default 24 → 16M entities
404
404
  generationBits?: 8 | 12 | 16 // default 8 → 256 recycles
405
- buffer?: SharedArrayBuffer // opt-in SAB backing
406
- bufferByteOffset?: number // when sharing one SAB across worlds
405
+ buffer?: SharedArrayBuffer // RESERVED — no effect in 0.x (see note below)
406
+ bufferByteOffset?: number // RESERVED — paired with buffer; no effect in 0.x
407
407
  }
408
408
  ```
409
409
 
410
+ > **`buffer` / `bufferByteOffset` are reserved and currently unimplemented.** Setting them has no effect: a world always allocates its own column storage and never reads a caller-supplied SAB. For Worker handoff use the snapshot-copy transport — post `transferableSnapshot(world)` and rebuild via `adoptSnapshot` from `aiecsjs/worker` (see [Multi-threading Guide](#multi-threading-guide)). The fields are kept for forward-compatibility with the true shared-column backing targeted for 0.3+.
411
+
410
412
  ### Entity — `aiecsjs`
411
413
 
412
414
  | Function | Signature | Stability |
@@ -586,7 +588,7 @@ These tips are derived from public ECS benchmarks (noctjs/ecs-benchmark, ddmills
586
588
 
587
589
  ## Multi-threading Guide
588
590
 
589
- aiecsjs is **SharedArrayBuffer-ready**: a world's archetype columns can live in shared memory and a Worker can iterate them in parallel.
591
+ aiecsjs hands a world to a Worker via a **transferable snapshot**: the world is serialized into a `SharedArrayBuffer` (a plain `ArrayBuffer` when SAB is unavailable) and the Worker reconstructs a fresh world from it. In 0.x this is a snapshot-**copy** transport, not true shared-memory column aliasing — the two worlds do not see each other's writes after the handoff. True shared columns are targeted for 0.3+ (see [`STABILITY.md`](./STABILITY.md), `aiecsjs/worker`).
590
592
 
591
593
  ### Capability detection
592
594
 
@@ -601,21 +603,28 @@ In browsers, `SharedArrayBuffer` requires the page to be **cross-origin isolated
601
603
 
602
604
  ### Main thread
603
605
 
606
+ Post the whole `transferableSnapshot(world)` — it already carries `{ buffer, meta }`. Do **not** allocate your own SAB and pass it to `createWorld`; `WorldOptions.buffer` is reserved and currently has no effect (see [Entity — `aiecsjs`](#entity--aiecsjs)).
607
+
604
608
  ```ts
605
- const buffer = new SharedArrayBuffer(64 * 1024 * 1024) // 64 MB
606
- const world = createWorld({ buffer })
609
+ import { createWorld } from 'aiecsjs'
610
+ import { transferableSnapshot } from 'aiecsjs/worker'
611
+
612
+ const world = createWorld()
607
613
 
608
614
  // populate world...
609
615
 
610
616
  const worker = new Worker(new URL('./sim-worker.ts', import.meta.url), { type: 'module' })
611
- worker.postMessage({ buffer, meta: transferableSnapshot(world).meta })
617
+ worker.postMessage(transferableSnapshot(world))
612
618
  ```
613
619
 
614
620
  ### Worker thread
615
621
 
622
+ `adoptSnapshot` is imported from the **`aiecsjs/worker`** sub-path (it is not exported from the root entry).
623
+
616
624
  ```ts
617
625
  // sim-worker.ts
618
- import { adoptSnapshot, defineComponent, defineQuery, forEachEntityIndexed, Types } from 'aiecsjs'
626
+ import { defineComponent, defineQuery, forEachEntityIndexed, Types } from 'aiecsjs'
627
+ import { adoptSnapshot } from 'aiecsjs/worker'
619
628
 
620
629
  const Position = defineComponent({ x: Types.f32, y: Types.f32 })
621
630
  const Velocity = defineComponent({ x: Types.f32, y: Types.f32 })
@@ -940,7 +949,7 @@ A: It will be on first stable publish. Until then, the docs are the contract.
940
949
  - **AoS components** not SAB-shareable across workers.
941
950
  - **Network delta serializer** wire format is experimental in 0.1; may change.
942
951
  - **WebGPU integration is one-way** (CPU → GPU). No compute-shader system generation.
943
- - **Limited dev-mode validation.** Production builds skip invariant checks for speed; dev builds (`process.env.NODE_ENV !== 'production'`) include argument-order and entity-existence checks.
952
+ - **No build-mode-gated validation.** There is no `process.env.NODE_ENV` branching — the same checks run in every build. Entity-liveness is validated unconditionally on the mutation paths (`addComponent` / `setComponent` throw on a dead entity), so there is no separate "dev build" with extra runtime guards. Argument order is enforced statically by the TypeScript types, not by a runtime check.
944
953
 
945
954
  ## Contributing
946
955
 
package/README_ZHTW.md CHANGED
@@ -31,7 +31,7 @@ pipe(movement)(world, 1/60)
31
31
 
32
32
  > **欄位迭代請用 `forEachEntityIndexed`。** 其 callback 為 `(e, i, ...cols)`:`e` 是封裝後的 `EntityId`(直接用於 `destroyEntity`、`hasComponent`、`getComponent`、command buffer),`i` 則是**安全的欄位索引** —— 以它索引每個 SoA 欄位(`pos.x[i]`)。封裝後的 `e` **不是**欄位索引:它只有在 slot 尚未被回收(世代 0)時才等於索引;任何 `destroyEntity` 回收 slot 之後,`e !== i`,以 `e` 索引欄位會讀到錯誤的 slot(越界 → `undefined`/`NaN`)。`forEachEntityIndexed` 直接給你正確的 `i`,因此這個陷阱已在程式碼層面消除。若只需要 `EntityId`,仍可用 `forEachEntity`(必要時以 `getEntityIndex(e)` 索引欄位)。
33
33
 
34
- > **狀態:實驗版(v0.5.x)。** `STABILITY.md` 中載明的 API 表面在 0.x 系列內承諾穩定,但仍可能微調。1.0 穩定凍結會在收集社群回饋後執行。
34
+ > **狀態:0.5.7 — 實驗版(0.5.x 系列)。** `STABILITY.md` 中載明的 API 表面在 0.x 系列內承諾穩定,但仍可能微調。1.0 穩定凍結會在收集社群回饋後執行。
35
35
 
36
36
  ## 目錄
37
37
 
@@ -56,7 +56,7 @@ pipe(movement)(world, 1/60)
56
56
  ## 為什麼選 aiecsjs?
57
57
 
58
58
  - **原型優先儲存** — 擁有相同元件集合的實體共用一張連續表格;查詢時直接以 `for` 迴圈走訪平行的 TypedArray。從架構上就保證快取友善。
59
- - **零設定的 TypeScript 推導** — `defineQuery([Position, Velocity])` 回傳的迭代器會丟出 `(eid, posCols, velCols)`,欄位型別自動從 `defineComponent` 推導。不必手寫泛型。
59
+ - **一流的 TypeScript 支援** — `EntityId`、component、world、query 皆有型別,且不必手寫泛型。迭代輔助函式以位置參數傳入 SoA 欄位視圖(`forEachEntityIndexed(w, q, (e, i, pos, vel) => …)`);目前**欄位參數為 `any` 型別**(靜態元組型別欄位屬未來工作),而 `e`(`EntityId`)與 `i`(`number`)則完整具型別。
60
60
  - **AI 優先的文件契約** — 每個公開匯出都有穩定度標籤與 `since` 版本。內建 `llms.txt`、`llms-full.txt`、`api.json`,讓 LLM 工具直接讀懂 API 表面。
61
61
 
62
62
  ### 與其他函式庫比較
@@ -65,7 +65,7 @@ pipe(movement)(world, 1/60)
65
65
  |---|---|---|---|---|
66
66
  | 儲存模型 | 原型 + SoA 欄位 | SparseSet + bitmask + SoA/AoS | 原型 + JS 物件 | 可選(packed/sparse/compact)+ ArrayBuffer |
67
67
  | API 風格 | 函式式 + `pipe` | 函式式 + `pipe` | 鏈式 OO | 裝飾器 class |
68
- | 查詢 TS 推導 | 欄位元組支援 | 手動 | 述詞推導 | class-based |
68
+ | 查詢 TS 推導 | `e`/`i` 具型別;欄位為 `any` | 手動 | 述詞推導 | class-based |
69
69
  | 多執行緒 | SAB 快照傳輸(0.x);真共享欄位預計 0.3+ | SAB-ready,排程自理 | 單執行緒 | Roadmap(未實作) |
70
70
  | AI 文件 | `llms.txt` + `llms-full.txt` + `api.json` | 無 | 無 | 無 |
71
71
  | 維護狀態 | 活躍(新) | 活躍 | 趨緩(npm 已 ~3 年) | 活躍 |
@@ -344,7 +344,7 @@ Observer 會在變動呼叫內同步觸發。用於需要在變動發生瞬間
344
344
 
345
345
  ### Command buffer:何時與為何
346
346
 
347
- 黃金法則:**不要在正在迭代的實體上新增或移除元件。** 這樣做可能讓某些實體被跳過或被處理兩次,因為原型歸屬中途改變了。請用 command buffer 延後執行:
347
+ 黃金法則:**迭代中要新增或移除元件,請透過 command buffer** —— 切勿在迭代中直接修改該實體的元件集合。新增或移除元件會在迭代途中改變 archetype 歸屬,可能讓某些實體被跳過或被處理兩次。迭代中呼叫 `destroyEntity` **是安全的**(迭代會每一步重讀存活列數,因此 callback 絕不會收到保留的 eid 0、也不會收到已 destroy 的實體),但有兩個注意事項:被換位填入已釋放列的倖存者會**延到下一個 pass**(本 pass 不會再被走訪),且 destroy 之後的迭代順序不保證。元件變更請用 command buffer 延後執行:
348
348
 
349
349
  ```ts
350
350
  import { withCommandBuffer } from 'aiecsjs/commands'
@@ -409,11 +409,13 @@ type WorldOptions = {
409
409
  maxEntities?: number // 預設 1_000_000
410
410
  indexBits?: 20 | 24 // 預設 24 → 16M 實體
411
411
  generationBits?: 8 | 12 | 16 // 預設 8 → 256 次回收
412
- buffer?: SharedArrayBuffer // 啟用 SAB 儲存
413
- bufferByteOffset?: number // 一個 SAB 給多個 world 用時的位移
412
+ buffer?: SharedArrayBuffer // 保留欄位 —— 0.x 無效(見下方說明)
413
+ bufferByteOffset?: number // 保留欄位 —— 與 buffer 配對;0.x 無效
414
414
  }
415
415
  ```
416
416
 
417
+ > **`buffer` / `bufferByteOffset`為保留欄位,目前尚未實作。** 設定它們沒有任何效果:world 一律自行配置欄位儲存,從不讀取呼叫端提供的 SAB。Worker 交接請改用 snapshot 複製傳輸 —— post `transferableSnapshot(world)`,並從 `aiecsjs/worker` 以 `adoptSnapshot` 重建(見 [多執行緒指引](#多執行緒指引))。保留這些欄位是為了與 0.3+ 規劃中的真正共享欄位列保持向前相容。
418
+
417
419
  ### Entity — `aiecsjs`
418
420
 
419
421
  | 函式 | Signature | 穩定度 |
@@ -593,7 +595,7 @@ console.log('每幀毫秒:', (performance.now() - start) / 1000)
593
595
 
594
596
  ## 多執行緒指引
595
597
 
596
- aiecsjs **支援 SharedArrayBuffer**:world 的 archetype 欄位可放在共享記憶體中,並由 Worker 平行迭代。
598
+ aiecsjs 透過 **transferable snapshot** 把 world 交給 Worker:world 會被序列化進一個 `SharedArrayBuffer`(SAB 不可用時退回普通 `ArrayBuffer`),Worker 端再從中重建一個全新的 world。0.x 中這是 snapshot **複製**傳輸,而非真正的共享記憶體欄位別名 —— 交接後兩個 world 不會看到彼此的寫入。真正的共享欄位列在 0.3+ 規劃中(見 [`STABILITY.md`](./STABILITY.md) 的 `aiecsjs/worker`)。
597
599
 
598
600
  ### 能力偵測
599
601
 
@@ -608,21 +610,28 @@ if (!IS_SAB_SUPPORTED) {
608
610
 
609
611
  ### 主執行緒
610
612
 
613
+ 直接 post 整個 `transferableSnapshot(world)` —— 它本身已帶有 `{ buffer, meta }`。請**不要**自行配置 SAB 再傳給 `createWorld`;`WorldOptions.buffer` 為保留欄位,目前沒有任何效果(見 [Entity — `aiecsjs`](#entity--aiecsjs))。
614
+
611
615
  ```ts
612
- const buffer = new SharedArrayBuffer(64 * 1024 * 1024) // 64 MB
613
- const world = createWorld({ buffer })
616
+ import { createWorld } from 'aiecsjs'
617
+ import { transferableSnapshot } from 'aiecsjs/worker'
618
+
619
+ const world = createWorld()
614
620
 
615
621
  // 填入實體與元件 ...
616
622
 
617
623
  const worker = new Worker(new URL('./sim-worker.ts', import.meta.url), { type: 'module' })
618
- worker.postMessage({ buffer, meta: transferableSnapshot(world).meta })
624
+ worker.postMessage(transferableSnapshot(world))
619
625
  ```
620
626
 
621
627
  ### Worker 端
622
628
 
629
+ `adoptSnapshot` 從 **`aiecsjs/worker`** sub-path 匯入(root entry 不匯出它)。
630
+
623
631
  ```ts
624
632
  // sim-worker.ts
625
- import { adoptSnapshot, defineComponent, defineQuery, forEachEntityIndexed, Types } from 'aiecsjs'
633
+ import { defineComponent, defineQuery, forEachEntityIndexed, Types } from 'aiecsjs'
634
+ import { adoptSnapshot } from 'aiecsjs/worker'
626
635
 
627
636
  const Position = defineComponent({ x: Types.f32, y: Types.f32 })
628
637
  const Velocity = defineComponent({ x: Types.f32, y: Types.f32 })
@@ -949,7 +958,7 @@ A:將在首次穩定發佈時上架。在那之前,文件即契約。
949
958
  - **AoS 元件** 無法跨 Worker 透過 SAB 共享。
950
959
  - **網路 delta 序列器** wire format 在 0.1 為 experimental,可能改變。
951
960
  - **WebGPU 整合為單向**(CPU → GPU)。無 compute-shader 系統生成。
952
- - **開發模式驗證有限。** Production build 跳過不變量檢查以追求速度;dev build(`process.env.NODE_ENV !== 'production'`)會包含參數順序與實體存活檢查。
961
+ - **無依建置模式切換的驗證。** 不存在 `process.env.NODE_ENV` 分支 —— 每種建置都跑相同的檢查。實體存活在 mutation 路徑上無條件驗證(`addComponent` / `setComponent` 對已 destroy 的實體會拋例外),因此沒有額外加裝 runtime guard 的獨立「dev build」。參數順序由 TypeScript 型別在靜態層強制,而非 runtime 檢查。
953
962
 
954
963
  ## 貢獻
955
964
 
package/api.json CHANGED
@@ -49,6 +49,7 @@
49
49
  "refOf",
50
50
  "deref",
51
51
  "aliveRef",
52
+ "EcsError",
52
53
  "EntityNotAliveError"
53
54
  ]
54
55
  },
@@ -1411,6 +1412,28 @@
1411
1412
  ],
1412
1413
  "seeAlso": ["refOf", "deref", "EntityRef"]
1413
1414
  },
1415
+ {
1416
+ "name": "EcsError",
1417
+ "kind": "class",
1418
+ "module": "aiecsjs",
1419
+ "since": "0.5.6",
1420
+ "stability": "stable",
1421
+ "deprecated": false,
1422
+ "signature": "class EcsError extends Error {}",
1423
+ "summary": "Thrown by core world/entity/component operations for invariant violations and misuse (bad world options, a destroyed or unknown world, exhausted component slots, capacity overflow). Carries the aiecsjs:-prefixed message.",
1424
+ "params": [],
1425
+ "returns": {
1426
+ "type": "EcsError",
1427
+ "description": "Error instance with the aiecsjs: message prefix."
1428
+ },
1429
+ "examples": [
1430
+ {
1431
+ "title": "Catch an aiecsjs invariant failure",
1432
+ "code": "try { createWorld({ indexBits: 99 }) } catch (e) { if (e instanceof EcsError) { /* an aiecsjs invariant was violated */ } }"
1433
+ }
1434
+ ],
1435
+ "seeAlso": ["createWorld", "EntityNotAliveError"]
1436
+ },
1414
1437
  {
1415
1438
  "name": "EntityNotAliveError",
1416
1439
  "kind": "class",
@@ -0,0 +1,2 @@
1
+ import {j,J,e,b,q,c,d,f as f$1}from'./chunk-2KCN5RVK.js';var E=1,f=new Map;function A(n){let e=(n.all??[]).map(o=>o.__id).sort((o,i)=>o-i).join("-"),t=(n.any??[]).map(o=>o.__id).sort((o,i)=>o-i).join("-"),r=(n.none??[]).map(o=>o.__id).sort((o,i)=>o-i).join("-");return `A${e}|Y${t}|N${r}`}function T(n){let e=Array.isArray(n)?{all:n}:n;for(let i of [...e.all??[],...e.any??[],...e.none??[]])if(!i||typeof i!="object"||typeof i.__id!="number")throw new TypeError("aiecsjs: defineQuery received a non-component value");let t=A(e),r=f.get(t);if(r)return r;let o={id:E++,mask:[],all:(e.all??[]).map(i=>i.__id),any:(e.any??[]).map(i=>i.__id),none:(e.none??[]).map(i=>i.__id),columnViewCache:[...e.all??[],...e.any??[]],reactiveKind:"normal",sourceQueryId:-1,sourceQuery:null};return f.set(t,o),o}function $(n){let e=n,t=`enter:${e.id}`,r=f.get(t);if(r)return r;let o={id:E++,mask:[],all:e.all,any:e.any,none:e.none,columnViewCache:e.columnViewCache,reactiveKind:"enter",sourceQueryId:e.id,sourceQuery:e};return f.set(t,o),o}function D(n){let e=n,t=`exit:${e.id}`,r=f.get(t);if(r)return r;let o={id:E++,mask:[],all:e.all,any:e.any,none:e.none,columnViewCache:e.columnViewCache,reactiveKind:"exit",sourceQueryId:e.id,sourceQuery:e};return f.set(t,o),o}function p(n,e){if(n.queries[e.id]===e&&n.queryMasks.has(e.id))return;let t=n.options.maskWordCount,r=b(t),o=b(t),i=b(t);for(let a of e.all){let u=C(a),d=q(n,u);c(r,d);}for(let a of e.any){let u=C(a),d=q(n,u);c(o,d);}for(let a of e.none){let u=C(a),d=q(n,u);c(i,d);}let c$1={withMask:r,anyMask:o,noneMask:i,anyHasBits:!d(o)};n.queryMasks.set(e.id,c$1),n.queries[e.id]=e,n.queryArchetypeCache[e.id]=null,n.queryArchetypeStamp[e.id]=-1;let s=[...f$1(r),...f$1(o),...f$1(i)];for(let a of s){let u=n.bitToQueries.get(a);u||(u=new Set,n.bitToQueries.set(a,u)),u.add(e.id);}e.reactiveKind!=="normal"&&(n.reactiveBuffers.has(e.id)||n.reactiveBuffers.set(e.id,{entered:[],exited:[]}),e.sourceQuery&&p(n,e.sourceQuery));}function m(n,e$1){if(p(n,e$1),n.queryArchetypeCache[e$1.id]&&n.queryArchetypeStamp[e$1.id]===n.queryVersion)return n.queryArchetypeCache[e$1.id];let t=n.queryMasks.get(e$1.id),r=n.options.maskWordCount,o=[];for(let i=0;i<n.archetypes.length;i++){let c=n.archetypes[i];e(c.mask,t.withMask,t.anyMask,t.noneMask,t.anyHasBits,r)&&o.push(i);}return n.queryArchetypeCache[e$1.id]=o,n.queryArchetypeStamp[e$1.id]=n.queryVersion,o}function H(n,e){let t=j(n),o=m(t,e),i=[];for(let c of o){let s=t.archetypes[c];i.push({id:s.id,mask:Array.from(s.mask),size:s.size});}return i}function L(n,e){let t=j(n),r=e,o=[];if(r.reactiveKind==="enter"){let c=t.reactiveBuffers.get(r.id);if(c){for(let s of c.entered)o.push(s);c.entered.length=0;}return o}if(r.reactiveKind==="exit"){let c=t.reactiveBuffers.get(r.id);if(c){for(let s of c.exited)o.push(s);c.exited.length=0;}return o}let i=m(t,r);for(let c of i){let s=t.archetypes[c];for(let a=0;a<s.size;a++)o.push(s.entities[a]);}return o}function*F(n,e){let t=j(n),r=e;if(r.reactiveKind!=="normal"){let i=t.reactiveBuffers.get(r.id);if(!i)return;let c=r.reactiveKind==="enter"?i.entered:i.exited;for(let s of c)yield s;c.length=0;return}let o=m(t,r);for(let i of o){let c=t.archetypes[i];for(let s=0;s<c.size;s++)yield c.entities[s];}}function O(n,e,t){let r=j(n),o=e;if(o.reactiveKind!=="normal"){let s=r.reactiveBuffers.get(o.id);if(!s)return;let a=o.reactiveKind==="enter"?s.entered:s.exited;if(a.length===0)return;let u=g(r,o);for(let d=0;d<a.length;d++){let y=a[d];w(t,y,u);}a.length=0;return}p(r,o);let i=m(r,o),c=g(r,o);for(let s of i){let a=r.archetypes[s],u=a.entities;for(let d=0;d<a.size;d++)w(t,u[d],c);}}function w(n,e,t){switch(t.length){case 0:n(e);break;case 1:n(e,t[0]);break;case 2:n(e,t[0],t[1]);break;case 3:n(e,t[0],t[1],t[2]);break;case 4:n(e,t[0],t[1],t[2],t[3]);break;case 5:n(e,t[0],t[1],t[2],t[3],t[4]);break;default:n(e,...t);}}function G(n,e,t){let r=j(n),o=e,i=r.options.indexMask;if(o.reactiveKind!=="normal"){let a=r.reactiveBuffers.get(o.id);if(!a)return;let u=o.reactiveKind==="enter"?a.entered:a.exited;if(u.length===0)return;let d=g(r,o);for(let y=0;y<u.length;y++){let h=u[y];W(t,h,h&i,d);}u.length=0;return}p(r,o);let c=m(r,o),s=g(r,o);for(let a of c){let u=r.archetypes[a],d=u.entities;for(let y=0;y<u.size;y++){let h=d[y];W(t,h,h&i,s);}}}function W(n,e,t,r){switch(r.length){case 0:n(e,t);break;case 1:n(e,t,r[0]);break;case 2:n(e,t,r[0],r[1]);break;case 3:n(e,t,r[0],r[1],r[2]);break;case 4:n(e,t,r[0],r[1],r[2],r[3]);break;case 5:n(e,t,r[0],r[1],r[2],r[3],r[4]);break;default:n(e,t,...r);}}function g(n,e){let t=[];for(let r of e.columnViewCache){let o=J(r),i=n.componentBitFor.get(o.id);if(i===void 0){t.push(void 0);continue}let c=n.componentStorageByBit[i];if(!c){t.push(void 0);continue}c.kind==="soa"?t.push(c.soa):c.kind==="aos"?t.push(c.aos):t.push(true);}return t}function N(n,e$1,t,r,o){for(let s of f.values())s.reactiveKind!=="normal"&&s.sourceQuery&&n.queries[s.sourceQuery.id]!==s.sourceQuery&&p(n,s.sourceQuery);let i=n.bitToQueries.get(t);if(!i)return;let c=n.options.maskWordCount;for(let s of i){let a=n.queries[s];if(!a||a.reactiveKind!=="normal")continue;let u=n.queryMasks.get(s);if(!u)continue;let d=e(r,u.withMask,u.anyMask,u.noneMask,u.anyHasBits,c),y=e(o,u.withMask,u.anyMask,u.noneMask,u.anyHasBits,c);!d&&y?_(n,s,"enter",e$1):d&&!y&&_(n,s,"exit",e$1);}}function _(n,e,t,r){for(let o of f.values()){if(o.sourceQueryId!==e||o.reactiveKind!==t)continue;p(n,o);let i=K(n,o.id);t==="enter"?i.entered.push(r):i.exited.push(r);}}function K(n,e){let t=n.reactiveBuffers.get(e);return t||(t={entered:[],exited:[]},n.reactiveBuffers.set(e,t)),t}function C(n){let e=S(n);if(!e)throw new Error(`aiecsjs: component id ${n} not registered`);return e}var x=null;function U(n){x=n;}function S(n){return x?x(n):void 0}export{T as a,$ as b,D as c,H as d,L as e,F as f,O as g,G as h,N as i,U as j};//# sourceMappingURL=chunk-22ICWJ5O.js.map
2
+ //# sourceMappingURL=chunk-22ICWJ5O.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/internal/query.ts"],"names":["nextQueryId","moduleQueryCache","descKey","d","all","c","a","b","any","none","defineQuery","arg","desc","key","cached","q","enterQuery","query","reactive","exitQuery","ensureQueryRegistered","state","ww","withMask","createMask","anyMask","noneMask","compId","info","getComponentInfoById","bit","getOrRegisterComponentBit","setBit","bundle","isMaskZero","involvedBits","listBits","s","getQueryArchetypes","words","list","arch","matches","queryArchetypes","world","getWorldState","ids","out","id","runQuery","buf","e","archIds","r","iterQuery","src","forEachEntity","fn","cols","buildColumnViews","i","callWithCols","ents","eid","forEachEntityIndexed","indexMask","callWithColsIndexed","comp","getComponentInfo","storage","recordEntityMaskChange","changedBit","prevMask","nextMask","involved","qid","wasMatch","isMatch","pushReactive","queryId","kind","ensureReactiveBuffer","componentId","lazyGetComponentInfo","_getComponentInfoFn","registerComponentLookup"],"mappings":"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","file":"chunk-22ICWJ5O.js","sourcesContent":["import { createMask, isMaskZero, listBits, matches, setBit } from './bitmask.js'\nimport { getComponentInfo } from './component.js'\nimport type {\n Archetype,\n ComponentInfo,\n ComponentLike,\n EntityId,\n Query,\n QueryDescriptor,\n QueryInternal,\n QueryMaskBundle,\n ReactiveBuffer,\n World,\n WorldState,\n} from './types.js'\nimport {\n getOrRegisterComponentBit,\n getWorldState,\n readEntityMask,\n tryGetComponentBit,\n} from './world.js'\n\nlet nextQueryId = 1\nconst moduleQueryCache = new Map<string, QueryInternal>()\n\nfunction descKey(d: QueryDescriptor): string {\n const all = (d.all ?? [])\n .map((c) => c.__id)\n .sort((a, b) => a - b)\n .join('-')\n const any = (d.any ?? [])\n .map((c) => c.__id)\n .sort((a, b) => a - b)\n .join('-')\n const none = (d.none ?? [])\n .map((c) => c.__id)\n .sort((a, b) => a - b)\n .join('-')\n return `A${all}|Y${any}|N${none}`\n}\n\nexport function defineQuery(arg: ComponentLike[] | QueryDescriptor): Query {\n const desc: QueryDescriptor = Array.isArray(arg) ? { all: arg } : arg\n\n // Validate all members are components\n for (const c of [...(desc.all ?? []), ...(desc.any ?? []), ...(desc.none ?? [])]) {\n if (!c || typeof c !== 'object' || typeof (c as any).__id !== 'number') {\n throw new TypeError('aiecsjs: defineQuery received a non-component value')\n }\n }\n\n const key = descKey(desc)\n const cached = moduleQueryCache.get(key)\n if (cached) return cached\n\n const q: QueryInternal = {\n id: nextQueryId++,\n mask: [],\n all: (desc.all ?? []).map((c) => c.__id),\n any: (desc.any ?? []).map((c) => c.__id),\n none: (desc.none ?? []).map((c) => c.__id),\n columnViewCache: [...(desc.all ?? []), ...(desc.any ?? [])],\n reactiveKind: 'normal',\n sourceQueryId: -1,\n sourceQuery: null,\n }\n moduleQueryCache.set(key, q)\n return q\n}\n\n/**\n * Reactive \"entered\" view of `query`: each read drains the entities that began\n * matching since the last read (via `runQuery` / `iterQuery` / `forEachEntity`).\n *\n * **MUST-DRAIN CONTRACT (unbounded buffer).** The enter buffer has **no cap**.\n * Every structural change that makes an entity newly match pushes one id; the\n * buffer only shrinks when you read the reactive view. A view that is created\n * but never read — e.g. a disabled system, or reading only the {@link exitQuery}\n * twin — accumulates one number per event **forever**, an unbounded memory leak\n * at churn rates (e.g. ~1k spawns/frame). Read every enter view you create, once\n * per frame. Dropping ids silently would corrupt enter/exit symmetry, so capping\n * is intentionally not done — draining is the caller's responsibility.\n */\nexport function enterQuery(query: Query): Query {\n const q = query as QueryInternal\n const key = `enter:${q.id}`\n const cached = moduleQueryCache.get(key)\n if (cached) return cached\n const reactive: QueryInternal = {\n id: nextQueryId++,\n mask: [],\n all: q.all,\n any: q.any,\n none: q.none,\n columnViewCache: q.columnViewCache,\n reactiveKind: 'enter',\n sourceQueryId: q.id,\n sourceQuery: q,\n }\n moduleQueryCache.set(key, reactive)\n return reactive\n}\n\n/**\n * Reactive \"exited\" view of `query`: each read drains the entities that stopped\n * matching since the last read (via `runQuery` / `iterQuery` / `forEachEntity`).\n *\n * **MUST-DRAIN CONTRACT (unbounded buffer).** The exit buffer has **no cap** —\n * same discipline as {@link enterQuery}. An unread exit view accumulates one id\n * per matching structural change (including every `destroyEntity` of a matching\n * entity) without bound. Read every exit view you create, once per frame. Capping\n * is intentionally not done because dropping ids would break enter/exit symmetry.\n */\nexport function exitQuery(query: Query): Query {\n const q = query as QueryInternal\n const key = `exit:${q.id}`\n const cached = moduleQueryCache.get(key)\n if (cached) return cached\n const reactive: QueryInternal = {\n id: nextQueryId++,\n mask: [],\n all: q.all,\n any: q.any,\n none: q.none,\n columnViewCache: q.columnViewCache,\n reactiveKind: 'exit',\n sourceQueryId: q.id,\n sourceQuery: q,\n }\n moduleQueryCache.set(key, reactive)\n return reactive\n}\n\n// --- Per-world query setup ---\n\nfunction ensureQueryRegistered(state: WorldState, q: QueryInternal): void {\n if (state.queries[q.id] === q && state.queryMasks.has(q.id)) return\n\n // Build per-world bitmasks (this may register new bits)\n const ww = state.options.maskWordCount\n const withMask = createMask(ww)\n const anyMask = createMask(ww)\n const noneMask = createMask(ww)\n for (const compId of q.all) {\n const info = getComponentInfoById(compId)\n const bit = getOrRegisterComponentBit(state, info)\n setBit(withMask, bit)\n }\n for (const compId of q.any) {\n const info = getComponentInfoById(compId)\n const bit = getOrRegisterComponentBit(state, info)\n setBit(anyMask, bit)\n }\n for (const compId of q.none) {\n const info = getComponentInfoById(compId)\n const bit = getOrRegisterComponentBit(state, info)\n setBit(noneMask, bit)\n }\n\n const bundle: QueryMaskBundle = {\n withMask,\n anyMask,\n noneMask,\n anyHasBits: !isMaskZero(anyMask),\n }\n state.queryMasks.set(q.id, bundle)\n\n state.queries[q.id] = q\n state.queryArchetypeCache[q.id] = null\n state.queryArchetypeStamp[q.id] = -1\n\n // Build bit → queries index for fast reactive lookup\n const involvedBits: number[] = [\n ...listBits(withMask),\n ...listBits(anyMask),\n ...listBits(noneMask),\n ]\n for (const b of involvedBits) {\n let s = state.bitToQueries.get(b)\n if (!s) {\n s = new Set<number>()\n state.bitToQueries.set(b, s)\n }\n s.add(q.id)\n }\n\n // Initialize reactive buffer for enter/exit queries\n if (q.reactiveKind !== 'normal') {\n if (!state.reactiveBuffers.has(q.id)) {\n state.reactiveBuffers.set(q.id, { entered: [], exited: [] })\n }\n // Also register the source query so recordEntityMaskChange will see it\n if (q.sourceQuery) ensureQueryRegistered(state, q.sourceQuery)\n }\n}\n\nfunction getQueryArchetypes(state: WorldState, q: QueryInternal): number[] {\n ensureQueryRegistered(state, q)\n if (state.queryArchetypeCache[q.id] && state.queryArchetypeStamp[q.id] === state.queryVersion) {\n return state.queryArchetypeCache[q.id]!\n }\n const bundle = state.queryMasks.get(q.id)!\n const words = state.options.maskWordCount\n const list: number[] = []\n for (let i = 0; i < state.archetypes.length; i++) {\n const arch = state.archetypes[i]!\n if (\n matches(arch.mask, bundle.withMask, bundle.anyMask, bundle.noneMask, bundle.anyHasBits, words)\n ) {\n list.push(i)\n }\n }\n state.queryArchetypeCache[q.id] = list\n state.queryArchetypeStamp[q.id] = state.queryVersion\n return list\n}\n\nexport function queryArchetypes(world: World, query: Query): readonly Archetype[] {\n const state = getWorldState(world)\n const q = query as QueryInternal\n const ids = getQueryArchetypes(state, q)\n const out: Archetype[] = []\n for (const id of ids) {\n const arch = state.archetypes[id]!\n out.push({ id: arch.id, mask: Array.from(arch.mask), size: arch.size })\n }\n return out\n}\n\nexport function runQuery(world: World, query: Query): readonly EntityId[] {\n const state = getWorldState(world)\n const q = query as QueryInternal\n const out: EntityId[] = []\n if (q.reactiveKind === 'enter') {\n const buf = state.reactiveBuffers.get(q.id)\n if (buf) {\n for (const e of buf.entered) out.push(e as EntityId)\n buf.entered.length = 0\n }\n return out\n }\n if (q.reactiveKind === 'exit') {\n const buf = state.reactiveBuffers.get(q.id)\n if (buf) {\n for (const e of buf.exited) out.push(e as EntityId)\n buf.exited.length = 0\n }\n return out\n }\n const archIds = getQueryArchetypes(state, q)\n for (const id of archIds) {\n const arch = state.archetypes[id]!\n for (let r = 0; r < arch.size; r++) {\n out.push(arch.entities[r] as EntityId)\n }\n }\n return out\n}\n\nexport function* iterQuery(world: World, query: Query): IterableIterator<EntityId> {\n const state = getWorldState(world)\n const q = query as QueryInternal\n if (q.reactiveKind !== 'normal') {\n const buf = state.reactiveBuffers.get(q.id)\n if (!buf) return\n const src = q.reactiveKind === 'enter' ? buf.entered : buf.exited\n for (const e of src) yield e as EntityId\n src.length = 0\n return\n }\n const archIds = getQueryArchetypes(state, q)\n for (const id of archIds) {\n const arch = state.archetypes[id]!\n for (let r = 0; r < arch.size; r++) {\n yield arch.entities[r] as EntityId\n }\n }\n}\n\n/**\n * Iterate every entity matching `query`, invoking `fn(e, ...cols)` once per row\n * with the packed {@link EntityId} and the query's SoA column views.\n *\n * **Caution — `e` is a packed EntityId, not a column subscript.** It carries the\n * generation in its high bits, so indexing a column view with it directly\n * (`pos.x[e]`) reads out of bounds once a slot has been recycled. Use `e` only\n * for identity operations (`destroyEntity` / `hasComponent` / `refOf`). To index\n * columns safely, prefer {@link forEachEntityIndexed} — which yields the masked\n * slot index `i` alongside `e` — or mask it yourself with {@link getEntityIndex}.\n *\n * @see {@link forEachEntityIndexed} — same iteration plus the safe column index `i`.\n * @see {@link getEntityIndex} — mask a packed EntityId to its raw slot index.\n */\nexport function forEachEntity(\n world: World,\n query: Query,\n fn: (eid: EntityId, ...cols: any[]) => void,\n): void {\n const state = getWorldState(world)\n const q = query as QueryInternal\n\n if (q.reactiveKind !== 'normal') {\n const buf = state.reactiveBuffers.get(q.id)\n if (!buf) return\n const src = q.reactiveKind === 'enter' ? buf.entered : buf.exited\n if (src.length === 0) return\n const cols = buildColumnViews(state, q)\n for (let i = 0; i < src.length; i++) {\n const e = src[i] as EntityId\n callWithCols(fn, e, cols)\n }\n src.length = 0\n return\n }\n\n ensureQueryRegistered(state, q)\n const archIds = getQueryArchetypes(state, q)\n const cols = buildColumnViews(state, q)\n for (const id of archIds) {\n const arch = state.archetypes[id]!\n const ents = arch.entities\n // Re-read `arch.size` each iteration (do NOT cache it as `n`): an in-loop\n // `destroyEntity` swap-pops the visited row, shrinks `arch.size`, and zeroes\n // the freed tail slot. A cached bound would keep walking into those zeroed\n // tail rows and hand the callback the reserved sentinel eid 0 (ECS-B-01).\n // The swapped-in survivor is intentionally skipped this pass (deferred to the\n // next). This is a scalar property read — no per-iteration allocation, so the\n // zero-allocation hot-path contract holds. Mirrors runQuery (:230) / iterQuery.\n for (let r = 0; r < arch.size; r++) {\n callWithCols(fn, ents[r] as EntityId, cols)\n }\n }\n}\n\nfunction callWithCols(\n fn: (eid: EntityId, ...cols: any[]) => void,\n eid: EntityId,\n cols: any[],\n): void {\n // Specialise for low arities to avoid spread allocation.\n switch (cols.length) {\n case 0:\n fn(eid)\n break\n case 1:\n fn(eid, cols[0])\n break\n case 2:\n fn(eid, cols[0], cols[1])\n break\n case 3:\n fn(eid, cols[0], cols[1], cols[2])\n break\n case 4:\n fn(eid, cols[0], cols[1], cols[2], cols[3])\n break\n case 5:\n fn(eid, cols[0], cols[1], cols[2], cols[3], cols[4])\n break\n default:\n fn(eid, ...cols)\n }\n}\n\n/**\n * Like {@link forEachEntity}, but yields the masked column index `i` alongside\n * the packed `EntityId`. The callback signature is `(e, i, ...cols)`:\n *\n * - `e` — the packed EntityId (carries the generation in its high bits). Use\n * it for in-loop `destroyEntity` / `hasComponent` / `refOf`, exactly as with\n * `forEachEntity`.\n * - `i` — `e & indexMask`, the raw slot index. This is the **correct subscript**\n * for SoA column views (`pos.x[i]`), and stays correct after a slot is\n * recycled — where indexing with the packed `e` would read out of bounds.\n * - `...cols` — the same column views `forEachEntity` passes.\n *\n * This closes the packed-EntityId footgun (A1): callers no longer need to call\n * `getEntityIndex(e)` (or hand-mask) themselves to index columns safely.\n */\nexport function forEachEntityIndexed(\n world: World,\n query: Query,\n fn: (e: EntityId, i: number, ...cols: any[]) => void,\n): void {\n const state = getWorldState(world)\n const q = query as QueryInternal\n const indexMask = state.options.indexMask\n\n if (q.reactiveKind !== 'normal') {\n const buf = state.reactiveBuffers.get(q.id)\n if (!buf) return\n const src = q.reactiveKind === 'enter' ? buf.entered : buf.exited\n if (src.length === 0) return\n const cols = buildColumnViews(state, q)\n for (let i = 0; i < src.length; i++) {\n const e = src[i] as EntityId\n callWithColsIndexed(fn, e, e & indexMask, cols)\n }\n src.length = 0\n return\n }\n\n ensureQueryRegistered(state, q)\n const archIds = getQueryArchetypes(state, q)\n const cols = buildColumnViews(state, q)\n for (const id of archIds) {\n const arch = state.archetypes[id]!\n const ents = arch.entities\n // Re-read `arch.size` each iteration — see forEachEntity for the rationale.\n // An in-loop `destroyEntity` swap-pops the row and zeroes the freed tail; a\n // cached bound would replay the sentinel eid 0 across the public boundary\n // (ECS-B-01). Scalar read only; the zero-allocation hot-path contract holds.\n for (let r = 0; r < arch.size; r++) {\n const e = ents[r] as EntityId\n callWithColsIndexed(fn, e, e & indexMask, cols)\n }\n }\n}\n\nfunction callWithColsIndexed(\n fn: (e: EntityId, i: number, ...cols: any[]) => void,\n e: EntityId,\n i: number,\n cols: any[],\n): void {\n // Specialise for low arities to avoid spread allocation.\n switch (cols.length) {\n case 0:\n fn(e, i)\n break\n case 1:\n fn(e, i, cols[0])\n break\n case 2:\n fn(e, i, cols[0], cols[1])\n break\n case 3:\n fn(e, i, cols[0], cols[1], cols[2])\n break\n case 4:\n fn(e, i, cols[0], cols[1], cols[2], cols[3])\n break\n case 5:\n fn(e, i, cols[0], cols[1], cols[2], cols[3], cols[4])\n break\n default:\n fn(e, i, ...cols)\n }\n}\n\nfunction buildColumnViews(state: WorldState, q: QueryInternal): any[] {\n const out: any[] = []\n for (const comp of q.columnViewCache) {\n const info = getComponentInfo(comp)\n const bit = state.componentBitFor.get(info.id)\n if (bit === undefined) {\n out.push(undefined)\n continue\n }\n const storage = state.componentStorageByBit[bit]\n if (!storage) {\n out.push(undefined)\n continue\n }\n if (storage.kind === 'soa') out.push(storage.soa)\n else if (storage.kind === 'aos') out.push(storage.aos)\n else out.push(true) // tag\n }\n return out\n}\n\n// --- Reactive query updates (called from migration code) ---\n\nexport function recordEntityMaskChange(\n state: WorldState,\n eid: EntityId,\n changedBit: number,\n prevMask: Uint32Array,\n nextMask: Uint32Array,\n): void {\n // Lazy-register any reactive queries (and their sources) so we can correctly\n // determine match transitions even if the user only ever called enterQuery/exitQuery.\n for (const q of moduleQueryCache.values()) {\n if (q.reactiveKind === 'normal') continue\n if (q.sourceQuery && state.queries[q.sourceQuery.id] !== q.sourceQuery) {\n ensureQueryRegistered(state, q.sourceQuery)\n }\n }\n\n const involved = state.bitToQueries.get(changedBit)\n if (!involved) return\n const words = state.options.maskWordCount\n for (const qid of involved) {\n const q = state.queries[qid]\n if (!q) continue\n if (q.reactiveKind !== 'normal') continue\n const bundle = state.queryMasks.get(qid)\n if (!bundle) continue\n const wasMatch = matches(\n prevMask,\n bundle.withMask,\n bundle.anyMask,\n bundle.noneMask,\n bundle.anyHasBits,\n words,\n )\n const isMatch = matches(\n nextMask,\n bundle.withMask,\n bundle.anyMask,\n bundle.noneMask,\n bundle.anyHasBits,\n words,\n )\n if (!wasMatch && isMatch) {\n pushReactive(state, qid, 'enter', eid)\n } else if (wasMatch && !isMatch) {\n pushReactive(state, qid, 'exit', eid)\n }\n }\n}\n\nfunction pushReactive(\n state: WorldState,\n queryId: number,\n kind: 'enter' | 'exit',\n eid: EntityId,\n): void {\n // Walk the module cache (not just state.queries) so reactive variants that\n // haven't been registered with this world yet still receive events.\n for (const r of moduleQueryCache.values()) {\n if (r.sourceQueryId !== queryId) continue\n if (r.reactiveKind !== kind) continue\n // Lazily register the reactive query in this world so subsequent reads can find it\n ensureQueryRegistered(state, r)\n const buf = ensureReactiveBuffer(state, r.id)\n if (kind === 'enter') buf.entered.push(eid as number)\n else buf.exited.push(eid as number)\n }\n}\n\nfunction ensureReactiveBuffer(state: WorldState, qid: number): ReactiveBuffer {\n let buf = state.reactiveBuffers.get(qid)\n if (!buf) {\n buf = { entered: [], exited: [] }\n state.reactiveBuffers.set(qid, buf)\n }\n return buf\n}\n\n// --- Helpers ---\n\nfunction getComponentInfoById(componentId: number): ComponentInfo {\n // We need access to the component registry's lookup by id. Re-import dynamically to avoid cycles.\n const info = lazyGetComponentInfo(componentId)\n if (!info) throw new Error(`aiecsjs: component id ${componentId} not registered`)\n return info\n}\n\nlet _getComponentInfoFn: ((id: number) => ComponentInfo | undefined) | null = null\nexport function registerComponentLookup(fn: (id: number) => ComponentInfo | undefined): void {\n _getComponentInfoFn = fn\n}\nfunction lazyGetComponentInfo(id: number): ComponentInfo | undefined {\n return _getComponentInfoFn ? _getComponentInfoFn(id) : undefined\n}\n\nexport function _resetQueryRegistry_FOR_TESTS_ONLY(): void {\n moduleQueryCache.clear()\n nextQueryId = 1\n}\n"]}
@@ -0,0 +1,2 @@
1
+ var T="0.5.7";function F(t){return new Uint32Array(t)}function z(t,n){let e=n>>>5;t[e]=(t[e]??0)|1<<(n&31);}function E(t,n){let e=n>>>5;t[e]=(t[e]??0)&~(1<<(n&31));}function A(t,n){let e=n>>>5;return ((t[e]??0)&1<<(n&31))!==0}function b(t){let n=new Uint32Array(t.length);for(let e=0;e<t.length;e++)n[e]=t[e]??0;return n}function W(t){let n=[];for(let e=0;e<t.length;e++)n.push((t[e]??0).toString(16));return n.join(",")}function wn(t){for(let n=0;n<t.length;n++)if((t[n]??0)!==0)return false;return true}function gn(t,n,e,o,r,i){let s=!r;for(let a=0;a<i;a++){let c=t[a]??0,f=n[a]??0,d=e[a]??0,u=o[a]??0;if((c&f)!==f||(c&u)!==0)return false;!s&&(c&d)!==0&&(s=true);}return s}function kn(t){let n=[];for(let e=0;e<t.length;e++){let o=t[e]??0;for(;o!==0;){let r=(e<<5)+D(o);n.push(r),o&=o-1;}}return n}function B(t,n,e,o){for(let r=0;r<e;r++){let i=t[n+r]??0;for(;i!==0;){let s=(r<<5)+D(i);o(s),i&=i-1;}}}function Cn(t,n,e,o,r,i,s){let a=!s;for(let c=0;c<e;c++){let f=t[n+c]??0,d=o[c]??0,u=r[c]??0,y=i[c]??0;if((f&d)!==d||(f&y)!==0)return false;!a&&(f&u)!==0&&(a=true);}return a}function D(t){return 31-Math.clz32(t&-t)}var p=class extends Error{constructor(n){super(n),this.name="EcsError";}};var v={initialCapacity:1024,maxEntities:1e6,indexBits:24,generationBits:8},nn=256,tn=1,x=new Map;function l(t){let n=x.get(t.id);if(!n)throw new p(`aiecsjs: world ${t.id} is destroyed or unknown`);if(n.destroyed)throw new p(`aiecsjs: world ${t.id} is destroyed`);return n}function en(t){x.set(t.id,t);}function on(t){x.delete(t);}function Mn(t){return x.has(t)}function rn(t){let n=t??{},e=n.indexBits??v.indexBits,o=n.generationBits??v.generationBits,r=nn;if(e<1||e>24)throw new p("aiecsjs: indexBits must be in [1, 24]");if(o<0||o>16)throw new p("aiecsjs: generationBits must be in [0, 16]");if(e+o>32)throw new p(`aiecsjs: indexBits (${e}) + generationBits (${o}) must be <= 32`);let i=1<<e,s=Math.max(1,Math.min(n.initialCapacity??v.initialCapacity,i)),a=Math.max(s,Math.min(n.maxEntities??v.maxEntities,i));return {initialCapacity:s,maxEntities:a,indexBits:e,generationBits:o,indexMask:(1<<e)-1,generationMask:o===0?0:(1<<o)-1,maxComponents:r,maskWordCount:Math.ceil(r/32),buffer:n.buffer??null,bufferByteOffset:n.bufferByteOffset??0}}function sn(t,n){return {id:0,mask:F(t),size:0,capacity:16,entities:new Uint32Array(16),entityRow:new Map,componentBits:[],edgeAdd:new Int32Array(n).fill(-1),edgeRemove:new Int32Array(n).fill(-1)}}function Un(t){let n=rn(t),e=tn++,o=n.generationBits>8?Uint16Array:Uint8Array,r=new o(n.initialCapacity),i={id:e,capacity:n.initialCapacity,version:T,options:n,size:0,nextFreshIndex:1,freeList:[],generations:r,destroyed:false,componentBitFor:new Map,componentInfoByBit:new Array(n.maxComponents).fill(null),componentStorageByBit:new Array(n.maxComponents).fill(null),nextComponentBit:0,entityArchetype:new Uint32Array(n.initialCapacity),entityMask:new Uint32Array(n.initialCapacity*n.maskWordCount),archetypes:[],archetypeByMaskHash:new Map,queryVersion:0,queries:[],queryMasks:new Map,queryArchetypeCache:[],queryArchetypeStamp:[],bitToQueries:new Map,reactiveBuffers:new Map,observers:[],relationStorage:new Map,sab:n.buffer,readOnly:false},s=sn(n.maskWordCount,n.maxComponents);return s.id=0,i.archetypes.push(s),i.archetypeByMaskHash.set(W(s.mask),0),en(i),an(i)}function an(t){return {id:t.id,get capacity(){return t.capacity},version:t.version}}function On(t){let n=x.get(t.id);!n||n.destroyed||(n.destroyed=true,n.archetypes=[],n.archetypeByMaskHash.clear(),n.componentInfoByBit=[],n.componentStorageByBit=[],n.queries=[],n.queryMasks.clear(),n.queryArchetypeCache=[],n.observers=[],n.relationStorage.clear(),n.reactiveBuffers.clear(),n.entityMask=new Uint32Array(0),n.entityArchetype=new Uint32Array(0),n.generations=new Uint8Array(0),n.freeList=[],n.componentBitFor.clear(),n.bitToQueries.clear(),n.queryArchetypeStamp=[],n.sab=null,on(t.id));}function Rn(t){let n=l(t);n.size=0,n.nextFreshIndex=1,n.freeList=[],n.generations.fill(0),n.entityArchetype.fill(0),n.entityMask.fill(0);for(let e of n.archetypes)e.size=0,e.entityRow.clear();for(let e of n.componentStorageByBit)if(e)if(e.kind==="soa"&&e.soa)for(let o of Object.keys(e.soa))e.soa[o]?.fill(0);else e.kind==="aos"&&e.aos&&e.aos.fill(void 0);n.queryVersion++;for(let e of n.reactiveBuffers.values())e.entered.length=0,e.exited.length=0;}function _n(t){return l(t).size}function Ln(t){return l(t).capacity}function M(t,n){if(n<=t.capacity)return;if(n>t.options.maxEntities)throw new p(`aiecsjs: requested capacity ${n} exceeds maxEntities ${t.options.maxEntities}`);let e=t.capacity;for(;e<n;)e=Math.min(e*2,t.options.maxEntities);cn(t,e);}function cn(t,n){let e=t.generations.constructor,o=new e(n);o.set(t.generations),t.generations=o;let r=new Uint32Array(n);r.set(t.entityArchetype),t.entityArchetype=r;let i=t.options.maskWordCount,s=new Uint32Array(n*i);s.set(t.entityMask),t.entityMask=s;for(let a of t.componentStorageByBit)if(a)if(a.kind==="soa"&&a.soa){let c=t.componentInfoByBit[a.bit];c&&fn(a.soa,c.fields,n);}else a.kind==="aos"&&a.aos&&(a.aos.length=n);t.capacity=n;}function fn(t,n,e){for(let o of n){let r=t[o.name];if(!r)continue;let i=e*o.vectorLen;if(r.length>=i)continue;let s=new o.ctor(i);s.set(r),t[o.name]=s;}}function N(t,n){let e=W(n),o=t.archetypeByMaskHash.get(e);if(o!==void 0)return {archId:o,created:false};let r=t.archetypes.length,i={id:r,mask:b(n),size:0,capacity:16,entities:new Uint32Array(16),entityRow:new Map,componentBits:dn(n),edgeAdd:new Int32Array(t.options.maxComponents).fill(-1),edgeRemove:new Int32Array(t.options.maxComponents).fill(-1)};return t.archetypes.push(i),t.archetypeByMaskHash.set(e,r),t.queryVersion++,{archId:r,created:true}}function k(t,n){if(n<=t.capacity)return;let e=t.capacity;for(;e<n;)e*=2;let o=new Uint32Array(e);o.set(t.entities),t.entities=o,t.capacity=e;}function dn(t){let n=[];for(let e=0;e<t.length;e++){let o=t[e]??0;for(;o!==0;){let r=o&-o,i=(e<<5)+(31-Math.clz32(r));n.push(i),o&=o-1;}}return n}function P(t,n){let e=t.componentBitFor.get(n.id);if(e!==void 0)return e;if(t.nextComponentBit>=t.options.maxComponents)throw new p(`aiecsjs: world reached maxComponents=${t.options.maxComponents}`);let o=t.nextComponentBit++;t.componentBitFor.set(n.id,o),t.componentInfoByBit[o]=n;let r;if(n.kind==="soa"){let i={};for(let s of n.fields)i[s.name]=new s.ctor(t.capacity*s.vectorLen);r={kind:"soa",componentId:n.id,bit:o,soa:i};}else n.kind==="aos"?r={kind:"aos",componentId:n.id,bit:o,aos:new Array(t.capacity)}:r={kind:"tag",componentId:n.id,bit:o};return t.componentStorageByBit[o]=r,o}function h(t,n){let e=t.options.maskWordCount,o=new Uint32Array(e),i=(n&t.options.indexMask)*e;for(let s=0;s<e;s++)o[s]=t.entityMask[i+s]??0;return o}function q(t,n,e){let o=t.options.maskWordCount,i=(n&t.options.indexMask)*o;for(let s=0;s<o;s++)t.entityMask[i+s]=e[s]??0;}function C(t,n){return t.componentBitFor.get(n.id)}function jn(t){if(!t||typeof t!="object")return false;let n=t;return typeof n.id!="number"||typeof n.version!="string"?false:x.has(n.id)}var O=1,un={i8:Int8Array,u8:Uint8Array,i16:Int16Array,u16:Uint16Array,i32:Int32Array,u32:Uint32Array,f32:Float32Array,f64:Float64Array,eid:Uint32Array,bool:Uint8Array},w=new Map;function Nn(t){let n=[];for(let[i,s]of Object.entries(t)){let a,c=1;if(typeof s=="string")a=s;else if(Array.isArray(s)){let[d,u]=s;a=d,c=u;}else throw new TypeError(`aiecsjs: invalid field declaration for "${i}"`);let f=un[a];if(!f)throw new TypeError(`aiecsjs: unknown field type "${a}" for field "${i}"`);n.push({name:i,type:a,vectorLen:c,ctor:f,bytesPerElement:f.BYTES_PER_ELEMENT});}let e=O++,o={id:e,kind:"soa",schema:t,fields:n,factory:null};return w.set(e,o),{__kind:"soa",__id:e,__schema:t}}function Pn(){let t=O++,n={id:t,kind:"tag",schema:null,fields:[],factory:null};return w.set(t,n),{__kind:"tag",__id:t}}function qn(t){let n=O++,e=t??(()=>({})),o={id:n,kind:"aos",schema:null,fields:[],factory:e};return w.set(n,o),{__kind:"aos",__id:n,__factory:e}}function g(t){let n=w.get(t.__id);if(!n)throw new Error("aiecsjs: component is not registered (call defineComponent/defineTag/defineObjectComponent)");return n}function $(t,n,e,o){let r=l(t);if(r.readOnly)throw new Error("aiecsjs: cannot mutate a read-only world");if(!m(r,n))throw new Error(`aiecsjs: addComponent on dead entity ${n}`);let i=g(e),s=P(r,i),a=h(r,n);if(A(a,s)){o!==void 0&&U(r,n,e,o);return}let c=b(a);z(c,s),V(r,n,c),U(r,n,e,o),yn(r,n,s),R(r,n,s,a,c);}function $n(t,n,e){let o=l(t);if(o.readOnly)throw new Error("aiecsjs: cannot mutate a read-only world");if(!m(o,n))return;let r=g(e),i=C(o,r);if(i===void 0)return;let s=h(o,n);if(!A(s,i))return;let a=b(s);E(a,i),V(o,n,a),ln(o,n,i);let c=n&o.options.indexMask,f=o.componentStorageByBit[i];f?.kind==="soa"&&f.soa?G(f.soa,r.fields,c):f?.kind==="aos"&&f.aos&&(f.aos[c]=void 0),R(o,n,i,s,a);}function Gn(t,n,e){let o=l(t);if(!m(o,n))return false;let r=g(e),i=C(o,r);if(i===void 0)return false;let s=h(o,n);return A(s,i)}function Hn(t,n,e){let o=l(t);if(!m(o,n))return;let r=g(e),i=C(o,r);if(i===void 0)return;let s=h(o,n);if(!A(s,i))return;let a=o.componentStorageByBit[i];if(a){if(a.kind==="soa")return a.soa;if(a.kind==="aos"){let c=n&o.options.indexMask;return a.aos?.[c]}return true}}function Vn(t,n,e,o){let r=l(t);if(r.readOnly)throw new Error("aiecsjs: cannot mutate a read-only world");if(!m(r,n))throw new Error(`aiecsjs: setComponent on dead entity ${n}`);let i=g(e),s=C(r,i);if(s===void 0){$(t,n,e,o);return}let a=h(r,n);if(!A(a,s)){$(t,n,e,o);return}U(r,n,e,o),pn(r,n,s,o);}function U(t,n,e,o){let r=g(e),i=t.componentBitFor.get(r.id);if(i===void 0)return;let s=t.componentStorageByBit[i];if(!s)return;let a=n&t.options.indexMask;if(r.kind==="soa"&&s.soa){if(o==null)return;let c=o;for(let f of r.fields){if(!(f.name in c))continue;let d=s.soa[f.name];if(!d)continue;let u=c[f.name];if(f.vectorLen===1)d[a]=typeof u=="boolean"?u?1:0:Number(u);else if(Array.isArray(u)||ArrayBuffer.isView(u)){let y=a*f.vectorLen,J=u;for(let I=0;I<f.vectorLen;I++)d[y+I]=Number(J[I]??0);}}}else if(r.kind==="aos"&&s.aos){let c=r.factory??(()=>({})),f=s.aos[a];if(f===void 0&&(f=c(),s.aos[a]=f),o&&typeof o=="object"){let d=o,u=f;for(let y of Object.keys(d))y==="__proto__"||y==="constructor"||y==="prototype"||(u[y]=d[y]);}}}function G(t,n,e){for(let o of n){let r=t[o.name];if(r)if(o.vectorLen===1)r[e]=0;else {let i=e*o.vectorLen;for(let s=0;s<o.vectorLen;s++)r[i+s]=0;}}}function H(t,n){let e=t.options.maskWordCount,o=n&t.options.indexMask,r=o*e;B(t.entityMask,r,e,i=>{let s=t.componentStorageByBit[i],a=t.componentInfoByBit[i];s?.kind==="soa"&&s.soa&&a?G(s.soa,a.fields,o):s?.kind==="aos"&&s.aos&&(s.aos[o]=void 0);});}function V(t,n,e){let o=n&t.options.indexMask,r=t.entityArchetype[o]??0,i=t.archetypes[r];if(!i)return;let a=N(t,e).archId,c=t.archetypes[a];if(c){if(a!==r){let f=i.entityRow.get(n);if(f!==void 0){let u=i.size-1;if(f!==u){let y=i.entities[u]??0;i.entities[f]=y,i.entityRow.set(y,f);}i.entities[u]=0,i.entityRow.delete(n),i.size--;}k(c,c.size+1);let d=c.size;c.entities[d]=n,c.entityRow.set(n,d),c.size++,t.entityArchetype[o]=a;}q(t,n,e);}}var S={fireAdd:()=>{},fireRemove:()=>{},fireSet:()=>{}},Y=()=>{};function Yn(t){Y=t;}function R(t,n,e,o,r){Y(t,n,e,o,r);}function X(t,n,e){let o=t.options.maskWordCount,r=b(e),i=b(e);B(e,0,o,s=>{E(i,s),R(t,n,s,r,i),E(r,s);});}function Xn(t){S=t;}function yn(t,n,e){S.fireAdd(t,n,e);}function ln(t,n,e){S.fireRemove(t,n,e);}function pn(t,n,e,o){S.fireSet(t,n,e,o);}function Kn(t){return w.get(t)}function Qn(){return Array.from(w.values())}var j=24,mn=8,K=(1<<j)-1,Q=(1<<mn)-1;function Z(t,n,e){return ((n&e.generationMask)<<e.indexBits|t&e.indexMask)>>>0}function tt(t,n){return t&n.indexMask}function et(t,n){return t>>>n.indexBits&n.generationMask}function ot(t){let n=l(t);if(n.readOnly)throw new Error("aiecsjs: cannot createEntity on a read-only world (worker-attached)");let e;if(n.freeList.length>0)e=n.freeList.pop();else {if(n.nextFreshIndex>=n.options.maxEntities)throw new Error(`aiecsjs: reached maxEntities ${n.options.maxEntities}`);n.nextFreshIndex>=n.capacity&&M(n,n.nextFreshIndex+1),e=n.nextFreshIndex++;}let o=n.generations[e]??0,r=Z(e,o,n.options),i=n.archetypes[0];if(!i)throw new Error("aiecsjs: missing empty archetype");k(i,i.size+1);let s=i.size;i.entities[s]=r,i.entityRow.set(r,s),i.size++,n.entityArchetype[e]=0;let a=n.options.maskWordCount,c=e*a;for(let f=0;f<a;f++)n.entityMask[c+f]=0;return n.size++,r}function rt(t,n){if(t.readOnly)throw new Error("aiecsjs: cannot create entities on a read-only world (worker-attached)");if(n<=0||n>=t.options.maxEntities)throw new Error(`aiecsjs: slot index ${n} out of range`);n>=t.capacity&&M(t,n+1);let e=t.generations[n]??0,o=Z(n,e,t.options);if(m(t,o))return o;if(n>=t.nextFreshIndex){for(let c=t.nextFreshIndex;c<n;c++)t.freeList.push(c);t.nextFreshIndex=n+1;}else {let c=t.freeList.lastIndexOf(n);if(c!==-1){let f=t.freeList.length-1;t.freeList[c]=t.freeList[f],t.freeList.pop();}}let r=t.archetypes[0];if(!r)throw new Error("aiecsjs: missing empty archetype");k(r,r.size+1);let i=r.size;r.entities[i]=o,r.entityRow.set(o,i),r.size++,t.entityArchetype[n]=0;let s=t.options.maskWordCount,a=n*s;for(let c=0;c<s;c++)t.entityMask[a+c]=0;return t.size++,o}function it(t,n){let e=l(t);if(e.readOnly)throw new Error("aiecsjs: cannot destroyEntity on a read-only world");if(!m(e,n))return;let o=n&e.options.indexMask,r=h(e,n),{dispatchDestroyObservers:i}=bn();i(e,n),An(e,n),H(e,n);let s=e.entityArchetype[o]??0,a=e.archetypes[s];if(a){let d=a.entityRow.get(n);if(d!==void 0){let u=a.size-1;if(d!==u){let y=a.entities[u]??0;a.entities[d]=y,a.entityRow.set(y,d);}a.entities[u]=0,a.entityRow.delete(n),a.size--;}}X(e,n,r),e.entityArchetype[o]=0;let c=e.options.maskWordCount,f=o*c;for(let d=0;d<c;d++)e.entityMask[f+d]=0;e.generations[o]=(e.generations[o]??0)+1&e.options.generationMask,e.freeList.push(o),e.size--;}function hn(t,n){let e=l(t);return m(e,n)}function m(t,n){let e=n&t.options.indexMask;if(e<=0||e>=t.capacity)return false;let o=t.entityArchetype[e]??0,r=t.archetypes[o];if(!r||!r.entityRow.has(n))return false;let i=t.generations[e]??0,s=n>>>t.options.indexBits&t.options.generationMask;return i===s}function st(t){return t&K}function at(t){return t>>>j&Q}function ct(t,n){return ((n&Q)<<j|t&K)>>>0}function ft(t,n){return typeof n!="number"?false:hn(t,n)}var _=null;function dt(t){_=t;}function bn(){return _||{dispatchDestroyObservers:()=>{}}}var L=null;function ut(t){L=t;}function An(t,n){L&&L(t,n);}export{st as A,at as B,ct as C,ft as D,dt as E,ut as F,Nn as G,Pn as H,qn as I,g as J,$ as K,$n as L,Gn as M,Hn as N,Vn as O,Yn as P,Xn as Q,Kn as R,Qn as S,T as a,F as b,z as c,wn as d,gn as e,kn as f,B as g,Cn as h,p as i,l as j,Mn as k,Un as l,On as m,Rn as n,_n as o,Ln as p,P as q,jn as r,Z as s,tt as t,et as u,ot as v,rt as w,it as x,hn as y,m as z};//# sourceMappingURL=chunk-2KCN5RVK.js.map
2
+ //# sourceMappingURL=chunk-2KCN5RVK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/version.ts","../src/internal/bitmask.ts","../src/internal/errors.ts","../src/internal/world.ts","../src/internal/component.ts","../src/internal/entity.ts"],"names":["VERSION","createMask","wordCount","setBit","mask","bit","w","clearBit","testBit","cloneMask","src","out","i","maskHash","m","parts","isMaskZero","matches","withMask","anyMask","noneMask","anyHasBits","words","anyHit","wm","am","nm","listBits","word","ctz32","forEachSetBit","base","fn","wi","matchesEntityMask","entityMask","v","EcsError","message","DEFAULT_OPTIONS","DEFAULT_MAX_COMPONENTS","nextWorldId","worldRegistry","getWorldState","world","state","registerWorld","unregisterWorld","id","isWorldRegistered","resolveOptions","opts","o","indexBits","generationBits","maxComponents","maxByIndex","initialCapacity","maxEntities","createEmptyArchetype","maskWordCount","createWorld","options","resolved","generationCtor","generations","empty","makePublicWorld","destroyWorld","resetWorld","arch","storage","k","buf","getWorldSize","getWorldCapacity","ensureCapacity","needed","newCap","growEntityArrays","genCtor","newGen","newArch","newMask","info","growSoAColumns","soa","fields","f","old","newLen","next","findOrCreateArchetype","key","existing","collectBits","ensureArchetypeCapacity","bits","lsb","getOrRegisterComponentBit","readEntityMask","eid","writeEntityMask","tryGetComponentBit","isWorld","x","obj","nextComponentId","TYPE_CTOR","componentInfoById","defineComponent","schema","name","decl","type","vectorLen","t","len","ctor","defineTag","defineObjectComponent","factory","fac","getComponentInfo","component","addComponent","initial","isAliveInternal","prevMask","writeInitial","migrateEntity","fireAddObservers","notifyMaskChange","removeComponent","fireRemoveObservers","idx","clearSoAEntity","hasComponent","getComponent","setComponent","value","fireSetObservers","packedEid","col","val","arr","inst","target","clearAllEntityStorages","srcArchId","srcArch","destArchId","destArch","row","lastRow","moved","newRow","_dispatch","_maskChange","registerMaskChangeDispatch","prev","dispatchDestroyMaskChange","before","after","registerObserverDispatch","api","getComponentByInternalId","listAllComponents","DEFAULT_INDEX_BITS","DEFAULT_GENERATION_BITS","DEFAULT_INDEX_MASK","DEFAULT_GENERATION_MASK","packEid","gen","unpackIdx","unpackGen","createEntity","ensureEntityAtSlot","s","pos","last","destroyEntity","dispatchDestroyObservers","lazyObservers","cleanupRelationsOnDestroy","archId","entityExists","storedGen","refGen","getEntityIndex","getEntityGeneration","packEntity","index","generation","isEntity","_observersAPI","registerObserversAPI","_relationsCleanup","registerRelationsCleanup"],"mappings":"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","file":"chunk-2KCN5RVK.js","sourcesContent":["export const VERSION = '0.5.7'\n","// Multi-word Uint32 bitmask helpers.\n\nexport function createMask(wordCount: number): Uint32Array {\n return new Uint32Array(wordCount)\n}\n\nexport function setBit(mask: Uint32Array, bit: number): void {\n const w = bit >>> 5\n mask[w] = (mask[w] ?? 0) | (1 << (bit & 31))\n}\n\nexport function clearBit(mask: Uint32Array, bit: number): void {\n const w = bit >>> 5\n mask[w] = (mask[w] ?? 0) & ~(1 << (bit & 31))\n}\n\nexport function testBit(mask: Uint32Array, bit: number): boolean {\n const w = bit >>> 5\n return ((mask[w] ?? 0) & (1 << (bit & 31))) !== 0\n}\n\nexport function copyMask(dst: Uint32Array, src: Uint32Array): void {\n const n = src.length\n for (let i = 0; i < n; i++) dst[i] = src[i] ?? 0\n}\n\nexport function cloneMask(src: Uint32Array): Uint32Array {\n const out = new Uint32Array(src.length)\n for (let i = 0; i < src.length; i++) out[i] = src[i] ?? 0\n return out\n}\n\nexport function maskEquals(a: Uint32Array, b: Uint32Array): boolean {\n const n = a.length\n if (b.length !== n) return false\n for (let i = 0; i < n; i++) if ((a[i] ?? 0) !== (b[i] ?? 0)) return false\n return true\n}\n\nexport function maskHash(m: Uint32Array): string {\n // Stable string key for Map lookups. Hex-joined.\n const parts: string[] = []\n for (let i = 0; i < m.length; i++) {\n parts.push((m[i] ?? 0).toString(16))\n }\n return parts.join(',')\n}\n\nexport function isMaskZero(m: Uint32Array): boolean {\n for (let i = 0; i < m.length; i++) if ((m[i] ?? 0) !== 0) return false\n return true\n}\n\nexport function unionMask(a: Uint32Array, b: Uint32Array): Uint32Array {\n const out = new Uint32Array(a.length)\n for (let i = 0; i < a.length; i++) out[i] = (a[i] ?? 0) | (b[i] ?? 0)\n return out\n}\n\n/**\n * Test whether an archetype's mask matches a query.\n * - withMask: all of these bits must be present\n * - anyMask: if anyHasBits, at least one of these bits must be present\n * - noneMask: none of these bits may be present\n */\nexport function matches(\n mask: Uint32Array,\n withMask: Uint32Array,\n anyMask: Uint32Array,\n noneMask: Uint32Array,\n anyHasBits: boolean,\n words: number,\n): boolean {\n let anyHit = !anyHasBits\n for (let w = 0; w < words; w++) {\n const m = mask[w] ?? 0\n const wm = withMask[w] ?? 0\n const am = anyMask[w] ?? 0\n const nm = noneMask[w] ?? 0\n if ((m & wm) !== wm) return false\n if ((m & nm) !== 0) return false\n if (!anyHit && (m & am) !== 0) anyHit = true\n }\n return anyHit\n}\n\nexport function listBits(mask: Uint32Array): number[] {\n const out: number[] = []\n for (let w = 0; w < mask.length; w++) {\n let word = mask[w] ?? 0\n while (word !== 0) {\n const bit = (w << 5) + ctz32(word)\n out.push(bit)\n word &= word - 1\n }\n }\n return out\n}\n\n// Iterate set bits in a slice of a larger Uint32Array starting at `base`.\n// Shared by destroy paths and storage cleanup so the bit-extraction maths\n// lives in exactly one place.\nexport function forEachSetBit(\n mask: Uint32Array,\n base: number,\n words: number,\n fn: (bit: number) => void,\n): void {\n for (let wi = 0; wi < words; wi++) {\n let word = mask[base + wi] ?? 0\n while (word !== 0) {\n const bit = (wi << 5) + ctz32(word)\n fn(bit)\n word &= word - 1\n }\n }\n}\n\n// Match a query against an entity's mask stored as a slice inside a larger\n// Uint32Array. Reading directly from the parent array avoids the temporary\n// Uint32Array allocation on every observer dispatch.\nexport function matchesEntityMask(\n entityMask: Uint32Array,\n base: number,\n words: number,\n withMask: Uint32Array,\n anyMask: Uint32Array,\n noneMask: Uint32Array,\n anyHasBits: boolean,\n): boolean {\n let anyHit = !anyHasBits\n for (let i = 0; i < words; i++) {\n const m = entityMask[base + i] ?? 0\n const wm = withMask[i] ?? 0\n const am = anyMask[i] ?? 0\n const nm = noneMask[i] ?? 0\n if ((m & wm) !== wm) return false\n if ((m & nm) !== 0) return false\n if (!anyHit && (m & am) !== 0) anyHit = true\n }\n return anyHit\n}\n\nfunction ctz32(v: number): number {\n // Count trailing zeros in a 32-bit integer (assumes v !== 0)\n return 31 - Math.clz32(v & -v)\n}\n","// aiecsjs/internal/errors — named error types for the core.\n\n/**\n * Thrown by core world/entity/component operations for invariant violations and\n * misuse (bad world options, a destroyed/unknown world, exhausted component\n * slots, capacity overflow). Carries the existing `aiecsjs: `-prefixed message.\n *\n * Catch this to distinguish an aiecsjs-originated failure from an unrelated\n * runtime error, instead of string-matching on the message. Mirrors the\n * {@link EntityNotAliveError} class style.\n *\n * @example\n * try {\n * createWorld({ indexBits: 99 })\n * } catch (err) {\n * if (err instanceof EcsError) {\n * // an aiecsjs invariant was violated\n * }\n * }\n */\nexport class EcsError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'EcsError'\n }\n}\n","import { VERSION } from '../version.js'\nimport { cloneMask, copyMask, createMask, maskHash } from './bitmask.js'\nimport { EcsError } from './errors.js'\nimport type {\n ArchetypeState,\n ComponentInfo,\n FieldInfo,\n ResolvedWorldOptions,\n World,\n WorldComponentStorage,\n WorldOptions,\n WorldState,\n} from './types.js'\n\nexport const WORLD_BRAND = Symbol.for('aiecsjs.world')\n\nconst DEFAULT_OPTIONS: Required<Omit<WorldOptions, 'buffer' | 'bufferByteOffset'>> = {\n initialCapacity: 1024,\n maxEntities: 1_000_000,\n indexBits: 24,\n generationBits: 8,\n}\n\nconst DEFAULT_MAX_COMPONENTS = 256\n\nlet nextWorldId = 1\nconst worldRegistry = new Map<number, WorldState>()\n\nexport function getWorldState(world: World): WorldState {\n const state = worldRegistry.get(world.id)\n if (!state) throw new EcsError(`aiecsjs: world ${world.id} is destroyed or unknown`)\n if (state.destroyed) throw new EcsError(`aiecsjs: world ${world.id} is destroyed`)\n return state\n}\n\nexport function registerWorld(state: WorldState): void {\n worldRegistry.set(state.id, state)\n}\n\nexport function unregisterWorld(id: number): void {\n worldRegistry.delete(id)\n}\n\nexport function isWorldRegistered(id: number): boolean {\n return worldRegistry.has(id)\n}\n\nfunction resolveOptions(opts: WorldOptions | undefined): ResolvedWorldOptions {\n const o = opts ?? {}\n const indexBits = o.indexBits ?? DEFAULT_OPTIONS.indexBits\n const generationBits = o.generationBits ?? DEFAULT_OPTIONS.generationBits\n const maxComponents = DEFAULT_MAX_COMPONENTS\n if (indexBits < 1 || indexBits > 24) {\n throw new EcsError('aiecsjs: indexBits must be in [1, 24]')\n }\n if (generationBits < 0 || generationBits > 16) {\n throw new EcsError('aiecsjs: generationBits must be in [0, 16]')\n }\n if (indexBits + generationBits > 32) {\n throw new EcsError(\n `aiecsjs: indexBits (${indexBits}) + generationBits (${generationBits}) must be <= 32`,\n )\n }\n const maxByIndex = 1 << indexBits\n const initialCapacity = Math.max(\n 1,\n Math.min(o.initialCapacity ?? DEFAULT_OPTIONS.initialCapacity, maxByIndex),\n )\n const maxEntities = Math.max(\n initialCapacity,\n Math.min(o.maxEntities ?? DEFAULT_OPTIONS.maxEntities, maxByIndex),\n )\n return {\n initialCapacity,\n maxEntities,\n indexBits,\n generationBits,\n indexMask: (1 << indexBits) - 1,\n generationMask: generationBits === 0 ? 0 : (1 << generationBits) - 1,\n maxComponents,\n maskWordCount: Math.ceil(maxComponents / 32),\n buffer: o.buffer ?? null,\n bufferByteOffset: o.bufferByteOffset ?? 0,\n }\n}\n\nexport function createEmptyArchetype(maskWordCount: number, maxComponents: number): ArchetypeState {\n return {\n id: 0,\n mask: createMask(maskWordCount),\n size: 0,\n capacity: 16,\n entities: new Uint32Array(16),\n entityRow: new Map<number, number>(),\n componentBits: [],\n edgeAdd: new Int32Array(maxComponents).fill(-1),\n edgeRemove: new Int32Array(maxComponents).fill(-1),\n }\n}\n\nexport function createWorld(options?: WorldOptions): World {\n const resolved = resolveOptions(options)\n const id = nextWorldId++\n\n const generationCtor = resolved.generationBits > 8 ? Uint16Array : Uint8Array\n const generations = new generationCtor(resolved.initialCapacity)\n\n const state: WorldState = {\n id,\n capacity: resolved.initialCapacity,\n version: VERSION,\n options: resolved,\n size: 0,\n nextFreshIndex: 1, // 0 reserved\n freeList: [],\n generations,\n destroyed: false,\n componentBitFor: new Map<number, number>(),\n componentInfoByBit: new Array(resolved.maxComponents).fill(null),\n componentStorageByBit: new Array(resolved.maxComponents).fill(null),\n nextComponentBit: 0,\n entityArchetype: new Uint32Array(resolved.initialCapacity),\n entityMask: new Uint32Array(resolved.initialCapacity * resolved.maskWordCount),\n archetypes: [],\n archetypeByMaskHash: new Map<string, number>(),\n queryVersion: 0,\n queries: [],\n queryMasks: new Map(),\n queryArchetypeCache: [],\n queryArchetypeStamp: [],\n bitToQueries: new Map<number, Set<number>>(),\n reactiveBuffers: new Map(),\n observers: [],\n relationStorage: new Map(),\n sab: resolved.buffer,\n readOnly: false,\n }\n\n // Seed archetype 0 (the empty mask)\n const empty = createEmptyArchetype(resolved.maskWordCount, resolved.maxComponents)\n empty.id = 0\n state.archetypes.push(empty)\n state.archetypeByMaskHash.set(maskHash(empty.mask), 0)\n\n registerWorld(state)\n return makePublicWorld(state)\n}\n\nexport function makePublicWorld(state: WorldState): World {\n return {\n id: state.id,\n get capacity() {\n return state.capacity\n },\n version: state.version,\n } as World\n}\n\nexport function destroyWorld(world: World): void {\n const state = worldRegistry.get(world.id)\n if (!state || state.destroyed) return\n state.destroyed = true\n // Clear large buffers to help GC. Post-dispose ops already throw via\n // getWorldState (state.destroyed), so releasing internal state can't regress\n // live behaviour; the capacity getter closure in makePublicWorld is the only\n // thing pinning `state`, so we must drop the big per-entity arrays here or\n // they survive as long as the (typically retained) public world handle.\n state.archetypes = []\n state.archetypeByMaskHash.clear()\n state.componentInfoByBit = []\n state.componentStorageByBit = []\n state.queries = []\n state.queryMasks.clear()\n state.queryArchetypeCache = []\n state.observers = []\n state.relationStorage.clear()\n state.reactiveBuffers.clear()\n // Release the remaining large per-entity arrays / indices that the original\n // \"clear large buffers\" pass left allocated (these dominate memory for big\n // worlds). Swap to length-0 instances rather than mutating in place.\n state.entityMask = new Uint32Array(0)\n state.entityArchetype = new Uint32Array(0)\n state.generations = new Uint8Array(0)\n state.freeList = []\n state.componentBitFor.clear()\n state.bitToQueries.clear()\n state.queryArchetypeStamp = []\n state.sab = null\n unregisterWorld(world.id)\n}\n\nexport function resetWorld(world: World): void {\n const state = getWorldState(world)\n // Keep capacity and registered components; clear entities and per-entity state.\n state.size = 0\n state.nextFreshIndex = 1\n state.freeList = []\n state.generations.fill(0)\n state.entityArchetype.fill(0)\n state.entityMask.fill(0)\n // Wipe archetype memberships but keep archetype graph for stability.\n for (const arch of state.archetypes) {\n arch.size = 0\n arch.entityRow.clear()\n }\n // Clear SoA columns and AoS instances; storage allocation is preserved.\n for (const storage of state.componentStorageByBit) {\n if (!storage) continue\n if (storage.kind === 'soa' && storage.soa) {\n for (const k of Object.keys(storage.soa)) {\n storage.soa[k]?.fill(0)\n }\n } else if (storage.kind === 'aos' && storage.aos) {\n storage.aos.fill(undefined as unknown as never)\n }\n }\n state.queryVersion++\n for (const buf of state.reactiveBuffers.values()) {\n buf.entered.length = 0\n buf.exited.length = 0\n }\n}\n\nexport function getWorldSize(world: World): number {\n return getWorldState(world).size\n}\n\nexport function getWorldCapacity(world: World): number {\n return getWorldState(world).capacity\n}\n\n// --- Capacity growth ---\n\nexport function ensureCapacity(state: WorldState, needed: number): void {\n if (needed <= state.capacity) return\n if (needed > state.options.maxEntities) {\n throw new EcsError(\n `aiecsjs: requested capacity ${needed} exceeds maxEntities ${state.options.maxEntities}`,\n )\n }\n let newCap = state.capacity\n while (newCap < needed) newCap = Math.min(newCap * 2, state.options.maxEntities)\n growEntityArrays(state, newCap)\n}\n\nfunction growEntityArrays(state: WorldState, newCap: number): void {\n // generations\n const genCtor: any = state.generations.constructor\n const newGen = new genCtor(newCap) as Uint8Array | Uint16Array\n ;(newGen as Uint8Array).set(state.generations as Uint8Array)\n state.generations = newGen\n\n // entityArchetype\n const newArch = new Uint32Array(newCap)\n newArch.set(state.entityArchetype)\n state.entityArchetype = newArch\n\n // entityMask\n const wordCount = state.options.maskWordCount\n const newMask = new Uint32Array(newCap * wordCount)\n newMask.set(state.entityMask)\n state.entityMask = newMask\n\n // Component storages (SoA columns + AoS arrays)\n for (const storage of state.componentStorageByBit) {\n if (!storage) continue\n if (storage.kind === 'soa' && storage.soa) {\n const info = state.componentInfoByBit[storage.bit]\n if (info) growSoAColumns(storage.soa, info.fields, newCap)\n } else if (storage.kind === 'aos' && storage.aos) {\n storage.aos.length = newCap\n }\n }\n\n state.capacity = newCap\n}\n\nfunction growSoAColumns(soa: Record<string, any>, fields: FieldInfo[], newCap: number): void {\n for (const f of fields) {\n const old = soa[f.name]\n if (!old) continue\n const newLen = newCap * f.vectorLen\n if (old.length >= newLen) continue\n const next = new f.ctor(newLen)\n next.set(old)\n soa[f.name] = next\n }\n}\n\n// --- Archetype management ---\n\nexport function findOrCreateArchetype(\n state: WorldState,\n mask: Uint32Array,\n): { archId: number; created: boolean } {\n const key = maskHash(mask)\n const existing = state.archetypeByMaskHash.get(key)\n if (existing !== undefined) return { archId: existing, created: false }\n\n const id = state.archetypes.length\n const arch: ArchetypeState = {\n id,\n mask: cloneMask(mask),\n size: 0,\n capacity: 16,\n entities: new Uint32Array(16),\n entityRow: new Map<number, number>(),\n componentBits: collectBits(mask),\n edgeAdd: new Int32Array(state.options.maxComponents).fill(-1),\n edgeRemove: new Int32Array(state.options.maxComponents).fill(-1),\n }\n state.archetypes.push(arch)\n state.archetypeByMaskHash.set(key, id)\n state.queryVersion++\n return { archId: id, created: true }\n}\n\nexport function ensureArchetypeCapacity(arch: ArchetypeState, needed: number): void {\n if (needed <= arch.capacity) return\n let newCap = arch.capacity\n while (newCap < needed) newCap *= 2\n const next = new Uint32Array(newCap)\n next.set(arch.entities)\n arch.entities = next\n arch.capacity = newCap\n}\n\nfunction collectBits(mask: Uint32Array): number[] {\n const bits: number[] = []\n for (let w = 0; w < mask.length; w++) {\n let word = mask[w] ?? 0\n while (word !== 0) {\n const lsb = word & -word\n const bit = (w << 5) + (31 - Math.clz32(lsb))\n bits.push(bit)\n word &= word - 1\n }\n }\n return bits\n}\n\n// --- Component registration in a world ---\n\nexport function getOrRegisterComponentBit(state: WorldState, info: ComponentInfo): number {\n const existing = state.componentBitFor.get(info.id)\n if (existing !== undefined) return existing\n\n if (state.nextComponentBit >= state.options.maxComponents) {\n throw new EcsError(`aiecsjs: world reached maxComponents=${state.options.maxComponents}`)\n }\n const bit = state.nextComponentBit++\n state.componentBitFor.set(info.id, bit)\n state.componentInfoByBit[bit] = info\n\n // Create storage\n let storage: WorldComponentStorage\n if (info.kind === 'soa') {\n const soa: Record<string, any> = {}\n for (const f of info.fields) {\n soa[f.name] = new f.ctor(state.capacity * f.vectorLen)\n }\n storage = { kind: 'soa', componentId: info.id, bit, soa }\n } else if (info.kind === 'aos') {\n storage = { kind: 'aos', componentId: info.id, bit, aos: new Array(state.capacity) }\n } else {\n storage = { kind: 'tag', componentId: info.id, bit }\n }\n state.componentStorageByBit[bit] = storage\n return bit\n}\n\n// Read a bitmask out of state.entityMask[] into a fresh Uint32Array.\nexport function readEntityMask(state: WorldState, eid: number): Uint32Array {\n const w = state.options.maskWordCount\n const out = new Uint32Array(w)\n const idx = eid & state.options.indexMask\n const base = idx * w\n for (let i = 0; i < w; i++) out[i] = state.entityMask[base + i] ?? 0\n return out\n}\n\nexport function writeEntityMask(state: WorldState, eid: number, mask: Uint32Array): void {\n const w = state.options.maskWordCount\n const idx = eid & state.options.indexMask\n const base = idx * w\n for (let i = 0; i < w; i++) state.entityMask[base + i] = mask[i] ?? 0\n}\n\n// Get the bit of a component within a world without registering.\nexport function tryGetComponentBit(state: WorldState, info: ComponentInfo): number | undefined {\n return state.componentBitFor.get(info.id)\n}\n\nexport function isWorld(x: unknown): x is World {\n if (!x || typeof x !== 'object') return false\n const obj = x as { id?: unknown; version?: unknown }\n if (typeof obj.id !== 'number') return false\n if (typeof obj.version !== 'string') return false\n return worldRegistry.has(obj.id)\n}\n","import { clearBit, cloneMask, forEachSetBit, setBit, testBit } from './bitmask.js'\nimport { isAliveInternal } from './entity.js'\nimport type {\n AoSComponent,\n ComponentInfo,\n ComponentInit,\n ComponentLike,\n EntityId,\n FieldInfo,\n SoAColumns,\n SoAComponent,\n SoASchema,\n TagComponent,\n TypedArrayConstructor,\n World,\n WorldComponentStorage,\n WorldState,\n} from './types.js'\nimport {\n ensureArchetypeCapacity,\n findOrCreateArchetype,\n getOrRegisterComponentBit,\n getWorldState,\n readEntityMask,\n tryGetComponentBit,\n writeEntityMask,\n} from './world.js'\n\n// --- Component factories ---\n\nlet nextComponentId = 1\n\nconst TYPE_CTOR: Record<string, TypedArrayConstructor> = {\n i8: Int8Array,\n u8: Uint8Array,\n i16: Int16Array,\n u16: Uint16Array,\n i32: Int32Array,\n u32: Uint32Array,\n f32: Float32Array,\n f64: Float64Array,\n eid: Uint32Array,\n bool: Uint8Array,\n}\n\nconst componentInfoById = new Map<number, ComponentInfo>()\n\nexport function defineComponent<S extends SoASchema>(schema: S): SoAComponent<S> {\n const fields: FieldInfo[] = []\n for (const [name, decl] of Object.entries(schema)) {\n let type: keyof typeof TYPE_CTOR\n let vectorLen = 1\n if (typeof decl === 'string') {\n type = decl\n } else if (Array.isArray(decl)) {\n const [t, len] = decl\n type = t\n vectorLen = len\n } else {\n throw new TypeError(`aiecsjs: invalid field declaration for \"${name}\"`)\n }\n const ctor = TYPE_CTOR[type]\n if (!ctor) throw new TypeError(`aiecsjs: unknown field type \"${type}\" for field \"${name}\"`)\n fields.push({\n name,\n type: type as any,\n vectorLen,\n ctor,\n bytesPerElement: (ctor as any).BYTES_PER_ELEMENT,\n })\n }\n const id = nextComponentId++\n const info: ComponentInfo = { id, kind: 'soa', schema, fields, factory: null }\n componentInfoById.set(id, info)\n const handle: SoAComponent<S> = {\n __kind: 'soa',\n __id: id,\n __schema: schema,\n }\n return handle\n}\n\nexport function defineTag(): TagComponent {\n const id = nextComponentId++\n const info: ComponentInfo = { id, kind: 'tag', schema: null, fields: [], factory: null }\n componentInfoById.set(id, info)\n return { __kind: 'tag', __id: id }\n}\n\nexport function defineObjectComponent<T>(factory?: () => T): AoSComponent<T> {\n const id = nextComponentId++\n const fac = factory ?? (() => ({}) as T)\n const info: ComponentInfo = { id, kind: 'aos', schema: null, fields: [], factory: fac as any }\n componentInfoById.set(id, info)\n return { __kind: 'aos', __id: id, __factory: fac }\n}\n\nexport function getComponentInfo(component: ComponentLike): ComponentInfo {\n const info = componentInfoById.get(component.__id)\n if (!info)\n throw new Error(\n 'aiecsjs: component is not registered (call defineComponent/defineTag/defineObjectComponent)',\n )\n return info\n}\n\n// --- Component ops on entities ---\n\nexport function addComponent<C extends ComponentLike>(\n world: World,\n eid: EntityId,\n component: C,\n initial?: ComponentInit<C>,\n): void {\n const state = getWorldState(world)\n if (state.readOnly) throw new Error('aiecsjs: cannot mutate a read-only world')\n if (!isAliveInternal(state, eid)) {\n throw new Error(`aiecsjs: addComponent on dead entity ${eid}`)\n }\n const info = getComponentInfo(component)\n const bit = getOrRegisterComponentBit(state, info)\n\n const prevMask = readEntityMask(state, eid)\n if (testBit(prevMask, bit)) {\n if (initial !== undefined) writeInitial(state, eid as number, component, initial)\n return\n }\n const newMask = cloneMask(prevMask)\n setBit(newMask, bit)\n migrateEntity(state, eid as number, newMask)\n\n writeInitial(state, eid as number, component, initial)\n\n fireAddObservers(state, eid, bit)\n notifyMaskChange(state, eid, bit, prevMask, newMask)\n}\n\nexport function removeComponent<C extends ComponentLike>(\n world: World,\n eid: EntityId,\n component: C,\n): void {\n const state = getWorldState(world)\n if (state.readOnly) throw new Error('aiecsjs: cannot mutate a read-only world')\n if (!isAliveInternal(state, eid)) return\n const info = getComponentInfo(component)\n const bit = tryGetComponentBit(state, info)\n if (bit === undefined) return\n const prevMask = readEntityMask(state, eid)\n if (!testBit(prevMask, bit)) return\n\n // Write the new mask BEFORE firing observers so query-targeted observers\n // reading `state.entityMask` see the post-removal state (and thus correctly\n // detect \"entity left this query\"). Without this reorder, a query that\n // requires the removed component would still match during dispatch and the\n // remove observer would never fire. Component-targeted observers receive the\n // bit directly and don't depend on mask timing. addComponent already follows\n // this \"mutate then fire\" order; keeping removeComponent consistent.\n const newMask = cloneMask(prevMask)\n clearBit(newMask, bit)\n migrateEntity(state, eid as number, newMask)\n\n fireRemoveObservers(state, eid, bit)\n\n const idx = (eid as number) & state.options.indexMask\n const storage = state.componentStorageByBit[bit]\n if (storage?.kind === 'soa' && storage.soa) {\n clearSoAEntity(storage.soa, info.fields, idx)\n } else if (storage?.kind === 'aos' && storage.aos) {\n storage.aos[idx] = undefined\n }\n\n notifyMaskChange(state, eid, bit, prevMask, newMask)\n}\n\nexport function hasComponent<C extends ComponentLike>(\n world: World,\n eid: EntityId,\n component: C,\n): boolean {\n const state = getWorldState(world)\n if (!isAliveInternal(state, eid)) return false\n const info = getComponentInfo(component)\n const bit = tryGetComponentBit(state, info)\n if (bit === undefined) return false\n const mask = readEntityMask(state, eid)\n return testBit(mask, bit)\n}\n\nexport function getComponent<C extends ComponentLike>(\n world: World,\n eid: EntityId,\n component: C,\n): unknown {\n const state = getWorldState(world)\n if (!isAliveInternal(state, eid)) return undefined\n const info = getComponentInfo(component)\n const bit = tryGetComponentBit(state, info)\n if (bit === undefined) return undefined\n const mask = readEntityMask(state, eid)\n if (!testBit(mask, bit)) return undefined\n const storage = state.componentStorageByBit[bit]\n if (!storage) return undefined\n if (storage.kind === 'soa') return storage.soa\n if (storage.kind === 'aos') {\n const idx = (eid as number) & state.options.indexMask\n return storage.aos?.[idx]\n }\n return true // tag\n}\n\nexport function setComponent<C extends ComponentLike, V>(\n world: World,\n eid: EntityId,\n component: C,\n value: V,\n): void {\n const state = getWorldState(world)\n if (state.readOnly) throw new Error('aiecsjs: cannot mutate a read-only world')\n if (!isAliveInternal(state, eid)) throw new Error(`aiecsjs: setComponent on dead entity ${eid}`)\n const info = getComponentInfo(component)\n const bit = tryGetComponentBit(state, info)\n if (bit === undefined) {\n // Adding via set\n addComponent(world, eid, component, value as any)\n return\n }\n const mask = readEntityMask(state, eid)\n if (!testBit(mask, bit)) {\n addComponent(world, eid, component, value as any)\n return\n }\n writeInitial(state, eid as number, component, value as any)\n fireSetObservers(state, eid, bit, value)\n}\n\n// --- Internals ---\n\nfunction writeInitial(\n state: WorldState,\n packedEid: number,\n component: ComponentLike,\n initial: unknown,\n): void {\n const info = getComponentInfo(component)\n const bit = state.componentBitFor.get(info.id)\n if (bit === undefined) return\n const storage = state.componentStorageByBit[bit]\n if (!storage) return\n // Unpack to raw index for storage access\n const idx = packedEid & state.options.indexMask\n if (info.kind === 'soa' && storage.soa) {\n if (initial == null) return\n const obj = initial as Record<string, unknown>\n for (const f of info.fields) {\n if (!(f.name in obj)) continue\n const col = storage.soa[f.name]\n if (!col) continue\n const val = obj[f.name]\n if (f.vectorLen === 1) {\n col[idx] = typeof val === 'boolean' ? (val ? 1 : 0) : Number(val)\n } else if (Array.isArray(val) || ArrayBuffer.isView(val)) {\n const base = idx * f.vectorLen\n const arr = val as ArrayLike<number>\n for (let i = 0; i < f.vectorLen; i++) col[base + i] = Number(arr[i] ?? 0)\n }\n }\n } else if (info.kind === 'aos' && storage.aos) {\n const factory = info.factory ?? (() => ({}))\n let inst = storage.aos[idx]\n if (inst === undefined) {\n inst = factory()\n storage.aos[idx] = inst\n }\n if (initial && typeof initial === 'object') {\n // SECURITY: do NOT use `Object.assign(inst, initial)` here. When `initial`\n // comes from `JSON.parse(untrustedBytes)` — e.g. via `fromJSON`,\n // `deserializeWorld`, or app code piping a bridge payload — the parsed\n // object can carry an OWN `__proto__` property, and `Object.assign` uses\n // [[Set]] semantics which would trigger the proto setter and clobber the\n // instance's prototype chain. Explicit own-key copy with a deny-list\n // closes the prototype-pollution path.\n const src = initial as Record<string, unknown>\n const target = inst as Record<string, unknown>\n for (const key of Object.keys(src)) {\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') continue\n target[key] = src[key]\n }\n }\n }\n // tag: nothing\n}\n\nfunction clearSoAEntity(soa: SoAColumns, fields: FieldInfo[], eid: number): void {\n for (const f of fields) {\n const col = soa[f.name]\n if (!col) continue\n if (f.vectorLen === 1) {\n col[eid] = 0\n } else {\n const base = eid * f.vectorLen\n for (let i = 0; i < f.vectorLen; i++) col[base + i] = 0\n }\n }\n}\n\n// Clear every component-storage slot that the entity currently owns.\n// Walks the entity's mask; for each set bit, zeroes the SoA columns or\n// undefines the AoS slot at the entity index. Tag storages are bit-only.\n// Caller (e.g. destroyEntity) is expected to clear the mask separately.\nexport function clearAllEntityStorages(state: WorldState, eid: EntityId): void {\n const wordCount = state.options.maskWordCount\n const idx = (eid as number) & state.options.indexMask\n const base = idx * wordCount\n forEachSetBit(state.entityMask, base, wordCount, (bit) => {\n const storage = state.componentStorageByBit[bit]\n const info = state.componentInfoByBit[bit]\n if (storage?.kind === 'soa' && storage.soa && info) {\n clearSoAEntity(storage.soa, info.fields, idx)\n } else if (storage?.kind === 'aos' && storage.aos) {\n storage.aos[idx] = undefined\n }\n })\n}\n\nfunction migrateEntity(state: WorldState, packedEid: number, newMask: Uint32Array): void {\n // Unpack to raw index for sparse-array lookups\n const idx = packedEid & state.options.indexMask\n const srcArchId = state.entityArchetype[idx] ?? 0\n const srcArch = state.archetypes[srcArchId]\n if (!srcArch) return\n\n const found = findOrCreateArchetype(state, newMask)\n const destArchId = found.archId\n const destArch = state.archetypes[destArchId]\n if (!destArch) return\n\n if (destArchId !== srcArchId) {\n // Swap-pop from src (arch.entities / entityRow use packed eid as key)\n const row = srcArch.entityRow.get(packedEid)\n if (row !== undefined) {\n const lastRow = srcArch.size - 1\n if (row !== lastRow) {\n const moved = srcArch.entities[lastRow] ?? 0\n srcArch.entities[row] = moved\n srcArch.entityRow.set(moved, row)\n }\n srcArch.entities[lastRow] = 0\n srcArch.entityRow.delete(packedEid)\n srcArch.size--\n }\n\n // Append to dest (store packed eid)\n ensureArchetypeCapacity(destArch, destArch.size + 1)\n const newRow = destArch.size\n destArch.entities[newRow] = packedEid\n destArch.entityRow.set(packedEid, newRow)\n destArch.size++\n\n state.entityArchetype[idx] = destArchId\n }\n\n writeEntityMask(state, packedEid, newMask)\n}\n\n// --- Observer dispatch (lazy-bound) ---\n\ninterface ObserversDispatchAPI {\n fireAdd(state: WorldState, eid: EntityId, bit: number): void\n fireRemove(state: WorldState, eid: EntityId, bit: number): void\n fireSet(state: WorldState, eid: EntityId, bit: number, value: unknown): void\n}\nlet _dispatch: ObserversDispatchAPI = {\n fireAdd: () => {},\n fireRemove: () => {},\n fireSet: () => {},\n}\n\ntype MaskChangeFn = (\n state: WorldState,\n eid: EntityId,\n bit: number,\n prev: Uint32Array,\n next: Uint32Array,\n) => void\nlet _maskChange: MaskChangeFn = () => {}\nexport function registerMaskChangeDispatch(fn: MaskChangeFn): void {\n _maskChange = fn\n}\nfunction notifyMaskChange(\n state: WorldState,\n eid: number,\n bit: number,\n prev: Uint32Array,\n next: Uint32Array,\n): void {\n _maskChange(state, eid as EntityId, bit, prev, next)\n}\n\n// Fire the reactive enter/exit mask-change notification for an entity being\n// destroyed. destroyEntity clears the entity's mask wholesale rather than\n// removing components one-by-one, so it never reaches removeComponent's\n// `notifyMaskChange` call — leaving exitQuery buffers empty on destroy while a\n// component-by-component teardown would have populated them (asymmetric with\n// observe(q,'remove')). We replay the removals here.\n//\n// CORRECTNESS: transition ONE bit at a time through evolving masks, exactly as a\n// sequence of removeComponent() calls would. Passing a single (prevMask, empty)\n// pair once per set bit double-counts — a query matching on several of the\n// entity's components would see wasMatch=true,isMatch=false on every bit and push\n// the same exit N times. Clearing bits incrementally flips wasMatch=false after\n// the first component that breaks each query's match, so every query records\n// exactly one exit.\n//\n// SNAPSHOT DISCIPLINE: `prevMask` is captured at destroy entry (a private copy,\n// same discipline as dispatchDestroyObservers' preMask) so reentrant handlers\n// run earlier in destroy cannot mutate live state and suppress the exit. We\n// iterate that snapshot and mutate only our own clones.\nexport function dispatchDestroyMaskChange(\n state: WorldState,\n eid: EntityId,\n prevMask: Uint32Array,\n): void {\n const w = state.options.maskWordCount\n const before = cloneMask(prevMask) // current bit still set\n const after = cloneMask(prevMask) // current bit cleared\n forEachSetBit(prevMask, 0, w, (bit) => {\n clearBit(after, bit)\n notifyMaskChange(state, eid as number, bit, before, after)\n clearBit(before, bit)\n })\n}\nexport function registerObserverDispatch(api: ObserversDispatchAPI): void {\n _dispatch = api\n}\nfunction fireAddObservers(state: WorldState, eid: number, bit: number): void {\n _dispatch.fireAdd(state, eid as EntityId, bit)\n}\nfunction fireRemoveObservers(state: WorldState, eid: number, bit: number): void {\n _dispatch.fireRemove(state, eid as EntityId, bit)\n}\nfunction fireSetObservers(state: WorldState, eid: number, bit: number, value: unknown): void {\n _dispatch.fireSet(state, eid as EntityId, bit, value)\n}\n\n// --- Helper for serialize/worker ---\n\nexport function getComponentByInternalId(id: number): ComponentInfo | undefined {\n return componentInfoById.get(id)\n}\n\nexport function listAllComponents(): ComponentInfo[] {\n return Array.from(componentInfoById.values())\n}\n\nexport function _resetComponentRegistry_FOR_TESTS_ONLY(): void {\n componentInfoById.clear()\n nextComponentId = 1\n}\n","import { clearAllEntityStorages, dispatchDestroyMaskChange } from './component.js'\nimport type { EntityId, ResolvedWorldOptions, World, WorldState } from './types.js'\nimport { ensureArchetypeCapacity, ensureCapacity, getWorldState, readEntityMask } from './world.js'\n\n// --- Default bit layout constants (used by public getEntityIndex / getEntityGeneration / packEntity) ---\n// These use the default 24/8 split. See §4.4 limitation: callers using non-default\n// createWorld({ indexBits, generationBits }) should not rely on these functions for unpacking.\nexport const DEFAULT_INDEX_BITS = 24\nexport const DEFAULT_GENERATION_BITS = 8\nexport const DEFAULT_INDEX_MASK = (1 << DEFAULT_INDEX_BITS) - 1\nexport const DEFAULT_GENERATION_MASK = (1 << DEFAULT_GENERATION_BITS) - 1\n\n// --- Internal pack/unpack helpers (world-options-aware) ---\n\nexport function packEid(idx: number, gen: number, opts: ResolvedWorldOptions): EntityId {\n // `>>> 0` normalises to unsigned: for generation ≥ 128 (default 8-bit gen) the\n // signed `<<`/`|` would yield a negative number that diverges from the unsigned\n // value stored in `arch.entities` (Uint32Array), breaking entityRow lookups for\n // query-iterated high-generation entities. Keep EntityId a non-negative int32.\n return ((((gen & opts.generationMask) << opts.indexBits) | (idx & opts.indexMask)) >>>\n 0) as EntityId\n}\n\nexport function unpackIdx(eid: number, opts: ResolvedWorldOptions): number {\n return eid & opts.indexMask\n}\n\nexport function unpackGen(eid: number, opts: ResolvedWorldOptions): number {\n return (eid >>> opts.indexBits) & opts.generationMask\n}\n\nexport function createEntity(world: World): EntityId {\n const state = getWorldState(world)\n if (state.readOnly) {\n throw new Error('aiecsjs: cannot createEntity on a read-only world (worker-attached)')\n }\n\n let idx: number\n if (state.freeList.length > 0) {\n idx = state.freeList.pop()!\n } else {\n if (state.nextFreshIndex >= state.options.maxEntities) {\n throw new Error(`aiecsjs: reached maxEntities ${state.options.maxEntities}`)\n }\n if (state.nextFreshIndex >= state.capacity) {\n ensureCapacity(state, state.nextFreshIndex + 1)\n }\n idx = state.nextFreshIndex++\n }\n\n const gen = state.generations[idx] ?? 0\n const eid = packEid(idx, gen, state.options)\n\n // Move into the empty archetype (0)\n const arch = state.archetypes[0]\n if (!arch) throw new Error('aiecsjs: missing empty archetype')\n ensureArchetypeCapacity(arch, arch.size + 1)\n const row = arch.size\n arch.entities[row] = eid\n arch.entityRow.set(eid, row)\n arch.size++\n\n state.entityArchetype[idx] = 0\n // Reset entityMask row for this idx\n const w = state.options.maskWordCount\n const base = idx * w\n for (let i = 0; i < w; i++) state.entityMask[base + i] = 0\n\n state.size++\n return eid\n}\n\n// Ensure a LIVE entity occupies slot `idx`, returning its packed EntityId.\n// Used by delta apply() to materialise a replica entity at the SAME slot the\n// source used (the wire stores raw slot indices), so a source eid keeps\n// addressing the replica by slot. Mirrors createEntity's placement but targets\n// a specific slot:\n// - slot already live -> reuse it (return its current packed id)\n// - slot in the freeList -> reclaim it\n// - slot beyond the frontier -> advance nextFreshIndex, pushing the skipped\n// slots onto the freeList so they remain\n// allocatable (mirrors holes in the source)\n// The slot's CURRENT generation is used (never gen=0), so a replica whose\n// generation has advanced is handled without a dead-entity throw.\nexport function ensureEntityAtSlot(state: WorldState, idx: number): EntityId {\n if (state.readOnly) {\n /* v8 ignore next — defensive: apply() only writes to writable worlds */\n throw new Error('aiecsjs: cannot create entities on a read-only world (worker-attached)')\n }\n if (idx <= 0 || idx >= state.options.maxEntities) {\n /* v8 ignore next — defensive: apply() pre-guards the eid range */\n throw new Error(`aiecsjs: slot index ${idx} out of range`)\n }\n if (idx >= state.capacity) ensureCapacity(state, idx + 1)\n\n const gen = state.generations[idx] ?? 0\n const eid = packEid(idx, gen, state.options)\n if (isAliveInternal(state, eid)) return eid // already live — reuse\n\n // Reclaim the free slot.\n if (idx >= state.nextFreshIndex) {\n // Free the slots we skip over so they can still be allocated later.\n for (let s = state.nextFreshIndex; s < idx; s++) state.freeList.push(s)\n state.nextFreshIndex = idx + 1\n } else {\n // Below the frontier, so the slot must be in the freeList — remove it.\n const pos = state.freeList.lastIndexOf(idx)\n if (pos !== -1) {\n const last = state.freeList.length - 1\n state.freeList[pos] = state.freeList[last]!\n state.freeList.pop()\n }\n }\n\n // Place into the empty archetype (0) — identical to createEntity's tail.\n const arch = state.archetypes[0]\n if (!arch) throw new Error('aiecsjs: missing empty archetype')\n ensureArchetypeCapacity(arch, arch.size + 1)\n const row = arch.size\n arch.entities[row] = eid\n arch.entityRow.set(eid, row)\n arch.size++\n\n state.entityArchetype[idx] = 0\n const w = state.options.maskWordCount\n const base = idx * w\n for (let i = 0; i < w; i++) state.entityMask[base + i] = 0\n\n state.size++\n return eid\n}\n\nexport function destroyEntity(world: World, eid: EntityId): void {\n const state = getWorldState(world)\n if (state.readOnly) {\n throw new Error('aiecsjs: cannot destroyEntity on a read-only world')\n }\n if (!isAliveInternal(state, eid)) return\n\n const idx = eid & state.options.indexMask\n\n // Snapshot the pre-destroy mask BEFORE any teardown runs. dispatchDestroyObservers\n // (and relation cleanup) may reentrantly mutate live state.entityMask; capturing\n // here lets the reactive exit notification below fire against the state at destroy\n // entry — same snapshot discipline dispatchDestroyObservers uses for its preMask.\n const prevMask = readEntityMask(state, eid)\n\n // Fire onRemove for every component the entity has, plus reactive exit\n // (Late-bound to avoid circular imports — done via observers module.)\n const { dispatchDestroyObservers } = lazyObservers()\n dispatchDestroyObservers(state, eid)\n\n // Clean up relations referring to this entity\n cleanupRelationsOnDestroy(state, eid)\n\n // Zero the SoA columns / undefine the AoS slots the entity owned, before\n // the mask is cleared. Without this, destroyed entities leave stale data\n // visible to snapshots and serialisation.\n clearAllEntityStorages(state, eid)\n\n // Swap-pop from its archetype\n const archId = state.entityArchetype[idx] ?? 0\n const arch = state.archetypes[archId]\n if (arch) {\n const row = arch.entityRow.get(eid)\n if (row !== undefined) {\n const lastRow = arch.size - 1\n if (row !== lastRow) {\n const moved = arch.entities[lastRow] ?? 0\n arch.entities[row] = moved\n arch.entityRow.set(moved, row)\n }\n arch.entities[lastRow] = 0\n arch.entityRow.delete(eid)\n arch.size--\n }\n }\n\n // Notify the REACTIVE enter/exit surface that the entity is leaving every\n // query it was matching. destroyEntity clears the mask wholesale rather than\n // routing through removeComponent, so without this exitQuery buffers stay\n // empty on destroy (asymmetric with observe(q,'remove')). We pass the entry\n // snapshot so reentrant teardown handlers above cannot suppress the exit; the\n // helper computes post-state = empty mask (component absent).\n dispatchDestroyMaskChange(state, eid, prevMask)\n\n // Wipe state\n state.entityArchetype[idx] = 0\n const w = state.options.maskWordCount\n const base = idx * w\n for (let i = 0; i < w; i++) state.entityMask[base + i] = 0\n // Bump generation — use generationMask so non-default generationBits wraps correctly\n state.generations[idx] = ((state.generations[idx] ?? 0) + 1) & state.options.generationMask\n\n // freeList stores raw idx (not packed); createEntity packs on re-use\n state.freeList.push(idx)\n state.size--\n}\n\nexport function entityExists(world: World, eid: EntityId): boolean {\n const state = getWorldState(world)\n return isAliveInternal(state, eid)\n}\n\nexport function isAliveInternal(state: WorldState, eid: number): boolean {\n const idx = eid & state.options.indexMask\n if (idx <= 0) return false\n if (idx >= state.capacity) return false\n const archId = state.entityArchetype[idx] ?? 0\n const arch = state.archetypes[archId]\n if (!arch) return false\n if (!arch.entityRow.has(eid)) return false\n // Generation comparison: packed eid must match stored generation\n const storedGen = state.generations[idx] ?? 0\n const refGen = (eid >>> state.options.indexBits) & state.options.generationMask\n return storedGen === refGen\n}\n\n/**\n * Extract the index portion of a packed entity ID.\n *\n * Uses the default 24-bit index layout. If you created the world with a\n * non-default `indexBits`, use `EntityRef` + `deref` instead.\n */\nexport function getEntityIndex(eid: EntityId): number {\n return (eid as number) & DEFAULT_INDEX_MASK\n}\n\n/**\n * Extract the generation portion of a packed entity ID.\n *\n * Uses the default 8-bit generation layout. If you created the world with a\n * non-default `generationBits`, use `EntityRef` + `deref` instead.\n */\nexport function getEntityGeneration(eid: EntityId): number {\n return ((eid as number) >>> DEFAULT_INDEX_BITS) & DEFAULT_GENERATION_MASK\n}\n\n/**\n * Pack an index and generation into an EntityId using the default 24/8 bit layout.\n *\n * Uses the default `indexBits=24, generationBits=8`. If you created the world\n * with non-default bit sizes, this will produce values with incorrect layout.\n * Use `EntityRef` and `deref` for portable cross-world identity matching.\n */\nexport function packEntity(index: number, generation: number): EntityId {\n // `>>> 0` normalises to unsigned — see packEid. Keeps EntityId a non-negative int32.\n return ((((generation & DEFAULT_GENERATION_MASK) << DEFAULT_INDEX_BITS) |\n (index & DEFAULT_INDEX_MASK)) >>>\n 0) as EntityId\n}\n\nexport function isEntity(world: World, x: unknown): x is EntityId {\n if (typeof x !== 'number') return false\n return entityExists(world, x as EntityId)\n}\n\n// --- Lazy loaders to break import cycles ---\n\ninterface ObserversAPI {\n dispatchDestroyObservers(state: WorldState, eid: EntityId): void\n}\nlet _observersAPI: ObserversAPI | null = null\nexport function registerObserversAPI(api: ObserversAPI): void {\n _observersAPI = api\n}\nfunction lazyObservers(): ObserversAPI {\n if (!_observersAPI) {\n return { dispatchDestroyObservers: () => {} }\n }\n return _observersAPI\n}\n\nlet _relationsCleanup: ((state: WorldState, eid: EntityId) => void) | null = null\nexport function registerRelationsCleanup(fn: (state: WorldState, eid: EntityId) => void): void {\n _relationsCleanup = fn\n}\nfunction cleanupRelationsOnDestroy(state: WorldState, eid: EntityId): void {\n if (_relationsCleanup) _relationsCleanup(state, eid)\n}\n"]}