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
package/README.md CHANGED
@@ -27,50 +27,136 @@ npm install blecsd
27
27
 
28
28
  ## Quick Start
29
29
 
30
+ Create a terminal app with a bordered panel, text, and keyboard input:
31
+
30
32
  ```typescript
33
+ import { createWorld, createScreenEntity, createBoxEntity, createTextEntity } from 'blecsd/core';
34
+ import { createDirtyTracker } from 'blecsd/core';
31
35
  import {
32
- createWorld,
33
- addEntity,
34
- Position,
35
- Dimensions,
36
- Border,
37
- createBox,
38
- createList,
39
- createEventBus
40
- } from 'blecsd';
41
-
42
- // Create a world and entity
36
+ layoutSystem, renderSystem, outputSystem, cleanup,
37
+ setOutputStream, setOutputBuffer, setRenderBuffer,
38
+ } from 'blecsd/systems';
39
+ import { createProgram, createDoubleBuffer, getBackBuffer } from 'blecsd/terminal';
40
+
41
+ const cols = process.stdout.columns ?? 80;
42
+ const rows = process.stdout.rows ?? 24;
43
+
44
+ // 1. Initialize the terminal (alternate screen, hidden cursor, raw mode)
45
+ const program = createProgram();
46
+ await program.init();
47
+
48
+ // 2. Create the ECS world and screen entity
43
49
  const world = createWorld();
44
- const entity = addEntity(world);
45
-
46
- // Set position and dimensions using components
47
- Position.x[entity] = 2;
48
- Position.y[entity] = 1;
49
- Dimensions.width[entity] = 40;
50
- Dimensions.height[entity] = 10;
51
-
52
- // Create a box widget
53
- const box = createBox(world, entity, {
54
- border: { type: 'rounded' },
55
- title: 'My Application'
50
+ createScreenEntity(world, { width: cols, height: rows });
51
+
52
+ // 3. Wire up the render pipeline buffers
53
+ setOutputStream(process.stdout);
54
+ const db = createDoubleBuffer(cols, rows);
55
+ setOutputBuffer(db);
56
+ setRenderBuffer(createDirtyTracker(cols, rows), getBackBuffer(db));
57
+
58
+ // 4. Build your UI
59
+ const panel = createBoxEntity(world, {
60
+ x: 2, y: 1, width: 40, height: 12,
61
+ border: { type: 1, top: true, bottom: true, left: true, right: true },
56
62
  });
57
63
 
58
- // Create a list in another entity
59
- const listEntity = addEntity(world);
60
- const list = createList(world, listEntity, {
61
- items: [
62
- { label: 'Option 1', value: 'opt1' },
63
- { label: 'Option 2', value: 'opt2' },
64
- { label: 'Option 3', value: 'opt3' }
65
- ]
64
+ createTextEntity(world, {
65
+ x: 4, y: 2, text: 'My Dashboard', parent: panel,
66
66
  });
67
67
 
68
- // Type-safe events
69
- interface AppEvents {
70
- 'item:selected': { value: string };
68
+ // 5. Render
69
+ function render(): void {
70
+ layoutSystem(world);
71
+ renderSystem(world);
72
+ outputSystem(world);
71
73
  }
72
- const events = createEventBus<AppEvents>();
73
- events.on('item:selected', (e) => console.log(`Selected: ${e.value}`));
74
+
75
+ render();
76
+
77
+ // 6. Handle keyboard input
78
+ program.on('key', (event) => {
79
+ if (event.name === 'q' || (event.ctrl && event.name === 'c')) {
80
+ cleanup(world);
81
+ program.destroy();
82
+ process.exit(0);
83
+ }
84
+ render();
85
+ });
86
+ ```
87
+
88
+ ## Namespace Imports
89
+
90
+ blECSd organizes its API into discoverable namespace objects. Instead of importing dozens of individual functions, import a namespace and explore it with autocomplete:
91
+
92
+ ```typescript
93
+ import { position, scroll, content } from 'blecsd/components';
94
+ import { rope, colors, unicode } from 'blecsd/utils';
95
+ import { cursor, program, screen } from 'blecsd/terminal';
96
+
97
+ // Position operations
98
+ position.set(world, eid, 10, 5);
99
+ position.moveBy(world, eid, 1, 0);
100
+ position.zIndex.bringToFront(world, eid, siblings);
101
+
102
+ // Scroll control
103
+ scroll.by(world, eid, 0, 10);
104
+ scroll.toTop(world, eid);
105
+
106
+ // Text manipulation with rope data structure
107
+ const r = rope.create('Hello');
108
+ const modified = rope.insert(r, 5, ' World');
109
+ const text = rope.getText(modified);
110
+
111
+ // Color utilities
112
+ const hex = colors.rgbToHex(255, 100, 0);
113
+ const parsed = colors.parseColor('#ff6400');
114
+ ```
115
+
116
+ ### Import Tiers
117
+
118
+ | Tier | Import Path | Use Case |
119
+ |------|-------------|----------|
120
+ | **Tier 2 (Recommended)** | `'blecsd/core'`, `'blecsd/components'`, `'blecsd/systems'`, etc. | Full module access via subpaths |
121
+ | **Tier 1** | `'blecsd'` | Curated subset for small scripts |
122
+ | **Tier 3** | Deep imports | Internal only |
123
+
124
+ **Use subpath imports (Tier 2)** for all applications. They provide full API access, clear organization by domain, and reduced naming conflicts. The main `'blecsd'` entry re-exports a curated subset for convenience. See the [Export Patterns Guide](./docs/guides/export-patterns.md) for details.
125
+
126
+ ## Addon Packages
127
+
128
+ Specialized functionality is available as separate packages:
129
+
130
+ | Package | Description | Install |
131
+ |---------|-------------|---------|
132
+ | [@blecsd/3d](./packages/3d/) | 3D rendering with braille, halfblock, sixel, kitty backends | `npm i @blecsd/3d` |
133
+ | [@blecsd/ai](./packages/ai/) | LLM UI widgets: conversation, streaming markdown, token tracking | `npm i @blecsd/ai` |
134
+ | [@blecsd/audio](./packages/audio/) | Audio channel management and sound triggers | `npm i @blecsd/audio` |
135
+ | [@blecsd/game](./packages/game/) | High-level `createGame()` API for terminal games | `npm i @blecsd/game` |
136
+ | [@blecsd/media](./packages/media/) | GIF/PNG parsing, ANSI rendering, image/video widgets | `npm i @blecsd/media` |
137
+
138
+ Each addon package also provides namespace objects for discoverability:
139
+
140
+ ```typescript
141
+ // 3D math via namespaces
142
+ import { vec3, mat4, projection } from '@blecsd/3d';
143
+ const v = vec3.add(vec3.create(1, 0, 0), vec3.create(0, 1, 0));
144
+ const mvp = mat4.multiply(projection.perspective(60, 1.5, 0.1, 100), viewMatrix);
145
+
146
+ // AI widgets via namespaces
147
+ import { conversation, tokenTracker } from '@blecsd/ai';
148
+ conversation.addMessage(state, { role: 'user', content: 'Hello' });
149
+
150
+ // Media via namespaces
151
+ import { gif, png } from '@blecsd/media';
152
+ const frames = gif.parse.parseGIF(buffer);
153
+ ```
154
+
155
+ Addon packages also support subpath imports for tree-shaking:
156
+
157
+ ```typescript
158
+ import { vec3Add, vec3Cross } from '@blecsd/3d/math';
159
+ import { parseGIF } from '@blecsd/media/gif';
74
160
  ```
