aiecsjs 0.2.0 → 0.3.0

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.
package/api.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://yshengliao.github.io/aiecsjs/api-schema.json",
3
3
  "name": "aiecsjs",
4
- "version": "0.1.0",
4
+ "version": "0.3.0",
5
5
  "generated": "2026-05-27",
6
6
  "stability": "experimental",
7
7
  "license": "MIT",
@@ -12,14 +12,43 @@
12
12
  "name": "aiecsjs",
13
13
  "description": "Core entry point — world, entity, component, query, system, utilities.",
14
14
  "exports": [
15
- "createWorld", "disposeWorld", "destroyWorld", "resetWorld", "getWorldSize", "getWorldCapacity",
16
- "createEntity", "destroyEntity", "entityExists", "getEntityIndex", "getEntityGeneration", "packEntity",
17
- "defineComponent", "defineTag", "defineObjectComponent",
18
- "addComponent", "removeComponent", "hasComponent", "getComponent", "setComponent",
15
+ "createWorld",
16
+ "disposeWorld",
17
+ "destroyWorld",
18
+ "resetWorld",
19
+ "getWorldSize",
20
+ "getWorldCapacity",
21
+ "createEntity",
22
+ "destroyEntity",
23
+ "entityExists",
24
+ "getEntityIndex",
25
+ "getEntityGeneration",
26
+ "packEntity",
27
+ "defineComponent",
28
+ "defineTag",
29
+ "defineObjectComponent",
30
+ "addComponent",
31
+ "removeComponent",
32
+ "hasComponent",
33
+ "getComponent",
34
+ "setComponent",
19
35
  "Types",
20
- "defineQuery", "runQuery", "forEachEntity", "iterQuery", "enterQuery", "exitQuery", "queryArchetypes",
36
+ "defineQuery",
37
+ "runQuery",
38
+ "forEachEntity",
39
+ "iterQuery",
40
+ "enterQuery",
41
+ "exitQuery",
42
+ "queryArchetypes",
21
43
  "pipe",
22
- "VERSION", "IS_SAB_SUPPORTED", "isWorld", "isEntity"
44
+ "VERSION",
45
+ "IS_SAB_SUPPORTED",
46
+ "isWorld",
47
+ "isEntity",
48
+ "refOf",
49
+ "deref",
50
+ "aliveRef",
51
+ "EntityNotAliveError"
23
52
  ]
24
53
  },
25
54
  {
@@ -40,7 +69,13 @@
40
69
  {
41
70
  "name": "aiecsjs/serialize",
42
71
  "description": "Binary, JSON, and delta serialization.",
43
- "exports": ["serializeWorld", "deserializeWorld", "toJSON", "fromJSON", "createDeltaSerializer"]
72
+ "exports": [
73
+ "serializeWorld",
74
+ "deserializeWorld",
75
+ "toJSON",
76
+ "fromJSON",
77
+ "createDeltaSerializer"
78
+ ]
44
79
  },
45
80
  {
46
81
  "name": "aiecsjs/worker",
@@ -50,7 +85,13 @@
50
85
  {
51
86
  "name": "aiecsjs/relations",
52
87
  "description": "Entity relations and hierarchies (experimental, target 0.2).",
53
- "exports": ["defineRelation", "addRelation", "removeRelation", "getRelationTargets", "ChildOf"]
88
+ "exports": [
89
+ "defineRelation",
90
+ "addRelation",
91
+ "removeRelation",
92
+ "getRelationTargets",
93
+ "ChildOf"
94
+ ]
54
95
  }
55
96
  ],
56
97
  "exports": [
@@ -71,11 +112,20 @@
71
112
  "description": "Configuration; all fields have defaults. See WorldOptions type."
72
113
  }
73
114
  ],
74
- "returns": { "type": "World", "description": "Opaque world handle passed to all other API calls." },
115
+ "returns": {
116
+ "type": "World",
117
+ "description": "Opaque world handle passed to all other API calls."
118
+ },
75
119
  "examples": [
76
120
  { "title": "Minimal world", "code": "const world = createWorld()" },
77
- { "title": "Pre-allocated capacity", "code": "const world = createWorld({ initialCapacity: 16384 })" },
78
- { "title": "SAB-backed world", "code": "const world = createWorld({ buffer: new SharedArrayBuffer(64*1024*1024) })" }
121
+ {
122
+ "title": "Pre-allocated capacity",
123
+ "code": "const world = createWorld({ initialCapacity: 16384 })"
124
+ },
125
+ {
126
+ "title": "SAB-backed world",
127
+ "code": "const world = createWorld({ buffer: new SharedArrayBuffer(64*1024*1024) })"
128
+ }
79
129
  ],
80
130
  "seeAlso": ["destroyWorld", "resetWorld", "WorldOptions"]
81
131
  },
@@ -90,9 +140,16 @@
90
140
  "replacedBy": "disposeWorld",
91
141
  "signature": "function destroyWorld(world: World): void",
92
142
  "summary": "Release all internal buffers; the world reference becomes invalid. Use `disposeWorld` in new code; this alias is retained for backwards compatibility and is scheduled for removal in 1.0.",
93
- "params": [{ "name": "world", "type": "World", "optional": false, "description": "World to destroy." }],
143
+ "params": [
144
+ { "name": "world", "type": "World", "optional": false, "description": "World to destroy." }
145
+ ],
94
146
  "returns": { "type": "void", "description": "" },
95
- "examples": [{ "title": "Cleanup (deprecated form)", "code": "destroyWorld(world) // prefer disposeWorld(world)" }],
147
+ "examples": [
148
+ {
149
+ "title": "Cleanup (deprecated form)",
150
+ "code": "destroyWorld(world) // prefer disposeWorld(world)"
151
+ }
152
+ ],
96
153
  "seeAlso": ["disposeWorld", "createWorld", "resetWorld"]
97
154
  },
