blecsd 0.3.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +146 -147
- package/dist/{border-Jb7TrMob.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-4N7IFBRQ.js +4 -0
- package/dist/{chunk-DNRXW56C.js → chunk-4XCFTNGN.js} +1 -1
- package/dist/chunk-5YWRP2KG.js +3 -0
- package/dist/chunk-6PX5R326.js +1 -0
- package/dist/chunk-73Y45MLV.js +12 -0
- package/dist/chunk-7ZFQO3OQ.js +1 -0
- package/dist/chunk-A3GSH6MV.js +1 -0
- package/dist/chunk-A5B2BGUM.js +1 -0
- package/dist/chunk-AM6IDSXI.js +1 -0
- package/dist/chunk-EHYOVHRL.js +2 -0
- package/dist/chunk-EMZA6G2M.js +4 -0
- package/dist/chunk-EOFT3PNU.js +1 -0
- package/dist/chunk-ETFDYZVJ.js +1 -0
- package/dist/chunk-FUW7OD3H.js +1 -0
- package/dist/chunk-GRMSEMU7.js +1 -0
- package/dist/chunk-I7AUKTXE.js +1 -0
- package/dist/chunk-IANAVH2A.js +1 -0
- package/dist/chunk-JN2OGNK3.js +1 -0
- package/dist/chunk-JVMNMAHX.js +1 -0
- package/dist/chunk-K2QWNDXV.js +1 -0
- package/dist/chunk-KYNS3GBJ.js +2 -0
- package/dist/chunk-LI3ZYXUT.js +1 -0
- package/dist/chunk-LNEISTXM.js +1 -0
- package/dist/chunk-QABNK7IA.js +1 -0
- package/dist/chunk-QS5QXZNJ.js +1 -0
- package/dist/chunk-QTDRFJG2.js +1 -0
- package/dist/chunk-RJULLVTH.js +1 -0
- package/dist/chunk-SVHITP3F.js +2 -0
- package/dist/chunk-UKVY43V3.js +1 -0
- package/dist/chunk-VIT4KE6Q.js +1 -0
- package/dist/chunk-XG5PVDOP.js +1 -0
- package/dist/chunk-XH5GTWCV.js +1 -0
- package/dist/chunk-XYMPBCYW.js +1 -0
- package/dist/chunk-YRSSCEAS.js +1 -0
- package/dist/chunk-ZL46COQF.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 +7209 -6691
- package/dist/components/index.js +5 -1
- package/dist/core/index.d.ts +2501 -1262
- 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-kCS9-NVF.d.ts} +2 -2
- package/dist/{doubleBuffer-CKQFmlPN.d.ts → doubleBuffer-CWASihKh.d.ts} +1 -1
- package/dist/errors/index.js +1 -1
- package/dist/{inputActions-CRsUtTHM.d.ts → factories-vW7bn_He.d.ts} +21 -786
- package/dist/{gameLoop-C-Ez_i54.d.ts → gameLoop-C1AyRWyP.d.ts} +3 -3
- package/dist/index.d.ts +25 -500
- package/dist/index.js +1 -3
- package/dist/input/index.d.ts +1 -1
- package/dist/input/index.js +1 -1
- package/dist/inputStream-COARA4CP.d.ts +1182 -0
- package/dist/interactiveSystem-h92W9W4n.d.ts +1977 -0
- package/dist/{keyParser-BnHbg2iD.d.ts → keyParser-DReXe2j-.d.ts} +41 -41
- package/dist/{events-9ForpTfM.d.ts → mouseParser-CCqSEUVN.d.ts} +177 -2
- package/dist/{packedStore-BgvnEdE7.d.ts → packedStore-480t2X74.d.ts} +1 -1
- package/dist/panelMovement-DGzIQ8Ll.d.ts +1908 -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-CMcYew9Z.d.ts → scheduler-NbHT3-D2.d.ts} +3 -1
- package/dist/schemas/index.d.ts +6 -6
- package/dist/schemas/index.js +1 -1
- package/dist/systems/index.d.ts +1057 -1807
- package/dist/systems/index.js +1 -1
- package/dist/terminal/index.d.ts +7207 -2709
- 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/text/index.d.ts +263 -0
- package/dist/text/index.js +3 -0
- package/dist/textWrap-Ct2J8gO6.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 +827 -780
- 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 +2933 -1102
- package/dist/widgets/index.js +24 -1
- package/package.json +9 -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-2IEMMRUO.js +0 -1
- package/dist/chunk-35LCBY6P.js +0 -1
- package/dist/chunk-3AV52GY5.js +0 -1
- package/dist/chunk-3LHLSY3Y.js +0 -1
- package/dist/chunk-3O4TQHGK.js +0 -4
- package/dist/chunk-3UJWZ5ZN.js +0 -1
- package/dist/chunk-5PELJRUQ.js +0 -1
- package/dist/chunk-6M2J5QUA.js +0 -1
- package/dist/chunk-7IQEUVGF.js +0 -1
- package/dist/chunk-A6M6TFBL.js +0 -1
- package/dist/chunk-CIK4AMUA.js +0 -1
- package/dist/chunk-CUEUJAHK.js +0 -3
- package/dist/chunk-D42Q2KKR.js +0 -1
- package/dist/chunk-DYEXOFUU.js +0 -2
- package/dist/chunk-DYU72XLL.js +0 -1
- package/dist/chunk-E4CJRSND.js +0 -1
- package/dist/chunk-EAY7B5GL.js +0 -1
- package/dist/chunk-FCMTWFSE.js +0 -1
- package/dist/chunk-FGHEFXLK.js +0 -1
- package/dist/chunk-FL56THSI.js +0 -25
- package/dist/chunk-G437VE43.js +0 -1
- package/dist/chunk-G7GIWWLE.js +0 -1
- package/dist/chunk-GGXNWT36.js +0 -8
- package/dist/chunk-HLFORKXS.js +0 -1
- package/dist/chunk-J7MBKEBY.js +0 -1
- package/dist/chunk-K3SX2LY5.js +0 -1
- package/dist/chunk-LDAFEXN5.js +0 -1
- package/dist/chunk-LYSK5S63.js +0 -1
- package/dist/chunk-MKMFUXLB.js +0 -33
- package/dist/chunk-MQWPHPUM.js +0 -1
- package/dist/chunk-MTI376CU.js +0 -5
- package/dist/chunk-MTV2RJZD.js +0 -1
- package/dist/chunk-NZ55KBM6.js +0 -1
- package/dist/chunk-OB66FB4F.js +0 -1
- package/dist/chunk-OMMJ7B5P.js +0 -1
- package/dist/chunk-OR3BZY7C.js +0 -1
- package/dist/chunk-PXXGH3BV.js +0 -1
- package/dist/chunk-R7AICVRN.js +0 -2
- package/dist/chunk-RZ7FGVI6.js +0 -1
- package/dist/chunk-SHUC6JWA.js +0 -1
- package/dist/chunk-TWSWTBYL.js +0 -1
- package/dist/chunk-UMGTXSQB.js +0 -11
- package/dist/chunk-X3Q3T2SS.js +0 -4
- package/dist/chunk-XZJRWFOS.js +0 -1
- package/dist/chunk-ZAHG7Y3X.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/mouseParser-Cfrbn3AX.d.ts +0 -177
- package/dist/viewport3d-xI33-_wq.d.ts +0 -182
- package/dist/virtualViewport-Bpv6jlKt.d.ts +0 -1856
package/README.md
CHANGED
|
@@ -27,50 +27,124 @@ 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
|
|
31
33
|
import {
|
|
32
|
-
createWorld,
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
Border,
|
|
37
|
-
createBox,
|
|
38
|
-
createList,
|
|
39
|
-
createEventBus
|
|
34
|
+
createWorld, createScreenEntity, createBoxEntity,
|
|
35
|
+
createTextEntity, createListEntity, setText,
|
|
36
|
+
inputSystem, layoutSystem, renderSystem, outputSystem, cleanup,
|
|
37
|
+
enableInput, enableKeys,
|
|
40
38
|
} from 'blecsd';
|
|
41
39
|
|
|
42
|
-
//
|
|
40
|
+
// Set up the world and screen
|
|
43
41
|
const world = createWorld();
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
//
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
42
|
+
const screen = createScreenEntity(world, { width: 80, height: 24 });
|
|
43
|
+
|
|
44
|
+
// A bordered panel
|
|
45
|
+
const panel = createBoxEntity(world, {
|
|
46
|
+
x: 2, y: 1, width: 40, height: 12,
|
|
47
|
+
parent: screen,
|
|
48
|
+
border: { type: 1, top: true, bottom: true, left: true, right: true },
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
// Title text
|
|
52
|
+
createTextEntity(world, {
|
|
53
|
+
x: 4, y: 2, text: 'My Dashboard', parent: screen,
|
|
56
54
|
});
|
|
57
55
|
|
|
58
|
-
//
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
items: [
|
|
62
|
-
{ label: 'Option 1', value: 'opt1' },
|
|
63
|
-
{ label: 'Option 2', value: 'opt2' },
|
|
64
|
-
{ label: 'Option 3', value: 'opt3' }
|
|
65
|
-
]
|
|
56
|
+
// A selectable list
|
|
57
|
+
const list = createListEntity(world, {
|
|
58
|
+
x: 4, y: 4, width: 36, height: 6, parent: screen,
|
|
66
59
|
});
|
|
67
60
|
|
|
68
|
-
//
|
|
69
|
-
|
|
70
|
-
|
|
61
|
+
// Enable keyboard input and run the update loop
|
|
62
|
+
enableInput(world, screen);
|
|
63
|
+
enableKeys(world, screen);
|
|
64
|
+
|
|
65
|
+
function tick(): void {
|
|
66
|
+
inputSystem(world);
|
|
67
|
+
layoutSystem(world);
|
|
68
|
+
renderSystem(world);
|
|
69
|
+
outputSystem(world);
|
|
71
70
|
}
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
|
|
72
|
+
const interval = setInterval(tick, 16);
|
|
73
|
+
process.on('SIGINT', () => { clearInterval(interval); cleanup(world); });
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Namespace Imports
|
|
77
|
+
|
|
78
|
+
blECSd organizes its API into discoverable namespace objects. Instead of importing dozens of individual functions, import a namespace and explore it with autocomplete:
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
import { position, scroll, content } from 'blecsd/components';
|
|
82
|
+
import { rope, colors, unicode } from 'blecsd/utils';
|
|
83
|
+
import { cursor, program, screen } from 'blecsd/terminal';
|
|
84
|
+
|
|
85
|
+
// Position operations
|
|
86
|
+
position.set(world, eid, 10, 5);
|
|
87
|
+
position.moveBy(world, eid, 1, 0);
|
|
88
|
+
position.zIndex.bringToFront(world, eid, siblings);
|
|
89
|
+
|
|
90
|
+
// Scroll control
|
|
91
|
+
scroll.by(world, eid, 0, 10);
|
|
92
|
+
scroll.toTop(world, eid);
|
|
93
|
+
|
|
94
|
+
// Text manipulation with rope data structure
|
|
95
|
+
const r = rope.create('Hello');
|
|
96
|
+
const modified = rope.insert(r, 5, ' World');
|
|
97
|
+
const text = rope.getText(modified);
|
|
98
|
+
|
|
99
|
+
// Color utilities
|
|
100
|
+
const hex = colors.rgbToHex(255, 100, 0);
|
|
101
|
+
const parsed = colors.parseColor('#ff6400');
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Import Tiers
|
|
105
|
+
|
|
106
|
+
| Tier | Import Path | Use Case |
|
|
107
|
+
|------|-------------|----------|
|
|
108
|
+
| **Tier 1** | `'blecsd'` | ~80 curated essentials (factories, systems, core helpers) |
|
|
109
|
+
| **Tier 2** | `'blecsd/components'`, `'blecsd/utils'`, etc. | Full module access via namespaces |
|
|
110
|
+
| **Tier 3** | Deep imports | Internal only |
|
|
111
|
+
|
|
112
|
+
Start with Tier 1 for prototyping, then use Tier 2 namespaces as your app grows. See the [Export Patterns Guide](./docs/guides/export-patterns.md) for details.
|
|
113
|
+
|
|
114
|
+
## Addon Packages
|
|
115
|
+
|
|
116
|
+
Specialized functionality is available as separate packages:
|
|
117
|
+
|
|
118
|
+
| Package | Description | Install |
|
|
119
|
+
|---------|-------------|---------|
|
|
120
|
+
| [@blecsd/3d](./packages/3d/) | 3D rendering with braille, halfblock, sixel, kitty backends | `npm i @blecsd/3d` |
|
|
121
|
+
| [@blecsd/ai](./packages/ai/) | LLM UI widgets: conversation, streaming markdown, token tracking | `npm i @blecsd/ai` |
|
|
122
|
+
| [@blecsd/audio](./packages/audio/) | Audio channel management and sound triggers | `npm i @blecsd/audio` |
|
|
123
|
+
| [@blecsd/game](./packages/game/) | High-level `createGame()` API for terminal games | `npm i @blecsd/game` |
|
|
124
|
+
| [@blecsd/media](./packages/media/) | GIF/PNG parsing, ANSI rendering, image/video widgets | `npm i @blecsd/media` |
|
|
125
|
+
|
|
126
|
+
Each addon package also provides namespace objects for discoverability:
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
// 3D math via namespaces
|
|
130
|
+
import { vec3, mat4, projection } from '@blecsd/3d';
|
|
131
|
+
const v = vec3.add(vec3.create(1, 0, 0), vec3.create(0, 1, 0));
|
|
132
|
+
const mvp = mat4.multiply(projection.perspective(60, 1.5, 0.1, 100), viewMatrix);
|
|
133
|
+
|
|
134
|
+
// AI widgets via namespaces
|
|
135
|
+
import { conversation, tokenTracker } from '@blecsd/ai';
|
|
136
|
+
conversation.addMessage(state, { role: 'user', content: 'Hello' });
|
|
137
|
+
|
|
138
|
+
// Media via namespaces
|
|
139
|
+
import { gif, png } from '@blecsd/media';
|
|
140
|
+
const frames = gif.parse.parseGIF(buffer);
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Addon packages also support subpath imports for tree-shaking:
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
import { vec3Add, vec3Cross } from '@blecsd/3d/math';
|
|
147
|
+
import { parseGIF } from '@blecsd/media/gif';
|
|
74
148
|
```
|
|
75
149
|
|
|
76
150
|
## Widgets
|
|
@@ -121,69 +195,38 @@ events.on('item:selected', (e) => console.log(`Selected: ${e.value}`));
|
|
|
121
195
|
| Viewport3d | 3D scene renderer |
|
|
122
196
|
| VirtualizedList | Efficient list for large datasets |
|
|
123
197
|
|
|
124
|
-
##
|
|
198
|
+
## Components
|
|
125
199
|
|
|
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 |
|
|
200
|
+
blECSd provides ECS components that work with any bitECS world. Each component has a corresponding namespace object for typed access:
|
|
137
201
|
|
|
138
|
-
|
|
202
|
+
```typescript
|
|
203
|
+
import { position, content, list, scroll } from 'blecsd/components';
|
|
139
204
|
|
|
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.
|
|
205
|
+
position.set(world, eid, 10, 5); // set x, y
|
|
206
|
+
content.set(world, eid, 'Hello'); // set text content
|
|
207
|
+
list.select(world, eid, 2); // select item at index
|
|
208
|
+
scroll.toBottom(world, eid); // scroll to end
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
| Component | Namespace | Purpose |
|
|
212
|
+
|-----------|-----------|---------|
|
|
213
|
+
| Animation | `animation` | Frame-based sprite animations |
|
|
214
|
+
| Border | `border` | Box borders (single, double, rounded, bold, ascii) |
|
|
215
|
+
| Camera | `camera` | Viewport, target following, bounds |
|
|
216
|
+
| Collision | `collision` | AABB/circle collision detection, layers, triggers |
|
|
217
|
+
| Content | `content` | Text content, alignment, wrapping, tag parsing |
|
|
218
|
+
| Dimensions | `dimensions` | Width, height, min/max constraints, percentages |
|
|
219
|
+
| Focusable | `focus` | Keyboard focus, tab order |
|
|
220
|
+
| Hierarchy | `hierarchy` | Parent-child relationships, traversal |
|
|
221
|
+
| List | `list` | List widget state, selection, virtualization |
|
|
222
|
+
| Position | `position` | X/Y coordinates, z-index, absolute positioning |
|
|
223
|
+
| Renderable | `renderable` | Colors, visibility, dirty tracking |
|
|
224
|
+
| Scrollable | `scroll` | Scroll position, scrollbars, virtual viewport |
|
|
225
|
+
| Table | `table` | Table state, columns, rows, sorting |
|
|
226
|
+
| TextInput | `textInput` | Text input, cursor, selection, validation |
|
|
227
|
+
| Velocity | `velocity` | Movement with speed, friction, max speed |
|
|
228
|
+
|
|
229
|
+
See [API Reference](./docs/api/index.md) for the complete list of all 41 components.
|
|
187
230
|
|
|
188
231
|
## Systems
|
|
189
232
|
|
|
@@ -221,67 +264,21 @@ blECSd is a library, not a framework:
|
|
|
221
264
|
4. **You own the world**: Functions take `world` as a parameter; we never hold global state
|
|
222
265
|
|
|
223
266
|
```typescript
|
|
224
|
-
|
|
225
|
-
import {
|
|
226
|
-
createWorld,
|
|
227
|
-
addEntity,
|
|
228
|
-
Position,
|
|
229
|
-
Renderable,
|
|
230
|
-
layoutSystem,
|
|
231
|
-
renderSystem
|
|
232
|
-
} from 'blecsd';
|
|
267
|
+
import { createWorld, addEntity, layoutSystem, renderSystem } from 'blecsd';
|
|
268
|
+
import { position, renderable } from 'blecsd/components';
|
|
233
269
|
|
|
234
270
|
const world = createWorld();
|
|
235
271
|
const eid = addEntity(world);
|
|
236
272
|
|
|
237
|
-
// Use
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
Renderable.visible[eid] = 1;
|
|
273
|
+
// Use namespace helpers for typed access
|
|
274
|
+
position.set(world, eid, 10, 5);
|
|
275
|
+
renderable.show(world, eid);
|
|
241
276
|
|
|
242
277
|
// Call systems when you want
|
|
243
278
|
layoutSystem(world);
|
|
244
279
|
renderSystem(world);
|
|
245
280
|
```
|
|
246
281
|
|
|
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
282
|
## Use Cases
|
|
286
283
|
|
|
287
284
|
- **Dashboards**: System monitors, log viewers, status displays
|
|
@@ -289,6 +286,8 @@ const callbacks = createComponentStore<() => void>({ iterable: false });
|
|
|
289
286
|
- **CLI Tools**: Forms, menus, progress indicators
|
|
290
287
|
- **Dev Tools**: Debug panels, profilers, inspectors
|
|
291
288
|
- **Games**: Roguelikes, text adventures, puzzle games
|
|
289
|
+
- **AI Interfaces**: LLM chat, streaming output, token tracking (via @blecsd/ai)
|
|
290
|
+
- **3D Terminals**: Wireframe viewers, model inspectors (via @blecsd/3d)
|
|
292
291
|
|
|
293
292
|
## Comparison
|
|
294
293
|
|
|
@@ -312,6 +311,7 @@ Choose blECSd if you want data-oriented design, physics-based animations, or gam
|
|
|
312
311
|
|
|
313
312
|
### API Reference
|
|
314
313
|
- [API Reference](./docs/api/index.md): Components, widgets, systems, terminal I/O
|
|
314
|
+
- [Export Patterns](./docs/guides/export-patterns.md): Import tiers, namespaces, module map
|
|
315
315
|
- [Terminal Widget](./docs/api/widgets/terminal.md): ANSI rendering and PTY shell support
|
|
316
316
|
|
|
317
317
|
### Guides
|
|
@@ -323,8 +323,7 @@ Choose blECSd if you want data-oriented design, physics-based animations, or gam
|
|
|
323
323
|
- [Keyboard Shortcuts](./docs/guides/keyboard-shortcuts.md): Custom keybindings
|
|
324
324
|
|
|
325
325
|
### Examples
|
|
326
|
-
- [Examples](
|
|
327
|
-
- [Examples Repository](https://github.com/Kadajett/blECSd-Examples): Standalone runnable examples
|
|
326
|
+
- [Examples Repository](https://github.com/Kadajett/blECSd-Examples): File manager, multiplexer, system monitor, ANSI viewer, telnet server, and more
|
|
328
327
|
|
|
329
328
|
## Development
|
|
330
329
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { W as World, E as Entity } from './types-
|
|
1
|
+
import { W as World, E as Entity } from './types-B8LmNkzG.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Border component for element borders.
|
|
@@ -264,4 +264,4 @@ declare function disableAllBorders(world: World, eid: Entity): Entity;
|
|
|
264
264
|
*/
|
|
265
265
|
declare function getBorderChar(world: World, eid: Entity, position: 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'horizontal' | 'vertical'): number | undefined;
|
|
266
266
|
|
|
267
|
-
export { BORDER_ASCII as B, DEFAULT_BORDER_BG as D,
|
|
267
|
+
export { BORDER_ASCII as B, DEFAULT_BORDER_BG as D, hasBorderVisible as a, getBorderChar as b, setBorderChars as c, disableAllBorders as d, enableAllBorders as e, BORDER_BOLD as f, getBorder as g, hasBorder as h, BORDER_DASHED as i, BORDER_DASHED_HEAVY as j, BORDER_DOUBLE as k, BORDER_ROUNDED as l, BORDER_SINGLE as m, Border as n, type BorderCharset as o, type BorderData as p, type BorderOptions as q, BorderType as r, setBorder as s, DEFAULT_BORDER_FG as t };
|
|
@@ -502,4 +502,4 @@ interface CellChange {
|
|
|
502
502
|
*/
|
|
503
503
|
declare function diffBuffers(oldBuffer: ScreenBufferData, newBuffer: ScreenBufferData): CellChange[];
|
|
504
504
|
|
|
505
|
-
export { Attr as A, type Cell as C, DEFAULT_BG as D, type ScreenBufferData as S, type
|
|
505
|
+
export { Attr as A, type Cell as C, DEFAULT_BG as D, type ScreenBufferData as S, type CellChange as a, cellIndex as b, clearBuffer as c, cellsEqual as d, cloneCell as e, fillRect as f, getCell as g, copyRegion as h, createCell as i, createScreenBuffer as j, diffBuffers as k, hasAttr as l, isInBounds as m, setChar as n, withoutAttr as o, writeString as p, type AttrFlags as q, resizeBuffer as r, setCell as s, DEFAULT_FG as t, DEFAULT_CHAR as u, withAttr as w };
|