blecsd 0.4.0 → 0.6.2

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 (156) hide show
  1. package/README.md +169 -147
  2. package/dist/blend-BZDmQFAm.d.ts +1215 -0
  3. package/dist/{border-DGNDfT6T.d.ts → border-Br-Jc027.d.ts} +2 -2
  4. package/dist/{cell-DwIu2ryP.d.ts → cell-5Ty_3yMs.d.ts} +1 -1
  5. package/dist/cellRenderer-D0-DJXWl.d.ts +374 -0
  6. package/dist/chunk-3PGACJB6.js +1 -0
  7. package/dist/{chunk-DNRXW56C.js → chunk-4EV3YS7F.js} +1 -1
  8. package/dist/chunk-4XW4WIPH.js +1 -0
  9. package/dist/chunk-7CLV3LTZ.js +4 -0
  10. package/dist/chunk-7ZFQO3OQ.js +1 -0
  11. package/dist/chunk-AM6IDSXI.js +1 -0
  12. package/dist/chunk-APPZ3YHO.js +0 -0
  13. package/dist/chunk-EHYOVHRL.js +2 -0
  14. package/dist/chunk-EKE2BXPS.js +1 -0
  15. package/dist/chunk-EOFT3PNU.js +1 -0
  16. package/dist/chunk-ESMSDY3P.js +1 -0
  17. package/dist/chunk-FJLSHFCF.js +1 -0
  18. package/dist/chunk-FUW7OD3H.js +1 -0
  19. package/dist/chunk-GIMWA5WA.js +1 -0
  20. package/dist/chunk-GRMSEMU7.js +1 -0
  21. package/dist/chunk-I7AUKTXE.js +1 -0
  22. package/dist/chunk-IXUFU6TE.js +3 -0
  23. package/dist/chunk-JB5KFQPD.js +1 -0
  24. package/dist/chunk-JCLNGU3K.js +1 -0
  25. package/dist/chunk-JN2OGNK3.js +1 -0
  26. package/dist/chunk-JRRJCATR.js +1 -0
  27. package/dist/chunk-JWIVZCKW.js +1 -0
  28. package/dist/chunk-K5UMVDQX.js +1 -0
  29. package/dist/chunk-KYNS3GBJ.js +2 -0
  30. package/dist/chunk-L4FIDOS6.js +1 -0
  31. package/dist/chunk-LIVVHEOU.js +1 -0
  32. package/dist/chunk-LNEISTXM.js +1 -0
  33. package/dist/chunk-M5FXA5FL.js +1 -0
  34. package/dist/chunk-MEJJLDEQ.js +1 -0
  35. package/dist/chunk-NYIMY4UV.js +1 -0
  36. package/dist/chunk-PQZTNWLA.js +1 -0
  37. package/dist/chunk-QS5QXZNJ.js +1 -0
  38. package/dist/chunk-SXOBHRXF.js +2 -0
  39. package/dist/chunk-T2EQLWMN.js +1 -0
  40. package/dist/chunk-T62UPG63.js +4 -0
  41. package/dist/chunk-TPBILYDM.js +10 -0
  42. package/dist/chunk-UWS6FIU5.js +1 -0
  43. package/dist/chunk-W64J7C25.js +4 -0
  44. package/dist/chunk-W6RELN6A.js +1 -0
  45. package/dist/chunk-XYMPBCYW.js +1 -0
  46. package/dist/chunk-ZAJI53SZ.js +1 -0
  47. package/dist/cli/init.js +1 -1
  48. package/dist/{componentStorage-CJTh-TPO.d.ts → componentStorage-CXJvx4Lt.d.ts} +2 -2
  49. package/dist/components/index.d.ts +7762 -7682
  50. package/dist/components/index.js +5 -1
  51. package/dist/core/index.d.ts +4851 -4261
  52. package/dist/core/index.js +1 -1
  53. package/dist/debug/index.d.ts +310 -84
  54. package/dist/debug/index.js +8 -1
  55. package/dist/{dirtyTracking-C4v8MmM9.d.ts → dirtyTracking-D0SQrEeo.d.ts} +2 -2
  56. package/dist/{doubleBuffer-CKQFmlPN.d.ts → doubleBuffer-d9yVNtj1.d.ts} +22 -2
  57. package/dist/errors/index.js +1 -1
  58. package/dist/{events-9ForpTfM.d.ts → events-CGqK6LGt.d.ts} +2 -2
  59. package/dist/{inputActions-Fyw14_Gm.d.ts → factories-vW7bn_He.d.ts} +21 -786
  60. package/dist/{gameLoop-CSTb7e0L.d.ts → gameLoop-C1AyRWyP.d.ts} +3 -3
  61. package/dist/index.d.ts +25 -1217
  62. package/dist/index.js +1 -3
  63. package/dist/input/index.d.ts +1 -1
  64. package/dist/input/index.js +1 -1
  65. package/dist/inputStream-BoFAEJ7g.d.ts +1385 -0
  66. package/dist/interactiveSystem-Dtv3xERg.d.ts +2292 -0
  67. package/dist/{keyParser-m7fWto6g.d.ts → keyParser-DReXe2j-.d.ts} +28 -28
  68. package/dist/{mouseParser-B7p5ow7K.d.ts → mouseParser-CTNGolIA.d.ts} +1 -1
  69. package/dist/{packedStore-BgvnEdE7.d.ts → packedStore-480t2X74.d.ts} +1 -1
  70. package/dist/panelMovement-DSLYdNOL.d.ts +1909 -0
  71. package/dist/{parser-iMHmQuUh.d.ts → parser-Q1YLXYpF.d.ts} +1 -1
  72. package/dist/positioning-DiUivJXa.d.ts +917 -0
  73. package/dist/{renderable-CwqGwrEV.d.ts → renderable-IbSJao5y.d.ts} +2 -2
  74. package/dist/{scheduler-DeeZleia.d.ts → scheduler-NbHT3-D2.d.ts} +1 -1
  75. package/dist/schemas/index.d.ts +6 -6
  76. package/dist/schemas/index.js +1 -1
  77. package/dist/style/index.d.ts +851 -0
  78. package/dist/style/index.js +1 -0
  79. package/dist/styleInheritance-CuRb5Dmp.d.ts +251 -0
  80. package/dist/systems/index.d.ts +786 -1882
  81. package/dist/systems/index.js +1 -1
  82. package/dist/terminal/index.d.ts +5542 -2460
  83. package/dist/terminal/index.js +1 -1
  84. package/dist/terminalBuffer-BbUz27qM.d.ts +691 -0
  85. package/dist/{terminus-14-bold-HWSPRLJD.js → terminus-14-bold-ZS4IH465.js} +1 -1
  86. package/dist/{terminus-14-normal-T3SWMH4D.js → terminus-14-normal-HD5N7F5W.js} +1 -1
  87. package/dist/testing/index.d.ts +923 -0
  88. package/dist/testing/index.js +7 -0
  89. package/dist/text/index.d.ts +263 -0
  90. package/dist/text/index.js +3 -0
  91. package/dist/textWrap-sY-PZzE7.d.ts +761 -0
  92. package/dist/{tilemap-BirMJdbu.d.ts → tilemap-ByvTsepD.d.ts} +5 -5
  93. package/dist/{types-CPB4CpbH.d.ts → types-B8LmNkzG.d.ts} +1 -1
  94. package/dist/utils/index.d.ts +829 -782
  95. package/dist/utils/index.js +32 -1
  96. package/dist/{virtualScrollback-D9uLFe8l.d.ts → virtualScrollback-CiooIebp.d.ts} +4 -4
  97. package/dist/virtualViewport-fIlbIGPt.d.ts +657 -0
  98. package/dist/{virtualizedLineStore-DwPEvPkk.d.ts → virtualizedLineStore-DfyhojPZ.d.ts} +1 -1
  99. package/dist/widgets/bigText.d.ts +13 -13
  100. package/dist/widgets/bigText.js +1 -1
  101. package/dist/widgets/fonts/index.d.ts +1 -1
  102. package/dist/widgets/fonts/index.js +1 -1
  103. package/dist/widgets/index.d.ts +1620 -910
  104. package/dist/widgets/index.js +24 -1
  105. package/package.json +23 -22
  106. package/dist/3d/index.d.ts +0 -5
  107. package/dist/3d/index.js +0 -1
  108. package/dist/audio/index.d.ts +0 -177
  109. package/dist/audio/index.js +0 -1
  110. package/dist/chunk-25OEBENM.js +0 -3
  111. package/dist/chunk-26STV7ZS.js +0 -1
  112. package/dist/chunk-2NMGUEFC.js +0 -4
  113. package/dist/chunk-35LCBY6P.js +0 -1
  114. package/dist/chunk-4PRDJTCM.js +0 -1
  115. package/dist/chunk-5PELJRUQ.js +0 -1
  116. package/dist/chunk-5VEKHA3B.js +0 -5
  117. package/dist/chunk-6KEM3OS2.js +0 -11
  118. package/dist/chunk-6XWY6GB7.js +0 -1
  119. package/dist/chunk-735KKTP3.js +0 -1
  120. package/dist/chunk-7SWJNDOL.js +0 -26
  121. package/dist/chunk-APKUNIMB.js +0 -1
  122. package/dist/chunk-CJCSZRV6.js +0 -1
  123. package/dist/chunk-DMBMCCLN.js +0 -1
  124. package/dist/chunk-DQTVJITR.js +0 -1
  125. package/dist/chunk-DSKQ5J4R.js +0 -1
  126. package/dist/chunk-E4CJRSND.js +0 -1
  127. package/dist/chunk-EF4DC6IN.js +0 -1
  128. package/dist/chunk-EJAKECSN.js +0 -1
  129. package/dist/chunk-FNQRUMFD.js +0 -1
  130. package/dist/chunk-GJ3RS2VG.js +0 -1
  131. package/dist/chunk-KTVEMB2I.js +0 -1
  132. package/dist/chunk-KYAPE44E.js +0 -8
  133. package/dist/chunk-LI4Y7TBZ.js +0 -1
  134. package/dist/chunk-NHOL4BN6.js +0 -1
  135. package/dist/chunk-NPNUUSIB.js +0 -1
  136. package/dist/chunk-NZ55KBM6.js +0 -1
  137. package/dist/chunk-OFRWGW2G.js +0 -1
  138. package/dist/chunk-OMMJ7B5P.js +0 -1
  139. package/dist/chunk-OMU5BSAS.js +0 -2
  140. package/dist/chunk-P3ZLIQJP.js +0 -1
  141. package/dist/chunk-PWI36BQJ.js +0 -1
  142. package/dist/chunk-QQMUDJ32.js +0 -2
  143. package/dist/chunk-R3ICZOE4.js +0 -1
  144. package/dist/chunk-RZ7FGVI6.js +0 -1
  145. package/dist/chunk-S6WS46FE.js +0 -1
  146. package/dist/chunk-TSARUU56.js +0 -1
  147. package/dist/chunk-WJRVUAZR.js +0 -33
  148. package/dist/chunk-WY5EZOOL.js +0 -1
  149. package/dist/chunk-YY6RZCZH.js +0 -4
  150. package/dist/chunk-ZPGJCHXH.js +0 -1
  151. package/dist/chunk-ZPL2J25N.js +0 -1
  152. package/dist/game/index.d.ts +0 -486
  153. package/dist/game/index.js +0 -1
  154. package/dist/index-DBS5Uefn.d.ts +0 -3156
  155. package/dist/viewport3d-xI33-_wq.d.ts +0 -182
  156. package/dist/virtualViewport-DTSN6jFk.d.ts +0 -1856
