blecsd 0.2.0 → 0.4.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 (124) hide show
  1. package/LICENSE +4 -2
  2. package/README.md +167 -65
  3. package/dist/3d/index.d.ts +2 -2
  4. package/dist/3d/index.js +1 -1
  5. package/dist/audio/index.d.ts +2 -2
  6. package/dist/{border-D_Jb4ZJV.d.ts → border-DGNDfT6T.d.ts} +20 -10
  7. package/dist/chunk-25OEBENM.js +3 -0
  8. package/dist/chunk-26STV7ZS.js +1 -0
  9. package/dist/chunk-2NMGUEFC.js +4 -0
  10. package/dist/{chunk-LYSK5S63.js → chunk-4PRDJTCM.js} +1 -1
  11. package/dist/chunk-5N3O25O7.js +1 -0
  12. package/dist/chunk-5VEKHA3B.js +5 -0
  13. package/dist/chunk-6KEM3OS2.js +11 -0
  14. package/dist/chunk-6PX5R326.js +1 -0
  15. package/dist/chunk-6XWY6GB7.js +1 -0
  16. package/dist/chunk-735KKTP3.js +1 -0
  17. package/dist/chunk-7SWJNDOL.js +26 -0
  18. package/dist/chunk-APKUNIMB.js +1 -0
  19. package/dist/{chunk-FGHEFXLK.js → chunk-CJCSZRV6.js} +1 -1
  20. package/dist/chunk-DMBMCCLN.js +1 -0
  21. package/dist/chunk-DQTVJITR.js +1 -0
  22. package/dist/chunk-DSKQ5J4R.js +1 -0
  23. package/dist/chunk-E4CJRSND.js +1 -0
  24. package/dist/{chunk-OB66FB4F.js → chunk-EF4DC6IN.js} +1 -1
  25. package/dist/chunk-EJAKECSN.js +1 -0
  26. package/dist/chunk-FNQRUMFD.js +1 -0
  27. package/dist/chunk-GJ3RS2VG.js +1 -0
  28. package/dist/{chunk-TYMY2TBR.js → chunk-JHCKPCUH.js} +3 -3
  29. package/dist/{chunk-2UBBZFE4.js → chunk-KTVEMB2I.js} +1 -1
  30. package/dist/chunk-KYAPE44E.js +8 -0
  31. package/dist/chunk-LI4Y7TBZ.js +1 -0
  32. package/dist/chunk-NHOL4BN6.js +1 -0
  33. package/dist/chunk-NPDPBAW6.js +4 -0
  34. package/dist/chunk-NPNUUSIB.js +1 -0
  35. package/dist/chunk-OFRWGW2G.js +1 -0
  36. package/dist/chunk-OMU5BSAS.js +2 -0
  37. package/dist/chunk-P3ZLIQJP.js +1 -0
  38. package/dist/chunk-PWI36BQJ.js +1 -0
  39. package/dist/{chunk-VNZ6CWJA.js → chunk-QQMUDJ32.js} +2 -2
  40. package/dist/chunk-R3ICZOE4.js +1 -0
  41. package/dist/chunk-RJULLVTH.js +1 -0
  42. package/dist/{chunk-3B7MIVW6.js → chunk-RZ7FGVI6.js} +1 -1
  43. package/dist/chunk-S6WS46FE.js +1 -0
  44. package/dist/{chunk-TWSWTBYL.js → chunk-TSARUU56.js} +1 -1
  45. package/dist/chunk-WJRVUAZR.js +33 -0
  46. package/dist/{chunk-JKVHO4LH.js → chunk-WY5EZOOL.js} +1 -1
  47. package/dist/chunk-YY6RZCZH.js +4 -0
  48. package/dist/chunk-ZPGJCHXH.js +1 -0
  49. package/dist/chunk-ZPL2J25N.js +1 -0
  50. package/dist/cli/init.d.ts +1 -1
  51. package/dist/{componentStorage-DTkj1Qyj.d.ts → componentStorage-CJTh-TPO.d.ts} +1 -1
  52. package/dist/components/index.d.ts +7137 -5587
  53. package/dist/components/index.js +1 -1
  54. package/dist/core/index.d.ts +4138 -3169
  55. package/dist/core/index.js +1 -1
  56. package/dist/debug/index.d.ts +491 -98
  57. package/dist/debug/index.js +1 -1
  58. package/dist/dirtyTracking-C4v8MmM9.d.ts +235 -0
  59. package/dist/errors/index.d.ts +12 -12
  60. package/dist/errors/index.js +1 -1
  61. package/dist/{events-BbbxkgvX.d.ts → events-9ForpTfM.d.ts} +75 -2
  62. package/dist/game/index.d.ts +8 -8
  63. package/dist/game/index.js +1 -1
  64. package/dist/{gameLoop-BIPW7-OY.d.ts → gameLoop-CSTb7e0L.d.ts} +2 -2
  65. package/dist/{index-zSGJ2eUk.d.ts → index-DBS5Uefn.d.ts} +2 -2
  66. package/dist/index.d.ts +1005 -26
  67. package/dist/index.js +3 -1
  68. package/dist/input/index.d.ts +1 -1
  69. package/dist/input/index.js +1 -1
  70. package/dist/{inputActions-CefRUBuT.d.ts → inputActions-Fyw14_Gm.d.ts} +11 -722
  71. package/dist/{keyParser-Bwm8-l7v.d.ts → keyParser-m7fWto6g.d.ts} +18 -18
  72. package/dist/{mouseParser-Cfrbn3AX.d.ts → mouseParser-B7p5ow7K.d.ts} +1 -1
  73. package/dist/{packedStore-480t2X74.d.ts → packedStore-BgvnEdE7.d.ts} +1 -1
  74. package/dist/{renderable-jTMOA-GK.d.ts → renderable-CwqGwrEV.d.ts} +9 -9
  75. package/dist/scheduler-DeeZleia.d.ts +150 -0
  76. package/dist/systems/index.d.ts +473 -37
  77. package/dist/systems/index.js +1 -1
  78. package/dist/terminal/index.d.ts +2481 -2225
  79. package/dist/terminal/index.js +1 -1
  80. package/dist/{tilemap-j0twN9-y.d.ts → tilemap-BirMJdbu.d.ts} +2 -2
  81. package/dist/{types-BcsvoKzf.d.ts → types-CPB4CpbH.d.ts} +2 -2
  82. package/dist/utils/index.d.ts +28 -27
  83. package/dist/utils/index.js +1 -1
  84. package/dist/{virtualScrollback-DvZTRU8a.d.ts → virtualScrollback-D9uLFe8l.d.ts} +4 -4
  85. package/dist/{virtualViewport-Dx2iJliO.d.ts → virtualViewport-DTSN6jFk.d.ts} +370 -848
  86. package/dist/widgets/bigText.d.ts +1 -1
  87. package/dist/widgets/bigText.js +1 -1
  88. package/dist/widgets/index.d.ts +12079 -5902
  89. package/dist/widgets/index.js +1 -1
  90. package/package.json +102 -6
  91. package/dist/chunk-35I22JJO.js +0 -1
  92. package/dist/chunk-3APDF6RW.js +0 -1
  93. package/dist/chunk-3EGGGI5J.js +0 -3
  94. package/dist/chunk-4GISPPOH.js +0 -33
  95. package/dist/chunk-4X4N4HNQ.js +0 -2
  96. package/dist/chunk-6N6BRCEM.js +0 -4
  97. package/dist/chunk-AXZQAH4X.js +0 -1
  98. package/dist/chunk-BCADUCOZ.js +0 -1
  99. package/dist/chunk-CIK4AMUA.js +0 -1
  100. package/dist/chunk-EAY7B5GL.js +0 -1
  101. package/dist/chunk-EJ5WVDDZ.js +0 -6
  102. package/dist/chunk-FMFEOAML.js +0 -1
  103. package/dist/chunk-FYEBZAWN.js +0 -1
  104. package/dist/chunk-G7GIWWLE.js +0 -1
  105. package/dist/chunk-GYHI26UE.js +0 -1
  106. package/dist/chunk-H2YAOJDW.js +0 -1
  107. package/dist/chunk-JUWDTH25.js +0 -1
  108. package/dist/chunk-K2B2OXQ5.js +0 -5
  109. package/dist/chunk-K3SX2LY5.js +0 -1
  110. package/dist/chunk-KD55INV7.js +0 -1
  111. package/dist/chunk-KFAK4A3G.js +0 -1
  112. package/dist/chunk-LB3JA744.js +0 -19
  113. package/dist/chunk-LCN2ZITE.js +0 -1
  114. package/dist/chunk-P6CJO3BC.js +0 -1
  115. package/dist/chunk-PSXXMBVJ.js +0 -1
  116. package/dist/chunk-PXXGH3BV.js +0 -1
  117. package/dist/chunk-SHUC6JWA.js +0 -1
  118. package/dist/chunk-VCW7EOZ4.js +0 -12
  119. package/dist/chunk-W5OU7Z6J.js +0 -1
  120. package/dist/chunk-WHF27JF3.js +0 -4
  121. package/dist/chunk-WNG4A3K7.js +0 -4
  122. package/dist/chunk-WY3KY2TR.js +0 -1
  123. package/dist/chunk-XZA63ZPO.js +0 -1
  124. package/dist/scheduler-DcfoFuum.d.ts +0 -86