75
161
 
76
162
  ## Widgets
@@ -121,69 +207,38 @@ events.on('item:selected', (e) => console.log(`Selected: ${e.value}`));
121
207
  | Viewport3d | 3D scene renderer |
122
208
  | VirtualizedList | Efficient list for large datasets |
123
209
 
124
- ## Form Controls
210
+ ## Components
125
211
 
126
- | Control | Description |
127
- |---------|-------------|
128
- | Textarea | Multi-line text editor with cursor, selection |
129
- | Textbox | Single-line text input with cursor support |
130
- | Checkbox | Boolean toggle with customizable characters |
131
- | RadioButton | Single selection from group |
132
- | Switch | Toggle switch control |
133
- | Select | Dropdown selection menu (via List component) |
134
- | ProgressBar | Progress indicator, horizontal/vertical |
135
- | Form | Form field management, validation, submit |
136
- | Button | Clickable button with hover/focus states |
212
+ blECSd provides ECS components that work with any bitECS world. Each component has a corresponding namespace object for typed access:
137
213
 
138
- ## Components
214
+ ```typescript
215
+ import { position, content, list, scroll } from 'blecsd/components';
139
216
 
140
- blECSd provides ECS components that work with any bitECS world:
141
-
142
- | Component | Purpose |
143
- |-----------|---------|
144
- | Animation | Frame-based sprite animations |
145
- | Behavior | Behavior tree execution |
146
- | Border | Box borders (single, double, rounded, bold, ascii) |
147
- | Button | Button state and configuration |
148
- | Camera | Viewport, target following, bounds |
149
- | Checkbox | Checkbox state |
150
- | Collision | AABB/circle collision detection, layers, triggers |
151
- | Content | Text content, alignment, wrapping, tag parsing |
152
- | Dimensions | Width, height, min/max constraints, percentages |
153
- | Focusable | Keyboard focus, tab order |
154
- | Form | Form field management |
155
- | Health | Health/damage system |
156
- | Hierarchy | Parent-child relationships, traversal |
157
- | Input | Input capture state |
158
- | Interactive | Click, hover, drag states |
159
- | Label | Text labels with positioning |
160
- | List | List widget state |
161
- | Padding | Inner spacing |
162
- | Particle | Particle system data |
163
- | Position | X/Y coordinates, z-index, absolute positioning |
164
- | ProgressBar | Progress bar state |
165
- | RadioButton | Radio button state |
166
- | Renderable | Colors, visibility, dirty tracking |
167
- | Screen | Screen buffer data |
168
- | Scrollable | Scroll position, content size, scrollbars |
169
- | Scrollbar | Scrollbar state |
170
- | Select | Selection dropdown state |
171
- | Shadow | Drop shadows with opacity, blending |
172
- | Slider | Slider state |
173
- | Spinner | Loading spinner state |
174
- | Sprite | Sprite sheets, frames |
175
- | StateMachine | Finite state machine with events, transitions |
176
- | Table | Table widget state |
177
- | TerminalBuffer | Terminal emulator buffer |
178
- | TextInput | Text input state |
179
- | TextSelection | Text selection state |
180
- | Tilemap | Tilemap rendering data |
181
- | Timer | Timer/countdown state |
182
- | UserData | Custom user data storage |
183
- | Velocity | Movement with speed, friction, max speed |
184
- | VirtualViewport | Virtualized content rendering |
185
-
186
- See [API Reference](./docs/api/index.md) for the complete list.
217
+ position.set(world, eid, 10, 5); // set x, y
218
+ content.set(world, eid, 'Hello'); // set text content
219
+ list.select(world, eid, 2); // select item at index
220
+ scroll.toBottom(world, eid); // scroll to end
221
+ ```
222
+
223
+ | Component | Namespace | Purpose |
224
+ |-----------|-----------|---------|
225
+ | Animation | `animation` | Frame-based sprite animations |
226
+ | Border | `border` | Box borders (single, double, rounded, bold, ascii) |
227
+ | Camera | `camera` | Viewport, target following, bounds |
228
+ | Collision | `collision` | AABB/circle collision detection, layers, triggers |
229
+ | Content | `content` | Text content, alignment, wrapping, tag parsing |
230
+ | Dimensions | `dimensions` | Width, height, min/max constraints, percentages |
231
+ | Focusable | `focus` | Keyboard focus, tab order |
232
+ | Hierarchy | `hierarchy` | Parent-child relationships, traversal |
233
+ | List | `list` | List widget state, selection, virtualization |
234
+ | Position | `position` | X/Y coordinates, z-index, absolute positioning |
235
+ | Renderable | `renderable` | Colors, visibility, dirty tracking |
236
+ | Scrollable | `scroll` | Scroll position, scrollbars, virtual viewport |
237
+ | Table | `table` | Table state, columns, rows, sorting |
238
+ | TextInput | `textInput` | Text input, cursor, selection, validation |
239
+ | Velocity | `velocity` | Movement with speed, friction, max speed |
240
+
241
+ See [API Reference](./docs/api/index.md) for the complete list of all 41 components.
187
242
 
