blecsd 0.4.0 → 0.6.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.
Files changed (142) hide show
  1. package/README.md +145 -145
  2. package/dist/{border-DGNDfT6T.d.ts → border-Br-Jc027.d.ts} +2 -2
  3. package/dist/{cell-DwIu2ryP.d.ts → cell-5Ty_3yMs.d.ts} +1 -1
  4. package/dist/cellRenderer-D0-DJXWl.d.ts +374 -0
  5. package/dist/chunk-4N7IFBRQ.js +4 -0
  6. package/dist/{chunk-DNRXW56C.js → chunk-4XCFTNGN.js} +1 -1
  7. package/dist/chunk-5YWRP2KG.js +3 -0
  8. package/dist/chunk-73Y45MLV.js +12 -0
  9. package/dist/chunk-7ZFQO3OQ.js +1 -0
  10. package/dist/chunk-A3GSH6MV.js +1 -0
  11. package/dist/chunk-A5B2BGUM.js +1 -0
  12. package/dist/chunk-AM6IDSXI.js +1 -0
  13. package/dist/chunk-EHYOVHRL.js +2 -0
  14. package/dist/chunk-EMZA6G2M.js +4 -0
  15. package/dist/chunk-EOFT3PNU.js +1 -0
  16. package/dist/chunk-ETFDYZVJ.js +1 -0
  17. package/dist/chunk-FUW7OD3H.js +1 -0
  18. package/dist/chunk-GRMSEMU7.js +1 -0
  19. package/dist/chunk-I7AUKTXE.js +1 -0
  20. package/dist/chunk-IANAVH2A.js +1 -0
  21. package/dist/chunk-JN2OGNK3.js +1 -0
  22. package/dist/chunk-JVMNMAHX.js +1 -0
  23. package/dist/chunk-K2QWNDXV.js +1 -0
  24. package/dist/chunk-KYNS3GBJ.js +2 -0
  25. package/dist/chunk-LI3ZYXUT.js +1 -0
  26. package/dist/chunk-LNEISTXM.js +1 -0
  27. package/dist/chunk-QABNK7IA.js +1 -0
  28. package/dist/chunk-QS5QXZNJ.js +1 -0
  29. package/dist/chunk-QTDRFJG2.js +1 -0
  30. package/dist/chunk-SVHITP3F.js +2 -0
  31. package/dist/chunk-UKVY43V3.js +1 -0
  32. package/dist/chunk-VIT4KE6Q.js +1 -0
  33. package/dist/chunk-XG5PVDOP.js +1 -0
  34. package/dist/chunk-XH5GTWCV.js +1 -0
  35. package/dist/chunk-XYMPBCYW.js +1 -0
  36. package/dist/chunk-YRSSCEAS.js +1 -0
  37. package/dist/chunk-ZL46COQF.js +1 -0
  38. package/dist/cli/init.js +1 -1
  39. package/dist/{componentStorage-CJTh-TPO.d.ts → componentStorage-CXJvx4Lt.d.ts} +2 -2
  40. package/dist/components/index.d.ts +8172 -7777
  41. package/dist/components/index.js +5 -1
  42. package/dist/core/index.d.ts +4777 -3942
  43. package/dist/core/index.js +1 -1
  44. package/dist/debug/index.d.ts +310 -84
  45. package/dist/debug/index.js +8 -1
  46. package/dist/{dirtyTracking-C4v8MmM9.d.ts → dirtyTracking-kCS9-NVF.d.ts} +2 -2
  47. package/dist/{doubleBuffer-CKQFmlPN.d.ts → doubleBuffer-CWASihKh.d.ts} +1 -1
  48. package/dist/errors/index.js +1 -1
  49. package/dist/{inputActions-Fyw14_Gm.d.ts → factories-vW7bn_He.d.ts} +21 -786
  50. package/dist/{gameLoop-CSTb7e0L.d.ts → gameLoop-C1AyRWyP.d.ts} +3 -3
  51. package/dist/index.d.ts +24 -1217
  52. package/dist/index.js +1 -3
  53. package/dist/input/index.d.ts +1 -1
  54. package/dist/input/index.js +1 -1
  55. package/dist/inputStream-COARA4CP.d.ts +1182 -0
  56. package/dist/interactiveSystem-h92W9W4n.d.ts +1977 -0
  57. package/dist/{keyParser-m7fWto6g.d.ts → keyParser-DReXe2j-.d.ts} +28 -28
  58. package/dist/{events-9ForpTfM.d.ts → mouseParser-CCqSEUVN.d.ts} +177 -2
  59. package/dist/{packedStore-BgvnEdE7.d.ts → packedStore-480t2X74.d.ts} +1 -1
  60. package/dist/panelMovement-DGzIQ8Ll.d.ts +1908 -0
  61. package/dist/{parser-iMHmQuUh.d.ts → parser-Q1YLXYpF.d.ts} +1 -1
  62. package/dist/positioning-DiUivJXa.d.ts +917 -0
  63. package/dist/{renderable-CwqGwrEV.d.ts → renderable-IbSJao5y.d.ts} +2 -2
  64. package/dist/{scheduler-DeeZleia.d.ts → scheduler-NbHT3-D2.d.ts} +1 -1
  65. package/dist/schemas/index.d.ts +6 -6
  66. package/dist/schemas/index.js +1 -1
  67. package/dist/systems/index.d.ts +785 -1882
  68. package/dist/systems/index.js +1 -1
  69. package/dist/terminal/index.d.ts +7563 -3387
  70. package/dist/terminal/index.js +1 -1
  71. package/dist/terminalBuffer-BbUz27qM.d.ts +691 -0
  72. package/dist/{terminus-14-bold-HWSPRLJD.js → terminus-14-bold-ZS4IH465.js} +1 -1
  73. package/dist/{terminus-14-normal-T3SWMH4D.js → terminus-14-normal-HD5N7F5W.js} +1 -1
  74. package/dist/text/index.d.ts +263 -0
  75. package/dist/text/index.js +3 -0
  76. package/dist/textWrap-Ct2J8gO6.d.ts +761 -0
  77. package/dist/{tilemap-BirMJdbu.d.ts → tilemap-ByvTsepD.d.ts} +5 -5
  78. package/dist/{types-CPB4CpbH.d.ts → types-B8LmNkzG.d.ts} +1 -1
  79. package/dist/utils/index.d.ts +829 -782
  80. package/dist/utils/index.js +32 -1
  81. package/dist/{virtualScrollback-D9uLFe8l.d.ts → virtualScrollback-CiooIebp.d.ts} +4 -4
  82. package/dist/virtualViewport-fIlbIGPt.d.ts +657 -0
  83. package/dist/{virtualizedLineStore-DwPEvPkk.d.ts → virtualizedLineStore-DfyhojPZ.d.ts} +1 -1
  84. package/dist/widgets/bigText.d.ts +13 -13
  85. package/dist/widgets/bigText.js +1 -1
  86. package/dist/widgets/fonts/index.d.ts +1 -1
  87. package/dist/widgets/fonts/index.js +1 -1
  88. package/dist/widgets/index.d.ts +1620 -910
  89. package/dist/widgets/index.js +24 -1
  90. package/package.json +9 -22
  91. package/dist/3d/index.d.ts +0 -5
  92. package/dist/3d/index.js +0 -1
  93. package/dist/audio/index.d.ts +0 -177
  94. package/dist/audio/index.js +0 -1
  95. package/dist/chunk-25OEBENM.js +0 -3
  96. package/dist/chunk-26STV7ZS.js +0 -1
  97. package/dist/chunk-2NMGUEFC.js +0 -4
  98. package/dist/chunk-35LCBY6P.js +0 -1
  99. package/dist/chunk-4PRDJTCM.js +0 -1
  100. package/dist/chunk-5PELJRUQ.js +0 -1
  101. package/dist/chunk-5VEKHA3B.js +0 -5
  102. package/dist/chunk-6KEM3OS2.js +0 -11
  103. package/dist/chunk-6XWY6GB7.js +0 -1
  104. package/dist/chunk-735KKTP3.js +0 -1
  105. package/dist/chunk-7SWJNDOL.js +0 -26
  106. package/dist/chunk-APKUNIMB.js +0 -1
  107. package/dist/chunk-CJCSZRV6.js +0 -1
  108. package/dist/chunk-DMBMCCLN.js +0 -1
  109. package/dist/chunk-DQTVJITR.js +0 -1
  110. package/dist/chunk-DSKQ5J4R.js +0 -1
  111. package/dist/chunk-E4CJRSND.js +0 -1
  112. package/dist/chunk-EF4DC6IN.js +0 -1
  113. package/dist/chunk-EJAKECSN.js +0 -1
  114. package/dist/chunk-FNQRUMFD.js +0 -1
  115. package/dist/chunk-GJ3RS2VG.js +0 -1
  116. package/dist/chunk-KTVEMB2I.js +0 -1
  117. package/dist/chunk-KYAPE44E.js +0 -8
  118. package/dist/chunk-LI4Y7TBZ.js +0 -1
  119. package/dist/chunk-NHOL4BN6.js +0 -1
  120. package/dist/chunk-NPNUUSIB.js +0 -1
  121. package/dist/chunk-NZ55KBM6.js +0 -1
  122. package/dist/chunk-OFRWGW2G.js +0 -1
  123. package/dist/chunk-OMMJ7B5P.js +0 -1
  124. package/dist/chunk-OMU5BSAS.js +0 -2
  125. package/dist/chunk-P3ZLIQJP.js +0 -1
  126. package/dist/chunk-PWI36BQJ.js +0 -1
  127. package/dist/chunk-QQMUDJ32.js +0 -2
  128. package/dist/chunk-R3ICZOE4.js +0 -1
  129. package/dist/chunk-RZ7FGVI6.js +0 -1
  130. package/dist/chunk-S6WS46FE.js +0 -1
  131. package/dist/chunk-TSARUU56.js +0 -1
  132. package/dist/chunk-WJRVUAZR.js +0 -33
  133. package/dist/chunk-WY5EZOOL.js +0 -1
  134. package/dist/chunk-YY6RZCZH.js +0 -4
  135. package/dist/chunk-ZPGJCHXH.js +0 -1
  136. package/dist/chunk-ZPL2J25N.js +0 -1
  137. package/dist/game/index.d.ts +0 -486
  138. package/dist/game/index.js +0 -1
  139. package/dist/index-DBS5Uefn.d.ts +0 -3156
  140. package/dist/mouseParser-B7p5ow7K.d.ts +0 -177
  141. package/dist/viewport3d-xI33-_wq.d.ts +0 -182
  142. package/dist/virtualViewport-DTSN6jFk.d.ts +0 -1856