@@ -0,0 +1,235 @@
1
+ import { E as Entity, W as World } from './types-CPB4CpbH.js';
2
+
3
+ /**
4
+ * Unified dirty tracking system for efficient rendering.
5
+ * Combines entity-level tracking with cell-level bitsets for optimal performance.
6
+ *
7
+ * @module core/dirtyTracking
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { createDirtyTracker, markEntityDirty, getDirtyRegions } from 'blecsd';
12
+ *
13
+ * // Create tracker
14
+ * const tracker = createDirtyTracker(80, 24);
15
+ *
16
+ * // Mark entity as dirty (automatically tracks bounds)
17
+ * markEntityDirty(tracker, world, entityId);
18
+ *
19
+ * // Get dirty regions for rendering
20
+ * const regions = getDirtyRegions(tracker);
21
+ * for (const rect of regions) {
22
+ * renderRect(rect.x, rect.y, rect.width, rect.height);
23
+ * }
24
+ *
25
+ * // Clear after rendering
26
+ * clearDirtyTracking(tracker);
27
+ * ```
28
+ */
29
+
30
+ /**
31
+ * Rectangle representing a dirty region.
32
+ */
33
+ interface DirtyRect {
34
+ readonly x: number;
35
+ readonly y: number;
36
+ readonly width: number;
37
+ readonly height: number;
38
+ }
39
+ /**
40
+ * Cached entity bounds for motion detection.
41
+ * @internal
42
+ */
43
+ interface EntityBoundsCache {
44
+ prevX: number;
45
+ prevY: number;
46
+ prevWidth: number;
47
+ prevHeight: number;
48
+ wasVisible: boolean;
49
+ }
50
+ /**
51
+ * Unified dirty tracker combining entity-level and cell-level tracking.
52
+ */
53
+ interface DirtyTracker {
54
+ /** Screen width in cells */
55
+ readonly width: number;
56
+ /** Screen height in cells */
57
+ readonly height: number;
58
+ /** Bitset for dirty cells (one bit per cell) */
59
+ readonly dirtyCells: Uint8Array;
60
+ /** Set of dirty entities */
61
+ readonly dirtyEntities: Set<Entity>;
62
+ /** Cache of previous entity bounds */
63
+ readonly entityBoundsCache: Map<Entity, EntityBoundsCache>;
64
+ /** Computed dirty regions (lazily calculated) */
65
+ readonly dirtyRegions: DirtyRect[];
66
+ /** Whether dirtyRegions needs recalculation */
67
+ regionsStale: boolean;
68
+ /** Force full screen redraw */
69
+ forceFullRedraw: boolean;
70
+ /** Frame counter for debugging */
71
+ frameCount: number;
72
+ }
73
+ /**
74
+ * Creates a new unified dirty tracker.
75
+ *
76
+ * @param width - Screen width in cells
77
+ * @param height - Screen height in cells
78
+ * @returns New dirty tracker instance
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * const tracker = createDirtyTracker(80, 24);
83
+ * ```
84
+ */
85
+ declare function createDirtyTracker(width: number, height: number): DirtyTracker;
86
+ /**
87
+ * Marks an entity as dirty, tracking its bounds for optimal region calculation.
88
+ *
89
+ * @param tracker - Dirty tracker instance
90
+ * @param world - ECS world
91
+ * @param eid - Entity ID
92
+ *
93
+ * @example
94
+ * ```typescript
95
+ * // Entity moved or changed - mark it dirty
96
+ * markEntityDirty(tracker, world, boxEntity);
97
+ * ```
98
+ */
99
+ declare function markEntityDirty(tracker: DirtyTracker, world: World, eid: Entity): void;
100
+ /**
101
+ * Removes an entity from dirty tracking (call when entity is destroyed).
102
+ *
103
+ * @param tracker - Dirty tracker instance
104
+ * @param eid - Entity ID
105
+ *
106
+ * @example
107
+ * ```typescript
108
+ * // Entity destroyed - clean up tracking
109
+ * removeEntityFromTracking(tracker, destroyedEntity);
110
+ * ```
111
+ */
112
+ declare function removeEntityFromTracking(tracker: DirtyTracker, eid: Entity): void;
113
+ /**
114
+ * Marks a single cell as dirty using bitset.
115
+ *
116
+ * @param tracker - Dirty tracker instance
117
+ * @param x - Cell X coordinate
118
+ * @param y - Cell Y coordinate
119
+ *
120
+ * @example
121
+ * ```typescript
122
+ * // Mark specific cell dirty
123
+ * markCellDirty(tracker, 10, 5);
124
+ * ```
125
+ */
126
+ declare function markCellDirty(tracker: DirtyTracker, x: number, y: number): void;
127
+ /**
128
+ * Checks if a cell is marked dirty.
129
+ *
130
+ * @param tracker - Dirty tracker instance
131
+ * @param x - Cell X coordinate
132
+ * @param y - Cell Y coordinate
133
+ * @returns True if cell is dirty
134
+ *
135
+ * @example
136
+ * ```typescript
137
+ * if (isCellDirty(tracker, 10, 5)) {
138
+ * // Cell needs redraw
139
+ * }
140
+ * ```
141
+ */
142
+ declare function isCellDirty(tracker: DirtyTracker, x: number, y: number): boolean;
143
+ /**
144
+ * Marks a rectangular region as dirty using cell bitsets.
145
+ *
146
+ * @param tracker - Dirty tracker instance
147
+ * @param x - Region X coordinate
148
+ * @param y - Region Y coordinate
149
+ * @param width - Region width
150
+ * @param height - Region height
151
+ *
152
+ * @example
153
+ * ```typescript
154
+ * // Mark 10x5 region dirty
155
+ * markRegionDirty(tracker, 0, 0, 10, 5);
156
+ * ```
157
+ */
158
+ declare function markRegionDirty(tracker: DirtyTracker, x: number, y: number, width: number, height: number): void;
159
+ /**
160
+ * Converts bitset dirty cells into coalesced rectangular regions.
161
+ * Uses scanline algorithm for efficient region merging.
162
+ *
163
+ * @param tracker - Dirty tracker instance
164
+ * @returns Array of dirty rectangles
165
+ *
166
+ * @example
167
+ * ```typescript
168
+ * const regions = getDirtyRegions(tracker);
169
+ * for (const rect of regions) {
170
+ * console.log(`Dirty: ${rect.x},${rect.y} ${rect.width}x${rect.height}`);
171
+ * }
172
+ * ```
173
+ */
174
+ declare function getDirtyRegions(tracker: DirtyTracker): readonly DirtyRect[];
175
+ /**
176
+ * Checks if tracker has any dirty regions.
177
+ *
178
+ * @param tracker - Dirty tracker instance
179
+ * @returns True if any cells are dirty
180
+ *
181
+ * @example
182
+ * ```typescript
183
+ * if (hasDirtyRegions(tracker)) {
184
+ * render();
185
+ * }
186
+ * ```
187
+ */
188
+ declare function hasDirtyRegions(tracker: DirtyTracker): boolean;
189
+ /**
190
+ * Clears all dirty tracking state after rendering.
191
+ *
192
+ * @param tracker - Dirty tracker instance
193
+ *
194
+ * @example
195
+ * ```typescript
196
+ * // After rendering
197
+ * render(getDirtyRegions(tracker));
198
+ * clearDirtyTracking(tracker);
199
+ * ```
200
+ */
201
+ declare function clearDirtyTracking(tracker: DirtyTracker): void;
202
+ /**
203
+ * Forces a full screen redraw on next render.
204
+ *
205
+ * @param tracker - Dirty tracker instance
206
+ *
207
+ * @example
208
+ * ```typescript
209
+ * // Terminal resized - force full redraw
210
+ * forceFullRedraw(tracker);
211
+ * ```
212
+ */
213
+ declare function forceFullRedraw(tracker: DirtyTracker): void;
214
+ /**
215
+ * Gets debug statistics about dirty tracking state.
216
+ *
217
+ * @param tracker - Dirty tracker instance
218
+ * @returns Debug statistics
219
+ *
220
+ * @example
221
+ * ```typescript
222
+ * const stats = getDirtyTrackingStats(tracker);
223
+ * console.log(`Dirty cells: ${stats.dirtyCellCount}`);
224
+ * console.log(`Dirty entities: ${stats.dirtyEntityCount}`);
225
+ * ```
226
+ */
227
+ declare function getDirtyTrackingStats(tracker: DirtyTracker): {
228
+ readonly dirtyCellCount: number;
229
+ readonly dirtyEntityCount: number;
230
+ readonly cachedEntityCount: number;
231
+ readonly dirtyRegionCount: number;
232
+ readonly frameCount: number;
233
+ };
234
+
235
+ export { type DirtyTracker as D, createDirtyTracker as a, getDirtyTrackingStats as b, clearDirtyTracking as c, markEntityDirty as d, markRegionDirty as e, forceFullRedraw as f, getDirtyRegions as g, hasDirtyRegions as h, isCellDirty as i, type DirtyRect as j, markCellDirty as m, removeEntityFromTracking as r };
@@ -342,19 +342,19 @@ type BlECSdErrorKind = 'validation' | 'terminal' | 'system' | 'entity' | 'compon
342
342
  */