188
243
  ## Systems
189
244
 
@@ -221,67 +276,31 @@ blECSd is a library, not a framework:
221
276
  4. **You own the world**: Functions take `world` as a parameter; we never hold global state
222
277
 
223
278
  ```typescript
224
- // Your world, your control
225
- import {
226
- createWorld,
227
- addEntity,
228
- Position,
229
- Renderable,
230
- layoutSystem,
231
- renderSystem
232
- } from 'blecsd';
279
+ import { createWorld, addEntity } from 'blecsd/core';
280
+ import { createDirtyTracker } from 'blecsd/core';
281
+ import { layoutSystem, renderSystem, outputSystem, setOutputStream, setOutputBuffer, setRenderBuffer } from 'blecsd/systems';
282
+ import { createDoubleBuffer, getBackBuffer } from 'blecsd/terminal';
283
+ import { position, renderable } from 'blecsd/components';
233
284
 
234
285
  const world = createWorld();
235
286
  const eid = addEntity(world);
236
287
 
237
- // Use components directly - no setters needed
238
- Position.x[eid] = 10;
239
- Position.y[eid] = 5;
240
- Renderable.visible[eid] = 1;
288
+ // Use namespace helpers for typed access
289
+ position.set(world, eid, 10, 5);
290
+ renderable.show(world, eid);
291
+
292
+ // Initialize buffers (required for render/output systems)
293
+ setOutputStream(process.stdout);
294
+ const db = createDoubleBuffer(80, 24);
295
+ setOutputBuffer(db);
296
+ setRenderBuffer(createDirtyTracker(80, 24), getBackBuffer(db));
241
297
 
242
298
  // Call systems when you want
243
299
  layoutSystem(world);
244
300
  renderSystem(world);
301
+ outputSystem(world);
245
302
  ```