98
155
  {
@@ -104,7 +161,9 @@
104
161
  "deprecated": false,
105
162
  "signature": "function disposeWorld(world: World): void",
106
163
  "summary": "Release all internal buffers; the world reference becomes invalid. Aligns with the ai*js ecosystem `dispose()` convention (aifsmjs Runtime, aibridgejs Bridge).",
107
- "params": [{ "name": "world", "type": "World", "optional": false, "description": "World to dispose." }],
164
+ "params": [
165
+ { "name": "world", "type": "World", "optional": false, "description": "World to dispose." }
166
+ ],
108
167
  "returns": { "type": "void", "description": "" },
109
168
  "examples": [{ "title": "Cleanup", "code": "disposeWorld(world)" }],
110
169
  "seeAlso": ["createWorld", "resetWorld"]
@@ -118,9 +177,16 @@
118
177
  "deprecated": false,
119
178
  "signature": "function resetWorld(world: World): void",
120
179
  "summary": "Wipe entities and components but keep the world allocated. Useful for hot module reload.",
121
- "params": [{ "name": "world", "type": "World", "optional": false, "description": "World to reset." }],
180
+ "params": [
181
+ { "name": "world", "type": "World", "optional": false, "description": "World to reset." }
182
+ ],
122
183
  "returns": { "type": "void", "description": "" },
123
- "examples": [{ "title": "Reset for HMR", "code": "if (import.meta.hot) import.meta.hot.dispose(() => resetWorld(world))" }],
184
+ "examples": [
185
+ {
186
+ "title": "Reset for HMR",
187
+ "code": "if (import.meta.hot) import.meta.hot.dispose(() => resetWorld(world))"
188
+ }
189
+ ],
124
190
  "seeAlso": ["createWorld", "destroyWorld"]
125
191
  },
126
192
  {
@@ -132,9 +198,13 @@
132
198
  "deprecated": false,
133
199
  "signature": "function getWorldSize(world: World): number",
134
200
  "summary": "Number of alive entities in the world.",
135
- "params": [{ "name": "world", "type": "World", "optional": false, "description": "Target world." }],
201
+ "params": [
202
+ { "name": "world", "type": "World", "optional": false, "description": "Target world." }
203
+ ],
136
204
  "returns": { "type": "number", "description": "Alive entity count." },
137
- "examples": [{ "title": "Status print", "code": "console.log('alive:', getWorldSize(world))" }],
205
+ "examples": [
206
+ { "title": "Status print", "code": "console.log('alive:', getWorldSize(world))" }
207
+ ],
138
208
  "seeAlso": ["getWorldCapacity"]
139
209
  },
140
210
  {
@@ -146,7 +216,9 @@
146
216
  "deprecated": false,
147
217
  "signature": "function getWorldCapacity(world: World): number",
148
218
  "summary": "Current upper bound on entity slot count. May grow if maxEntities allows.",
149
- "params": [{ "name": "world", "type": "World", "optional": false, "description": "Target world." }],
219
+ "params": [
220
+ { "name": "world", "type": "World", "optional": false, "description": "Target world." }
221
+ ],
150
222
  "returns": { "type": "number", "description": "Capacity." },
151
223
  "examples": [],
152
224
  "seeAlso": ["getWorldSize", "WorldOptions"]
@@ -160,8 +232,13 @@
160
232
  "deprecated": false,
161
233
  "signature": "function createEntity(world: World): EntityId",
162
234
  "summary": "Allocate a fresh entity. Returns a versioned 32-bit ID.",
163
- "params": [{ "name": "world", "type": "World", "optional": false, "description": "Target world." }],
164
- "returns": { "type": "EntityId", "description": "Branded number containing index + generation." },
235
+ "params": [
236
+ { "name": "world", "type": "World", "optional": false, "description": "Target world." }
237
+ ],
238
+ "returns": {
239
+ "type": "EntityId",
240
+ "description": "Branded number containing index + generation."
241
+ },
165
242
  "throws": [{ "type": "Error", "when": "world has reached maxEntities cap." }],
166
243
  "examples": [{ "title": "Spawn one entity", "code": "const e = createEntity(world)" }],
167
244
  "seeAlso": ["destroyEntity", "entityExists", "packEntity"]
@@ -177,10 +254,20 @@
177
254
  "summary": "Remove all components, bump generation, free slot.",
178
255
  "params": [
179
256
  { "name": "world", "type": "World", "optional": false, "description": "Target world." },
180
- { "name": "eid", "type": "EntityId", "optional": false, "description": "Entity to destroy." }
257
+ {
258
+ "name": "eid",
259
+ "type": "EntityId",
260
+ "optional": false,
261
+ "description": "Entity to destroy."
262
+ }
181
263
  ],
182
264
  "returns": { "type": "void", "description": "" },
183
- "examples": [{ "title": "Cleanup dead entity", "code": "if (entityExists(world, e)) destroyEntity(world, e)" }],
265
+ "examples": [
266
+ {
267
+ "title": "Cleanup dead entity",
268
+ "code": "if (entityExists(world, e)) destroyEntity(world, e)"
269
+ }
270
+ ],
184
271
  "seeAlso": ["createEntity", "entityExists"]
185
272
  },
186
273
  {
@@ -209,7 +296,9 @@
209
296
  "deprecated": false,
210
297
  "signature": "function getEntityIndex(eid: EntityId): number",
211
298
  "summary": "Extract the index portion of a packed entity ID.",
212
- "params": [{ "name": "eid", "type": "EntityId", "optional": false, "description": "Packed entity ID." }],
299
+ "params": [
300
+ { "name": "eid", "type": "EntityId", "optional": false, "description": "Packed entity ID." }
301
+ ],
213
302
  "returns": { "type": "number", "description": "Index in [0, 2^indexBits)." },
214
303
  "examples": [],
215
304
  "seeAlso": ["getEntityGeneration", "packEntity"]
@@ -218,32 +307,52 @@
218
307
  "name": "getEntityGeneration",
219
308
  "kind": "function",
220
309
  "module": "aiecsjs",
221
- "since": "0.1.0",
222
- "stability": "experimental",
310
+ "since": "0.3.0",
311
+ "stability": "stable",
223
312
  "deprecated": false,
224
313
  "signature": "function getEntityGeneration(eid: EntityId): number",
225
- "summary": "Returns 0 in 0.x — generation is tracked internally for slot reuse but not encoded in the EntityId. Real generation reads land with ABA-safe `EntityRef` in 0.3+.",
226
- "params": [{ "name": "eid", "type": "EntityId", "optional": false, "description": "Packed entity ID." }],
227
- "returns": { "type": "number", "description": "Generation; always 0 in 0.1." },
228
- "examples": [],
229
- "seeAlso": ["getEntityIndex", "packEntity"]
314
+ "summary": "Extract the generation portion of a packed entity ID. Uses default 8-bit generation layout. For non-default `createWorld({ generationBits })`, use `EntityRef` + `deref` instead.",
315
+ "params": [
316
+ { "name": "eid", "type": "EntityId", "optional": false, "description": "Packed entity ID." }
317
+ ],
318
+ "returns": { "type": "number", "description": "Generation in [0, 2^generationBits)." },
319
+ "examples": [
320
+ {
321
+ "title": "Round-trip with packEntity",
322
+ "code": "const gen = getEntityGeneration(packEntity(42, 5)) // 5"
323
+ }
324
+ ],
325
+ "seeAlso": ["getEntityIndex", "packEntity", "refOf"]
230
326
  },