343
343
  interface ErrorContext {
344
344
  /** The entity ID involved (if applicable) */
345
- readonly entityId?: number;
345
+ readonly entityId?: number | undefined;
346
346
  /** The component name involved (if applicable) */
347
- readonly componentName?: string;
347
+ readonly componentName?: string | undefined;
348
348
  /** The system name involved (if applicable) */
349
- readonly systemName?: string;
349
+ readonly systemName?: string | undefined;
350
350
  /** The file path involved (if applicable) */
351
- readonly filePath?: string;
351
+ readonly filePath?: string | undefined;
352
352
  /** The function name where error occurred */
353
- readonly functionName?: string;
353
+ readonly functionName?: string | undefined;
354
354
  /** Additional data for debugging */
355
- readonly data?: Readonly<Record<string, unknown>>;
355
+ readonly data?: Readonly<Record<string, unknown>> | undefined;
356
356
  /** Zod validation issues (for validation errors) */
357
- readonly zodIssues?: readonly core.$ZodIssue[];
357
+ readonly zodIssues?: readonly core.$ZodIssue[] | undefined;
358
358
  }
359
359
  /**
360
360
  * Base error data common to all BlECSd errors.
@@ -369,9 +369,9 @@ interface BlECSdErrorBase<K extends BlECSdErrorKind, C extends BlECSdErrorCodeTy
369
369
  /** Timestamp when error was created */