246
303
 
247
- ## PackedStore: Cache-Friendly Storage
248
-
249
- blECSd includes a `PackedStore<T>` primitive for systems that iterate over entities in hot paths (rendering, animation, collision). It provides O(1) add/remove/get with dense, cache-friendly iteration.
250
-
251
- ### The Three-Vector Pattern
252
-
253
- PackedStore uses four parallel arrays to keep live data contiguous:
254
-
255
- ```
256
- data[] Dense values, packed into [0, size) with no gaps
257
- dataIndex[] Maps handle.index -> position in data[]
258
- id[] Maps data position -> handle.index (inverse of dataIndex)
259
- generations[] Generation counter per slot for stale handle detection
260
- ```
261
-
262
- Removals use swap-and-pop: the last element fills the gap, so `data[]` is always contiguous. This means iterating `data[0..size]` hits sequential memory with no pointer chasing, which is 2-5x faster than `Map.forEach` for iteration-heavy workloads.
263
-
264
- ### createComponentStore\<T\>()
265
-
266
- For most code, use `createComponentStore<T>()` instead of PackedStore directly. It provides a Map-like API (`get`, `set`, `has`, `delete`, `forEach`) with two backing modes:
267
-
268
- ```typescript
269
- import { createComponentStore } from 'blecsd';
270
-
271
- // Iterable mode: backed by PackedStore, dense iteration via forEach/data()
272
- // Use for stores iterated in hot paths (widget rendering, layout, animation)
273
- const renderData = createComponentStore<RenderInfo>({ iterable: true });
274
-
275
- // Non-iterable mode (default): backed by a plain Map
276
- // Use for point lookups like callback registries or config
277
- const callbacks = createComponentStore<() => void>({ iterable: false });
278
- ```
279
-
280
- | Mode | Backing | Iteration | Best for |
281
- |------|---------|-----------|----------|
282
- | `iterable: true` | PackedStore | Dense, cache-friendly | Hot paths (render, animate, layout) |
283
- | `iterable: false` | Map | Standard Map iteration | Callbacks, config, point lookups |
284
-
285
304
  ## Use Cases
286
305
 
287
306
  - **Dashboards**: System monitors, log viewers, status displays
@@ -289,6 +308,8 @@ const callbacks = createComponentStore<() => void>({ iterable: false });
289
308
  - **CLI Tools**: Forms, menus, progress indicators
290
309
  - **Dev Tools**: Debug panels, profilers, inspectors
291
310
  - **Games**: Roguelikes, text adventures, puzzle games
311
+ - **AI Interfaces**: LLM chat, streaming output, token tracking (via @blecsd/ai)
312
+ - **3D Terminals**: Wireframe viewers, model inspectors (via @blecsd/3d)
292
313
 
293
314
  ## Comparison
294
315
 
@@ -312,6 +333,7 @@ Choose blECSd if you want data-oriented design, physics-based animations, or gam
312
333
 
313
334
  ### API Reference
314
335
  - [API Reference](./docs/api/index.md): Components, widgets, systems, terminal I/O
336
+ - [Export Patterns](./docs/guides/export-patterns.md): Import tiers, namespaces, module map
315
337
  - [Terminal Widget](./docs/api/widgets/terminal.md): ANSI rendering and PTY shell support
316
338
 
317
339
  ### Guides