231
327
  {
232
328
  "name": "packEntity",
233
329
  "kind": "function",
234
330
  "module": "aiecsjs",
235
- "since": "0.1.0",
236
- "stability": "experimental",
331
+ "since": "0.3.0",
332
+ "stability": "stable",
237
333
  "deprecated": false,
238
334
  "signature": "function packEntity(index: number, generation: number): EntityId",
239
- "summary": "Identity helper in 0.x — returns `index` unchanged because EntityId is a bare slot index. Real packing lands with ABA-safe `EntityRef` in 0.3+.",
335
+ "summary": "Pack an index and generation into an EntityId using default 24/8 bit layout. For non-default `createWorld({ indexBits, generationBits })`, use `EntityRef` + `deref` instead.",
240
336
  "params": [
241
337
  { "name": "index", "type": "number", "optional": false, "description": "Entity index." },
242
- { "name": "generation", "type": "number", "optional": false, "description": "Entity generation (ignored in 0.1)." }
338
+ {
339
+ "name": "generation",
340
+ "type": "number",
341
+ "optional": false,
342
+ "description": "Entity generation."
343
+ }
243
344
  ],
244
- "returns": { "type": "EntityId", "description": "In 0.1 this equals `index`." },
245
- "examples": [],
246
- "seeAlso": ["getEntityIndex", "getEntityGeneration"]
345
+ "returns": {
346
+ "type": "EntityId",
347
+ "description": "Packed value: `(generation << 24) | index`."
348
+ },
349
+ "examples": [
350
+ {
351
+ "title": "Pack and unpack",
352
+ "code": "const eid = packEntity(42, 5); getEntityIndex(eid) // 42"
353
+ }
354
+ ],
355
+ "seeAlso": ["getEntityIndex", "getEntityGeneration", "refOf"]
247
356
  },
248
357
  {
249
358
  "name": "defineComponent",
@@ -262,10 +371,19 @@
262
371
  "description": "Map of field name → field type. Field type is a member of Types, or [type, vectorLength] for fixed-size vectors."
263
372
  }
264
373
  ],
265
- "returns": { "type": "SoAComponent<S>", "description": "Component handle used in addComponent/getComponent/etc." },
374
+ "returns": {
375
+ "type": "SoAComponent<S>",
376
+ "description": "Component handle used in addComponent/getComponent/etc."
377
+ },
266
378
  "examples": [
267
- { "title": "Position with two scalars", "code": "const Position = defineComponent({ x: Types.f32, y: Types.f32 })" },
268
- { "title": "Transform with vector field", "code": "const Transform = defineComponent({ pos: [Types.f32, 3], scale: Types.f32 })" }
379
+ {
380
+ "title": "Position with two scalars",
381
+ "code": "const Position = defineComponent({ x: Types.f32, y: Types.f32 })"
382
+ },
383
+ {
384
+ "title": "Transform with vector field",
385
+ "code": "const Transform = defineComponent({ pos: [Types.f32, 3], scale: Types.f32 })"
386
+ }
269
387
  ],
270
388
  "seeAlso": ["defineTag", "defineObjectComponent", "Types", "addComponent"]
271
389
  },
@@ -302,7 +420,10 @@
302
420
  ],
303
421
  "returns": { "type": "AoSComponent<T>", "description": "AoS component handle." },
304
422
  "examples": [
305
- { "title": "Reference to a Three.js mesh", "code": "const MeshRef = defineObjectComponent<{ mesh: any }>(() => ({ mesh: null }))" }
423
+ {
424
+ "title": "Reference to a Three.js mesh",
425
+ "code": "const MeshRef = defineObjectComponent<{ mesh: any }>(() => ({ mesh: null }))"
426
+ }
306
427
  ],
307
428
  "seeAlso": ["defineComponent", "setComponent", "getComponent"]
308
429
  },
@@ -317,9 +438,24 @@
317
438
  "summary": "Attach a component to an entity. Argument order is (world, eid, component, init) — different from bitECS.",
318
439
  "params": [
319
440
  { "name": "world", "type": "World", "optional": false, "description": "Target world." },
320
- { "name": "eid", "type": "EntityId", "optional": false, "description": "Entity to attach to." },
321
- { "name": "component", "type": "ComponentLike", "optional": false, "description": "Component handle." },
322
- { "name": "initial", "type": "Partial<...> | undefined", "optional": true, "description": "Initial values; shape depends on component kind." }
441
+ {
442
+ "name": "eid",
443
+ "type": "EntityId",
444
+ "optional": false,
445
+ "description": "Entity to attach to."
446
+ },
447
+ {
448
+ "name": "component",
449
+ "type": "ComponentLike",
450
+ "optional": false,
451
+ "description": "Component handle."
452
+ },
453
+ {
454
+ "name": "initial",
455
+ "type": "Partial<...> | undefined",
456
+ "optional": true,
457
+ "description": "Initial values; shape depends on component kind."
458
+ }
323
459
  ],
324
460
  "returns": { "type": "void", "description": "" },
325
461
  "throws": [
@@ -327,7 +463,10 @@
327
463
  { "type": "Error", "when": "eid does not exist (dev mode only)." }
328
464
  ],
329
465
  "examples": [
330
- { "title": "Add SoA component with init", "code": "addComponent(world, e, Position, { x: 10, y: 20 })" },
466
+ {
467
+ "title": "Add SoA component with init",
468
+ "code": "addComponent(world, e, Position, { x: 10, y: 20 })"
469
+ },
331
470
  { "title": "Add tag", "code": "addComponent(world, e, Player)" }
332
471
  ],
333
472
  "seeAlso": ["removeComponent", "hasComponent", "getComponent", "setComponent"]
@@ -343,8 +482,18 @@
343
482
  "summary": "Detach a component from an entity. Triggers archetype migration.",
344
483
  "params": [
345
484
  { "name": "world", "type": "World", "optional": false, "description": "Target world." },
346
- { "name": "eid", "type": "EntityId", "optional": false, "description": "Entity to detach from." },
347
- { "name": "component", "type": "ComponentLike", "optional": false, "description": "Component handle." }
485
+ {
486
+ "name": "eid",
487
+ "type": "EntityId",
488
+ "optional": false,
489
+ "description": "Entity to detach from."
490
+ },
491
+ {
492
+ "name": "component",
493
+ "type": "ComponentLike",
494
+ "optional": false,
495
+ "description": "Component handle."
496
+ }
348
497
  ],
