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.
- package/README.md +169 -147
- package/dist/blend-BZDmQFAm.d.ts +1215 -0
- package/dist/{border-DGNDfT6T.d.ts → border-Br-Jc027.d.ts} +2 -2
- package/dist/{cell-DwIu2ryP.d.ts → cell-5Ty_3yMs.d.ts} +1 -1
- package/dist/cellRenderer-D0-DJXWl.d.ts +374 -0
- package/dist/chunk-3PGACJB6.js +1 -0
- package/dist/{chunk-DNRXW56C.js → chunk-4EV3YS7F.js} +1 -1
- package/dist/chunk-4XW4WIPH.js +1 -0
- package/dist/chunk-7CLV3LTZ.js +4 -0
- package/dist/chunk-7ZFQO3OQ.js +1 -0
- package/dist/chunk-AM6IDSXI.js +1 -0
- package/dist/chunk-APPZ3YHO.js +0 -0
- package/dist/chunk-EHYOVHRL.js +2 -0
- package/dist/chunk-EKE2BXPS.js +1 -0
- package/dist/chunk-EOFT3PNU.js +1 -0
- package/dist/chunk-ESMSDY3P.js +1 -0
- package/dist/chunk-FJLSHFCF.js +1 -0
- package/dist/chunk-FUW7OD3H.js +1 -0
- package/dist/chunk-GIMWA5WA.js +1 -0
- package/dist/chunk-GRMSEMU7.js +1 -0
- package/dist/chunk-I7AUKTXE.js +1 -0
- package/dist/chunk-IXUFU6TE.js +3 -0
- package/dist/chunk-JB5KFQPD.js +1 -0
- package/dist/chunk-JCLNGU3K.js +1 -0
- package/dist/chunk-JN2OGNK3.js +1 -0
- package/dist/chunk-JRRJCATR.js +1 -0
- package/dist/chunk-JWIVZCKW.js +1 -0
- package/dist/chunk-K5UMVDQX.js +1 -0
- package/dist/chunk-KYNS3GBJ.js +2 -0
- package/dist/chunk-L4FIDOS6.js +1 -0
- package/dist/chunk-LIVVHEOU.js +1 -0
- package/dist/chunk-LNEISTXM.js +1 -0
- package/dist/chunk-M5FXA5FL.js +1 -0
- package/dist/chunk-MEJJLDEQ.js +1 -0
- package/dist/chunk-NYIMY4UV.js +1 -0
- package/dist/chunk-PQZTNWLA.js +1 -0
- package/dist/chunk-QS5QXZNJ.js +1 -0
- package/dist/chunk-SXOBHRXF.js +2 -0
- package/dist/chunk-T2EQLWMN.js +1 -0
- package/dist/chunk-T62UPG63.js +4 -0
- package/dist/chunk-TPBILYDM.js +10 -0
- package/dist/chunk-UWS6FIU5.js +1 -0
- package/dist/chunk-W64J7C25.js +4 -0
- package/dist/chunk-W6RELN6A.js +1 -0
- package/dist/chunk-XYMPBCYW.js +1 -0
- package/dist/chunk-ZAJI53SZ.js +1 -0
- package/dist/cli/init.js +1 -1
- package/dist/{componentStorage-CJTh-TPO.d.ts → componentStorage-CXJvx4Lt.d.ts} +2 -2
- package/dist/components/index.d.ts +7762 -7682
- package/dist/components/index.js +5 -1
- package/dist/core/index.d.ts +4851 -4261
- package/dist/core/index.js +1 -1
- package/dist/debug/index.d.ts +310 -84
- package/dist/debug/index.js +8 -1
- package/dist/{dirtyTracking-C4v8MmM9.d.ts → dirtyTracking-D0SQrEeo.d.ts} +2 -2
- package/dist/{doubleBuffer-CKQFmlPN.d.ts → doubleBuffer-d9yVNtj1.d.ts} +22 -2
- package/dist/errors/index.js +1 -1
- package/dist/{events-9ForpTfM.d.ts → events-CGqK6LGt.d.ts} +2 -2
- package/dist/{inputActions-Fyw14_Gm.d.ts → factories-vW7bn_He.d.ts} +21 -786
- package/dist/{gameLoop-CSTb7e0L.d.ts → gameLoop-C1AyRWyP.d.ts} +3 -3
- package/dist/index.d.ts +25 -1217
- package/dist/index.js +1 -3
- package/dist/input/index.d.ts +1 -1
- package/dist/input/index.js +1 -1
- package/dist/inputStream-BoFAEJ7g.d.ts +1385 -0
- package/dist/interactiveSystem-Dtv3xERg.d.ts +2292 -0
- package/dist/{keyParser-m7fWto6g.d.ts → keyParser-DReXe2j-.d.ts} +28 -28
- package/dist/{mouseParser-B7p5ow7K.d.ts → mouseParser-CTNGolIA.d.ts} +1 -1
- package/dist/{packedStore-BgvnEdE7.d.ts → packedStore-480t2X74.d.ts} +1 -1
- package/dist/panelMovement-DSLYdNOL.d.ts +1909 -0
- package/dist/{parser-iMHmQuUh.d.ts → parser-Q1YLXYpF.d.ts} +1 -1
- package/dist/positioning-DiUivJXa.d.ts +917 -0
- package/dist/{renderable-CwqGwrEV.d.ts → renderable-IbSJao5y.d.ts} +2 -2
- package/dist/{scheduler-DeeZleia.d.ts → scheduler-NbHT3-D2.d.ts} +1 -1
- package/dist/schemas/index.d.ts +6 -6
- package/dist/schemas/index.js +1 -1
- package/dist/style/index.d.ts +851 -0
- package/dist/style/index.js +1 -0
- package/dist/styleInheritance-CuRb5Dmp.d.ts +251 -0
- package/dist/systems/index.d.ts +786 -1882
- package/dist/systems/index.js +1 -1
- package/dist/terminal/index.d.ts +5542 -2460
- package/dist/terminal/index.js +1 -1
- package/dist/terminalBuffer-BbUz27qM.d.ts +691 -0
- package/dist/{terminus-14-bold-HWSPRLJD.js → terminus-14-bold-ZS4IH465.js} +1 -1
- package/dist/{terminus-14-normal-T3SWMH4D.js → terminus-14-normal-HD5N7F5W.js} +1 -1
- package/dist/testing/index.d.ts +923 -0
- package/dist/testing/index.js +7 -0
- package/dist/text/index.d.ts +263 -0
- package/dist/text/index.js +3 -0
- package/dist/textWrap-sY-PZzE7.d.ts +761 -0
- package/dist/{tilemap-BirMJdbu.d.ts → tilemap-ByvTsepD.d.ts} +5 -5
- package/dist/{types-CPB4CpbH.d.ts → types-B8LmNkzG.d.ts} +1 -1
- package/dist/utils/index.d.ts +829 -782
- package/dist/utils/index.js +32 -1
- package/dist/{virtualScrollback-D9uLFe8l.d.ts → virtualScrollback-CiooIebp.d.ts} +4 -4
- package/dist/virtualViewport-fIlbIGPt.d.ts +657 -0
- package/dist/{virtualizedLineStore-DwPEvPkk.d.ts → virtualizedLineStore-DfyhojPZ.d.ts} +1 -1
- package/dist/widgets/bigText.d.ts +13 -13
- package/dist/widgets/bigText.js +1 -1
- package/dist/widgets/fonts/index.d.ts +1 -1
- package/dist/widgets/fonts/index.js +1 -1
- package/dist/widgets/index.d.ts +1620 -910
- package/dist/widgets/index.js +24 -1
- package/package.json +23 -22
- package/dist/3d/index.d.ts +0 -5
- package/dist/3d/index.js +0 -1
- package/dist/audio/index.d.ts +0 -177
- package/dist/audio/index.js +0 -1
- package/dist/chunk-25OEBENM.js +0 -3
- package/dist/chunk-26STV7ZS.js +0 -1
- package/dist/chunk-2NMGUEFC.js +0 -4
- package/dist/chunk-35LCBY6P.js +0 -1
- package/dist/chunk-4PRDJTCM.js +0 -1
- package/dist/chunk-5PELJRUQ.js +0 -1
- package/dist/chunk-5VEKHA3B.js +0 -5
- package/dist/chunk-6KEM3OS2.js +0 -11
- package/dist/chunk-6XWY6GB7.js +0 -1
- package/dist/chunk-735KKTP3.js +0 -1
- package/dist/chunk-7SWJNDOL.js +0 -26
- package/dist/chunk-APKUNIMB.js +0 -1
- package/dist/chunk-CJCSZRV6.js +0 -1
- package/dist/chunk-DMBMCCLN.js +0 -1
- package/dist/chunk-DQTVJITR.js +0 -1
- package/dist/chunk-DSKQ5J4R.js +0 -1
- package/dist/chunk-E4CJRSND.js +0 -1
- package/dist/chunk-EF4DC6IN.js +0 -1
- package/dist/chunk-EJAKECSN.js +0 -1
- package/dist/chunk-FNQRUMFD.js +0 -1
- package/dist/chunk-GJ3RS2VG.js +0 -1
- package/dist/chunk-KTVEMB2I.js +0 -1
- package/dist/chunk-KYAPE44E.js +0 -8
- package/dist/chunk-LI4Y7TBZ.js +0 -1
- package/dist/chunk-NHOL4BN6.js +0 -1
- package/dist/chunk-NPNUUSIB.js +0 -1
- package/dist/chunk-NZ55KBM6.js +0 -1
- package/dist/chunk-OFRWGW2G.js +0 -1
- package/dist/chunk-OMMJ7B5P.js +0 -1
- package/dist/chunk-OMU5BSAS.js +0 -2
- package/dist/chunk-P3ZLIQJP.js +0 -1
- package/dist/chunk-PWI36BQJ.js +0 -1
- package/dist/chunk-QQMUDJ32.js +0 -2
- package/dist/chunk-R3ICZOE4.js +0 -1
- package/dist/chunk-RZ7FGVI6.js +0 -1
- package/dist/chunk-S6WS46FE.js +0 -1
- package/dist/chunk-TSARUU56.js +0 -1
- package/dist/chunk-WJRVUAZR.js +0 -33
- package/dist/chunk-WY5EZOOL.js +0 -1
- package/dist/chunk-YY6RZCZH.js +0 -4
- package/dist/chunk-ZPGJCHXH.js +0 -1
- package/dist/chunk-ZPL2J25N.js +0 -1
- package/dist/game/index.d.ts +0 -486
- package/dist/game/index.js +0 -1
- package/dist/index-DBS5Uefn.d.ts +0 -3156
- package/dist/viewport3d-xI33-_wq.d.ts +0 -182
- 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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
-
|
|
45
|
-
|
|
46
|
-
//
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
//
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
|
|
59
|
-
|
|
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
|
-
//
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
// 5. Render
|
|
69
|
+
function render(): void {
|
|
70
|
+
layoutSystem(world);
|
|
71
|
+
renderSystem(world);
|
|
72
|
+
outputSystem(world);
|
|
71
73
|
}
|
|
72
|
-
|
|
73
|
-
|
|
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
|
-
##
|
|
210
|
+
## Components
|
|
125
211
|
|
|
126
|
-
|
|
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
|
-
|
|
214
|
+
```typescript
|
|
215
|
+
import { position, content, list, scroll } from 'blecsd/components';
|
|
139
216
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
|
147
|
-
|
|
148
|
-
|
|
|
149
|
-
|
|
|
150
|
-
|
|
|
151
|
-
|
|
|
152
|
-
|
|
|
153
|
-
|
|
|
154
|
-
|
|
|
155
|
-
|
|
|
156
|
-
|
|
|
157
|
-
|
|
|
158
|
-
|
|
|
159
|
-
|
|
|
160
|
-
|
|
|
161
|
-
|
|
|
162
|
-
|
|
|
163
|
-
|
|
164
|
-
|
|
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
|
-
|
|
225
|
-
import {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
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
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
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
|