@@ -0,0 +1,1909 @@
1
+ import { S as Scheduler } from './scheduler-NbHT3-D2.js';
2
+ import { S as System, W as World, E as Entity } from './types-B8LmNkzG.js';
3
+ import { a as EventBus, U as UIEventMap } from './events-CGqK6LGt.js';
4
+ import { K as KeyEvent } from './keyParser-DReXe2j-.js';
5
+ import { M as MouseEvent } from './mouseParser-CTNGolIA.js';
6
+ import { Writable } from 'node:stream';
7
+ import { a as CellChange, S as ScreenBufferData, C as Cell } from './cell-5Ty_3yMs.js';
8
+ import { D as DoubleBufferData } from './doubleBuffer-d9yVNtj1.js';
9
+ import { a as DirtyTracker } from './dirtyTracking-D0SQrEeo.js';
10
+
11
+ /**
12
+ * Animation system for updating sprite animations.
13
+ * Processes all entities with Animation component.
14
+ * @module systems/animationSystem
15
+ */
16
+
17
+ /**
18
+ * Query all entities with the Animation component.
19
+ *
20
+ * PERF: Returns iterable query result to avoid per-frame allocation.
21
+ *
22
+ * @param world - The ECS world
23
+ * @returns Iterable of entity IDs with Animation component
24
+ */
25
+ declare function queryAnimation(world: World): Iterable<number>;
26
+ /**
27
+ * Checks if an entity has the Animation component (via system store).
28
+ *
29
+ * @param world - The ECS world
30
+ * @param eid - Entity to check
31
+ * @returns true if entity has Animation component
32
+ */
33
+ declare function hasAnimationSystem(world: World, eid: number): boolean;
34
+ /**
35
+ * Animation system that updates all entities with Animation component.
36
+ *
37
+ * This system should be registered in the UPDATE phase of the game loop.
38
+ * It reads delta time from getDeltaTime() which is set by the scheduler.
39
+ *
40
+ * For each playing animation, the system:
41
+ * 1. Adds elapsed time (scaled by speed)
42
+ * 2. Checks if current frame duration exceeded
43
+ * 3. Advances to next frame (respecting direction)
44
+ * 4. Handles loop/stop when animation completes
45
+ * 5. Updates the entity's Sprite component frame
46
+ *
47
+ * @param world - The ECS world to process
48
+ * @returns The world (unchanged reference)
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * import { createScheduler, LoopPhase, animationSystem } from 'blecsd';
53
+ *
54
+ * const scheduler = createScheduler();
55
+ * scheduler.registerSystem(LoopPhase.UPDATE, animationSystem);
56
+ *
57
+ * // In game loop
58
+ * scheduler.run(world, deltaTime);
59
+ * ```
60
+ */
61
+ declare const animationSystem: System;
62
+ /**
63
+ * Creates a new animation system.
64
+ *
65
+ * Factory function that returns the animationSystem.
66
+ * Useful for cases where you need a fresh reference.
67
+ *
68
+ * @returns The animation system function
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * import { createAnimationSystem, createScheduler, LoopPhase } from 'blecsd';
73
+ *
74
+ * const scheduler = createScheduler();
75
+ * const system = createAnimationSystem();
76
+ * scheduler.registerSystem(LoopPhase.UPDATE, system);
77
+ * ```
78
+ */
79
+ declare function createAnimationSystem(): System;
80
+ /**
81
+ * Registers the animation system with a scheduler.
82
+ *
83
+ * Convenience function that registers animationSystem in the UPDATE phase.
84
+ *
85
+ * @param scheduler - The scheduler to register with
86
+ * @param priority - Optional priority within the UPDATE phase (default: 0)
87
+ *
88
+ * @example
89
+ * ```typescript
90
+ * import { createScheduler, registerAnimationSystem } from 'blecsd';
91
+ *
92
+ * const scheduler = createScheduler();
93
+ * registerAnimationSystem(scheduler);
94
+ *
95
+ * // Animation updates will now happen in UPDATE phase
96
+ * scheduler.run(world, deltaTime);
97
+ * ```
98
+ */
99
+ declare function registerAnimationSystem(scheduler: Scheduler, priority?: number): void;
100
+ /**
101
+ * Manually update animations for specific entities.
102
+ *
103
+ * Useful when you need to update animations outside of the system,
104
+ * such as in tests or custom update loops.
105
+ *
106
+ * @param world - The ECS world
107
+ * @param entities - Array of entity IDs to update
108
+ * @param deltaTime - Time elapsed in seconds
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * import { updateAnimations, queryAnimation } from 'blecsd';
113
+ *
114
+ * // Manual update (typically use the system instead)
115
+ * const entities = queryAnimation(world);
116
+ * updateAnimations(world, entities, 0.016); // ~60fps frame
117
+ * ```
118
+ */
119
+ declare function updateAnimations(world: World, entities: readonly number[], deltaTime: number): void;
120
+
121
+ /**
122
+ * Focus Management System
123
+ *
124
+ * Handles keyboard focus navigation and focus state management.
125
+ * Tracks which entity is focused and provides tab/arrow navigation.
126
+ *
127
+ * @module systems/focusSystem
128
+ *
129
+ * @example
130
+ * ```typescript
131
+ * import {
132
+ * focusSystem,
133
+ * focusNext,
134
+ * focusPrev,
135
+ * focusEntity,
136
+ * getFocused,
137
+ * blurAll,
138
+ * } from 'blecsd';
139
+ *
140
+ * // Register with scheduler
141
+ * const scheduler = createScheduler();
142
+ * scheduler.registerSystem(LoopPhase.INPUT, focusSystem);
143
+ *
144
+ * // Navigate focus
145
+ * focusNext(world); // Focus next element
146
+ * focusPrev(world); // Focus previous element
147
+ *
148
+ * // Direct focus
149
+ * focusEntity(world, buttonEntity);
150
+ *
151
+ * // Check current focus
152
+ * const focused = getFocused(world);
153
+ * ```
154
+ */
155
+
156
+ /**
157
+ * Focus event types.
158
+ */
159
+ type FocusEventType = 'focus' | 'blur';
160
+ /**
161
+ * Focus event data.
162
+ */
163
+ interface FocusEventData {
164
+ /** The entity gaining/losing focus */
165
+ readonly entity: Entity;
166
+ /** The previously focused entity (for focus events) */
167
+ readonly previousEntity: Entity | null;
168
+ /** The next focused entity (for blur events) */
169
+ readonly nextEntity: Entity | null;
170
+ }
171
+ /**
172
+ * Focus event map for type-safe event handling.
173
+ */
174
+ interface FocusEventMap {
175
+ focus: FocusEventData;
176
+ blur: FocusEventData;
177
+ }
178
+ /**
179
+ * Gets the focus event bus, creating if needed.
180
+ *
181
+ * @returns The focus event bus
182
+ *
183
+ * @example
184
+ * ```typescript
185
+ * const bus = getFocusEventBus();
186
+ * bus.on('focus', (data) => {
187
+ * console.log(`Entity ${data.entity} focused`);
188
+ * });
189
+ * ```
190
+ */
191
+ declare function getFocusEventBus(): EventBus<FocusEventMap>;
192
+ /**
193
+ * Resets the focus event bus. Used for testing.
194
+ * @internal
195
+ */
196
+ declare function resetFocusEventBus(): void;
197
+ /**
198
+ * Gets all focusable entities sorted by tab order.
199
+ *
200
+ * @param world - The ECS world
201
+ * @returns Sorted array of focusable entity IDs
202
+ */
203
+ declare function getFocusableEntities(world: World): Entity[];
204
+ /**
205
+ * Gets the currently focused entity.
206
+ *
207
+ * @param world - The ECS world
208
+ * @returns The focused entity or null if none focused
209
+ *
210
+ * @example
211
+ * ```typescript
212
+ * const focused = getFocused(world);
213
+ * if (focused) {
214
+ * console.log(`Entity ${focused} is focused`);
215
+ * }
216
+ * ```
217
+ */
218
+ declare function getFocused(world: World): Entity | null;
219
+ /**
220
+ * Focuses a specific entity.
221
+ *
222
+ * @param world - The ECS world
223
+ * @param eid - The entity to focus
224
+ * @returns true if focus was set successfully
225
+ *
226
+ * @example
227
+ * ```typescript
228
+ * focusEntity(world, buttonEntity);
229
+ * ```
230
+ */
231
+ declare function focusEntity(world: World, eid: Entity): boolean;
232
+ /**
233
+ * Removes focus from all entities.
234
+ *
235
+ * @param world - The ECS world
236
+ *
237
+ * @example
238
+ * ```typescript
239
+ * blurAll(world);
240
+ * ```
241
+ */
242
+ declare function blurAll(world: World): void;
243
+ /**
244
+ * Focuses the next focusable entity in tab order.
245
+ *
246
+ * @param world - The ECS world
247
+ * @returns The newly focused entity, or null if none available
248
+ *
249
+ * @example
250
+ * ```typescript
251
+ * // Handle Tab key
252
+ * if (key === 'Tab') {
253
+ * focusNext(world);
254
+ * }
255
+ * ```
256
+ */
257
+ declare function focusNext(world: World): Entity | null;
258
+ /**
259
+ * Focuses the previous focusable entity in tab order.
260
+ *
261
+ * @param world - The ECS world
262
+ * @returns The newly focused entity, or null if none available
263
+ *
264
+ * @example
265
+ * ```typescript
266
+ * // Handle Shift+Tab key
267
+ * if (key === 'Tab' && shiftKey) {
268
+ * focusPrev(world);
269
+ * }
270
+ * ```
271
+ */
272
+ declare function focusPrev(world: World): Entity | null;
273
+ /**
274
+ * Focuses the first focusable entity.
275
+ *
276
+ * @param world - The ECS world
277
+ * @returns The focused entity, or null if none available
278
+ */
279
+ declare function focusFirst(world: World): Entity | null;
280
+ /**
281
+ * Focuses the last focusable entity.
282
+ *
283
+ * @param world - The ECS world
284
+ * @returns The focused entity, or null if none available
285
+ */
286
+ declare function focusLast(world: World): Entity | null;
287
+ /**
288
+ * Pushes current focus onto the stack and focuses a new entity.
289
+ *
290
+ * Use this when opening modals or popups to preserve the previous focus
291
+ * state for restoration later.
292
+ *
293
+ * @param world - The ECS world
294
+ * @param eid - The entity to focus (e.g., modal or popup)
295
+ * @returns true if push was successful
296
+ *
297
+ * @example
298
+ * ```typescript
299
+ * import { focusPush, focusPop } from 'blecsd';
300
+ *
301
+ * // Open modal - save current focus and focus modal
302
+ * function openModal(world: World, modalEntity: Entity): void {
303
+ * focusPush(world, modalEntity);
304
+ * }
305
+ *
306
+ * // Close modal - restore previous focus
307
+ * function closeModal(world: World): void {
308
+ * focusPop(world);
309
+ * }
310
+ * ```
311
+ */
312
+ declare function focusPush(world: World, eid: Entity): boolean;
313
+ /**
314
+ * Pops the focus stack and restores the previous focus.
315
+ *
316
+ * Use this when closing modals or popups to restore focus to the
317
+ * element that was focused before.
318
+ *
319
+ * @param world - The ECS world
320
+ * @returns The restored entity, or null if stack was empty
321
+ *
322
+ * @example
323
+ * ```typescript
324
+ * import { focusPop } from 'blecsd';
325
+ *
326
+ * // Close modal and restore focus
327
+ * const previousFocus = focusPop(world);
328
+ * if (previousFocus) {
329
+ * console.log(`Focus restored to entity ${previousFocus}`);
330
+ * }
331
+ * ```
332
+ */
333
+ declare function focusPop(world: World): Entity | null;
334
+ /**
335
+ * Saves the current focus without affecting the stack.
336
+ *
337
+ * Use this for temporary focus changes that need to be restored
338
+ * without the full stack mechanism.
339
+ *
340
+ * @param world - The ECS world
341
+ *
342
+ * @example
343
+ * ```typescript
344
+ * import { saveFocus, restoreFocus } from 'blecsd';
345
+ *
346
+ * // Save current focus before temporary change
347
+ * saveFocus(world);
348
+ *
349
+ * // ... do something that changes focus ...
350
+ *
351
+ * // Restore the saved focus
352
+ * restoreFocus(world);
353
+ * ```
354
+ */
355
+ declare function saveFocus(world: World): void;
356
+ /**
357
+ * Restores the previously saved focus.
358
+ *
359
+ * @param world - The ECS world
360
+ * @returns The restored entity, or null if no saved focus or entity invalid
361
+ *
362
+ * @example
363
+ * ```typescript
364
+ * import { restoreFocus } from 'blecsd';
365
+ *
366
+ * const restored = restoreFocus(world);
367
+ * ```
368
+ */
369
+ declare function restoreFocus(world: World): Entity | null;
370
+ /**
371
+ * Rewinds focus to the last valid entity in the stack.
372
+ *
373
+ * This is useful when the currently focused entity is destroyed or
374
+ * becomes unfocusable. It searches backwards through the focus stack
375
+ * to find an entity that still exists and is focusable.
376
+ *
377
+ * @param world - The ECS world
378
+ * @returns The entity that received focus, or null if none found
379
+ *
380
+ * @example
381
+ * ```typescript
382
+ * import { rewindFocus } from 'blecsd';
383
+ *
384
+ * // After destroying a focused entity
385
+ * rewindFocus(world);
386
+ * ```
387
+ */
388
+ declare function rewindFocus(world: World): Entity | null;
389
+ /**
390
+ * Moves focus by a specified offset in the tab order.
391
+ *
392
+ * Positive offset moves forward (like Tab), negative moves backward
393
+ * (like Shift+Tab). The offset wraps around at the ends.
394
+ *
395
+ * @param world - The ECS world
396
+ * @param offset - Number of positions to move (positive=forward, negative=backward)
397
+ * @returns The newly focused entity, or null if none available
398
+ *
399
+ * @example
400
+ * ```typescript
401
+ * import { focusOffset } from 'blecsd';
402
+ *
403
+ * // Move focus forward by 2
404
+ * focusOffset(world, 2);
405
+ *
406
+ * // Move focus backward by 1
407
+ * focusOffset(world, -1);
408
+ * ```
409
+ */
410
+ declare function focusOffset(world: World, offset: number): Entity | null;
411
+ /**
412
+ * Gets the current focus stack depth.
413
+ *
414
+ * @param world - The ECS world
415
+ * @returns Number of entries in the focus stack
416
+ */
417
+ declare function getFocusStackDepth(world: World): number;
418
+ /**
419
+ * Clears the focus stack.
420
+ *
421
+ * Use with caution - this removes all saved focus states.
422
+ *
423
+ * @param world - The ECS world
424
+ */
425
+ declare function clearFocusStack(world: World): void;
426
+ /**
427
+ * Peeks at the top of the focus stack without popping.
428
+ *
429
+ * @param world - The ECS world
430
+ * @returns The entity at the top of the stack, or null if empty
431
+ */
432
+ declare function peekFocusStack(world: World): Entity | null;
433
+ /**
434
+ * Focus system that processes focus-related input.
435
+ *
436
+ * Currently this system validates focus state (ensuring focused entity
437
+ * is still focusable and visible). Tab key handling should be done
438
+ * in the input system or user code.
439
+ *
440
+ * @param world - The ECS world
441
+ * @returns The world
442
+ *
443
+ * @example
444
+ * ```typescript
445
+ * import { focusSystem, createScheduler, LoopPhase } from 'blecsd';
446
+ *
447
+ * const scheduler = createScheduler();
448
+ * scheduler.registerSystem(LoopPhase.INPUT, focusSystem);
449
+ * ```
450
+ */
451
+ declare const focusSystem: System;
452
+ /**
453
+ * Creates a focus system.
454
+ *
455
+ * @returns A new focus system function
456
+ */
457
+ declare function createFocusSystem(): System;
458
+
459
+ /**
460
+ * Input system for processing keyboard and mouse events.
461
+ * Handles hit testing, focus management, and event dispatch.
462
+ * @module systems/inputSystem
463
+ */
464
+
465
+ /**
466
+ * Input event types that can be queued.
467
+ */
468
+ type InputEventType = 'key' | 'mouse';
469
+ /**
470
+ * Queued key event.
471
+ */
472
+ interface QueuedKeyEvent {
473
+ type: 'key';
474
+ event: KeyEvent;
475
+ timestamp: number;
476
+ }
477
+ /**
478
+ * Queued mouse event.
479
+ */
480
+ interface QueuedMouseEvent {
481
+ type: 'mouse';
482
+ event: MouseEvent;
483
+ timestamp: number;
484
+ }
485
+ /**
486
+ * Union of all queued input events.
487
+ */
488
+ type QueuedInputEvent = QueuedKeyEvent | QueuedMouseEvent;
489
+ /**
490
+ * Result of hit testing a point.
491
+ */
492
+ interface HitTestResult {
493
+ /** Entity that was hit */
494
+ entity: Entity;
495
+ /** Local X coordinate within the entity */
496
+ localX: number;
497
+ /** Local Y coordinate within the entity */
498
+ localY: number;
499
+ /** Z-index of the entity */
500
+ zIndex: number;
501
+ }
502
+ /**
503
+ * Input system state and configuration.
504
+ */
505
+ interface InputSystemState {
506
+ /** Queue of pending input events */
507
+ eventQueue: QueuedInputEvent[];
508
+ /** Entity that currently has mouse capture (for drag operations) */
509
+ capturedEntity: Entity | null;
510
+ /** Last known mouse position */
511
+ lastMouseX: number;
512
+ lastMouseY: number;
513
+ /** Entity under the mouse last frame */
514
+ lastHoveredEntity: Entity | null;
515
+ /** Global event bus for dispatching UI events */
516
+ eventBus: EventBus<UIEventMap>;
517
+ }
518
+ /**
519
+ * Global input system state.
520
+ * Can be accessed and modified for testing or custom input handling.
521
+ */
522
+ declare const inputState: InputSystemState;
523
+ /**
524
+ * Resets input system state.
525
+ * Useful for testing or when reinitializing the input system.
526
+ *
527
+ * @example
528
+ * ```typescript
529
+ * import { resetInputState } from 'blecsd';
530
+ *
531
+ * // Clear all pending events and state
532
+ * resetInputState();
533
+ * ```
534
+ */
535
+ declare function resetInputState(): void;
536
+ /**
537
+ * Queues a keyboard event for processing.
538
+ *
539
+ * @param event - The parsed key event from the input stream
540
+ *
541
+ * @example
542
+ * ```typescript
543
+ * import { queueKeyEvent } from 'blecsd';
544
+ *
545
+ * // Queue a key event for next frame
546
+ * queueKeyEvent({ name: 'a', ctrl: false, meta: false, shift: false, raw: 'a' });
547
+ * ```
548
+ */
549
+ declare function queueKeyEvent(event: KeyEvent): void;
550
+ /**
551
+ * Queues a mouse event for processing.
552
+ *
553
+ * @param event - The parsed mouse event from the input stream
554
+ *
555
+ * @example
556
+ * ```typescript
557
+ * import { queueMouseEvent } from 'blecsd';
558
+ *
559
+ * // Queue a mouse event for next frame
560
+ * queueMouseEvent({ x: 10, y: 5, button: 'left', action: 'press', raw: '' });
561
+ * ```
562
+ */
563
+ declare function queueMouseEvent(event: MouseEvent): void;
564
+ /**
565
+ * Gets the current event queue.
566
+ * Mainly useful for debugging and testing.
567
+ */
568
+ declare function getEventQueue(): readonly QueuedInputEvent[];
569
+ /**
570
+ * Clears all queued events.
571
+ */
572
+ declare function clearEventQueue(): void;
573
+ /**
574
+ * Gets the global input event bus.
575
+ * Use this to subscribe to UI events from anywhere.
576
+ *
577
+ * @returns The global UI event bus
578
+ *
579
+ * @example
580
+ * ```typescript
581
+ * import { getInputEventBus } from 'blecsd';
582
+ *
583
+ * const eventBus = getInputEventBus();
584
+ * eventBus.on('click', (event) => {
585
+ * console.log(`Clicked at ${event.x}, ${event.y}`);
586
+ * });
587
+ * ```
588
+ */
589
+ declare function getInputEventBus(): EventBus<UIEventMap>;
590
+ /**
591
+ * Captures mouse events to a specific entity.
592
+ * While captured, all mouse events are sent to this entity
593
+ * regardless of hit testing. Used for drag operations.
594
+ *
595
+ * @param entity - Entity to capture events to, or null to release
596
+ *
597
+ * @example
598
+ * ```typescript
599
+ * import { captureMouseTo, releaseMouse } from 'blecsd';
600
+ *
601
+ * // Start drag
602
+ * captureMouseTo(entityId);
603
+ *
604
+ * // End drag
605
+ * releaseMouse();
606
+ * ```
607
+ */
608
+ declare function captureMouseTo(entity: Entity | null): void;
609
+ /**
610
+ * Releases mouse capture.
611
+ */
612
+ declare function releaseMouse(): void;
613
+ /**
614
+ * Checks if an entity is currently capturing mouse events.
615
+ */
616
+ declare function isMouseCaptured(): boolean;
617
+ /**
618
+ * Gets the entity currently capturing mouse events.
619
+ */
620
+ declare function getMouseCaptureEntity(): Entity | null;
621
+ /**
622
+ * Tests if a point is inside an entity's bounding box.
623
+ * Uses Position and Dimensions components.
624
+ *
625
+ * @param world - The ECS world
626
+ * @param eid - Entity to test
627
+ * @param x - X coordinate to test
628
+ * @param y - Y coordinate to test
629
+ * @returns true if point is inside entity bounds
630
+ *
631
+ * @example
632
+ * ```typescript
633
+ * import { pointInEntity } from 'blecsd';
634
+ *
635
+ * if (pointInEntity(world, entity, mouseX, mouseY)) {
636
+ * console.log('Mouse is over entity');
637
+ * }
638
+ * ```
639
+ */
640
+ declare function pointInEntity(world: World, eid: Entity, x: number, y: number): boolean;
641
+ /**
642
+ * Performs hit testing at a point to find all entities under it.
643
+ * Returns entities sorted by z-index (highest first).
644
+ *
645
+ * PERF: Uses iterator directly to avoid intermediate array allocation.
646
+ *
647
+ * @param world - The ECS world
648
+ * @param x - X coordinate to test
649
+ * @param y - Y coordinate to test
650
+ * @returns Array of hit test results, sorted by z-index (highest first)
651
+ *
652
+ * @example
653
+ * ```typescript
654
+ * import { hitTest } from 'blecsd';
655
+ *
656
+ * const hits = hitTest(world, mouseX, mouseY);
657
+ * if (hits.length > 0) {
658
+ * const topEntity = hits[0].entity;
659
+ * console.log(`Top entity at click: ${topEntity}`);
660
+ * }
661
+ * ```
662
+ */
663
+ declare function hitTest(world: World, x: number, y: number): HitTestResult[];
664
+ /**
665
+ * Gets the topmost interactive entity at a point.
666
+ * Only returns entities that can receive input.
667
+ *
668
+ * @param world - The ECS world
669
+ * @param x - X coordinate to test
670
+ * @param y - Y coordinate to test
671
+ * @returns The topmost interactive entity or null
672
+ */
673
+ declare function getInteractiveEntityAt(world: World, x: number, y: number): Entity | null;
674
+ /**
675
+ * The input system processes all queued input events.
676
+ * This system should be registered in the INPUT phase (automatically protected).
677
+ *
678
+ * The system:
679
+ * 1. Processes all queued key and mouse events
680
+ * 2. Updates KeyboardInput and MouseInput components
681
+ * 3. Performs hit testing for mouse events
682
+ * 4. Updates Interactive component state (hovered, pressed)
683
+ * 5. Manages focus changes (click to focus, Tab navigation)
684
+ * 6. Dispatches UI events to the event bus
685
+ *
686
+ * @param world - The ECS world to process
687
+ * @returns The world (unchanged reference)
688
+ *
689
+ * @example
690
+ * ```typescript
691
+ * import { createScheduler, inputSystem, registerInputSystem } from 'blecsd';
692
+ *
693
+ * const scheduler = createScheduler();
694
+ * registerInputSystem(scheduler);
695
+ *
696
+ * // In game loop
697
+ * scheduler.run(world, deltaTime);
698
+ * ```
699
+ */
700
+ declare const inputSystem: System;
701
+ /**
702
+ * Creates a new input system.
703
+ *
704
+ * Factory function that returns the inputSystem.
705
+ * Useful for cases where you need a fresh reference.
706
+ *
707
+ * @returns The input system function
708
+ *
709
+ * @example
710
+ * ```typescript
711
+ * import { createInputSystem, createScheduler } from 'blecsd';
712
+ *
713
+ * const scheduler = createScheduler();
714
+ * const system = createInputSystem();
715
+ * // Note: Use registerInputSystem instead for proper INPUT phase registration
716
+ * ```
717
+ */
718
+ declare function createInputSystem(): System;
719
+ /**
720
+ * Registers the input system with a scheduler.
721
+ *
722
+ * Registers inputSystem in the protected INPUT phase.
723
+ * This ensures input is always processed first.
724
+ *
725
+ * @param scheduler - The scheduler to register with
726
+ * @param priority - Optional priority within the INPUT phase (default: 0)
727
+ *
728
+ * @example
729
+ * ```typescript
730
+ * import { createScheduler, registerInputSystem } from 'blecsd';
731
+ *
732
+ * const scheduler = createScheduler();
733
+ * registerInputSystem(scheduler);
734
+ *
735
+ * // Input events will now be processed in INPUT phase
736
+ * scheduler.run(world, deltaTime);
737
+ * ```
738
+ */
739
+ declare function registerInputSystem(scheduler: Scheduler, priority?: number): void;
740
+ /**
741
+ * Clears input state for an entity.
742
+ * Resets KeyboardInput and MouseInput components to default state.
743
+ *
744
+ * @param world - The ECS world
745
+ * @param eid - Entity to clear input state for
746
+ *
747
+ * @example
748
+ * ```typescript
749
+ * import { clearEntityInput } from 'blecsd';
750
+ *
751
+ * // Clear all input state when entity loses focus
752
+ * clearEntityInput(world, entity);
753
+ * ```
754
+ */
755
+ declare function clearEntityInput(world: World, eid: Entity): void;
756
+ /**
757
+ * Query all entities that can receive input.
758
+ * Returns entities with either Interactive or Focusable components.
759
+ *
760
+ * PERF: Reuses module-level scratch array to avoid per-call allocation.
761
+ * The returned array is only valid until the next call to this function.
762
+ *
763
+ * @param world - The ECS world
764
+ * @returns Array of entity IDs that can receive input (reused buffer)
765
+ */
766
+ declare function queryInputReceivers(world: World): number[];
767
+
768
+ /**
769
+ * Layout system for computing entity positions and dimensions.
770
+ * Runs in the LAYOUT phase to pre-compute absolute positions in tree order.
771
+ * @module systems/layoutSystem
772
+ */
773
+
774
+ /**
775
+ * Computed Layout component stores the final computed positions and dimensions.
776
+ * This component is written by the layout system and read by the render system.
777
+ *
778
+ * @example
779
+ * ```typescript
780
+ * import { ComputedLayout, getComputedLayout } from 'blecsd';
781
+ *
782
+ * // After layout system runs, computed values are available
783
+ * const layout = getComputedLayout(world, entity);
784
+ * if (layout) {
785
+ * console.log(`Absolute: (${layout.x}, ${layout.y})`);
786
+ * console.log(`Size: ${layout.width}x${layout.height}`);
787
+ * }
788
+ * ```
789
+ */
790
+ declare const ComputedLayout: {
791
+ /** Computed absolute X position (screen column) */
792
+ x: Float32Array<ArrayBuffer>;
793
+ /** Computed absolute Y position (screen row) */
794
+ y: Float32Array<ArrayBuffer>;
795
+ /** Computed width in cells */
796
+ width: Float32Array<ArrayBuffer>;
797
+ /** Computed height in cells */
798
+ height: Float32Array<ArrayBuffer>;
799
+ /** Whether layout is valid (0 = needs recompute, 1 = valid) */
800
+ valid: Uint8Array<ArrayBuffer>;
801
+ };
802
+ /**
803
+ * Computed layout data returned by getComputedLayout.
804
+ */
805
+ interface ComputedLayoutData {
806
+ readonly x: number;
807
+ readonly y: number;
808
+ readonly width: number;
809
+ readonly height: number;
810
+ }
811
+ /**
812
+ * Gets the computed layout of an entity.
813
+ *
814
+ * @param world - The ECS world
815
+ * @param eid - The entity ID
816
+ * @returns Computed layout data or undefined if not available
817
+ *
818
+ * @example
819
+ * ```typescript
820
+ * const layout = getComputedLayout(world, entity);
821
+ * if (layout) {
822
+ * console.log(`Position: (${layout.x}, ${layout.y})`);
823
+ * }
824
+ * ```
825
+ */
826
+ declare function getComputedLayout(world: World, eid: Entity): ComputedLayoutData | undefined;
827
+ /**
828
+ * Checks if an entity has a valid computed layout.
829
+ *
830
+ * @param world - The ECS world
831
+ * @param eid - The entity ID
832
+ * @returns true if the entity has a valid computed layout
833
+ */
834
+ declare function hasComputedLayout(world: World, eid: Entity): boolean;
835
+ /**
836
+ * Invalidates the computed layout of an entity.
837
+ * Call this when position or dimensions change to trigger recalculation.
838
+ *
839
+ * @param world - The ECS world
840
+ * @param eid - The entity ID
841
+ */
842
+ declare function invalidateLayout(world: World, eid: Entity): void;
843
+ /**
844
+ * Layout system that computes absolute positions for all entities.
845
+ * Runs in tree order (parents before children) to support relative positioning.
846
+ *
847
+ * The system:
848
+ * 1. Finds all root entities (no parent)
849
+ * 2. Computes layout for each root and its descendants
850
+ * 3. Handles percentage dimensions relative to parent
851
+ * 4. Respects min/max constraints
852
+ * 5. Stores results in ComputedLayout component
853
+ *
854
+ * @param world - The ECS world
855
+ * @returns The world (unchanged)
856
+ *
857
+ * @example
858
+ * ```typescript
859
+ * import { layoutSystem, createScheduler, LoopPhase } from 'blecsd';
860
+ *
861
+ * const scheduler = createScheduler();
862
+ * scheduler.registerSystem(LoopPhase.LAYOUT, layoutSystem);
863
+ * ```
864
+ */
865
+ declare const layoutSystem: System;
866
+ /**
867
+ * Creates the layout system function.
868
+ * This is an alternative to using the layoutSystem directly for custom configuration.
869
+ *
870
+ * @returns A new layout system function
871
+ *
872
+ * @example
873
+ * ```typescript
874
+ * import { createLayoutSystem, createScheduler, LoopPhase } from 'blecsd';
875
+ *
876
+ * const scheduler = createScheduler();
877
+ * scheduler.registerSystem(LoopPhase.LAYOUT, createLayoutSystem());
878
+ * ```
879
+ */
880
+ declare function createLayoutSystem(): System;
881
+ /**
882
+ * Forces a full layout recalculation for all entities.
883
+ * Call this after major changes like screen resize.
884
+ *
885
+ * @param world - The ECS world
886
+ *
887
+ * @example
888
+ * ```typescript
889
+ * import { invalidateAllLayouts } from 'blecsd';
890
+ *
891
+ * // After terminal resize
892
+ * invalidateAllLayouts(world);
893
+ * ```
894
+ */
895
+ declare function invalidateAllLayouts(world: World): void;
896
+ /**
897
+ * Computes layout for a single entity immediately.
898
+ * Useful for getting layout outside the normal system loop.
899
+ *
900
+ * @param world - The ECS world
901
+ * @param eid - The entity ID
902
+ * @returns Computed layout data or undefined if entity lacks Position
903
+ *
904
+ * @example
905
+ * ```typescript
906
+ * import { computeLayoutNow } from 'blecsd';
907
+ *
908
+ * const layout = computeLayoutNow(world, entity);
909
+ * if (layout) {
910
+ * console.log(`Position: (${layout.x}, ${layout.y})`);
911
+ * }
912
+ * ```
913
+ */
914
+ declare function computeLayoutNow(world: World, eid: Entity): ComputedLayoutData | undefined;
915
+ /**
916
+ * Gets the computed content bounds for an entity (position + dimensions).
917
+ * Returns the bounding rectangle in screen coordinates.
918
+ *
919
+ * @param world - The ECS world
920
+ * @param eid - The entity ID
921
+ * @returns Bounding rectangle or undefined
922
+ *
923
+ * @example
924
+ * ```typescript
925
+ * import { getComputedBounds } from 'blecsd';
926
+ *
927
+ * const bounds = getComputedBounds(world, entity);
928
+ * if (bounds) {
929
+ * console.log(`Bounds: (${bounds.left}, ${bounds.top}) to (${bounds.right}, ${bounds.bottom})`);
930
+ * }
931
+ * ```
932
+ */
933
+ declare function getComputedBounds(world: World, eid: Entity): {
934
+ left: number;
935
+ top: number;
936
+ right: number;
937
+ bottom: number;
938
+ } | undefined;
939
+
940
+ /**
941
+ * Output system for writing rendered buffer to terminal.
942
+ * Runs in the POST_RENDER phase after all rendering is complete.
943
+ * @module systems/outputSystem
944
+ */
945
+
946
+ /**
947
+ * Output state maintained across frames.
948
+ */
949
+ interface OutputState {
950
+ /** Last cursor X position (0-indexed) */
951
+ lastX: number;
952
+ /** Last cursor Y position (0-indexed) */
953
+ lastY: number;
954
+ /** Last foreground color */
955
+ lastFg: number;
956
+ /** Last background color */
957
+ lastBg: number;
958
+ /** Last attributes */
959
+ lastAttrs: number;
960
+ /** Whether we're in alternate screen mode */
961
+ alternateScreen: boolean;
962
+ /** Whether mouse tracking is enabled */
963
+ mouseTracking: boolean;
964
+ /** Mouse tracking mode */
965
+ mouseMode: string | null;
966
+ /** Whether synchronized output is active */
967
+ syncOutput: boolean;
968
+ /** Whether bracketed paste mode is enabled */
969
+ bracketedPaste: boolean;
970
+ /** Whether focus reporting is enabled */
971
+ focusReporting: boolean;
972
+ }
973
+ /**
974
+ * Creates initial output state.
975
+ */
976
+ declare function createOutputState(): OutputState;
977
+ declare function generateOutput(world: World, state: OutputState, changes: readonly CellChange[], skipSort?: boolean): string;
978
+ /**
979
+ * Sets the output stream for the output system.
980
+ *
981
+ * @param stream - Writable stream (typically process.stdout)
982
+ *
983
+ * @example
984
+ * ```typescript
985
+ * import { setOutputStream } from 'blecsd';
986
+ *
987
+ * setOutputStream(process.stdout);
988
+ * ```
989
+ */
990
+ declare function setOutputStream(stream: Writable): void;
991
+ /**
992
+ * Gets the current output stream.
993
+ *
994
+ * @returns The current output stream or null
995
+ */
996
+ declare function getOutputStream(): Writable | null;
997
+ /**
998
+ * Clears the output stream reference.
999
+ */
1000
+ declare function clearOutputStream(): void;
1001
+ /**
1002
+ * Sets the double buffer for the output system.
1003
+ *
1004
+ * @param db - The double buffer
1005
+ *
1006
+ * @example
1007
+ * ```typescript
1008
+ * import { setOutputBuffer, createDoubleBuffer } from 'blecsd';
1009
+ *
1010
+ * const db = createDoubleBuffer(80, 24);
1011
+ * setOutputBuffer(db);
1012
+ * ```
1013
+ */
1014
+ declare function setOutputBuffer(db: DoubleBufferData): void;
1015
+ /**
1016
+ * Gets the current output buffer.
1017
+ *
1018
+ * @returns The current double buffer or null
1019
+ */
1020
+ declare function getOutputBuffer(): DoubleBufferData | null;
1021
+ /**
1022
+ * Clears the output buffer reference.
1023
+ */
1024
+ declare function clearOutputBuffer(): void;
1025
+ /**
1026
+ * Gets or creates the output state.
1027
+ *
1028
+ * @returns The output state
1029
+ */
1030
+ declare function getOutputState(): OutputState;
1031
+ /**
1032
+ * Resets the output state.
1033
+ */
1034
+ declare function resetOutputState(): void;
1035
+ /**
1036
+ * Output system that writes rendered content to the terminal.
1037
+ *
1038
+ * The system:
1039
+ * 1. Gets minimal updates from the double buffer
1040
+ * 2. Generates optimized ANSI sequences
1041
+ * 3. Writes to the output stream
1042
+ * 4. Swaps buffers and clears dirty regions
1043
+ *
1044
+ * @param world - The ECS world
1045
+ * @returns The world (unchanged)
1046
+ *
1047
+ * @example
1048
+ * ```typescript
1049
+ * import {
1050
+ * outputSystem,
1051
+ * setOutputStream,
1052
+ * setOutputBuffer,
1053
+ * createScheduler,
1054
+ * LoopPhase,
1055
+ * } from 'blecsd';
1056
+ *
1057
+ * // Setup
1058
+ * setOutputStream(process.stdout);
1059
+ * setOutputBuffer(doubleBuffer);
1060
+ *
1061
+ * // Register in POST_RENDER phase
1062
+ * const scheduler = createScheduler();
1063
+ * scheduler.registerSystem(LoopPhase.POST_RENDER, outputSystem);
1064
+ * ```
1065
+ */
1066
+ declare const outputSystem: System;
1067
+ /**
1068
+ * Creates the output system function.
1069
+ *
1070
+ * @returns A new output system function
1071
+ *
1072
+ * @example
1073
+ * ```typescript
1074
+ * import { createOutputSystem, createScheduler, LoopPhase } from 'blecsd';
1075
+ *
1076
+ * const scheduler = createScheduler();
1077
+ * scheduler.registerSystem(LoopPhase.POST_RENDER, createOutputSystem());
1078
+ * ```
1079
+ */
1080
+ declare function createOutputSystem(): System;
1081
+ /**
1082
+ * Writes raw output to the stream.
1083
+ * Bypasses the double buffer for immediate output.
1084
+ *
1085
+ * @param data - String data to write
1086
+ *
1087
+ * @example
1088
+ * ```typescript
1089
+ * import { writeRaw } from 'blecsd';
1090
+ *
1091
+ * // Write raw ANSI sequence
1092
+ * writeRaw('\x1b[2J'); // Clear screen
1093
+ * ```
1094
+ */
1095
+ declare function writeRaw(data: string): void;
1096
+ /**
1097
+ * Hides the terminal cursor.
1098
+ *
1099
+ * @example
1100
+ * ```typescript
1101
+ * import { hideCursor } from 'blecsd';
1102
+ *
1103
+ * hideCursor();
1104
+ * ```
1105
+ */
1106
+ declare function hideCursor(): void;
1107
+ /**
1108
+ * Shows the terminal cursor.
1109
+ *
1110
+ * @example
1111
+ * ```typescript
1112
+ * import { showCursor } from 'blecsd';
1113
+ *
1114
+ * showCursor();
1115
+ * ```
1116
+ */
1117
+ declare function showCursor(): void;
1118
+ /**
1119
+ * Enters alternate screen buffer mode.
1120
+ *
1121
+ * @example
1122
+ * ```typescript
1123
+ * import { enterAlternateScreen } from 'blecsd';
1124
+ *
1125
+ * enterAlternateScreen();
1126
+ * // ... render application ...
1127
+ * leaveAlternateScreen();
1128
+ * ```
1129
+ */
1130
+ declare function enterAlternateScreen(): void;
1131
+ /**
1132
+ * Leaves alternate screen buffer mode.
1133
+ *
1134
+ * @example
1135
+ * ```typescript
1136
+ * import { leaveAlternateScreen } from 'blecsd';
1137
+ *
1138
+ * leaveAlternateScreen();
1139
+ * ```
1140
+ */
1141
+ declare function leaveAlternateScreen(): void;
1142
+ /**
1143
+ * Clears the entire screen.
1144
+ *
1145
+ * @example
1146
+ * ```typescript
1147
+ * import { clearScreen } from 'blecsd';
1148
+ *
1149
+ * clearScreen();
1150
+ * ```
1151
+ */
1152
+ declare function clearScreen(): void;
1153
+ /**
1154
+ * Moves cursor to home position (0, 0).
1155
+ *
1156
+ * @example
1157
+ * ```typescript
1158
+ * import { cursorHome } from 'blecsd';
1159
+ *
1160
+ * cursorHome();
1161
+ * ```
1162
+ */
1163
+ declare function cursorHome(): void;
1164
+ /**
1165
+ * Resets all terminal attributes.
1166
+ *
1167
+ * @example
1168
+ * ```typescript
1169
+ * import { resetAttributes } from 'blecsd';
1170
+ *
1171
+ * resetAttributes();
1172
+ * ```
1173
+ */
1174
+ declare function resetAttributes(): void;
1175
+ /**
1176
+ * Rings the terminal bell.
1177
+ *
1178
+ * @example
1179
+ * ```typescript
1180
+ * import { bell } from 'blecsd';
1181
+ *
1182
+ * bell(); // Produce audible or visual bell
1183
+ * ```
1184
+ */
1185
+ declare function bell(): void;
1186
+ /**
1187
+ * Moves cursor to a specific position.
1188
+ *
1189
+ * @param x - Column position (0-indexed)
1190
+ * @param y - Row position (0-indexed)
1191
+ *
1192
+ * @example
1193
+ * ```typescript
1194
+ * import { moveTo } from 'blecsd';
1195
+ *
1196
+ * moveTo(10, 5); // Move to column 10, row 5
1197
+ * ```
1198
+ */
1199
+ declare function moveTo(x: number, y: number): void;
1200
+ /**
1201
+ * Enables mouse tracking in the terminal.
1202
+ *
1203
+ * @param mode - Mouse tracking mode: 'normal' (clicks only), 'button' (clicks + drag), or 'any' (all motion). Default is 'any'.
1204
+ *
1205
+ * @example
1206
+ * ```typescript
1207
+ * import { enableMouseTracking } from 'blecsd';
1208
+ *
1209
+ * enableMouseTracking('any'); // Track all mouse motion
1210
+ * enableMouseTracking('button'); // Track only when button pressed
1211
+ * enableMouseTracking('normal'); // Track clicks only
1212
+ * ```
1213
+ */
1214
+ declare function enableMouseTracking(mode?: 'normal' | 'button' | 'any'): void;
1215
+ /**
1216
+ * Disables mouse tracking in the terminal.
1217
+ *
1218
+ * @example
1219
+ * ```typescript
1220
+ * import { disableMouseTracking } from 'blecsd';
1221
+ *
1222
+ * disableMouseTracking();
1223
+ * ```
1224
+ */
1225
+ declare function disableMouseTracking(): void;
1226
+ /**
1227
+ * Sets the terminal cursor shape.
1228
+ *
1229
+ * @param shape - Cursor shape: 'block', 'underline', or 'bar'
1230
+ *
1231
+ * @example
1232
+ * ```typescript
1233
+ * import { setTerminalCursorShape } from 'blecsd';
1234
+ *
1235
+ * setTerminalCursorShape('block'); // Block cursor
1236
+ * setTerminalCursorShape('underline'); // Underline cursor
1237
+ * setTerminalCursorShape('bar'); // Bar/vertical line cursor
1238
+ * ```
1239
+ */
1240
+ declare function setTerminalCursorShape(shape: 'block' | 'underline' | 'bar'): void;
1241
+ /**
1242
+ * Sets the terminal window title.
1243
+ *
1244
+ * @param title - Window title string
1245
+ *
1246
+ * @example
1247
+ * ```typescript
1248
+ * import { setWindowTitle } from 'blecsd';
1249
+ *
1250
+ * setWindowTitle('My Terminal App');
1251
+ * ```
1252
+ */
1253
+ declare function setWindowTitle(title: string): void;
1254
+ /**
1255
+ * Begins synchronized output mode.
1256
+ * Prevents partial screen updates from being displayed.
1257
+ *
1258
+ * @example
1259
+ * ```typescript
1260
+ * import { beginSyncOutput, endSyncOutput } from 'blecsd';
1261
+ *
1262
+ * beginSyncOutput();
1263
+ * // ... render multiple updates ...
1264
+ * endSyncOutput(); // All updates appear atomically
1265
+ * ```
1266
+ */
1267
+ declare function beginSyncOutput(): void;
1268
+ /**
1269
+ * Ends synchronized output mode.
1270
+ *
1271
+ * @example
1272
+ * ```typescript
1273
+ * import { endSyncOutput } from 'blecsd';
1274
+ *
1275
+ * endSyncOutput();
1276
+ * ```
1277
+ */
1278
+ declare function endSyncOutput(): void;
1279
+ /**
1280
+ * Saves the current cursor position.
1281
+ *
1282
+ * @example
1283
+ * ```typescript
1284
+ * import { saveCursorPosition, restoreCursorPosition } from 'blecsd';
1285
+ *
1286
+ * saveCursorPosition();
1287
+ * // ... move cursor and draw ...
1288
+ * restoreCursorPosition(); // Return to saved position
1289
+ * ```
1290
+ */
1291
+ declare function saveCursorPosition(): void;
1292
+ /**
1293
+ * Restores the previously saved cursor position.
1294
+ *
1295
+ * @example
1296
+ * ```typescript
1297
+ * import { restoreCursorPosition } from 'blecsd';
1298
+ *
1299
+ * restoreCursorPosition();
1300
+ * ```
1301
+ */
1302
+ declare function restoreCursorPosition(): void;
1303
+ /**
1304
+ * Enables bracketed paste mode in the terminal.
1305
+ * When enabled, pasted text is bracketed with special sequences.
1306
+ *
1307
+ * @example
1308
+ * ```typescript
1309
+ * import { enableBracketedPasteMode } from 'blecsd';
1310
+ *
1311
+ * enableBracketedPasteMode();
1312
+ * ```
1313
+ */
1314
+ declare function enableBracketedPasteMode(): void;
1315
+ /**
1316
+ * Disables bracketed paste mode in the terminal.
1317
+ *
1318
+ * @example
1319
+ * ```typescript
1320
+ * import { disableBracketedPasteMode } from 'blecsd';
1321
+ *
1322
+ * disableBracketedPasteMode();
1323
+ * ```
1324
+ */
1325
+ declare function disableBracketedPasteMode(): void;
1326
+ /**
1327
+ * Enables focus reporting in the terminal.
1328
+ * When enabled, the terminal sends focus in/out events.
1329
+ *
1330
+ * @example
1331
+ * ```typescript
1332
+ * import { enableFocusReporting } from 'blecsd';
1333
+ *
1334
+ * enableFocusReporting();
1335
+ * ```
1336
+ */
1337
+ declare function enableFocusReporting(): void;
1338
+ /**
1339
+ * Disables focus reporting in the terminal.
1340
+ *
1341
+ * @example
1342
+ * ```typescript
1343
+ * import { disableFocusReporting } from 'blecsd';
1344
+ *
1345
+ * disableFocusReporting();
1346
+ * ```
1347
+ */
1348
+ declare function disableFocusReporting(): void;
1349
+ /**
1350
+ * Flushes output and resets terminal state.
1351
+ * Call this before exiting the application.
1352
+ *
1353
+ * @example
1354
+ * ```typescript
1355
+ * import { cleanup } from 'blecsd';
1356
+ *
1357
+ * // Before exiting
1358
+ * cleanup();
1359
+ * ```
1360
+ */
1361
+ declare function cleanup(): void;
1362
+
1363
+ /**
1364
+ * Render system for drawing entities to the screen buffer.
1365
+ * Runs in the RENDER phase after layout computation.
1366
+ * @module systems/renderSystem
1367
+ */
1368
+
1369
+ /**
1370
+ * Render context passed to render functions.
1371
+ */
1372
+ interface RenderContext {
1373
+ /** The ECS world */
1374
+ readonly world: World;
1375
+ /** The screen buffer to render to */
1376
+ readonly buffer: ScreenBufferData;
1377
+ /** The dirty tracker for optimized rendering */
1378
+ readonly dirtyTracker: DirtyTracker;
1379
+ }
1380
+ /**
1381
+ * Computed bounds for an entity.
1382
+ */
1383
+ interface EntityBounds {
1384
+ readonly x: number;
1385
+ readonly y: number;
1386
+ readonly width: number;
1387
+ readonly height: number;
1388
+ }
1389
+ /**
1390
+ * Renders the background fill for an entity.
1391
+ *
1392
+ * @param ctx - Render context
1393
+ * @param eid - Entity ID
1394
+ * @param bounds - Entity bounds
1395
+ *
1396
+ * @example
1397
+ * ```typescript
1398
+ * import { renderBackground } from 'blecsd';
1399
+ *
1400
+ * renderBackground(ctx, entity, bounds);
1401
+ * ```
1402
+ */
1403
+ declare function renderBackground(ctx: RenderContext, eid: Entity, bounds: EntityBounds): void;
1404
+ /**
1405
+ * Renders the border for an entity.
1406
+ *
1407
+ * @param ctx - Render context
1408
+ * @param eid - Entity ID
1409
+ * @param bounds - Entity bounds
1410
+ *
1411
+ * @example
1412
+ * ```typescript
1413
+ * import { renderBorder } from 'blecsd';
1414
+ *
1415
+ * renderBorder(ctx, entity, bounds);
1416
+ * ```
1417
+ */
1418
+ declare function renderBorder(ctx: RenderContext, eid: Entity, bounds: EntityBounds): void;
1419
+ /**
1420
+ * Renders the content area of an entity.
1421
+ * This is a placeholder that can be extended for specific content types.
1422
+ *
1423
+ * @param ctx - Render context
1424
+ * @param eid - Entity ID
1425
+ * @param contentBounds - Content area bounds (inside border)
1426
+ *
1427
+ * @example
1428
+ * ```typescript
1429
+ * import { renderContent } from 'blecsd';
1430
+ *
1431
+ * renderContent(ctx, entity, contentBounds);
1432
+ * ```
1433
+ */
1434
+ declare function renderContent(_ctx: RenderContext, _eid: Entity, _contentBounds: EntityBounds): void;
1435
+ /**
1436
+ * Renders a scrollbar for an entity.
1437
+ * Currently a placeholder for future scrollable content support.
1438
+ *
1439
+ * @param ctx - Render context
1440
+ * @param eid - Entity ID
1441
+ * @param bounds - Entity bounds
1442
+ *
1443
+ * @example
1444
+ * ```typescript
1445
+ * import { renderScrollbar } from 'blecsd';
1446
+ *
1447
+ * renderScrollbar(ctx, entity, bounds);
1448
+ * ```
1449
+ */
1450
+ declare function renderScrollbar(_ctx: RenderContext, _eid: Entity, _bounds: EntityBounds): void;
1451
+ /**
1452
+ * Recursively renders an entity and its children in tree order.
1453
+ * @internal Currently unused, reserved for future tree-based rendering mode.
1454
+ *
1455
+ * @param ctx - Render context
1456
+ * @param eid - Entity ID
1457
+ */
1458
+ /**
1459
+ * Viewport bounds for culling off-screen entities.
1460
+ * Defaults to null (no culling). Set via setViewportBounds().
1461
+ */
1462
+ interface ViewportBounds {
1463
+ readonly x: number;
1464
+ readonly y: number;
1465
+ readonly width: number;
1466
+ readonly height: number;
1467
+ }
1468
+ /**
1469
+ * Sets the viewport bounds for culling.
1470
+ * Entities outside these bounds will be skipped during rendering.
1471
+ *
1472
+ * Pass null to disable viewport culling (default).
1473
+ * Typically set to screen dimensions for scrollable content optimization.
1474
+ *
1475
+ * @param bounds - Viewport bounds or null to disable culling
1476
+ *
1477
+ * @example
1478
+ * ```typescript
1479
+ * import { setViewportBounds } from 'blecsd';
1480
+ *
1481
+ * // Enable viewport culling for 80x24 screen
1482
+ * setViewportBounds({ x: 0, y: 0, width: 80, height: 24 });
1483
+ *
1484
+ * // Disable viewport culling
1485
+ * setViewportBounds(null);
1486
+ * ```
1487
+ */
1488
+ declare function setViewportBounds(bounds: ViewportBounds | null): void;
1489
+ /**
1490
+ * Gets the current viewport bounds.
1491
+ *
1492
+ * @returns Current viewport bounds or null if disabled
1493
+ */
1494
+ declare function getViewportBounds(): ViewportBounds | null;
1495
+ /**
1496
+ * Sets the dirty tracker and screen buffer for the render system.
1497
+ * Must be called before running the render system.
1498
+ *
1499
+ * @param tracker - The dirty tracker for optimized rendering
1500
+ * @param buffer - The screen buffer to render to
1501
+ *
1502
+ * @example
1503
+ * ```typescript
1504
+ * import { setRenderBuffer, createDirtyTracker } from 'blecsd';
1505
+ * import { createScreenBuffer } from 'blecsd';
1506
+ *
1507
+ * const tracker = createDirtyTracker(80, 24);
1508
+ * const buffer = createScreenBuffer(80, 24);
1509
+ * setRenderBuffer(tracker, buffer);
1510
+ * ```
1511
+ */
1512
+ declare function setRenderBuffer(tracker: DirtyTracker, buffer: ScreenBufferData): void;
1513
+ /**
1514
+ * Gets the current dirty tracker.
1515
+ *
1516
+ * @returns The current dirty tracker or null
1517
+ */
1518
+ declare function getRenderBuffer(): DirtyTracker | null;
1519
+ /**
1520
+ * Clears the render buffer references.
1521
+ */
1522
+ declare function clearRenderBuffer(): void;
1523
+ /**
1524
+ * Enables or disables z-order occlusion culling.
1525
+ * When enabled, entities fully hidden behind higher z-index entities are skipped during rendering.
1526
+ *
1527
+ * Disabled by default. Enable for applications with many overlapping widgets (modals, dialogs, overlays)
1528
+ * where the performance benefit outweighs the culling overhead.
1529
+ *
1530
+ * @param enabled - Whether to enable occlusion culling (default: false)
1531
+ *
1532
+ * @example
1533
+ * ```typescript
1534
+ * import { setOcclusionCulling } from 'blecsd';
1535
+ *
1536
+ * // Enable occlusion culling for layered UI
1537
+ * setOcclusionCulling(true);
1538
+ * ```
1539
+ */
1540
+ declare function setOcclusionCulling(enabled: boolean): void;
1541
+ /**
1542
+ * Gets the current occlusion culling state.
1543
+ *
1544
+ * @returns True if occlusion culling is enabled
1545
+ */
1546
+ declare function isOcclusionCullingEnabled(): boolean;
1547
+ /**
1548
+ * Render system that draws visible, dirty entities to the screen buffer.
1549
+ * Entities are rendered in z-index order (lower z first, higher z on top).
1550
+ *
1551
+ * The system:
1552
+ * 1. Queries all entities with Position and Renderable
1553
+ * 2. Filters to visible, dirty entities
1554
+ * 3. Sorts by z-index
1555
+ * 4. Applies viewport bounds culling (skips off-screen entities)
1556
+ * 5. Applies z-order occlusion culling (skips fully hidden entities)
1557
+ * 6. Renders each visible entity (background, border, content)
1558
+ * 7. Marks entities as clean
1559
+ *
1560
+ * Viewport culling: entities completely outside the viewport bounds are skipped
1561
+ * to improve performance in scrollable content with many off-screen entities.
1562
+ * Enable via `setViewportBounds({ x, y, width, height })`.
1563
+ *
1564
+ * Occlusion culling: entities fully covered by higher z-index entities are
1565
+ * skipped to improve performance in layered UIs (modals, dialogs, overlays).
1566
+ * Enable via `setOcclusionCulling(true)`.
1567
+ *
1568
+ * @param world - The ECS world
1569
+ * @returns The world (unchanged)
1570
+ *
1571
+ * @example
1572
+ * ```typescript
1573
+ * import { renderSystem, setRenderBuffer, setViewportBounds, createScheduler, LoopPhase } from 'blecsd';
1574
+ *
1575
+ * const scheduler = createScheduler();
1576
+ * scheduler.registerSystem(LoopPhase.RENDER, renderSystem);
1577
+ *
1578
+ * // Set render buffer and enable viewport culling
1579
+ * setRenderBuffer(dirtyTracker, screenBuffer);
1580
+ * setViewportBounds({ x: 0, y: 0, width: 80, height: 24 });
1581
+ *
1582
+ * scheduler.run(world, deltaTime);
1583
+ * ```
1584
+ */
1585
+ declare const renderSystem: System;
1586
+ /**
1587
+ * Creates the render system function.
1588
+ * This is an alternative to using the renderSystem directly for custom configuration.
1589
+ *
1590
+ * @returns A new render system function
1591
+ *
1592
+ * @example
1593
+ * ```typescript
1594
+ * import { createRenderSystem, createScheduler, LoopPhase } from 'blecsd';
1595
+ *
1596
+ * const scheduler = createScheduler();
1597
+ * scheduler.registerSystem(LoopPhase.RENDER, createRenderSystem());
1598
+ * ```
1599
+ */
1600
+ declare function createRenderSystem(): System;
1601
+ /**
1602
+ * Renders text to a buffer at the specified position.
1603
+ * Utility function for widgets to render text content.
1604
+ *
1605
+ * @param buffer - Screen buffer
1606
+ * @param x - X position
1607
+ * @param y - Y position
1608
+ * @param text - Text to render
1609
+ * @param fg - Foreground color
1610
+ * @param bg - Background color
1611
+ * @param attrs - Text attributes
1612
+ * @returns Number of characters written
1613
+ *
1614
+ * @example
1615
+ * ```typescript
1616
+ * import { renderText, Attr } from 'blecsd';
1617
+ *
1618
+ * renderText(buffer, 10, 5, 'Hello', 0xffffffff, 0x000000ff, Attr.BOLD);
1619
+ * ```
1620
+ */
1621
+ declare function renderText(buffer: ScreenBufferData, x: number, y: number, text: string, fg: number, bg: number, attrs?: number): number;
1622
+ /**
1623
+ * Renders a filled rectangle to a buffer.
1624
+ * Utility function for widgets.
1625
+ *
1626
+ * @param buffer - Screen buffer
1627
+ * @param x - X position
1628
+ * @param y - Y position
1629
+ * @param width - Rectangle width
1630
+ * @param height - Rectangle height
1631
+ * @param cell - Cell to fill with
1632
+ *
1633
+ * @example
1634
+ * ```typescript
1635
+ * import { renderRect, createCell } from 'blecsd';
1636
+ *
1637
+ * renderRect(buffer, 10, 5, 20, 10, createCell(' ', 0xffffffff, 0x0000ffff));
1638
+ * ```
1639
+ */
1640
+ declare function renderRect(buffer: ScreenBufferData, x: number, y: number, width: number, height: number, cell: Cell): void;
1641
+ /**
1642
+ * Marks all entities as dirty, forcing a full re-render.
1643
+ *
1644
+ * @param world - The ECS world
1645
+ *
1646
+ * @example
1647
+ * ```typescript
1648
+ * import { markAllDirty } from 'blecsd';
1649
+ *
1650
+ * // Force re-render of all entities
1651
+ * markAllDirty(world);
1652
+ * ```
1653
+ */
1654
+ declare function markAllDirty(world: World): void;
1655
+
1656
+ /**
1657
+ * Fast panel movement and resizing system.
1658
+ *
1659
+ * Provides instant panel position updates on input with deferred
1660
+ * content re-layout. Uses dirty rect optimization and optional
1661
+ * content simplification during drag for 60fps movement.
1662
+ *
1663
+ * @module systems/panelMovement
1664
+ */
1665
+
1666
+ /**
1667
+ * Resize handle positions.
1668
+ */
1669
+ type ResizeHandle = 'top' | 'bottom' | 'left' | 'right' | 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight';
1670
+ /**
1671
+ * Panel movement constraints.
1672
+ */
1673
+ interface PanelConstraints {
1674
+ /** Minimum panel width (default: 4) */
1675
+ readonly minWidth: number;
1676
+ /** Minimum panel height (default: 2) */
1677
+ readonly minHeight: number;
1678
+ /** Maximum panel width (0 = no limit) */
1679
+ readonly maxWidth: number;
1680
+ /** Maximum panel height (0 = no limit) */
1681
+ readonly maxHeight: number;
1682
+ /** Constrain movement to screen bounds */
1683
+ readonly constrainToScreen: boolean;
1684
+ /** Screen width for constraining */
1685
+ readonly screenWidth: number;
1686
+ /** Screen height for constraining */
1687
+ readonly screenHeight: number;
1688
+ /** Snap to grid size (0 = no snap) */
1689
+ readonly snapGrid: number;
1690
+ }
1691
+ /**
1692
+ * Panel movement/resize state.
1693
+ */
1694
+ interface PanelMoveState {
1695
+ /** Currently moving entity */
1696
+ readonly entity: Entity | undefined;
1697
+ /** Whether a move is in progress */
1698
+ readonly isMoving: boolean;
1699
+ /** Whether a resize is in progress */
1700
+ readonly isResizing: boolean;
1701
+ /** Active resize handle */
1702
+ readonly resizeHandle: ResizeHandle | undefined;
1703
+ /** Starting mouse/cursor position */
1704
+ readonly startX: number;
1705
+ readonly startY: number;
1706
+ /** Starting panel position */
1707
+ readonly panelStartX: number;
1708
+ readonly panelStartY: number;
1709
+ /** Starting panel dimensions */
1710
+ readonly panelStartWidth: number;
1711
+ readonly panelStartHeight: number;
1712
+ /** Whether content layout is deferred (simplified rendering during move) */
1713
+ readonly layoutDeferred: boolean;
1714
+ }
1715
+ /**
1716
+ * Configuration for panel movement behavior.
1717
+ */
1718
+ interface PanelMoveConfig {
1719
+ /** Defer content layout during move for performance (default: true) */
1720
+ readonly deferLayout: boolean;
1721
+ /** Show resize outline instead of live resize (default: false) */
1722
+ readonly outlineResize: boolean;
1723
+ /** Number of pixels to move with keyboard (default: 1) */
1724
+ readonly keyboardStep: number;
1725
+ /** Number of pixels to resize with keyboard (default: 1) */
1726
+ readonly keyboardResizeStep: number;
1727
+ }
1728
+ /**
1729
+ * Dirty rectangle representing changed area.
1730
+ */
1731
+ interface DirtyRect {
1732
+ readonly x: number;
1733
+ readonly y: number;
1734
+ readonly width: number;
1735
+ readonly height: number;
1736
+ }
1737
+ /**
1738
+ * Result of a panel move or resize operation.
1739
+ */
1740
+ interface MoveResult {
1741
+ /** New position X */
1742
+ readonly x: number;
1743
+ /** New position Y */
1744
+ readonly y: number;
1745
+ /** New width (for resize) */
1746
+ readonly width: number;
1747
+ /** New height (for resize) */
1748
+ readonly height: number;
1749
+ /** Dirty rectangles that need redrawing */
1750
+ readonly dirtyRects: readonly DirtyRect[];
1751
+ /** Whether the operation was clamped by constraints */
1752
+ readonly clamped: boolean;
1753
+ }
1754
+ /**
1755
+ * Creates initial panel move state.
1756
+ *
1757
+ * @returns Fresh move state
1758
+ *
1759
+ * @example
1760
+ * ```typescript
1761
+ * import { createPanelMoveState } from 'blecsd';
1762
+ *
1763
+ * const moveState = createPanelMoveState();
1764
+ * ```
1765
+ */
1766
+ declare function createPanelMoveState(): PanelMoveState;
1767
+ /**
1768
+ * Creates panel move configuration with defaults.
1769
+ *
1770
+ * @param config - Partial overrides
1771
+ * @returns Full configuration
1772
+ */
1773
+ declare function createPanelMoveConfig(config?: Partial<PanelMoveConfig>): PanelMoveConfig;
1774
+ /**
1775
+ * Creates panel constraints with defaults.
1776
+ *
1777
+ * @param constraints - Partial overrides
1778
+ * @returns Full constraints
1779
+ */
1780
+ declare function createPanelConstraints(constraints?: Partial<PanelConstraints>): PanelConstraints;
1781
+ /**
1782
+ * Begins a panel move operation.
1783
+ *
1784
+ * @param state - Current move state
1785
+ * @param entity - Entity to move
1786
+ * @param mouseX - Starting mouse X
1787
+ * @param mouseY - Starting mouse Y
1788
+ * @param panelX - Current panel X position
1789
+ * @param panelY - Current panel Y position
1790
+ * @param panelWidth - Current panel width
1791
+ * @param panelHeight - Current panel height
1792
+ * @param config - Move configuration
1793
+ * @returns Updated state
1794
+ *
1795
+ * @example
1796
+ * ```typescript
1797
+ * import { createPanelMoveState, beginMove } from 'blecsd';
1798
+ *
1799
+ * let state = createPanelMoveState();
1800
+ * state = beginMove(state, eid, mouseX, mouseY, panelX, panelY, 30, 10);
1801
+ * ```
1802
+ */
1803
+ declare function beginMove(state: PanelMoveState, entity: Entity, mouseX: number, mouseY: number, panelX: number, panelY: number, panelWidth: number, panelHeight: number, config?: Partial<PanelMoveConfig>): PanelMoveState;
1804
+ /**
1805
+ * Begins a panel resize operation.
1806
+ *
1807
+ * @param state - Current move state
1808
+ * @param entity - Entity to resize
1809
+ * @param handle - Resize handle being dragged
1810
+ * @param mouseX - Starting mouse X
1811
+ * @param mouseY - Starting mouse Y
1812
+ * @param panelX - Current panel X
1813
+ * @param panelY - Current panel Y
1814
+ * @param panelWidth - Current panel width
1815
+ * @param panelHeight - Current panel height
1816
+ * @param config - Move configuration
1817
+ * @returns Updated state
1818
+ */
1819
+ declare function beginResize(state: PanelMoveState, entity: Entity, handle: ResizeHandle, mouseX: number, mouseY: number, panelX: number, panelY: number, panelWidth: number, panelHeight: number, config?: Partial<PanelMoveConfig>): PanelMoveState;
1820
+ /**
1821
+ * Updates a panel move with new cursor position.
1822
+ * Returns the new panel position with constraints applied.
1823
+ *
1824
+ * @param state - Current move state
1825
+ * @param mouseX - Current mouse X
1826
+ * @param mouseY - Current mouse Y
1827
+ * @param constraints - Panel constraints
1828
+ * @returns Move result with new position and dirty rects
1829
+ *
1830
+ * @example
1831
+ * ```typescript
1832
+ * import { updateMove, createPanelConstraints } from 'blecsd';
1833
+ *
1834
+ * const result = updateMove(state, mouseX, mouseY, createPanelConstraints());
1835
+ * setPosition(world, eid, result.x, result.y);
1836
+ * ```
1837
+ */
1838
+ declare function updateMove(state: PanelMoveState, mouseX: number, mouseY: number, constraints?: Partial<PanelConstraints>): MoveResult;
1839
+ declare function updateResize(state: PanelMoveState, mouseX: number, mouseY: number, constraints?: Partial<PanelConstraints>): MoveResult;
1840
+ /**
1841
+ * Ends the current move or resize operation.
1842
+ *
1843
+ * @param state - Current move state
1844
+ * @returns Reset state
1845
+ */
1846
+ declare function endMoveOrResize(state: PanelMoveState): PanelMoveState;
1847
+ /**
1848
+ * Cancels the current move or resize, returning to original position.
1849
+ *
1850
+ * @param state - Current move state
1851
+ * @returns Object with original position and reset state
1852
+ */
1853
+ declare function cancelMoveOrResize(state: PanelMoveState): {
1854
+ state: PanelMoveState;
1855
+ restoreX: number;
1856
+ restoreY: number;
1857
+ restoreWidth: number;
1858
+ restoreHeight: number;
1859
+ };
1860
+ /**
1861
+ * Moves a panel by keyboard step amount.
1862
+ *
1863
+ * @param x - Current X position
1864
+ * @param y - Current Y position
1865
+ * @param width - Panel width
1866
+ * @param height - Panel height
1867
+ * @param direction - Movement direction
1868
+ * @param step - Step amount
1869
+ * @param constraints - Panel constraints
1870
+ * @returns New position
1871
+ */
1872
+ declare function keyboardMove(x: number, y: number, width: number, height: number, direction: 'up' | 'down' | 'left' | 'right', step: number, constraints?: Partial<PanelConstraints>): {
1873
+ x: number;
1874
+ y: number;
1875
+ };
1876
+ /**
1877
+ * Resizes a panel by keyboard step amount.
1878
+ *
1879
+ * @param width - Current width
1880
+ * @param height - Current height
1881
+ * @param direction - Resize direction
1882
+ * @param step - Step amount
1883
+ * @param constraints - Panel constraints
1884
+ * @returns New dimensions
1885
+ */
1886
+ declare function keyboardResize(width: number, height: number, direction: 'grow-horizontal' | 'shrink-horizontal' | 'grow-vertical' | 'shrink-vertical', step: number, constraints?: Partial<PanelConstraints>): {
1887
+ width: number;
1888
+ height: number;
1889
+ };
1890
+ /**
1891
+ * Detects which resize handle a click position corresponds to.
1892
+ *
1893
+ * @param clickX - Click X relative to panel
1894
+ * @param clickY - Click Y relative to panel
1895
+ * @param panelWidth - Panel width
1896
+ * @param panelHeight - Panel height
1897
+ * @param borderSize - Size of the resize border area (default: 1)
1898
+ * @returns The resize handle, or undefined if not on a border
1899
+ */
1900
+ declare function detectResizeHandle(clickX: number, clickY: number, panelWidth: number, panelHeight: number, borderSize?: number): ResizeHandle | undefined;
1901
+ /**
1902
+ * Merges overlapping dirty rectangles for efficient redraw.
1903
+ *
1904
+ * @param rects - Array of dirty rectangles
1905
+ * @returns Merged bounding rectangle
1906
+ */
1907
+ declare function mergeDirtyRects(rects: readonly DirtyRect[]): DirtyRect | undefined;
1908
+
1909
+ export { clearEventQueue as $, focusFirst as A, focusLast as B, focusOffset as C, type DirtyRect as D, blurAll as E, getFocused as F, getFocusableEntities as G, getFocusEventBus as H, resetFocusEventBus as I, focusPush as J, focusPop as K, peekFocusStack as L, getFocusStackDepth as M, clearFocusStack as N, saveFocus as O, restoreFocus as P, rewindFocus as Q, createInputSystem as R, registerInputSystem as S, type InputSystemState as T, queryInputReceivers as U, hitTest as V, pointInEntity as W, getInteractiveEntityAt as X, queueKeyEvent as Y, queueMouseEvent as Z, getEventQueue as _, animationSystem as a, isOcclusionCullingEnabled as a$, clearEntityInput as a0, getInputEventBus as a1, resetInputState as a2, captureMouseTo as a3, releaseMouse as a4, isMouseCaptured as a5, getMouseCaptureEntity as a6, createLayoutSystem as a7, computeLayoutNow as a8, getComputedLayout as a9, beginSyncOutput as aA, endSyncOutput as aB, createPanelMoveState as aC, createPanelMoveConfig as aD, createPanelConstraints as aE, beginMove as aF, beginResize as aG, updateMove as aH, updateResize as aI, endMoveOrResize as aJ, cancelMoveOrResize as aK, detectResizeHandle as aL, mergeDirtyRects as aM, keyboardMove as aN, keyboardResize as aO, createRenderSystem as aP, getRenderBuffer as aQ, clearRenderBuffer as aR, markAllDirty as aS, renderContent as aT, renderBackground as aU, renderBorder as aV, renderScrollbar as aW, renderText as aX, renderRect as aY, getViewportBounds as aZ, setViewportBounds as a_, getComputedBounds as aa, hasComputedLayout as ab, invalidateLayout as ac, invalidateAllLayouts as ad, createOutputSystem as ae, createOutputState as af, clearOutputBuffer as ag, clearOutputStream as ah, generateOutput as ai, getOutputBuffer as aj, getOutputStream as ak, getOutputState as al, resetOutputState as am, moveTo as an, saveCursorPosition as ao, restoreCursorPosition as ap, setTerminalCursorShape as aq, setWindowTitle as ar, resetAttributes as as, bell as at, enableMouseTracking as au, disableMouseTracking as av, enableBracketedPasteMode as aw, disableBracketedPasteMode as ax, enableFocusReporting as ay, disableFocusReporting as az, clearScreen as b, setOcclusionCulling as b0, ComputedLayout as b1, type ComputedLayoutData as b2, type FocusEventData as b3, type FocusEventMap as b4, type FocusEventType as b5, type HitTestResult as b6, type InputEventType as b7, type MoveResult as b8, type OutputState as b9, type PanelConstraints as ba, type PanelMoveConfig as bb, type PanelMoveState as bc, type QueuedInputEvent as bd, type QueuedKeyEvent as be, type QueuedMouseEvent as bf, type RenderContext as bg, type ResizeHandle as bh, inputState as bi, cleanup as c, cursorHome as d, enterAlternateScreen as e, focusSystem as f, leaveAlternateScreen as g, hideCursor as h, inputSystem as i, setOutputStream as j, setRenderBuffer as k, layoutSystem as l, showCursor as m, createAnimationSystem as n, outputSystem as o, registerAnimationSystem as p, hasAnimationSystem as q, renderSystem as r, setOutputBuffer as s, queryAnimation as t, updateAnimations as u, createFocusSystem as v, writeRaw as w, focusEntity as x, focusNext as y, focusPrev as z };