349
498
  "returns": { "type": "void", "description": "" },
350
499
  "examples": [],
@@ -362,7 +511,12 @@
362
511
  "params": [
363
512
  { "name": "world", "type": "World", "optional": false, "description": "Target world." },
364
513
  { "name": "eid", "type": "EntityId", "optional": false, "description": "Entity to test." },
365
- { "name": "component", "type": "ComponentLike", "optional": false, "description": "Component handle." }
514
+ {
515
+ "name": "component",
516
+ "type": "ComponentLike",
517
+ "optional": false,
518
+ "description": "Component handle."
519
+ }
366
520
  ],
367
521
  "returns": { "type": "boolean", "description": "Presence flag." },
368
522
  "examples": [],
@@ -380,11 +534,22 @@
380
534
  "params": [
381
535
  { "name": "world", "type": "World", "optional": false, "description": "Target world." },
382
536
  { "name": "eid", "type": "EntityId", "optional": false, "description": "Entity to read." },
383
- { "name": "component", "type": "ComponentLike", "optional": false, "description": "Component handle." }
537
+ {
538
+ "name": "component",
539
+ "type": "ComponentLike",
540
+ "optional": false,
541
+ "description": "Component handle."
542
+ }
384
543
  ],
385
- "returns": { "type": "ComponentView<C>", "description": "Column map (SoA) or per-entity object (AoS)." },
544
+ "returns": {
545
+ "type": "ComponentView<C>",
546
+ "description": "Column map (SoA) or per-entity object (AoS)."
547
+ },
386
548
  "examples": [
387
- { "title": "Read SoA value", "code": "const pos = getComponent(world, e, Position); console.log(pos.x[e], pos.y[e])" }
549
+ {
550
+ "title": "Read SoA value",
551
+ "code": "const pos = getComponent(world, e, Position); console.log(pos.x[e], pos.y[e])"
552
+ }
388
553
  ],
389
554
  "seeAlso": ["setComponent", "hasComponent"]
390
555
  },
@@ -400,7 +565,12 @@
400
565
  "params": [
401
566
  { "name": "world", "type": "World", "optional": false, "description": "Target world." },
402
567
  { "name": "eid", "type": "EntityId", "optional": false, "description": "Entity to write." },
403
- { "name": "component", "type": "ComponentLike", "optional": false, "description": "Component handle." },
568
+ {
569
+ "name": "component",
570
+ "type": "ComponentLike",
571
+ "optional": false,
572
+ "description": "Component handle."
573
+ },
404
574
  { "name": "value", "type": "V", "optional": false, "description": "New values." }
405
575
  ],
406
576
  "returns": { "type": "void", "description": "" },
@@ -430,7 +600,10 @@
430
600
  "throws": [{ "type": "TypeError", "when": "any descriptor argument is not a Component." }],
431
601
  "examples": [
432
602
  { "title": "Shorthand all-of", "code": "const movers = defineQuery([Position, Velocity])" },
433
- { "title": "Full descriptor with exclusions", "code": "const visibleEnemies = defineQuery({ all: [Position, Sprite, Enemy], none: [Hidden] })" }
603
+ {
604
+ "title": "Full descriptor with exclusions",
605
+ "code": "const visibleEnemies = defineQuery({ all: [Position, Sprite, Enemy], none: [Hidden] })"
606
+ }
434
607
  ],
435
608
  "seeAlso": ["runQuery", "forEachEntity", "iterQuery", "enterQuery", "exitQuery"]
436
609
  },
@@ -463,7 +636,12 @@
463
636
  "params": [
464
637
  { "name": "world", "type": "World", "optional": false, "description": "Target world." },
465
638
  { "name": "query", "type": "Query", "optional": false, "description": "Query handle." },
466
- { "name": "fn", "type": "(eid, ...columns) => void", "optional": false, "description": "Per-entity callback. Receives eid then component column views in declaration order." }
639
+ {
640
+ "name": "fn",
641
+ "type": "(eid, ...columns) => void",
642
+ "optional": false,
643
+ "description": "Per-entity callback. Receives eid then component column views in declaration order."
644
+ }
467
645
  ],
468
646
  "returns": { "type": "void", "description": "" },
469
647
  "examples": [
@@ -488,7 +666,9 @@
488
666
  { "name": "query", "type": "Query", "optional": false, "description": "Query handle." }
489
667
  ],
490
668
  "returns": { "type": "IterableIterator<EntityId>", "description": "Iterator." },
491
- "examples": [{ "title": "for...of usage", "code": "for (const e of iterQuery(world, q)) { /* ... */ }" }],
669
+ "examples": [
670
+ { "title": "for...of usage", "code": "for (const e of iterQuery(world, q)) { /* ... */ }" }
671
+ ],
492
672
  "seeAlso": ["forEachEntity"]
493
673
  },
494
674
  {
@@ -500,9 +680,13 @@
500
680
  "deprecated": false,
501
681
  "signature": "function enterQuery(query: Query): Query",
502
682
  "summary": "Reactive query that yields only entities newly matching this frame.",
503
- "params": [{ "name": "query", "type": "Query", "optional": false, "description": "Source query." }],
683
+ "params": [
684
+ { "name": "query", "type": "Query", "optional": false, "description": "Source query." }
685
+ ],
504
686
  "returns": { "type": "Query", "description": "Reactive query handle." },
505
- "examples": [{ "title": "Mount-on-enter", "code": "const becameVisible = enterQuery(visibleQ)" }],
687
+ "examples": [
688
+ { "title": "Mount-on-enter", "code": "const becameVisible = enterQuery(visibleQ)" }
689
+ ],
506
690
  "seeAlso": ["exitQuery", "defineQuery"]
507
691
  },
508
692
  {
@@ -514,7 +698,9 @@
514
698
  "deprecated": false,
515
699
  "signature": "function exitQuery(query: Query): Query",
516
700
  "summary": "Reactive query that yields only entities that left the match this frame.",
517
- "params": [{ "name": "query", "type": "Query", "optional": false, "description": "Source query." }],
701
+ "params": [
702
+ { "name": "query", "type": "Query", "optional": false, "description": "Source query." }
703
+ ],
518
704
  "returns": { "type": "Query", "description": "Reactive query handle." },
519
705
  "examples": [],
520
706
  "seeAlso": ["enterQuery", "defineQuery"]
@@ -533,7 +719,12 @@
533
719
  { "name": "query", "type": "Query", "optional": false, "description": "Query handle." }
534
720
  ],