@@ -0,0 +1,917 @@
1
+ import { W as World, E as Entity } from './types-B8LmNkzG.js';
2
+ import * as bitecs from 'bitecs';
3
+ import { ComponentRef, QueryTerm, QueryResult } from 'bitecs';
4
+ import { z } from 'zod';
5
+
6
+ /**
7
+ * Entity disposal and cleanup system.
8
+ *
9
+ * Handles proper cleanup of entities including:
10
+ * - Deferred destruction (mark for destruction, process at frame end)
11
+ * - Hierarchy cleanup (remove from parent, destroy children)
12
+ * - Lifecycle event emission
13
+ * - Store cleanup
14
+ * - Entity recycling
15
+ *
16
+ * @module core/disposal
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * import { destroyEntity, destroyAllChildren, flushDestroyQueue } from 'blecsd';
21
+ *
22
+ * // Mark entity for destruction (deferred)
23
+ * destroyEntity(world, entity);
24
+ *
25
+ * // At end of frame, process all pending destructions
26
+ * flushDestroyQueue(world);
27
+ *
28
+ * // Or destroy immediately
29
+ * destroyEntity(world, entity, { immediate: true });
30
+ * ```
31
+ */
32
+
33
+ /**
34
+ * Options for entity destruction.
35
+ */
36
+ interface DestroyOptions {
37
+ /**
38
+ * If true, destroy immediately instead of deferring to end of frame.
39
+ * Use with caution as this may cause issues during iteration.
40
+ */
41
+ immediate?: boolean;
42
+ /**
43
+ * If true, also destroy all children recursively.
44
+ * Defaults to true.
45
+ */
46
+ destroyChildren?: boolean;
47
+ /**
48
+ * If true, emit destroy event before cleanup.
49
+ * Defaults to true.
50
+ */
51
+ emitEvent?: boolean;
52
+ }
53
+ /**
54
+ * Callback for custom cleanup when an entity is destroyed.
55
+ */
56
+ type CleanupCallback = (world: World, entity: Entity) => void;
57
+ /**
58
+ * Registers a cleanup callback that runs when any entity is destroyed.
59
+ *
60
+ * Use this to register store cleanup functions.
61
+ *
62
+ * @param callback - Function to call during entity cleanup
63
+ * @returns Function to unregister the callback
64
+ *
65
+ * @example
66
+ * ```typescript
67
+ * import { registerCleanupCallback } from 'blecsd';
68
+ *
69
+ * // Register cleanup for a custom store
70
+ * const unregister = registerCleanupCallback((world, entity) => {
71
+ * myCustomStore.delete(entity);
72
+ * });
73
+ *
74
+ * // Later, unregister if needed
75
+ * unregister();
76
+ * ```
77
+ */
78
+ declare function registerCleanupCallback(callback: CleanupCallback): () => void;
79
+ /**
80
+ * Clears all registered cleanup callbacks.
81
+ * Primarily for testing.
82
+ */
83
+ declare function clearCleanupCallbacks(): void;
84
+ /**
85
+ * Marks an entity for destruction.
86
+ *
87
+ * By default, destruction is deferred to the end of the frame via
88
+ * `flushDestroyQueue()`. This prevents issues when destroying entities
89
+ * during iteration.
90
+ *
91
+ * @param world - The ECS world
92
+ * @param entity - The entity to destroy
93
+ * @param options - Destruction options
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * import { destroyEntity } from 'blecsd';
98
+ *
99
+ * // Deferred destruction (recommended)
100
+ * destroyEntity(world, entity);
101
+ *
102
+ * // Immediate destruction
103
+ * destroyEntity(world, entity, { immediate: true });
104
+ *
105
+ * // Don't destroy children
106
+ * destroyEntity(world, entity, { destroyChildren: false });
107
+ * ```
108
+ */
109
+ declare function destroyEntity(world: World, entity: Entity, options?: DestroyOptions): void;
110
+ /**
111
+ * Destroys all children of an entity without destroying the parent.
112
+ *
113
+ * @param world - The ECS world
114
+ * @param parent - The parent entity
115
+ * @param options - Destruction options (immediate applies to all children)
116
+ *
117
+ * @example
118
+ * ```typescript
119
+ * import { destroyAllChildren } from 'blecsd';
120
+ *
121
+ * // Clear all children from a container
122
+ * destroyAllChildren(world, container);
123
+ * ```
124
+ */
125
+ declare function destroyAllChildren(world: World, parent: Entity, options?: DestroyOptions): void;
126
+ /**
127
+ * Checks if an entity is marked for destruction.
128
+ *
129
+ * @param entity - The entity to check
130
+ * @returns true if entity is queued for destruction
131
+ */
132
+ declare function isMarkedForDestruction(entity: Entity): boolean;
133
+ /**
134
+ * Processes all entities marked for destruction.
135
+ *
136
+ * Should be called at the end of each frame, typically in POST_RENDER phase.
137
+ *
138
+ * @param world - The ECS world
139
+ * @returns Number of entities destroyed
140
+ *
141
+ * @example
142
+ * ```typescript
143
+ * import { flushDestroyQueue } from 'blecsd';
144
+ *
145
+ * // In your game loop's post-render phase:
146
+ * const destroyed = flushDestroyQueue(world);
147
+ * ```
148
+ */
149
+ declare function flushDestroyQueue(world: World): number;
150
+ /**
151
+ * Destroys all entities in a world.
152
+ *
153
+ * This performs immediate destruction of all entities.
154
+ *
155
+ * @param world - The ECS world to clear
156
+ *
157
+ * @example
158
+ * ```typescript
159
+ * import { destroyWorld } from 'blecsd';
160
+ *
161
+ * // Clean up everything before resetting
162
+ * destroyWorld(world);
163
+ * ```
164
+ */
165
+ declare function destroyWorld(world: World): void;
166
+ /**
167
+ * Gets the number of entities currently queued for destruction.
168
+ *
169
+ * @param world - Optional world to check (if not provided, returns global count)
170
+ * @returns Number of entities in destroy queue
171
+ */
172
+ declare function getDestroyQueueSize(world?: World): number;
173
+ /**
174
+ * Clears the destruction queue without destroying entities.
175
+ *
176
+ * Use with caution - entities will remain but won't be destroyed.
177
+ *
178
+ * @param world - The ECS world
179
+ */
180
+ declare function clearDestroyQueue(world: World): void;
181
+ /**
182
+ * Resets all disposal state.
183
+ * Primarily for testing.
184
+ */
185
+ declare function resetDisposalState(): void;
186
+
187
+ /**
188
+ * ECS World creation and management
189
+ * @module core/world
190
+ */
191
+
192
+ /**
193
+ * Creates a new ECS world for the game.
194
+ *
195
+ * @returns A new World instance
196
+ *
197
+ * @example
198
+ * ```typescript
199
+ * import { createWorld } from 'blecsd';
200
+ *
201
+ * const world = createWorld();
202
+ * ```
203
+ */
204
+ declare function createWorld(): World;
205
+ /**
206
+ * Resets an existing world, removing all entities and resetting component data.
207
+ * Useful for level reloading or game restart.
208
+ *
209
+ * @param world - The world to reset
210
+ *
211
+ * @example
212
+ * ```typescript
213
+ * import { createWorld, resetWorld } from 'blecsd';
214
+ *
215
+ * const world = createWorld();
216
+ * // ... game runs ...
217
+ * resetWorld(world); // Clear everything for new game
218
+ * ```
219
+ */
220
+ declare function resetWorld(world: World): void;
221
+
222
+ /**
223
+ * Creates a new entity in the world.
224
+ *
225
+ * @param world - The ECS world to add the entity to
226
+ * @returns The newly created entity ID
227
+ *
228
+ * @example
229
+ * ```typescript
230
+ * import { createWorld, addEntity } from 'blecsd';
231
+ *
232
+ * const world = createWorld();
233
+ * const player = addEntity(world);
234
+ * const enemy = addEntity(world);
235
+ * ```
236
+ */
237
+ declare function addEntity(world: World): Entity;
238
+ /**
239
+ * Removes an entity and all its components from the world.
240
+ *
241
+ * @param world - The ECS world containing the entity
242
+ * @param eid - The entity ID to remove
243
+ *
244
+ * @example
245
+ * ```typescript
246
+ * import { createWorld, addEntity, removeEntity } from 'blecsd';
247
+ *
248
+ * const world = createWorld();
249
+ * const entity = addEntity(world);
250
+ * // ... use entity ...
251
+ * removeEntity(world, entity); // Clean up when done
252
+ * ```
253
+ */
254
+ declare function removeEntity(world: World, eid: Entity): void;
255
+ /**
256
+ * Checks if an entity exists in the world.
257
+ *
258
+ * @param world - The ECS world to check
259
+ * @param eid - The entity ID to check
260
+ * @returns True if the entity exists, false otherwise
261
+ *
262
+ * @example
263
+ * ```typescript
264
+ * import { createWorld, addEntity, removeEntity, entityExists } from 'blecsd';
265
+ *
266
+ * const world = createWorld();
267
+ * const entity = addEntity(world);
268
+ *
269
+ * console.log(entityExists(world, entity)); // true
270
+ * removeEntity(world, entity);
271
+ * console.log(entityExists(world, entity)); // false
272
+ * ```
273
+ */
274
+ declare function entityExists(world: World, eid: Entity): boolean;
275
+ /**
276
+ * Gets all entity IDs currently in the world.
277
+ *
278
+ * @param world - The ECS world to query
279
+ * @returns Array of all entity IDs in the world
280
+ *
281
+ * @example
282
+ * ```typescript
283
+ * import { createWorld, addEntity, getAllEntities } from 'blecsd';
284
+ *
285
+ * const world = createWorld();
286
+ * addEntity(world);
287
+ * addEntity(world);
288
+ * addEntity(world);
289
+ *
290
+ * const entities = getAllEntities(world);
291
+ * console.log(entities.length); // 3
292
+ * ```
293
+ */
294
+ declare function getAllEntities(world: World): readonly Entity[];
295
+ /**
296
+ * Adds a component to an entity.
297
+ *
298
+ * @param world - The ECS world
299
+ * @param eid - The entity to add the component to
300
+ * @param component - The component to add
301
+ *
302
+ * @example
303
+ * ```typescript
304
+ * import { createWorld, addEntity, addComponent, Position } from 'blecsd';
305
+ *
306
+ * const world = createWorld();
307
+ * const entity = addEntity(world);
308
+ * addComponent(world, entity, Position);
309
+ * Position.x[entity] = 100;
310
+ * Position.y[entity] = 50;
311
+ * ```
312
+ */
313
+ declare function addComponent(world: World, eid: Entity, component: ComponentRef): void;
314
+ /**
315
+ * Checks if an entity has a specific component.
316
+ *
317
+ * @param world - The ECS world
318
+ * @param eid - The entity to check
319
+ * @param component - The component to check for
320
+ * @returns True if the entity has the component, false otherwise
321
+ *
322
+ * @example
323
+ * ```typescript
324
+ * import { createWorld, addEntity, addComponent, hasComponent, Position } from 'blecsd';
325
+ *
326
+ * const world = createWorld();
327
+ * const entity = addEntity(world);
328
+ *
329
+ * console.log(hasComponent(world, entity, Position)); // false
330
+ * addComponent(world, entity, Position);
331
+ * console.log(hasComponent(world, entity, Position)); // true
332
+ * ```
333
+ */
334
+ declare function hasComponent(world: World, eid: Entity, component: ComponentRef): boolean;
335
+ /**
336
+ * Removes a component from an entity.
337
+ *
338
+ * @param world - The ECS world
339
+ * @param eid - The entity to remove the component from
340
+ * @param component - The component to remove
341
+ *
342
+ * @example
343
+ * ```typescript
344
+ * import { createWorld, addEntity, addComponent, removeComponent, hasComponent, Position } from 'blecsd';
345
+ *
346
+ * const world = createWorld();
347
+ * const entity = addEntity(world);
348
+ * addComponent(world, entity, Position);
349
+ *
350
+ * console.log(hasComponent(world, entity, Position)); // true
351
+ * removeComponent(world, entity, Position);
352
+ * console.log(hasComponent(world, entity, Position)); // false
353
+ * ```
354
+ */
355
+ declare function removeComponent(world: World, eid: Entity, component: ComponentRef): void;
356
+ /**
357
+ * Queries the world for entities that have all specified components.
358
+ *
359
+ * @param world - The ECS world to query
360
+ * @param components - Array of components that entities must have
361
+ * @returns Array of entity IDs that match the query
362
+ *
363
+ * @example
364
+ * ```typescript
365
+ * import { createWorld, addEntity, addComponent, query, Position, Velocity } from 'blecsd';
366
+ *
367
+ * const world = createWorld();
368
+ *
369
+ * // Create entities with different component combinations
370
+ * const staticEntity = addEntity(world);
371
+ * addComponent(world, staticEntity, Position);
372
+ *
373
+ * const movingEntity = addEntity(world);
374
+ * addComponent(world, movingEntity, Position);
375
+ * addComponent(world, movingEntity, Velocity);
376
+ *
377
+ * // Query for entities with both Position and Velocity
378
+ * const movingEntities = query(world, [Position, Velocity]);
379
+ * console.log(movingEntities.length); // 1 (only movingEntity)
380
+ * ```
381
+ */
382
+ declare function query(world: World, components: QueryTerm[]): QueryResult;
383
+ /**
384
+ * Registers a component with the world. This is typically called automatically
385
+ * when components are first used, but can be useful for advanced scenarios.
386
+ *
387
+ * @param world - The ECS world
388
+ * @param component - The component to register
389
+ *
390
+ * @example
391
+ * ```typescript
392
+ * import { createWorld, registerComponent, Position } from 'blecsd';
393
+ *
394
+ * const world = createWorld();
395
+ * registerComponent(world, Position);
396
+ * ```
397
+ */
398
+ declare const registerComponent: (world: bitecs.World, component: ComponentRef) => bitecs.ComponentData;
399
+ /**
400
+ * Creates a component with a custom backing store. Useful for components that
401
+ * need special memory layouts or interop with external systems.
402
+ *
403
+ * @param store - Custom store object with typed arrays
404
+ * @returns A component that uses the provided store
405
+ *
406
+ * @example
407
+ * ```typescript
408
+ * import { withStore } from 'blecsd';
409
+ *
410
+ * // Create a component backed by custom Float32Arrays
411
+ * const CustomPosition = withStore({
412
+ * x: new Float32Array(10000),
413
+ * y: new Float32Array(10000),
414
+ * });
415
+ * ```
416
+ */
417
+ declare const withStore: <T>(createStore: (eid: bitecs.EntityId) => T) => (relation: bitecs.Relation<T>) => bitecs.Relation<T>;
418
+
419
+ /**
420
+ * Hit Test System with Z-Order Aware Clickable Sorting
421
+ *
422
+ * Provides efficient hit testing for mouse interactions, sorting clickable
423
+ * elements by z-index so the topmost element receives events first.
424
+ *
425
+ * @module core/hitTest
426
+ *
427
+ * @example
428
+ * ```typescript
429
+ * import {
430
+ * createClickableCache,
431
+ * hitTest,
432
+ * hitTestAll,
433
+ * invalidateClickableCache,
434
+ * } from 'blecsd';
435
+ *
436
+ * // Create cache for efficient hit testing
437
+ * const cache = createClickableCache();
438
+ *
439
+ * // Hit test at mouse position - returns topmost entity
440
+ * const topEntity = hitTest(world, mouseX, mouseY, cache);
441
+ *
442
+ * // Get all entities under point, sorted by z-index (highest first)
443
+ * const allEntities = hitTestAll(world, mouseX, mouseY, cache);
444
+ *
445
+ * // Invalidate cache when hierarchy changes
446
+ * invalidateClickableCache(cache);
447
+ * ```
448
+ */
449
+
450
+ /**
451
+ * Cache for clickable element sorting.
452
+ *
453
+ * Maintains a sorted list of clickable/hoverable entities for efficient
454
+ * hit testing. The cache is invalidated when the hierarchy changes.
455
+ */
456
+ interface ClickableCache {
457
+ /** Sorted entities (highest z-index first) */
458
+ entities: Entity[];
459
+ /** Whether cache needs rebuilding */
460
+ dirty: boolean;
461
+ /** Last known count for quick dirty check */
462
+ lastCount: number;
463
+ }
464
+ /**
465
+ * Result of a hit test operation.
466
+ */
467
+ interface HitTestResult {
468
+ /** The entity under the point (topmost if multiple) */
469
+ readonly entity: Entity;
470
+ /** Z-index of the entity */
471
+ readonly zIndex: number;
472
+ }
473
+ /**
474
+ * Options for hit testing.
475
+ */
476
+ interface HitTestOptions {
477
+ /** Use cached positions for faster testing (default: true) */
478
+ useCachedPositions?: boolean;
479
+ /** Only test clickable entities (default: true) */
480
+ clickableOnly?: boolean;
481
+ /** Only test hoverable entities (default: false) */
482
+ hoverableOnly?: boolean;
483
+ /** Test both clickable and hoverable (default: false) */
484
+ interactiveOnly?: boolean;
485
+ }
486
+ /**
487
+ * Creates a new clickable cache.
488
+ *
489
+ * The cache stores a z-index sorted list of interactive entities
490
+ * for efficient hit testing.
491
+ *
492
+ * @returns A new ClickableCache
493
+ *
494
+ * @example
495
+ * ```typescript
496
+ * import { createClickableCache } from 'blecsd';
497
+ *
498
+ * const cache = createClickableCache();
499
+ * ```
500
+ */
501
+ declare function createClickableCache(): ClickableCache;
502
+ /**
503
+ * Marks the clickable cache as needing rebuild.
504
+ *
505
+ * Call this when:
506
+ * - Entities are added or removed
507
+ * - Z-index values change
508
+ * - Interactive state changes (clickable/hoverable toggled)
509
+ *
510
+ * @param cache - The clickable cache
511
+ *
512
+ * @example
513
+ * ```typescript
514
+ * import { invalidateClickableCache } from 'blecsd';
515
+ *
516
+ * // After adding a new clickable entity
517
+ * invalidateClickableCache(cache);
518
+ * ```
519
+ */
520
+ declare function invalidateClickableCache(cache: ClickableCache): void;
521
+ /**
522
+ * Checks if the cache needs rebuilding.
523
+ *
524
+ * @param cache - The clickable cache
525
+ * @returns true if cache is dirty
526
+ */
527
+ declare function isCacheDirty(cache: ClickableCache): boolean;
528
+ /**
529
+ * Rebuilds the clickable cache if needed.
530
+ *
531
+ * Queries for all interactive entities and sorts them by z-index
532
+ * in descending order (highest z-index first for hit testing).
533
+ *
534
+ * @param world - The ECS world
535
+ * @param cache - The clickable cache
536
+ *
537
+ * @example
538
+ * ```typescript
539
+ * import { updateClickableCache } from 'blecsd';
540
+ *
541
+ * // Rebuild cache before hit testing
542
+ * updateClickableCache(world, cache);
543
+ * ```
544
+ */
545
+ declare function updateClickableCache(world: World, cache: ClickableCache): void;
546
+ /**
547
+ * Gets the current sorted clickable entities from cache.
548
+ *
549
+ * @param world - The ECS world
550
+ * @param cache - The clickable cache
551
+ * @returns Array of entities sorted by z-index (highest first)
552
+ */
553
+ declare function getClickableEntities(world: World, cache: ClickableCache): readonly Entity[];
554
+ /**
555
+ * Gets the count of clickable entities.
556
+ *
557
+ * @param world - The ECS world
558
+ * @param cache - The clickable cache
559
+ * @returns Number of clickable/hoverable entities
560
+ */
561
+ declare function getClickableCount(world: World, cache: ClickableCache): number;
562
+ declare function hitTest(world: World, x: number, y: number, cache?: ClickableCache, options?: HitTestOptions): Entity | null;
563
+ /**
564
+ * Performs a hit test and returns all entities at the point.
565
+ *
566
+ * Returns entities sorted by z-index (highest first).
567
+ *
568
+ * @param world - The ECS world
569
+ * @param x - Screen X coordinate
570
+ * @param y - Screen Y coordinate
571
+ * @param cache - Optional clickable cache for efficiency
572
+ * @param options - Hit test options
573
+ * @returns Array of entities at the point, sorted by z-index (highest first)
574
+ *
575
+ * @example
576
+ * ```typescript
577
+ * import { hitTestAll, createClickableCache } from 'blecsd';
578
+ *
579
+ * const cache = createClickableCache();
580
+ *
581
+ * // Get all entities under mouse position
582
+ * const entities = hitTestAll(world, mouseX, mouseY, cache);
583
+ *
584
+ * for (const eid of entities) {
585
+ * console.log(`Entity ${eid} at z=${getZIndex(world, eid)}`);
586
+ * }
587
+ * ```
588
+ */
589
+ declare function hitTestAll(world: World, x: number, y: number, cache?: ClickableCache, options?: HitTestOptions): Entity[];
590
+ /**
591
+ * Performs a hit test with detailed results.
592
+ *
593
+ * @param world - The ECS world
594
+ * @param x - Screen X coordinate
595
+ * @param y - Screen Y coordinate
596
+ * @param cache - Optional clickable cache for efficiency
597
+ * @param options - Hit test options
598
+ * @returns Array of HitTestResults with entity and z-index
599
+ *
600
+ * @example
601
+ * ```typescript
602
+ * import { hitTestDetailed, createClickableCache } from 'blecsd';
603
+ *
604
+ * const cache = createClickableCache();
605
+ *
606
+ * const results = hitTestDetailed(world, mouseX, mouseY, cache);
607
+ * for (const { entity, zIndex } of results) {
608
+ * console.log(`Entity ${entity} at z=${zIndex}`);
609
+ * }
610
+ * ```
611
+ */
612
+ declare function hitTestDetailed(world: World, x: number, y: number, cache?: ClickableCache, options?: HitTestOptions): HitTestResult[];
613
+ /**
614
+ * Checks if any clickable entity is under the point.
615
+ *
616
+ * @param world - The ECS world
617
+ * @param x - Screen X coordinate
618
+ * @param y - Screen Y coordinate
619
+ * @param cache - Optional clickable cache
620
+ * @returns true if any clickable entity is under the point
621
+ */
622
+ declare function hasClickableAt(world: World, x: number, y: number, cache?: ClickableCache): boolean;
623
+ /**
624
+ * Checks if any hoverable entity is under the point.
625
+ *
626
+ * @param world - The ECS world
627
+ * @param x - Screen X coordinate
628
+ * @param y - Screen Y coordinate
629
+ * @param cache - Optional clickable cache
630
+ * @returns true if any hoverable entity is under the point
631
+ */
632
+ declare function hasHoverableAt(world: World, x: number, y: number, cache?: ClickableCache): boolean;
633
+ /**
634
+ * Gets the topmost clickable entity at a point.
635
+ *
636
+ * Convenience wrapper for hitTest with clickableOnly=true.
637
+ *
638
+ * @param world - The ECS world
639
+ * @param x - Screen X coordinate
640
+ * @param y - Screen Y coordinate
641
+ * @param cache - Optional clickable cache
642
+ * @returns Topmost clickable entity or null
643
+ */
644
+ declare function getClickableAt(world: World, x: number, y: number, cache?: ClickableCache): Entity | null;
645
+ /**
646
+ * Gets the topmost hoverable entity at a point.
647
+ *
648
+ * Convenience wrapper for hitTest with hoverableOnly=true.
649
+ *
650
+ * @param world - The ECS world
651
+ * @param x - Screen X coordinate
652
+ * @param y - Screen Y coordinate
653
+ * @param cache - Optional clickable cache
654
+ * @returns Topmost hoverable entity or null
655
+ */
656
+ declare function getHoverableAt(world: World, x: number, y: number, cache?: ClickableCache): Entity | null;
657
+ /**
658
+ * Gets all clickable entities at a point.
659
+ *
660
+ * @param world - The ECS world
661
+ * @param x - Screen X coordinate
662
+ * @param y - Screen Y coordinate
663
+ * @param cache - Optional clickable cache
664
+ * @returns Array of clickable entities (highest z-index first)
665
+ */
666
+ declare function getAllClickablesAt(world: World, x: number, y: number, cache?: ClickableCache): Entity[];
667
+ /**
668
+ * Gets all hoverable entities at a point.
669
+ *
670
+ * @param world - The ECS world
671
+ * @param x - Screen X coordinate
672
+ * @param y - Screen Y coordinate
673
+ * @param cache - Optional clickable cache
674
+ * @returns Array of hoverable entities (highest z-index first)
675
+ */
676
+ declare function getAllHoverablesAt(world: World, x: number, y: number, cache?: ClickableCache): Entity[];
677
+
678
+ /**
679
+ * Advanced positioning system with percentage and expression support.
680
+ * Resolves position values to absolute coordinates.
681
+ * @module core/positioning
682
+ */
683
+
684
+ /**
685
+ * Position value types supported by the positioning system.
686
+ * - number: absolute position in cells
687
+ * - string: percentage ('50%'), expression ('50%-5'), or keyword ('center', 'half')
688
+ */
689
+ type PositionValue = number | string;
690
+ /**
691
+ * Schema for validating position values.
692
+ * Accepts numbers, percentage strings, expressions, and keywords.
693
+ *
694
+ * @example
695
+ * ```typescript
696
+ * import { PositionValueSchema } from 'blecsd';
697
+ *
698
+ * PositionValueSchema.parse(10); // Valid: absolute
699
+ * PositionValueSchema.parse('50%'); // Valid: percentage
700
+ * PositionValueSchema.parse('50%-5'); // Valid: expression
701
+ * PositionValueSchema.parse('center'); // Valid: keyword
702
+ * ```
703
+ */
704
+ declare const PositionValueSchema: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
705
+ /**
706
+ * Resolves a position value to an absolute coordinate.
707
+ *
708
+ * Supports:
709
+ * - Numbers: returned as-is
710
+ * - Percentages: '50%' → parentSize * 0.5
711
+ * - Expressions: '50%-5' → (parentSize * 0.5) - 5
712
+ * - Keywords:
713
+ * - 'center': (parentSize - elementSize) / 2
714
+ * - 'half': parentSize / 2
715
+ * - 'left'/'top': 0
716
+ * - 'right'/'bottom': parentSize - elementSize
717
+ *
718
+ * @param value - Position value to resolve
719
+ * @param parentSize - Size of the parent container
720
+ * @param elementSize - Size of the element (for centering)
721
+ * @returns Resolved absolute position
722
+ *
723
+ * @example
724
+ * ```typescript
725
+ * import { parsePosition } from 'blecsd';
726
+ *
727
+ * // Absolute position
728
+ * parsePosition(10, 100, 20); // 10
729
+ *
730
+ * // Percentage
731
+ * parsePosition('50%', 100, 20); // 50
732
+ *
733
+ * // Expression
734
+ * parsePosition('50%-5', 100, 20); // 45
735
+ * parsePosition('100%-10', 100, 20); // 90
736
+ *
737
+ * // Keywords
738
+ * parsePosition('center', 100, 20); // 40 ((100-20)/2)
739
+ * parsePosition('half', 100, 20); // 50 (100/2)
740
+ * parsePosition('right', 100, 20); // 80 (100-20)
741
+ * ```
742
+ */
743
+ declare function parsePosition(value: PositionValue, parentSize: number, elementSize?: number): number;
744
+ /**
745
+ * Resolves a position value that may be negative (from right/bottom edge).
746
+ * Negative values are converted to offsets from the opposite edge.
747
+ *
748
+ * @param value - Position value to resolve
749
+ * @param parentSize - Size of the parent container
750
+ * @param elementSize - Size of the element
751
+ * @returns Resolved absolute position
752
+ *
753
+ * @example
754
+ * ```typescript
755
+ * import { parsePositionWithNegative } from 'blecsd';
756
+ *
757
+ * // Positive values work normally
758
+ * parsePositionWithNegative(10, 100, 20); // 10
759
+ *
760
+ * // Negative values are from the right/bottom
761
+ * parsePositionWithNegative(-10, 100, 20); // 70 (100 - 10 - 20)
762
+ * parsePositionWithNegative(-5, 100, 10); // 85 (100 - 5 - 10)
763
+ * ```
764
+ */
765
+ declare function parsePositionWithNegative(value: PositionValue, parentSize: number, elementSize?: number): number;
766
+ /**
767
+ * Validates that a position value is within valid bounds.
768
+ *
769
+ * @param value - Resolved position value
770
+ * @param parentSize - Size of the parent container
771
+ * @param elementSize - Size of the element
772
+ * @returns Clamped position value within bounds
773
+ *
774
+ * @example
775
+ * ```typescript
776
+ * import { clampPosition } from 'blecsd';
777
+ *
778
+ * clampPosition(-10, 100, 20); // 0 (can't be negative)
779
+ * clampPosition(90, 100, 20); // 80 (element must fit)
780
+ * clampPosition(50, 100, 20); // 50 (within bounds)
781
+ * ```
782
+ */
783
+ declare function clampPosition(value: number, parentSize: number, elementSize?: number): number;
784
+ /**
785
+ * Checks if a position value is a percentage or expression containing a percentage.
786
+ *
787
+ * @param value - Position value to check
788
+ * @returns true if the value contains a percentage
789
+ *
790
+ * @example
791
+ * ```typescript
792
+ * import { isPercentagePosition } from 'blecsd';
793
+ *
794
+ * isPercentagePosition('50%'); // true
795
+ * isPercentagePosition('50%-5'); // true
796
+ * isPercentagePosition(50); // false
797
+ * isPercentagePosition('center'); // false
798
+ * ```
799
+ */
800
+ declare function isPercentagePosition(value: PositionValue): boolean;
801
+ /**
802
+ * Checks if a position value is a keyword.
803
+ *
804
+ * @param value - Position value to check
805
+ * @returns true if the value is a position keyword
806
+ *
807
+ * @example
808
+ * ```typescript
809
+ * import { isKeywordPosition } from 'blecsd';
810
+ *
811
+ * isKeywordPosition('center'); // true
812
+ * isKeywordPosition('half'); // true
813
+ * isKeywordPosition('50%'); // false
814
+ * isKeywordPosition(50); // false
815
+ * ```
816
+ */
817
+ declare function isKeywordPosition(value: PositionValue): boolean;
818
+ /**
819
+ * Creates a position value that centers an element.
820
+ *
821
+ * @returns 'center' keyword
822
+ *
823
+ * @example
824
+ * ```typescript
825
+ * import { centerPosition, parsePosition } from 'blecsd';
826
+ *
827
+ * const pos = centerPosition();
828
+ * const resolved = parsePosition(pos, 100, 20); // 40
829
+ * ```
830
+ */
831
+ declare function centerPosition(): 'center';
832
+ /**
833
+ * Creates a percentage position value.
834
+ *
835
+ * @param percent - Percentage value (0-100)
836
+ * @returns Percentage string
837
+ *
838
+ * @example
839
+ * ```typescript
840
+ * import { percentPosition, parsePosition } from 'blecsd';
841
+ *
842
+ * const pos = percentPosition(50);
843
+ * const resolved = parsePosition(pos, 100, 0); // 50
844
+ * ```
845
+ */
846
+ declare function percentPosition(percent: number): string;
847
+ /**
848
+ * Creates a percentage position with an offset.
849
+ *
850
+ * @param percent - Percentage value (0-100)
851
+ * @param offset - Offset to add (negative to subtract)
852
+ * @returns Expression string
853
+ *
854
+ * @example
855
+ * ```typescript
856
+ * import { percentOffsetPosition, parsePosition } from 'blecsd';
857
+ *
858
+ * const pos = percentOffsetPosition(50, -5);
859
+ * const resolved = parsePosition(pos, 100, 0); // 45
860
+ *
861
+ * const pos2 = percentOffsetPosition(100, -10);
862
+ * const resolved2 = parsePosition(pos2, 100, 0); // 90
863
+ * ```
864
+ */
865
+ declare function percentOffsetPosition(percent: number, offset: number): string;
866
+ /**
867
+ * Resolves both X and Y position values at once.
868
+ *
869
+ * @param x - X position value
870
+ * @param y - Y position value
871
+ * @param parentWidth - Parent container width
872
+ * @param parentHeight - Parent container height
873
+ * @param elementWidth - Element width (for centering)
874
+ * @param elementHeight - Element height (for centering)
875
+ * @returns Resolved { x, y } coordinates
876
+ *
877
+ * @example
878
+ * ```typescript
879
+ * import { resolvePosition } from 'blecsd';
880
+ *
881
+ * const pos = resolvePosition('center', 'center', 100, 80, 20, 10);
882
+ * // pos = { x: 40, y: 35 }
883
+ *
884
+ * const pos2 = resolvePosition('50%-5', '100%-10', 100, 80, 0, 0);
885
+ * // pos2 = { x: 45, y: 70 }
886
+ * ```
887
+ */
888
+ declare function resolvePosition(x: PositionValue, y: PositionValue, parentWidth: number, parentHeight: number, elementWidth?: number, elementHeight?: number): {
889
+ x: number;
890
+ y: number;
891
+ };
892
+ /**
893
+ * Resolves position values and clamps them to valid bounds.
894
+ *
895
+ * @param x - X position value
896
+ * @param y - Y position value
897
+ * @param parentWidth - Parent container width
898
+ * @param parentHeight - Parent container height
899
+ * @param elementWidth - Element width
900
+ * @param elementHeight - Element height
901
+ * @returns Resolved and clamped { x, y } coordinates
902
+ *
903
+ * @example
904
+ * ```typescript
905
+ * import { resolvePositionClamped } from 'blecsd';
906
+ *
907
+ * // Position that would go off-screen is clamped
908
+ * const pos = resolvePositionClamped('100%', '100%', 100, 80, 20, 10);
909
+ * // pos = { x: 80, y: 70 } (clamped so element fits)
910
+ * ```
911
+ */
912
+ declare function resolvePositionClamped(x: PositionValue, y: PositionValue, parentWidth: number, parentHeight: number, elementWidth?: number, elementHeight?: number): {
913
+ x: number;
914
+ y: number;
915
+ };
916
+
917
+ export { withStore as $, getHoverableAt as A, hasClickableAt as B, type CleanupCallback as C, type DestroyOptions as D, hasHoverableAt as E, hitTestAll as F, hitTestDetailed as G, type HitTestResult as H, invalidateClickableCache as I, isCacheDirty as J, isKeywordPosition as K, isMarkedForDestruction as L, isPercentagePosition as M, parsePosition as N, parsePositionWithNegative as O, type PositionValue as P, percentOffsetPosition as Q, percentPosition as R, query as S, registerCleanupCallback as T, registerComponent as U, removeComponent as V, resetDisposalState as W, resetWorld as X, resolvePosition as Y, resolvePositionClamped as Z, updateClickableCache as _, PositionValueSchema as a, addComponent as b, addEntity as c, createWorld as d, destroyWorld as e, hitTest as f, type ClickableCache as g, hasComponent as h, type HitTestOptions as i, centerPosition as j, clampPosition as k, clearCleanupCallbacks as l, clearDestroyQueue as m, createClickableCache as n, destroyAllChildren as o, destroyEntity as p, entityExists as q, removeEntity as r, flushDestroyQueue as s, getAllClickablesAt as t, getAllEntities as u, getAllHoverablesAt as v, getClickableAt as w, getClickableCount as x, getClickableEntities as y, getDestroyQueueSize as z };