370
370
  readonly timestamp: number;
371
371
  /** Original cause (if wrapping another error) */
372
- readonly cause?: Error;
372
+ readonly cause?: Error | undefined;
373
373
  /** Additional context for debugging */
374
- readonly context?: ErrorContext;
374
+ readonly context?: ErrorContext | undefined;
375
375
  }
376
376
  /**
377
377
  * Validation error for input/config validation failures.
@@ -459,16 +459,16 @@ interface NativeBlECSdError extends Error {
459
459
  */
460
460
  interface ErrorOptions {
461
461
  /** Original cause (if wrapping another error) */
462
- readonly cause?: Error;
462
+ readonly cause?: Error | undefined;
463
463
  /** Additional context for debugging */
464
- readonly context?: ErrorContext;
464
+ readonly context?: ErrorContext | undefined;
465
465
  }
466
466
  /**
467
467
  * Options for validation errors with Zod issues.
468
468
  */
469
469
  interface ValidationErrorOptions extends ErrorOptions {
470
470
  /** Zod validation issues */
471
- readonly zodIssues?: readonly core.$ZodIssue[];
471
+ readonly zodIssues?: readonly core.$ZodIssue[] | undefined;
472
472
  }
473
473
  /**
474
474
  * Creates a validation error.
@@ -1 +1 @@
1
- export{a as BLECSD_ERROR_SYMBOL,k as BlECSdErrorCode,f as ComponentErrorCode,i as ConfigErrorCode,e as EntityErrorCode,g as InputErrorCode,j as InternalErrorCode,h as RenderErrorCode,d as SystemErrorCode,c as TerminalErrorCode,b as ValidationErrorCode,p as createComponentError,s as createConfigError,o as createEntityError,q as createInputError,t as createInternalError,r as createRenderError,n as createSystemError,m as createTerminalError,l as createValidationError,O as err,W as flatMap,v as fromNativeError,J as hasBlECSdErrorShape,L as hasCause,K as hasContext,H as hasErrorCode,M as hasZodIssues,I as isBlECSdError,B as isComponentError,E as isConfigError,A as isEntityError,Q as isErr,G as isErrorKind,C as isInputError,F as isInternalError,P as isOk,D as isRenderError,z as isSystemError,y as isTerminalError,x as isValidationError,U as map,V as mapError,N as ok,u as toNativeError,R as unwrap,S as unwrapOr,T as unwrapOrElse,w as wrapError}from'../chunk-3B7MIVW6.js';import'../chunk-5PELJRUQ.js';
1
+ export{a as BLECSD_ERROR_SYMBOL,k as BlECSdErrorCode,f as ComponentErrorCode,i as ConfigErrorCode,e as EntityErrorCode,g as InputErrorCode,j as InternalErrorCode,h as RenderErrorCode,d as SystemErrorCode,c as TerminalErrorCode,b as ValidationErrorCode,p as createComponentError,s as createConfigError,o as createEntityError,q as createInputError,t as createInternalError,r as createRenderError,n as createSystemError,m as createTerminalError,l as createValidationError,O as err,W as flatMap,v as fromNativeError,J as hasBlECSdErrorShape,L as hasCause,K as hasContext,H as hasErrorCode,M as hasZodIssues,I as isBlECSdError,B as isComponentError,E as isConfigError,A as isEntityError,Q as isErr,G as isErrorKind,C as isInputError,F as isInternalError,P as isOk,D as isRenderError,z as isSystemError,y as isTerminalError,x as isValidationError,U as map,V as mapError,N as ok,u as toNativeError,R as unwrap,S as unwrapOr,T as unwrapOrElse,w as wrapError}from'../chunk-RZ7FGVI6.js';import'../chunk-5PELJRUQ.js';
@@ -1,4 +1,4 @@
1
- import { U as Unsubscribe } from './types-BcsvoKzf.js';
1
+ import { U as Unsubscribe, W as World, E as Entity } from './types-CPB4CpbH.js';
2
2
 
3
3
  /**
4
4
  * Typed EventEmitter implementation for type-safe event handling
@@ -85,6 +85,12 @@ interface ScreenEventMap {
85
85
  frameTime: number;
86
86
  };
87
87
  destroy: Record<string, never>;
88
+ warning: {
89
+ type: string;
90
+ message: string;
91
+ metadata: Record<string, unknown>;
92
+ timestamp: number;
93
+ };
88
94
  }
89
95
  /**
90
96
  * Type-safe EventBus interface.
@@ -121,5 +127,72 @@ interface EventBus<T extends EventMap> {
121
127
  * ```
122
128
  */