535
721
  "returns": { "type": "readonly Archetype[]", "description": "Archetype handles." },
536
- "examples": [{ "title": "Per-archetype upload", "code": "for (const a of queryArchetypes(world, q)) { /* a.size, a.mask */ }" }],
722
+ "examples": [
723
+ {
724
+ "title": "Per-archetype upload",
725
+ "code": "for (const a of queryArchetypes(world, q)) { /* a.size, a.mask */ }"
726
+ }
727
+ ],
537
728
  "seeAlso": ["defineQuery"]
538
729
  },
539
730
  {
@@ -545,10 +736,20 @@
545
736
  "deprecated": false,
546
737
  "signature": "function pipe<W extends World, Ctx>(...systems: System<W, Ctx>[]): System<W, Ctx>",
547
738
  "summary": "Compose systems left-to-right. Associative; always returns the same World reference.",
548
- "params": [{ "name": "systems", "type": "System<W, Ctx>[]", "optional": false, "description": "Systems to compose." }],
739
+ "params": [
740
+ {
741
+ "name": "systems",
742
+ "type": "System<W, Ctx>[]",
743
+ "optional": false,
744
+ "description": "Systems to compose."
745
+ }
746
+ ],
549
747
  "returns": { "type": "System<W, Ctx>", "description": "Composed system." },
550
748
  "examples": [
551
- { "title": "Frame tick", "code": "const tick = pipe(input, physics, render); tick(world, dt)" }
749
+ {
750
+ "title": "Frame tick",
751
+ "code": "const tick = pipe(input, physics, render); tick(world, dt)"
752
+ }
552
753
  ],
553
754
  "seeAlso": ["createLoop"]
554
755
  },
@@ -561,10 +762,20 @@
561
762
  "deprecated": false,
562
763
  "signature": "function createLoop(options: LoopOptions): { start(): void; stop(): void }",
563
764
  "summary": "Fixed-timestep accumulator loop. Calls onUpdate with constant dt; onRender once per animation frame with an interpolation alpha.",
564
- "params": [{ "name": "options", "type": "LoopOptions", "optional": false, "description": "Loop configuration." }],
765
+ "params": [
766
+ {
767
+ "name": "options",
768
+ "type": "LoopOptions",
769
+ "optional": false,
770
+ "description": "Loop configuration."
771
+ }
772
+ ],
565
773
  "returns": { "type": "{ start(), stop() }", "description": "Loop control handle." },
566
774
  "examples": [
567
- { "title": "60Hz loop", "code": "const loop = createLoop({ fixed: 1/60, onUpdate: dt => tick(world, dt) }); loop.start()" }
775
+ {
776
+ "title": "60Hz loop",
777
+ "code": "const loop = createLoop({ fixed: 1/60, onUpdate: dt => tick(world, dt) }); loop.start()"
778
+ }
568
779
  ],
569
780
  "seeAlso": ["pipe"]
570
781
  },
@@ -577,8 +788,13 @@
577
788
  "deprecated": false,
578
789
  "signature": "function createCommandBuffer(world: World): CommandBuffer",
579
790
  "summary": "Create a buffer that queues structural mutations until flushed.",
580
- "params": [{ "name": "world", "type": "World", "optional": false, "description": "Target world." }],
581
- "returns": { "type": "CommandBuffer", "description": "Buffer with add/remove/destroy/create methods." },
791
+ "params": [
792
+ { "name": "world", "type": "World", "optional": false, "description": "Target world." }
793
+ ],
794
+ "returns": {
795
+ "type": "CommandBuffer",
796
+ "description": "Buffer with add/remove/destroy/create methods."
797
+ },
582
798
  "examples": [],
583
799
  "seeAlso": ["flush", "withCommandBuffer"]
584
800
  },
@@ -591,7 +807,14 @@
591
807
  "deprecated": false,
592
808
  "signature": "function flush(cb: CommandBuffer): void",
593
809
  "summary": "Apply all queued operations to the world.",
594
- "params": [{ "name": "cb", "type": "CommandBuffer", "optional": false, "description": "Buffer to flush." }],
810
+ "params": [
811
+ {
812
+ "name": "cb",
813
+ "type": "CommandBuffer",
814
+ "optional": false,
815
+ "description": "Buffer to flush."
816
+ }
817
+ ],
595
818
  "returns": { "type": "void", "description": "" },
596
819
  "examples": [],
597
820
  "seeAlso": ["createCommandBuffer", "withCommandBuffer"]
@@ -607,11 +830,19 @@
607
830
  "summary": "Scoped command buffer; auto-flushes at end of callback. Forwards the return value.",
608
831
  "params": [
609
832
  { "name": "world", "type": "World", "optional": false, "description": "Target world." },
610
- { "name": "fn", "type": "(cb: CommandBuffer) => R", "optional": false, "description": "Callback receiving the buffer." }
833
+ {
834
+ "name": "fn",
835
+ "type": "(cb: CommandBuffer) => R",
836
+ "optional": false,
837
+ "description": "Callback receiving the buffer."
838
+ }
611
839
  ],
612
840
  "returns": { "type": "R", "description": "Whatever the callback returned." },
613
841
  "examples": [
614
- { "title": "Safe destroy in iter", "code": "withCommandBuffer(world, cb => { forEachEntity(world, dying, e => cb.destroy(e)) })" }
842
+ {
843
+ "title": "Safe destroy in iter",
844
+ "code": "withCommandBuffer(world, cb => { forEachEntity(world, dying, e => cb.destroy(e)) })"
845
+ }
615
846
  ],
616
847
  "seeAlso": ["createCommandBuffer"]
617
848
  },
@@ -627,9 +858,24 @@
627
858
  "params": [
628
859
  { "name": "world", "type": "World", "optional": false, "description": "Target world." },
629
860
  { "name": "query", "type": "Query", "optional": false, "description": "Query handle." },
630
- { "name": "event", "type": "'add'|'remove'|'set'", "optional": false, "description": "Event kind." },
631
- { "name": "handler", "type": "(eid) => void", "optional": false, "description": "Callback." },
632
- { "name": "opts", "type": "ObserverOptions", "optional": true, "description": "Optional `{ signal?: AbortSignal }`. Added in 0.2.0." }
861
+ {
862
+ "name": "event",
863
+ "type": "'add'|'remove'|'set'",
864
+ "optional": false,
865
+ "description": "Event kind."
866
+ },
867
+ {
868
+ "name": "handler",
869
+ "type": "(eid) => void",
870
+ "optional": false,
871
+ "description": "Callback."
872
+ },
873
+ {
874
+ "name": "opts",
875
+ "type": "ObserverOptions",
876
+ "optional": true,
877
+ "description": "Optional `{ signal?: AbortSignal }`. Added in 0.2.0."
878
+ }
633
879
  ],
