@jboltai/tokui 0.1.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_EN.md ADDED
@@ -0,0 +1,438 @@
1
+ # TokUI - From Token To UI
2
+
3
+ English | **[简体中文](./README.md)**
4
+
5
+ > TokUI is the world's first For AI & zero-dependency streaming UI framework. Describe components with a minimal DSL on the backend, push over SSE or WebSocket, and render incrementally on the frontend — the first token starts painting the DOM, letting AI produce more flexible, expressive UI with minimal tokens.
6
+
7
+ [![npm version](https://img.shields.io/npm/v/@jboltai/tokui.svg)](https://www.npmjs.com/package/@jboltai/tokui)
8
+ [![npm downloads](https://img.shields.io/npm/dm/@jboltai/tokui.svg)](https://www.npmjs.com/package/@jboltai/tokui)
9
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
10
+ [![zero runtime deps](https://img.shields.io/badge/runtime%20deps-0-brightgreen.svg)](#)
11
+ [![bundle size](https://img.shields.io/bundlephobia/minzip/@jboltai/tokui.svg)](https://bundlephobia.com/package/@jboltai/tokui)
12
+
13
+ [Try on StackBlitz](https://stackblitz.com/github/jboltai/tokui) · [Component gallery demo](./demo/index.html) · [DSL reference](./demo/TOKUI_DSL_REFERENCE.md) · [Docs site](https://tokui.jboltai.com/)
14
+
15
+ ---
16
+
17
+ ## Table of Contents
18
+
19
+ - [Features](#features)
20
+ - [Architecture](#architecture)
21
+ - [Quick Start](#quick-start)
22
+ - [DSL Syntax Cheatsheet](#dsl-syntax-cheatsheet)
23
+ - [Component Inventory](#component-inventory)
24
+ - [Builder API (Server-side)](#builder-api-server-side)
25
+ - [Theme System](#theme-system)
26
+ - [Extending Components](#extending-components)
27
+ - [Testing](#testing)
28
+ - [Demo](#demo)
29
+ - [Project Structure](#project-structure)
30
+ - [Roadmap](#roadmap)
31
+ - [License](#license)
32
+
33
+ ---
34
+
35
+ ## Features
36
+
37
+ - **Zero runtime dependencies** — pure native APIs on both frontend and backend, no runtime npm packages; the built artifact is self-contained (~86KB gzipped ESM).
38
+ - **Streaming-first** — state-machine incremental parser, renders as chunks arrive, starts drawing DOM on the first character.
39
+ - **Concise DSL** — `[card tt:Title][p Content][/card]` describes a component in one line; easy for AI to generate, easy for humans to read.
40
+ - **Framework-agnostic** — usable with vanilla JS, plus official React / Vue / Svelte / Web Component adapters.
41
+ - **Pluggable components** — register with `renderer.register(type, fn)`, 30+ components out of the box (card, table, form, chart, Markdown, code highlight, etc.).
42
+ - **Safe events** — handlers are named references (`clk:` / `sub:`), must be pre-registered via `registerHandler`; no executable code injection.
43
+ - **Theme-driven** — CSS variables + `data-tokui-theme` switching, with a built-in 10-level palette generator using an HSB algorithm.
44
+ - **SSR-friendly** — `import` does not touch `window`/`document`; safe to import on the server in Next.js / Nuxt / SvelteKit (rendering happens on the client).
45
+ - **Graceful degradation** — unregistered components render as `div.tokui-unknown`; render errors produce a `details.tokui-error`; a single failure won't crash the page.
46
+ - **Resource protection** — `maxBuffer` (1MB) and `maxDepth` (100) prevent resource exhaustion from malicious or oversized input.
47
+
48
+ ---
49
+
50
+ ## Architecture
51
+
52
+ ### Three-layer Data Flow
53
+
54
+ ```
55
+ Backend TokUIBuilder emits DSL → SSE push → Frontend TokUIParser incremental parse → TokUIRenderer renders DOM
56
+ ```
57
+
58
+ ### Core Modules
59
+
60
+ | Module | Responsibility |
61
+ |--------|----------------|
62
+ | `core/parser.js` | State-machine (TEXT / TAG_OPEN / TAG_CLOSE) streaming parser; supports `feed()` incremental and `parse()` one-shot |
63
+ | `core/renderer.js` | Component rendering engine; `slotStack` for nested container slots, `VARIANTS` whitelist for variants, depth cap 50 |
64
+ | `core/event-bus.js` | Event bus singleton; `registerHandler(name, fn)` registration, `clk:`/`sub:` binding in DSL |
65
+ | `core/theme.js` | CSS-variable-driven theme manager; `data-tokui-theme` switching |
66
+ | `core/color-generator.js` | 10-level palette and theme-token generator using an HSB algorithm |
67
+ | `components/*` | Component library split by type; unified registration via `index.js` |
68
+ | `server/tokui-builder.js` | Chainable API to generate DSL; `toString()` and `toChunks()` outputs |
69
+ | `server/sse-server.js` | Node.js native `http` SSE demo server |
70
+
71
+ ---
72
+
73
+ ## Quick Start
74
+
75
+ ### Install
76
+
77
+ ```bash
78
+ # npm
79
+ npm install @jboltai/tokui
80
+
81
+ # pnpm
82
+ pnpm add @jboltai/tokui
83
+
84
+ # yarn
85
+ yarn add @jboltai/tokui
86
+ ```
87
+
88
+ ### CDN (zero-build)
89
+
90
+ ```html
91
+ <link rel="stylesheet" href="https://unpkg.com/@jboltai/tokui/dist/tokui.css">
92
+ <script src="https://unpkg.com/@jboltai/tokui/dist/tokui.umd.js"></script>
93
+ <!-- Exposed as the window.TokUI namespace -->
94
+ ```
95
+
96
+ > jsdelivr works too: replace `unpkg.com` with `cdn.jsdelivr.net/npm`.
97
+
98
+ ### Import the stylesheet (npm projects)
99
+
100
+ ```js
101
+ import '@jboltai/tokui/css'; // import once (bundled library styles)
102
+ ```
103
+
104
+ ### Three Rendering Modes
105
+
106
+ **1. One-shot render**
107
+
108
+ ```js
109
+ import { TokUI } from '@jboltai/tokui';
110
+
111
+ const tokui = new TokUI({ container: '#app' });
112
+ tokui.render('[h1 Hello TokUI][p Some text]');
113
+ ```
114
+
115
+ **2. Streaming render (`feed()` incremental input)**
116
+
117
+ ```js
118
+ const tokui = new TokUI({ container: '#app' });
119
+ tokui.startStream();
120
+ tokui.feed('[card tt:');
121
+ tokui.feed('Streaming Card]');
122
+ tokui.feed('[p Content renders as it arrives]');
123
+ tokui.feed('[/card]');
124
+ tokui.endStream(); // flush buffer
125
+ ```
126
+
127
+ **3. SSE connection (server push)**
128
+
129
+ ```js
130
+ const tokui = new TokUI({
131
+ container: '#chat',
132
+ onEvent: (type, data) => {
133
+ if (type === 'streamEnd') console.log('stream ended');
134
+ }
135
+ });
136
+ tokui.connect('/api/chat', { prompt: 'Draw a login card' });
137
+ ```
138
+
139
+ > SSE protocol convention: each `data:` line is JSON; the `tokui` field is fed to the parser; `[DONE]` marks end of stream.
140
+
141
+ ### Node.js Usage (server-side Builder)
142
+
143
+ ```js
144
+ import { TokUIBuilder } from '@jboltai/tokui/builder';
145
+
146
+ const b = new TokUIBuilder();
147
+ b.card({ tt: 'Title' }).h2('Content').p('Description').end();
148
+ console.log(b.toString()); // [card tt:Title][h2 Content][p Description][/card]
149
+ ```
150
+
151
+ > The Builder is pure logic and runs in any Node runtime (incl. Edge / Serverless); no DOM required.
152
+
153
+ ---
154
+
155
+ ## Using in Frameworks
156
+
157
+ Official adapters let you render DSL with a familiar declarative API. Each adapter peer-depends on its framework (no double-bundling) and pulls in `@jboltai/tokui` styles automatically.
158
+
159
+ | Package | For | Entry |
160
+ |---------|-----|-------|
161
+ | [`@jboltai/tokui-react`](./packages/react) | React 16.8+ | `<TokUIView dsl={...} />` + `useTokUIStream()` |
162
+ | [`@jboltai/tokui-vue`](./packages/vue) | Vue 3 | `<TokUIView :dsl="..." />` + `useTokUIStream()` |
163
+ | [`@jboltai/tokui-svelte`](./packages/svelte) | Svelte 3.46+ | `use:tokui={{ dsl }}` action + `<TokUI />` |
164
+ | [`@jboltai/tokui-webc`](./packages/webc) | Any / no framework | `<tokui-view dsl="..."></tokui-view>` custom element |
165
+
166
+ **React**
167
+
168
+ ```jsx
169
+ import { TokUIView } from '@jboltai/tokui-react';
170
+ export function App() {
171
+ return <TokUIView dsl="[card tt:Hi][p Streaming UI][/card]" theme="default" />;
172
+ }
173
+ ```
174
+
175
+ **Vue 3**
176
+
177
+ ```vue
178
+ <script setup>
179
+ import { TokUIView } from '@jboltai/tokui-vue';
180
+ const dsl = '[card tt:Hi][p Streaming UI][/card]';
181
+ </script>
182
+ <template><TokUIView :dsl="dsl" /></template>
183
+ ```
184
+
185
+ **Svelte**
186
+
187
+ ```svelte
188
+ <script>
189
+ import { tokui } from '@jboltai/tokui-svelte';
190
+ </script>
191
+ <div use:tokui={{ dsl: '[card tt:Hi][p Streaming UI][/card]' }}></div>
192
+ ```
193
+
194
+ **Web Component**
195
+
196
+ ```js
197
+ import defineTokuiElement from '@jboltai/tokui-webc';
198
+ defineTokuiElement(); // registers <tokui-view>
199
+ ```
200
+ ```html
201
+ <tokui-view dsl="[card tt:Hi][p Streaming UI][/card]"></tokui-view>
202
+ ```
203
+
204
+ See each adapter's README for streaming / SSE usage.
205
+
206
+ ---
207
+
208
+ ## DSL Syntax Cheatsheet
209
+
210
+ ```tokui
211
+ [type attr:value content] ; self-closing
212
+ [card tt:Title][p Content][/card] ; nested container
213
+ ph:"value with spaces" ; quote values containing spaces
214
+ v:"primary,sm" ; multiple variants comma-separated
215
+ stripe ; boolean attribute (key only)
216
+ ```
217
+
218
+ ### Common Attribute Shorthands
219
+
220
+ | Shorthand | Meaning | Shorthand | Meaning |
221
+ |-----------|---------|-----------|---------|
222
+ | `tt` | title | `tx` | text |
223
+ | `l` | label | `ph` | placeholder |
224
+ | `u` | url | `s` | src / source |
225
+ | `n` | name | `v` | value / variant |
226
+ | `act`| action | `mtd`| method |
227
+ | `clk`| onclick handler name | `sub`| onsubmit handler name |
228
+ | `dis`| disabled | `ro` | readonly |
229
+ | `req`| required | `chk`| checked |
230
+ | `id` | element id (also target of `upd`) | `w/h/bg/fc` | width/height/background/font-color |
231
+
232
+ ### Boolean Attributes (key only)
233
+
234
+ `stripe` `dis` `ro` `req` `chk` `multi` `auto` `plain` `round` `closable` `bordered` `open` `pill` `dot` `leaf` `inline` `rounded` `container`
235
+
236
+ The full list is defined in the `BOOLEAN_ATTRS` Set in `parser.js`.
237
+
238
+ ### Variant System
239
+
240
+ Writing `v:primary` in DSL produces the CSS class `tokui-btn--primary`. Variant names are validated against the `VARIANTS` whitelist; unknown variants are silently dropped.
241
+
242
+ ### Dynamic Updates
243
+
244
+ ```tokui
245
+ [upd id:targetId v/act/tt/tx:newValue] ; update value/action/title/text of a rendered component
246
+ ```
247
+
248
+ ### Full Reference
249
+
250
+ For the complete attribute table and container type list, see [`demo/TOKUI_DSL_REFERENCE.md`](./demo/TOKUI_DSL_REFERENCE.md).
251
+
252
+ ---
253
+
254
+ ## Component Inventory
255
+
256
+ Grouped by file, ready out of the box:
257
+
258
+ | File | Components |
259
+ |------|------------|
260
+ | `basic.js` | headings h1–h6, paragraph, link, Markdown, code block, syntax highlight, badge, button, tooltip, divider, etc. |
261
+ | `table.js` | tables (`table` / `thead` / `tbody` / `tr` / `desc`) |
262
+ | `form.js` | form, input, textarea, select, radio/checkbox, switch, date picker, tag input, etc. |
263
+ | `layout.js` | card, grid row/col, list, image gallery, description list, etc. |
264
+ | `chart.js` | pure-SVG zero-dependency charts: bar / line / pie / radar / donut / scatter / gantt / funnel |
265
+ | `lightbox.js` | image lightbox preview |
266
+
267
+ Container types (require `[/type]` closing tag; full list in the `CONTAINERS` Set of `parser.js`):
268
+
269
+ ```
270
+ form table thead tbody card ft row col list select radio code imgs md textarea
271
+ tabs tab accordion collapse dialog btngroup picker timeline steps drawer ol ul i
272
+ item think bubble toolbar badge-box dropdown transfer cascader tree tn step desc
273
+ carousel popover input-tag watermark menu
274
+ ```
275
+
276
+ ---
277
+
278
+ ## Builder API (Server-side)
279
+
280
+ `TokUIBuilder` offers a chainable API to generate DSL, with two output modes:
281
+
282
+ ```js
283
+ const b = new TokUIBuilder();
284
+
285
+ // toString() — one-shot full string output
286
+ b.card({ tt: 'Card' }).p('Content').end();
287
+ const dsl = b.toString();
288
+
289
+ // toChunks() — array of chunks, push one block at a time via SSE
290
+ const chunks = b.reset().card({ tt: 'Card' }).p('Content').end().toChunks();
291
+ ```
292
+
293
+ **Auto-close**: `toString()` / `toChunks()` internally call `_finalizeChunks()`, which auto-completes any unclosed containers — no manual `endAll()` needed.
294
+
295
+ **Dual-behavior methods**: `thead()`, `inputTag()`, `quickReply()`, `agent()` automatically switch between self-closing and container mode based on their arguments.
296
+
297
+ **Name avoidance**: layout uses `row_layout()` / `col_layout()` to avoid clashing with the table's `row()`.
298
+
299
+ ---
300
+
301
+ ## Theme System
302
+
303
+ Switch via CSS variables + `data-tokui-theme` attribute:
304
+
305
+ ```js
306
+ TokUI.setTheme('dark'); // switch to dark theme
307
+ ```
308
+
309
+ Built-in themes live in `src/styles/themes/`: `default.css`, `dark.css`.
310
+
311
+ Generate a custom theme palette with the color generator:
312
+
313
+ ```js
314
+ import { generatePalette, generateThemeTokens } from '@jboltai/tokui';
315
+ const tokens = generateThemeTokens({ primary: '#1677ff', danger: '#ff4d4f' });
316
+ // outputs { '--tokui-primary-1' ... '--tokui-primary-10' }, a 10-level CSS-variable mapping
317
+ ```
318
+
319
+ ---
320
+
321
+ ## Extending Components
322
+
323
+ Adding a new component takes four steps:
324
+
325
+ 1. **Register the render function** (`src/components/*.js`):
326
+
327
+ ```js
328
+ renderer.register('mycard', (node, rc, parentType) => {
329
+ const el = renderer.el('div', { class: 'tokui-mycard' });
330
+ el.textContent = node.attrs.tt || '';
331
+ rc(node.children, el); // recursively render children
332
+ return el;
333
+ });
334
+ ```
335
+
336
+ 2. **If it is a container type**, add it to the `CONTAINERS` Set in `src/core/parser.js`. If its content contains `[` that should not be parsed (e.g. code), also add it to the list in `_isRawContent()`.
337
+
338
+ 3. **Add a Builder method** (`src/server/tokui-builder.js`): use `_selfClosing()` for self-closing, `_open()` / `end()` for containers.
339
+
340
+ 4. **Add styles** (`src/styles/tokui.css`): class `.tokui-mycard`; variants use `.tokui-mycard--{variant}` and must be added to the `VARIANTS` whitelist in `renderer.js`.
341
+
342
+ Finally, add a test in `tests/`, and optionally a demo in the `DEMOS` array of `src/server/sse-server.js`.
343
+
344
+ ---
345
+
346
+ ## Testing
347
+
348
+ A custom runner built on Node.js's built-in `assert` module — zero test-framework dependencies:
349
+
350
+ ```bash
351
+ npm test # full suite: 24 files, 866+ cases
352
+ npm run test:parser # parser only
353
+ npm run test:builder
354
+ npm run test:core # event-bus + theme + renderer
355
+ npm run typecheck # tsc type check (with reverse @ts-expect-error assertions)
356
+ npm run coverage # c8 coverage (core modules ~91%)
357
+
358
+ node tests/test-xxx.js # run a single test file
359
+ ```
360
+
361
+ A failed assertion exits with code 1. Renderer tests depend on the minimal DOM mock in `tests/helpers/dom-mock.js`.
362
+
363
+ ---
364
+
365
+ ## Demo
366
+
367
+ Start the SSE demo server (port 3109; auto-kills and restarts the old process if the port is taken):
368
+
369
+ ```bash
370
+ npm run server
371
+ # open http://localhost:3109
372
+ ```
373
+
374
+ Demo entry:
375
+
376
+ - **`demo/index.html`** — component gallery showcasing all components, with theme switching and bilingual (zh/en) switching.
377
+
378
+ ---
379
+
380
+ ## Project Structure
381
+
382
+ ```
383
+ .
384
+ ├── src/
385
+ │ ├── core/ # parser, renderer, event bus, theme, color generator
386
+ │ ├── components/ # component library (basic/table/form/layout/chart/lightbox)
387
+ │ ├── server/ # Builder chainable API + SSE demo server
388
+ │ ├── styles/ # tokui.css + themes/ (default, dark)
389
+ │ └── index.js # main entry, integrates the TokUI class
390
+ ├── packages/ # framework adapter monorepo (pnpm workspace)
391
+ │ ├── react/ # @jboltai/tokui-react
392
+ │ ├── vue/ # @jboltai/tokui-vue
393
+ │ ├── svelte/ # @jboltai/tokui-svelte
394
+ │ ├── webc/ # @jboltai/tokui-webc (Web Component)
395
+ │ └── tokui/ # bare-name `tokui` alias package
396
+ ├── demo/ # gallery demo
397
+ ├── tests/ # custom-runner test suite (24 files / 866+ cases)
398
+ ├── docs/ # VitePress docs site
399
+ └── package.json
400
+ ```
401
+
402
+ ---
403
+
404
+ ## Roadmap
405
+
406
+ TokUI is evolving toward multi-language backend SDKs and multi-styling-library frontend themes. The tables below summarize current and planned capabilities.
407
+
408
+ > Legend: ✅ Supported · 🚧 Planned
409
+
410
+ ### Backend SDK — Multi-language Support
411
+
412
+ | Language / Runtime | Status | Notes |
413
+ |--------------------|:------:|-------|
414
+ | Node.js | ✅ | `TokUIBuilder` chainable API + SSE demo server (current implementation) |
415
+ | Python | 🚧 | Planned |
416
+ | Rust | 🚧 | Planned |
417
+ | Java | 🚧 | Planned |
418
+ | Go | 🚧 | Planned |
419
+ | C# / .NET | 🚧 | Under evaluation |
420
+ | Cross-language DSL spec lock-down | 🚧 | Shared parse contract so all SDKs produce identical output |
421
+
422
+ ### Frontend Integration
423
+
424
+ | Capability | Status | Notes |
425
+ |------------|:------:|-------|
426
+ | React / Vue / Svelte / Web Component adapters | ✅ | `@jboltai/tokui-{react,vue,svelte,webc}` |
427
+ | CSS-variable themes (`default` / `dark`) | ✅ | `data-tokui-theme` switching |
428
+ | HSB palette generator | ✅ | Generate a 10-level scale from any seed color |
429
+ | Variant system (`VARIANTS` whitelist) | ✅ | `v:primary` → `tokui-{type}--primary` |
430
+ | TailwindCSS adapter | 🚧 | Atomic-class mapping / theme-token bridge |
431
+ | UnoCSS adapter | 🚧 | Planned |
432
+ | Theme marketplace / sharing | 🚧 | Community-shareable theme packages |
433
+
434
+ ---
435
+
436
+ ## License
437
+
438
+ [MIT](./LICENSE)