123
129
  declare function createEventBus<T extends EventMap>(): EventBus<T>;
130
+ /**
131
+ * Function type for getting an EventBus for a specific entity.
132
+ * Returns undefined if the entity has no event bus.
133
+ *
134
+ * @typeParam T - Event map type
135
+ * @param world - The ECS world
136
+ * @param eid - The entity ID
137
+ * @returns The entity's EventBus, or undefined if none exists
138
+ *
139
+ * @example
140
+ * ```typescript
141
+ * import { createEventBus, type GetEntityEventBus } from 'blecsd';
142
+ *
143
+ * const entityBuses = new Map<Entity, EventBus<MyEvents>>();
144
+ * const getEventBus: GetEntityEventBus<MyEvents> = (world, eid) => entityBuses.get(eid);
145
+ * ```
146
+ */
147
+ type GetEntityEventBus<T extends EventMap> = (world: World, eid: Entity) => EventBus<T> | undefined;
148
+ /**
149
+ * Store for entity event buses.
150
+ * Maps entity IDs to their event buses.
151
+ *
152
+ * @typeParam T - Event map type
153
+ */
154
+ interface EntityEventBusStore<T extends EventMap> {
155
+ /** Gets the event bus for an entity */
156
+ get(world: World, eid: Entity): EventBus<T> | undefined;
157
+ /** Gets or creates an event bus for an entity */
158
+ getOrCreate(world: World, eid: Entity): EventBus<T>;
159
+ /** Sets the event bus for an entity */
160
+ set(world: World, eid: Entity, eventBus: EventBus<T>): void;
161
+ /** Checks if an entity has an event bus */
162
+ has(world: World, eid: Entity): boolean;
163
+ /** Removes the event bus for an entity */
164
+ delete(world: World, eid: Entity): boolean;
165
+ /** Clears all event buses */
166
+ clear(): void;
167
+ }
168
+ /**
169
+ * Creates a simple entity event bus store using a Map.
170
+ * Provides a centralized way to manage EventBus instances per entity.
171
+ *
172
+ * @typeParam T - Event map type
173
+ * @returns A new EntityEventBusStore instance
174
+ *
175
+ * @example
176
+ * ```typescript
177
+ * import { createEntityEventBusStore, createEventBus } from 'blecsd';
178
+ *
179
+ * interface MyEvents {
180
+ * click: { x: number; y: number };
181
+ * focus: Record<string, never>;
182
+ * }
183
+ *
184
+ * const store = createEntityEventBusStore<MyEvents>();
185
+ *
186
+ * // Get or create a bus for an entity
187
+ * const bus = store.getOrCreate(world, entityId);
188
+ * bus.on('click', (e) => console.log('clicked at', e.x, e.y));
189
+ *
190
+ * // Check if entity has a bus
191
+ * if (store.has(world, entityId)) {
192
+ * const existingBus = store.get(world, entityId);
193
+ * }
194
+ * ```
195
+ */
196
+ declare function createEntityEventBusStore<T extends EventMap>(): EntityEventBusStore<T>;
124
197
 