634
880
  "returns": { "type": "() => void", "description": "Disposer." },
635
881
  "examples": [],
@@ -646,9 +892,24 @@
646
892
  "summary": "Listen for component-add events on a specific component. `opts.signal` (since 0.2.0) auto-unsubscribes when aborted.",
647
893
  "params": [
648
894
  { "name": "world", "type": "World", "optional": false, "description": "Target world." },
649
- { "name": "component", "type": "ComponentLike", "optional": false, "description": "Component handle." },
650
- { "name": "handler", "type": "(eid) => void", "optional": false, "description": "Callback." },
651
- { "name": "opts", "type": "ObserverOptions", "optional": true, "description": "Optional `{ signal?: AbortSignal }`. Added in 0.2.0." }
895
+ {
896
+ "name": "component",
897
+ "type": "ComponentLike",
898
+ "optional": false,
899
+ "description": "Component handle."
900
+ },
901
+ {
902
+ "name": "handler",
903
+ "type": "(eid) => void",
904
+ "optional": false,
905
+ "description": "Callback."
906
+ },
907
+ {
908
+ "name": "opts",
909
+ "type": "ObserverOptions",
910
+ "optional": true,
911
+ "description": "Optional `{ signal?: AbortSignal }`. Added in 0.2.0."
912
+ }
652
913
  ],
653
914
  "returns": { "type": "() => void", "description": "Disposer." },
654
915
  "examples": [],
@@ -665,9 +926,24 @@
665
926
  "summary": "Listen for component-remove events. `opts.signal` (since 0.2.0) auto-unsubscribes when aborted.",
666
927
  "params": [
667
928
  { "name": "world", "type": "World", "optional": false, "description": "Target world." },
668
- { "name": "component", "type": "ComponentLike", "optional": false, "description": "Component handle." },
669
- { "name": "handler", "type": "(eid) => void", "optional": false, "description": "Callback." },
670
- { "name": "opts", "type": "ObserverOptions", "optional": true, "description": "Optional `{ signal?: AbortSignal }`. Added in 0.2.0." }
929
+ {
930
+ "name": "component",
931
+ "type": "ComponentLike",
932
+ "optional": false,
933
+ "description": "Component handle."
934
+ },
935
+ {
936
+ "name": "handler",
937
+ "type": "(eid) => void",
938
+ "optional": false,
939
+ "description": "Callback."
940
+ },
941
+ {
942
+ "name": "opts",
943
+ "type": "ObserverOptions",
944
+ "optional": true,
945
+ "description": "Optional `{ signal?: AbortSignal }`. Added in 0.2.0."
946
+ }
671
947
  ],
672
948
  "returns": { "type": "() => void", "description": "Disposer." },
673
949
  "examples": [],
@@ -685,8 +961,18 @@
685
961
  "params": [
686
962
  { "name": "world", "type": "World", "optional": false, "description": "Target world." },
687
963
  { "name": "component", "type": "C", "optional": false, "description": "Component handle." },
688
- { "name": "handler", "type": "(eid, value) => void", "optional": false, "description": "Callback receiving the new value." },
689
- { "name": "opts", "type": "ObserverOptions", "optional": true, "description": "Optional `{ signal?: AbortSignal }`. Added in 0.2.0." }
964
+ {
965
+ "name": "handler",
966
+ "type": "(eid, value) => void",
967
+ "optional": false,
968
+ "description": "Callback receiving the new value."
969
+ },
970
+ {
971
+ "name": "opts",
972
+ "type": "ObserverOptions",
973
+ "optional": true,
974
+ "description": "Optional `{ signal?: AbortSignal }`. Added in 0.2.0."
975
+ }
690
976
  ],
691
977
  "returns": { "type": "() => void", "description": "Disposer." },
692
978
  "examples": [],
@@ -703,7 +989,12 @@
703
989
  "summary": "Produce a versioned binary snapshot of the world.",
704
990
  "params": [
705
991
  { "name": "world", "type": "World", "optional": false, "description": "Target world." },
706
- { "name": "options", "type": "SerializeOptions", "optional": true, "description": "Restrict to a component subset." }
992
+ {
993
+ "name": "options",
994
+ "type": "SerializeOptions",
995
+ "optional": true,
996
+ "description": "Restrict to a component subset."
997
+ }
707
998
  ],
708
999
  "returns": { "type": "Uint8Array", "description": "Binary snapshot." },
709
1000
  "examples": [{ "title": "Save", "code": "const bytes = serializeWorld(world)" }],
@@ -719,8 +1010,18 @@
719
1010
  "signature": "function deserializeWorld(bytes: Uint8Array, options?: DeserializeOptions): World",
720
1011
  "summary": "Restore a world from binary bytes.",
721
1012
  "params": [
722
- { "name": "bytes", "type": "Uint8Array", "optional": false, "description": "Bytes from serializeWorld." },
723
- { "name": "options", "type": "DeserializeOptions", "optional": true, "description": "Migration behaviour for unknown versions." }
1013
+ {
1014
+ "name": "bytes",
1015
+ "type": "Uint8Array",
1016
+ "optional": false,
1017
+ "description": "Bytes from serializeWorld."
1018
+ },
1019
+ {
1020
+ "name": "options",
1021
+ "type": "DeserializeOptions",
1022
+ "optional": true,
1023
+ "description": "Migration behaviour for unknown versions."
1024
+ }
724
1025
  ],
725
1026
  "returns": { "type": "World", "description": "Restored world." },
726
1027
  "throws": [{ "type": "Error", "when": "version mismatch and onUnknownVersion is 'throw'." }],
@@ -736,7 +1037,9 @@
736
1037
  "deprecated": false,
737
1038
  "signature": "function toJSON(world: World): WorldSnapshot",
738
1039
  "summary": "Produce a human-readable JSON snapshot. Slower than serializeWorld; inspectable in DevTools.",
739
- "params": [{ "name": "world", "type": "World", "optional": false, "description": "Target world." }],
1040
+ "params": [
1041
+ { "name": "world", "type": "World", "optional": false, "description": "Target world." }
1042
+ ],
740
1043
  "returns": { "type": "WorldSnapshot", "description": "JSON-serializable object." },
741
1044
  "examples": [],
742
1045
  "seeAlso": ["fromJSON", "serializeWorld"]