125
- export { type EventBus as E, type ScreenEventMap as S, type UIEventMap as U, type EventHandler as a, type EventMap as b, createEventBus as c };
198
+ export { type EntityEventBusStore as E, type GetEntityEventBus as G, type ScreenEventMap as S, type UIEventMap as U, type EventBus as a, type EventHandler as b, type EventMap as c, createEntityEventBusStore as d, createEventBus as e };
@@ -1,13 +1,13 @@
1
1
  import { z } from 'zod';
2
- import { I as InputEventBufferData, a as InputState, B as BoxConfig, T as TextConfig, b as ButtonConfig, c as InputConfig, d as TextareaConfig, e as TextboxConfig, C as CheckboxConfig, R as RadioButtonConfig, f as RadioSetConfig, S as SelectConfig, g as SliderConfig, P as ProgressBarConfig, L as ListConfig, F as FormConfig, A as ActionBinding } from '../inputActions-CefRUBuT.js';
3
- import { G as GameLoop, L as LoopStats } from '../gameLoop-BIPW7-OY.js';
4
- import { W as World, E as Entity, U as Unsubscribe, L as LoopPhase, S as System } from '../types-BcsvoKzf.js';
5
- import { M as MouseEvent } from '../mouseParser-Cfrbn3AX.js';
2
+ import { W as World, E as Entity, U as Unsubscribe, L as LoopPhase, S as System } from '../types-CPB4CpbH.js';
3
+ import { I as InputEventBufferData, a as InputState, B as BoxConfig, T as TextConfig, b as ButtonConfig, c as InputConfig, d as TextareaConfig, e as TextboxConfig, C as CheckboxConfig, R as RadioButtonConfig, f as RadioSetConfig, S as SelectConfig, g as SliderConfig, P as ProgressBarConfig, L as ListConfig, F as FormConfig, A as ActionBinding } from '../inputActions-Fyw14_Gm.js';
4
+ import { G as GameLoop, L as LoopStats } from '../gameLoop-CSTb7e0L.js';
5
+ import { K as KeyName } from '../keyParser-m7fWto6g.js';
6
+ import { M as MouseEvent } from '../mouseParser-B7p5ow7K.js';
6
7
  import { K as KeyEvent } from '../program-BZaKqDKH.js';