@@ -750,7 +1053,14 @@
750
1053
  "deprecated": false,
751
1054
  "signature": "function fromJSON(snapshot: WorldSnapshot): World",
752
1055
  "summary": "Restore from a JSON snapshot.",
753
- "params": [{ "name": "snapshot", "type": "WorldSnapshot", "optional": false, "description": "Snapshot from toJSON." }],
1056
+ "params": [
1057
+ {
1058
+ "name": "snapshot",
1059
+ "type": "WorldSnapshot",
1060
+ "optional": false,
1061
+ "description": "Snapshot from toJSON."
1062
+ }
1063
+ ],
754
1064
  "returns": { "type": "World", "description": "Restored world." },
755
1065
  "examples": [],
756
1066
  "seeAlso": ["toJSON"]
@@ -766,11 +1076,22 @@
766
1076
  "summary": "Capture only changes since the previous capture. For network replication. Wire format may change before 1.0.",
767
1077
  "params": [
768
1078
  { "name": "world", "type": "World", "optional": false, "description": "Target world." },
769
- { "name": "options", "type": "SerializeOptions", "optional": true, "description": "Restrict to a component subset." }
1079
+ {
1080
+ "name": "options",
1081
+ "type": "SerializeOptions",
1082
+ "optional": true,
1083
+ "description": "Restrict to a component subset."
1084
+ }
770
1085
  ],
771
- "returns": { "type": "DeltaSerializer", "description": "Object with capture/apply/reset methods." },
1086
+ "returns": {
1087
+ "type": "DeltaSerializer",
1088
+ "description": "Object with capture/apply/reset methods."
1089
+ },
772
1090
  "examples": [
773
- { "title": "Send delta over WS", "code": "const tx = createDeltaSerializer(world, { components: [Position] }); setInterval(() => ws.send(tx.capture()), 50)" }
1091
+ {
1092
+ "title": "Send delta over WS",
1093
+ "code": "const tx = createDeltaSerializer(world, { components: [Position] }); setInterval(() => ws.send(tx.capture()), 50)"
1094
+ }
774
1095
  ],
775
1096
  "seeAlso": ["serializeWorld"]
776
1097
  },
@@ -783,9 +1104,13 @@
783
1104
  "deprecated": false,
784
1105
  "signature": "function transferableSnapshot(world: World): { buffer: SharedArrayBuffer; meta: WorldMeta }",
785
1106
  "summary": "Package a SAB-backed world for postMessage to a Worker.",
786
- "params": [{ "name": "world", "type": "World", "optional": false, "description": "SAB-backed world." }],
1107
+ "params": [
1108
+ { "name": "world", "type": "World", "optional": false, "description": "SAB-backed world." }
1109
+ ],
787
1110
  "returns": { "type": "TransferableSnapshot", "description": "buffer + meta to send." },
788
- "examples": [{ "title": "Send to worker", "code": "worker.postMessage(transferableSnapshot(world))" }],
1111
+ "examples": [
1112
+ { "title": "Send to worker", "code": "worker.postMessage(transferableSnapshot(world))" }
1113
+ ],
789
1114
  "seeAlso": ["adoptSnapshot", "attachWorld"]
790
1115
  },
791
1116
  {
@@ -797,8 +1122,18 @@
797
1122
  "deprecated": false,
798
1123
  "signature": "function adoptSnapshot(snap: { buffer: SharedArrayBuffer; meta: WorldMeta }): World",
799
1124
  "summary": "On the Worker side, materialise a world from a snapshot sent over postMessage.",
800
- "params": [{ "name": "snap", "type": "TransferableSnapshot", "optional": false, "description": "Snapshot received via onmessage." }],
801
- "returns": { "type": "World", "description": "Worker-side world view backed by the same SAB." },
1125
+ "params": [
1126
+ {
1127
+ "name": "snap",
1128
+ "type": "TransferableSnapshot",
1129
+ "optional": false,
1130
+ "description": "Snapshot received via onmessage."
1131
+ }
1132
+ ],
1133
+ "returns": {
1134
+ "type": "World",
1135
+ "description": "Worker-side world view backed by the same SAB."
1136
+ },
802
1137
  "examples": [],
803
1138
  "seeAlso": ["transferableSnapshot"]
804
1139
  },
@@ -812,8 +1147,18 @@
812
1147
  "signature": "function attachWorld(buffer: SharedArrayBuffer, options?: { readOnly?: boolean }): World",
813
1148
  "summary": "Attach to a SAB that was set up by another thread. Use readOnly when this thread should only read.",
814
1149
  "params": [
815
- { "name": "buffer", "type": "SharedArrayBuffer", "optional": false, "description": "Shared buffer." },
816
- { "name": "options", "type": "{ readOnly?: boolean }", "optional": true, "description": "Attach flags." }
1150
+ {
1151
+ "name": "buffer",
1152
+ "type": "SharedArrayBuffer",
1153
+ "optional": false,
1154
+ "description": "Shared buffer."
1155
+ },
1156
+ {
1157
+ "name": "options",
1158
+ "type": "{ readOnly?: boolean }",
1159
+ "optional": true,
1160
+ "description": "Attach flags."
1161
+ }
817
1162
  ],
818
1163
  "returns": { "type": "World", "description": "Attached world view." },
819
1164
  "examples": [],
@@ -828,7 +1173,9 @@
828
1173
  "deprecated": false,
829
1174
  "signature": "function detachWorld(world: World): void",
830
1175
  "summary": "Release this thread's view of a shared world. Does NOT free the SAB.",
831
- "params": [{ "name": "world", "type": "World", "optional": false, "description": "Attached world." }],
1176
+ "params": [
1177
+ { "name": "world", "type": "World", "optional": false, "description": "Attached world." }
1178
+ ],
832
1179
  "returns": { "type": "void", "description": "" },
833
1180
  "examples": [],
834
1181
  "seeAlso": ["attachWorld"]
@@ -842,10 +1189,20 @@
842
1189
  "deprecated": false,
843
1190
  "signature": "function defineRelation<T = void>(options?: { exclusive?: boolean }): Relation<T>",
844
1191
  "summary": "Declare a relation type between two entities. Documented for early feedback; implemented in 0.2.",
845
- "params": [{ "name": "options", "type": "{ exclusive?: boolean }", "optional": true, "description": "If exclusive, each source may relate to at most one target." }],
1192
+ "params": [
1193
+ {
1194
+ "name": "options",
1195
+ "type": "{ exclusive?: boolean }",
1196
+ "optional": true,
1197
+ "description": "If exclusive, each source may relate to at most one target."
1198
+ }
1199
+ ],
846
1200
  "returns": { "type": "Relation<T>", "description": "Relation handle." },