7
- import { K as KeyName } from '../keyParser-Bwm8-l7v.js';
8
- import '../border-D_Jb4ZJV.js';
9
- import '../scheduler-DcfoFuum.js';
10
8
  import 'bitecs';
9
+ import '../border-DGNDfT6T.js';
10
+ import '../scheduler-DeeZleia.js';
11
11
  import 'node:stream';
12
12
 
13
13
  /**
@@ -384,7 +384,7 @@ interface Game {
384
384
  * @example
385
385
  * ```typescript
386
386
  * game.registerSystem(LoopPhase.UPDATE, movementSystem);
387
- * game.registerSystem(LoopPhase.PHYSICS, collisionSystem);
387
+ * game.registerSystem(LoopPhase.ANIMATION, collisionSystem);
388
388
  * ```
389
389
  */
390
390
  registerSystem(phase: LoopPhase, system: System): Unsubscribe;
@@ -1 +1 @@
1
- export{a as GameConfigSchema,b as createGame}from'../chunk-2UBBZFE4.js';import'../chunk-4X4N4HNQ.js';import'../chunk-H2YAOJDW.js';import'../chunk-P6CJO3BC.js';import'../chunk-KFAK4A3G.js';import'../chunk-BCADUCOZ.js';import'../chunk-KD55INV7.js';import'../chunk-PSXXMBVJ.js';import'../chunk-LCN2ZITE.js';import'../chunk-FYEBZAWN.js';import'../chunk-W5OU7Z6J.js';import'../chunk-Z4EZERNE.js';import'../chunk-WNG4A3K7.js';import'../chunk-SHUC6JWA.js';import'../chunk-G7GIWWLE.js';import'../chunk-PXXGH3BV.js';import'../chunk-5PELJRUQ.js';
1
+ export{a as GameConfigSchema,b as createGame}from'../chunk-KTVEMB2I.js';import'../chunk-OMU5BSAS.js';import'../chunk-NPNUUSIB.js';import'../chunk-DMBMCCLN.js';import'../chunk-5N3O25O7.js';import'../chunk-R3ICZOE4.js';import'../chunk-DSKQ5J4R.js';import'../chunk-LI4Y7TBZ.js';import'../chunk-6XWY6GB7.js';import'../chunk-DQTVJITR.js';import'../chunk-ZPGJCHXH.js';import'../chunk-735KKTP3.js';import'../chunk-APKUNIMB.js';import'../chunk-NPDPBAW6.js';import'../chunk-GJ3RS2VG.js';import'../chunk-Z4EZERNE.js';import'../chunk-P3ZLIQJP.js';import'../chunk-5PELJRUQ.js';
@@ -1,5 +1,5 @@
1
- import { S as Scheduler } from './scheduler-DcfoFuum.js';
2
- import { W as World, S as System } from './types-BcsvoKzf.js';
1
+ import { S as Scheduler } from './scheduler-DeeZleia.js';
2
+ import { W as World, S as System } from './types-CPB4CpbH.js';
3
3
 
4
4
  /**
5
5
  * Game loop with input priority and lifecycle management.
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { W as World, E as Entity, S as System } from './types-BcsvoKzf.js';
2
+ import { W as World, E as Entity, S as System } from './types-CPB4CpbH.js';
3
3
  import { A as Animation3DConfig, C as Camera3DConfig, M as Material3DConfig, a as MouseInteraction3DConfig, T as Transform3DConfig, V as Viewport3DConfig, b as Animation3DConfigSchema, c as Camera3DConfigSchema, d as Material3DConfigSchema, e as MouseInteraction3DConfigSchema, f as Transform3DConfigSchema, g as Viewport3DConfigSchema, h as Viewport3DWidgetConfig, i as Viewport3DWidgetConfigSchema } from './viewport3d-xI33-_wq.js';
4
4
 
5
5
  /**
@@ -1019,7 +1019,7 @@ interface MeshData {
1019
1019
  /** Number of triangles (indices.length / 3) */
1020
1020
  readonly triangleCount: number;
1021
1021
  /** Optional vertex normals: [nx0, ny0, nz0, nx1, ny1, nz1, ...] */
1022
- readonly normals?: Float32Array;
1022
+ readonly normals?: Float32Array | undefined;
1023
1023
  }
1024
1024
  /**
1025
1025
  * Register mesh geometry data and return an ID.