847
1201
  "examples": [
848
- { "title": "Likes relation with data", "code": "const Likes = defineRelation<{ since: number }>()" }
1202
+ {
1203
+ "title": "Likes relation with data",
1204
+ "code": "const Likes = defineRelation<{ since: number }>()"
1205
+ }
849
1206
  ],
850
1207
  "seeAlso": ["addRelation", "removeRelation", "getRelationTargets", "ChildOf"]
851
1208
  },
@@ -860,7 +1217,12 @@
860
1217
  "summary": "Add a relation edge from source to target.",
861
1218
  "params": [],
862
1219
  "returns": { "type": "void", "description": "" },
863
- "examples": [{ "title": "Mark Alice as child of Parent", "code": "addRelation(world, alice, ChildOf, parent)" }],
1220
+ "examples": [
1221
+ {
1222
+ "title": "Mark Alice as child of Parent",
1223
+ "code": "addRelation(world, alice, ChildOf, parent)"
1224
+ }
1225
+ ],
864
1226
  "seeAlso": ["defineRelation"]
865
1227
  },
866
1228
  {
@@ -918,9 +1280,115 @@
918
1280
  "returns": { "type": "boolean", "description": "Type guard." },
919
1281
  "examples": [],
920
1282
  "seeAlso": ["isWorld", "entityExists"]
1283
+ },
1284
+ {
1285
+ "name": "refOf",
1286
+ "kind": "function",
1287
+ "module": "aiecsjs",
1288
+ "since": "0.3.0",
1289
+ "stability": "stable",
1290
+ "deprecated": false,
1291
+ "signature": "function refOf<T = unknown>(world: World, entity: EntityId): EntityRef<T>",
1292
+ "summary": "Create an ABA-safe reference to a live entity. Throws EntityNotAliveError if the entity is dead or invalid.",
1293
+ "params": [
1294
+ { "name": "world", "type": "World", "optional": false, "description": "Target world." },
1295
+ {
1296
+ "name": "entity",
1297
+ "type": "EntityId",
1298
+ "optional": false,
1299
+ "description": "Live entity to wrap."
1300
+ }
1301
+ ],
1302
+ "returns": {
1303
+ "type": "EntityRef<T>",
1304
+ "description": "Frozen ref object with id and worldId."
1305
+ },
1306
+ "throws": [
1307
+ { "type": "EntityNotAliveError", "when": "entity is dead, never created, or eid === 0." }
1308
+ ],
1309
+ "examples": [
1310
+ { "title": "Create a bullet ref", "code": "const ref = refOf<'bullet'>(world, e)" }
1311
+ ],
1312
+ "seeAlso": ["deref", "aliveRef", "EntityRef", "EntityNotAliveError"]
1313
+ },
1314
+ {
1315
+ "name": "deref",
1316
+ "kind": "function",
1317
+ "module": "aiecsjs",
1318
+ "since": "0.3.0",
1319
+ "stability": "stable",
1320
+ "deprecated": false,
1321
+ "signature": "function deref<T = unknown>(world: World, ref: EntityRef<T>): EntityId | null",
1322
+ "summary": "Resolve a ref to its live EntityId, or null if stale / cross-world / OOB. Never throws.",
1323
+ "params": [
1324
+ { "name": "world", "type": "World", "optional": false, "description": "Target world." },
1325
+ {
1326
+ "name": "ref",
1327
+ "type": "EntityRef<T>",
1328
+ "optional": false,
1329
+ "description": "Ref to validate."
1330
+ }
1331
+ ],
1332
+ "returns": { "type": "EntityId | null", "description": "Live entity id, or null if stale." },
1333
+ "examples": [
1334
+ {
1335
+ "title": "Guard clause pattern",
1336
+ "code": "const live = deref(world, ref)\nif (live !== null) { /* entity is alive */ }"
1337
+ }
1338
+ ],
1339
+ "seeAlso": ["refOf", "aliveRef", "EntityRef"]
1340
+ },
1341
+ {
1342
+ "name": "aliveRef",
1343
+ "kind": "function",
1344
+ "module": "aiecsjs",
1345
+ "since": "0.3.0",
1346
+ "stability": "stable",
1347
+ "deprecated": false,
1348
+ "signature": "function aliveRef<T = unknown>(world: World, ref: EntityRef<T>): boolean",
1349
+ "summary": "Boolean guard form of deref. Returns true if ref is alive, false otherwise. Never throws.",
1350
+ "params": [
1351
+ { "name": "world", "type": "World", "optional": false, "description": "Target world." },
1352
+ { "name": "ref", "type": "EntityRef<T>", "optional": false, "description": "Ref to check." }
1353
+ ],
1354
+ "returns": { "type": "boolean", "description": "true if entity is still alive." },
1355
+ "examples": [
1356
+ { "title": "Early return pattern", "code": "if (!aliveRef(world, bulletRef)) return" }
1357
+ ],
1358
+ "seeAlso": ["refOf", "deref", "EntityRef"]
1359
+ },
1360
+ {
1361
+ "name": "EntityNotAliveError",
1362
+ "kind": "class",
1363
+ "module": "aiecsjs",
1364
+ "since": "0.3.0",
1365
+ "stability": "stable",
1366
+ "deprecated": false,
1367
+ "signature": "class EntityNotAliveError extends Error { readonly eid: number }",
1368
+ "summary": "Thrown by refOf when the entity is not alive. deref and aliveRef never throw.",
1369
+ "params": [],
1370
+ "returns": {
1371
+ "type": "EntityNotAliveError",
1372
+ "description": "Error instance with eid property."
1373
+ },
1374
+ "examples": [
1375
+ {
1376
+ "title": "Catch specific error",
1377
+ "code": "try { refOf(world, staleEid) } catch (e) { if (e instanceof EntityNotAliveError) { /* handle */ } }"
1378
+ }
1379
+ ],
1380
+ "seeAlso": ["refOf"]
921
1381
  }
922
1382
  ],
923
1383
  "types": [
1384
+ {
1385
+ "name": "EntityRef",
1386
+ "kind": "type",
1387
+ "module": "aiecsjs",
1388
+ "since": "0.3.0",
1389
+ "stability": "stable",
1390
+ "definition": "interface EntityRef<T = unknown> { readonly id: EntityId; readonly worldId: number; readonly __phantom?: T }"
1391
+ },
924
1392
  {
925
1393
  "name": "WorldOptions",
926
1394
  "kind": "interface",