bitwrench 2.0.17 → 2.0.19

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 (72) hide show
  1. package/README.md +169 -75
  2. package/dist/bitwrench-bccl.cjs.js +228 -55
  3. package/dist/bitwrench-bccl.cjs.min.js +3 -3
  4. package/dist/bitwrench-bccl.esm.js +228 -55
  5. package/dist/bitwrench-bccl.esm.min.js +3 -3
  6. package/dist/bitwrench-bccl.umd.js +228 -55
  7. package/dist/bitwrench-bccl.umd.min.js +3 -3
  8. package/dist/bitwrench-code-edit.cjs.js +7 -9
  9. package/dist/bitwrench-code-edit.cjs.min.js +5 -7
  10. package/dist/bitwrench-code-edit.es5.js +6 -8
  11. package/dist/bitwrench-code-edit.es5.min.js +5 -7
  12. package/dist/bitwrench-code-edit.esm.js +7 -9
  13. package/dist/bitwrench-code-edit.esm.min.js +5 -7
  14. package/dist/bitwrench-code-edit.umd.js +7 -9
  15. package/dist/bitwrench-code-edit.umd.min.js +5 -7
  16. package/dist/bitwrench-debug.js +268 -0
  17. package/dist/bitwrench-debug.min.js +3 -0
  18. package/dist/bitwrench-lean.cjs.js +1190 -2348
  19. package/dist/bitwrench-lean.cjs.min.js +20 -20
  20. package/dist/bitwrench-lean.es5.js +1285 -2551
  21. package/dist/bitwrench-lean.es5.min.js +18 -18
  22. package/dist/bitwrench-lean.esm.js +1190 -2348
  23. package/dist/bitwrench-lean.esm.min.js +20 -20
  24. package/dist/bitwrench-lean.umd.js +1190 -2348
  25. package/dist/bitwrench-lean.umd.min.js +20 -20
  26. package/dist/bitwrench-util-css.cjs.js +236 -0
  27. package/dist/bitwrench-util-css.cjs.min.js +22 -0
  28. package/dist/bitwrench-util-css.es5.js +414 -0
  29. package/dist/bitwrench-util-css.es5.min.js +21 -0
  30. package/dist/bitwrench-util-css.esm.js +230 -0
  31. package/dist/bitwrench-util-css.esm.min.js +21 -0
  32. package/dist/bitwrench-util-css.umd.js +242 -0
  33. package/dist/bitwrench-util-css.umd.min.js +21 -0
  34. package/dist/bitwrench.cjs.js +1404 -2388
  35. package/dist/bitwrench.cjs.min.js +21 -21
  36. package/dist/bitwrench.css +503 -132
  37. package/dist/bitwrench.es5.js +1588 -2659
  38. package/dist/bitwrench.es5.min.js +19 -19
  39. package/dist/bitwrench.esm.js +1405 -2389
  40. package/dist/bitwrench.esm.min.js +21 -21
  41. package/dist/bitwrench.min.css +1 -1
  42. package/dist/bitwrench.umd.js +1404 -2388
  43. package/dist/bitwrench.umd.min.js +21 -21
  44. package/dist/builds.json +214 -104
  45. package/dist/bwserve.cjs.js +514 -68
  46. package/dist/bwserve.esm.js +513 -69
  47. package/dist/sri.json +46 -36
  48. package/package.json +6 -3
  49. package/readme.html +183 -85
  50. package/src/bitwrench-bccl-entry.js +3 -4
  51. package/src/bitwrench-bccl.js +224 -50
  52. package/src/bitwrench-code-edit.js +6 -8
  53. package/src/bitwrench-color-utils.js +31 -9
  54. package/src/bitwrench-debug.js +245 -0
  55. package/src/bitwrench-esm-entry.js +11 -0
  56. package/src/bitwrench-styles.js +474 -240
  57. package/src/bitwrench-util-css.js +229 -0
  58. package/src/bitwrench.js +689 -2042
  59. package/src/bwserve/attach.js +57 -0
  60. package/src/bwserve/bwclient.js +141 -0
  61. package/src/bwserve/bwshell.js +102 -0
  62. package/src/bwserve/client.js +151 -1
  63. package/src/bwserve/index.js +127 -28
  64. package/src/cli/attach.js +587 -0
  65. package/src/cli/convert.js +2 -5
  66. package/src/cli/index.js +7 -0
  67. package/src/cli/inject.js +1 -1
  68. package/src/cli/serve.js +185 -5
  69. package/src/generate-css.js +11 -4
  70. package/src/vendor/html2canvas.min.js +20 -0
  71. package/src/version.js +3 -3
  72. package/src/bwserve/shell.js +0 -106
package/README.md CHANGED
@@ -3,30 +3,64 @@
3
3
  [![License](https://img.shields.io/badge/License-BSD%202--Clause-blue.svg)](https://opensource.org/licenses/BSD-2-Clause)
4
4
  [![NPM version](https://img.shields.io/npm/v/bitwrench.svg?style=flat-square)](https://www.npmjs.com/package/bitwrench)
5
5
  [![CI](https://github.com/deftio/bitwrench/actions/workflows/ci.yml/badge.svg)](https://github.com/deftio/bitwrench/actions/workflows/ci.yml)
6
+ [![Coverage](https://img.shields.io/badge/coverage-96.3%25-brightgreen.svg)](https://github.com/deftio/bitwrench)
6
7
 
7
8
  [![bitwrench](./images/bitwrench-logo-med.png)](https://deftio.github.io/bitwrench/pages/)
8
9
 
9
- Bitwrench is a UI library in a single script that provides HTML generation, reactive state, CSS and theme generation, 30+ components, and a static site CLI — all from plain JavaScript objects, with zero dependencies and zero compile steps. Works in browsers (including IE11) and Node.js.
10
-
11
- ## Quick Example
10
+ Bitwrench builds UI from plain JavaScript objects -- one format for components, styling, state, and server rendering, with no build step and zero dependencies.
12
11
 
13
12
  ```javascript
14
- const card = {
15
- t: 'div', a: { class: 'bw-card' },
13
+ // Describe UI as a JavaScript object (a "TACO")
14
+ var page = {
15
+ t: 'div', a: { class: 'card' },
16
16
  c: [
17
- { t: 'h3', c: 'Hello bitwrench' },
18
- { t: 'p', c: 'UI as native JavaScript objects.' }
17
+ { t: 'h2', c: 'Hello' },
18
+ { t: 'p', c: 'UI as native JavaScript objects.' },
19
+ bw.makeButton({ text: 'Click me', variant: 'primary', onclick: fn })
19
20
  ]
20
21
  };
21
22
 
22
- // Mount to the DOM
23
- bw.DOM('#app', card);
24
-
25
- // Or render to an HTML string (Node.js, emails, static pages)
26
- const html = bw.html(card);
23
+ bw.DOM('#app', page); // -> live DOM
24
+ bw.html(page); // -> HTML string (Node.js, emails, SSR)
27
25
  ```
28
26
 
29
- Each object has four keys: **t** (tag), **a** (attributes), **c** (content), and optionally **o** (options for state and lifecycle). Nest them, loop them, compose them it's just JavaScript.
27
+ Each object has four keys: **t** (tag), **a** (attributes), **c** (content), **o** (options for state/lifecycle). Nest them, loop them, compose them -- it's just JavaScript.
28
+
29
+ ![Hero example output](./images/hero-example.png)
30
+
31
+ ### Why bitwrench?
32
+
33
+ **One file, everywhere.** At ~38KB gzipped with zero dependencies, bitwrench runs on anything with a browser -- phones, tablets, Raspberry Pi, even ESP32 microcontrollers. The device serves a single HTML page and pushes data as JSON; bitwrench handles all rendering, styling, and state on the client. No Node.js, no build step, no internet connection required.
34
+
35
+ Structure, styling, state, and server rendering are all handled as JavaScript objects:
36
+
37
+ - **No build toolchain** -- works with a `<script>` tag
38
+ - **50+ ready-made components** -- buttons, tables, modals, forms, charts, toasts -- one `make*()` call each, returns a composable TACO
39
+ - **CSS from JavaScript** -- `bw.css()` generates stylesheets, `bw.s()` composes inline styles, `bw.loadStyles()` derives a complete design system from 2 seed colors
40
+ - **Reactive state** -- `o.state` + `o.render` + `bw.update()` for stateful components; `bw.pub()`/`bw.sub()` for cross-component messaging
41
+ - **Dual rendering** -- same object renders to live DOM (`bw.DOM()`) or HTML string (`bw.html()`) for SSR, emails, or static sites
42
+ - **Server-driven UI** -- push UI updates from any backend (Python, C, Rust, Go) over SSE; `client.screenshot()` captures the page back as PNG/JPEG
43
+ - **CLI** -- `bwcli` converts Markdown, HTML, and JSON to styled standalone pages
44
+ - **Utilities** -- color interpolation, random data, lorem ipsum, cookies, URL params, file I/O
45
+
46
+
47
+
48
+ ### Coming from other Frameworks
49
+
50
+ Bitwrench uses JavaScript equivalents for most forms of front-end development. Here is a quick mapping (see the [docs](docs/README.md) and [Thinking in Bitwrench](docs/thinking-in-bitwrench.md) for more details).
51
+
52
+ | You're using | For | Bitwrench equivalent |
53
+ |---|---|---|
54
+ | React / Vue / Svelte | Components + reactivity | `{t, a, c, o}` objects + `o.state` + `o.render` |
55
+ | JSX / templates | Markup-in-JS | Native JS objects -- no compiler |
56
+ | Tailwind / CSS-in-JS | Styling | `bw.css()`, `bw.s()` style composition |
57
+ | Sass / PostCSS | CSS generation | `bw.css()` from JS objects (supports @media, @keyframes) |
58
+ | ThemeProvider / CSS vars | Theming | `bw.loadStyles()` / `bw.makeStyles()` from 2 seed colors |
59
+ | Streamlit / Gradio | Server-driven UI | bwserve SSE -- from any language (Python, Go, C, Rust) |
60
+ | Redux / Zustand / Pinia | State management | `o.state` + `bw.update()` + `bw.pub()/sub()` |
61
+ | Vite / webpack / Babel | Build tooling | Not needed -- open the HTML file |
62
+
63
+ See the [Framework Translation Table](docs/framework-translation-table.md) for side-by-side code comparisons across 22 operations.
30
64
 
31
65
  ## Installation
32
66
 
@@ -48,16 +82,6 @@ Or include directly in a page:
48
82
  <script src="https://cdn.jsdelivr.net/npm/bitwrench/dist/bitwrench.umd.min.js"></script>
49
83
  ```
50
84
 
51
- ## Features
52
-
53
- - **HTML from plain objects** — describe UI as JavaScript objects, render to live DOM with `bw.DOM()` or to HTML strings with `bw.html()` for server-side rendering, emails, and static pages
54
- - **Built-in reactivity** — `bw.update()` re-renders components when state changes, `bw.patch()` updates individual elements by ID, `bw.pub()`/`bw.sub()` provides decoupled messaging between any part of the application
55
- - **CSS and theme generation** — `bw.css()` generates stylesheets from objects, `bw.generateTheme()` derives a complete visual theme (buttons, alerts, badges, cards, forms, tables, dark mode) from 2-3 seed colors
56
- - **45+ ready-made components** — cards, buttons, sortable tables, form inputs, modals, dropdowns, accordions, tooltips, popovers, toasts, timelines, steppers, file uploads, stat cards — each a single function call that returns a composable object
57
- - **Server-driven UI (bwserve)** — push TACO rendering commands from Node.js to the browser over SSE; same protocol works from C (ESP32), Python, Rust, or any language via the `bwcli serve` pipe server
58
- - **Static site CLI** — the `bwcli` command converts Markdown, HTML, and JSON files into styled, self-contained pages with theme support
59
- - **Utilities** — color interpolation, random data generation, lorem ipsum, cookies, URL params, file I/O for both browser and Node.js
60
-
61
85
  ## Getting Started
62
86
 
63
87
  ```html
@@ -69,7 +93,7 @@ Or include directly in a page:
69
93
  <body>
70
94
  <div id="app"></div>
71
95
  <script>
72
- bw.loadDefaultStyles();
96
+ bw.loadStyles();
73
97
 
74
98
  bw.DOM('#app', {
75
99
  t: 'div', a: { class: 'bw-container' },
@@ -79,7 +103,11 @@ Or include directly in a page:
79
103
  title: 'Welcome',
80
104
  content: 'Built with plain JavaScript objects.'
81
105
  }),
82
- bw.makeButton({ text: 'Click me', variant: 'primary' })
106
+ bw.makeButton({
107
+ text: 'Click me',
108
+ variant: 'primary',
109
+ onclick: function() { alert('Hello!'); }
110
+ })
83
111
  ]
84
112
  });
85
113
  </script>
@@ -89,30 +117,34 @@ Or include directly in a page:
89
117
 
90
118
  ## Adding State
91
119
 
92
- Wrap any TACO in `bw.component()` to get a reactive component with `.get()`, `.set()`, and template bindings:
120
+ Add `o.state` and `o.render` to any TACO to make it stateful. The render function is called with the DOM element, and state lives on `el._bw_state`. Call `bw.update(el)` to re-render:
93
121
 
94
122
  ```javascript
95
- var counter = bw.component({
96
- t: 'div', c: [
97
- { t: 'span', c: 'Count: ${count}' },
98
- { t: 'button', c: '+1', a: {
99
- onclick: function() { counter.set('count', counter.get('count') + 1); }
100
- }}
101
- ],
123
+ var counter = {
124
+ t: 'div',
102
125
  o: {
103
126
  state: { count: 0 },
104
- methods: {
105
- reset: function(comp) { comp.set('count', 0); }
127
+ render: function(el) {
128
+ var s = el._bw_state;
129
+ bw.DOM(el, {
130
+ t: 'div', c: [
131
+ { t: 'h3', c: 'Count: ' + s.count },
132
+ bw.makeButton({ text: '+1', onclick: function() {
133
+ s.count++;
134
+ bw.update(el);
135
+ }})
136
+ ]
137
+ });
106
138
  }
107
139
  }
108
- });
140
+ };
109
141
 
110
142
  bw.DOM('#app', counter);
111
- counter.set('count', 42); // DOM updates automatically
112
- counter.reset(); // methods from o.methods are callable on the handle
113
143
  ```
114
144
 
115
- For low-level control, you can also use `o.render` + `bw.update()` directly see the [State Management guide](docs/state-management.md).
145
+ > **Important: event handlers go in `a: { onclick: fn }`, not in `o.mounted`.** Handlers attached via `addEventListener` in `o.mounted` are silently lost when a component re-renders. Always use `onclick`/`onchange`/etc. inside `a:` -- bitwrench re-attaches them on every render automatically.
146
+
147
+ See the [State Management guide](docs/state-management.md) for the full three-level component model.
116
148
 
117
149
  For communication between components, use pub/sub:
118
150
 
@@ -124,38 +156,64 @@ bw.sub('item-added', function(detail) {
124
156
  bw.pub('item-added', { name: 'Widget' });
125
157
  ```
126
158
 
159
+
160
+ ## CSS from JavaScript
161
+
162
+ `bw.css()` generates CSS from objects. `bw.s()` composes inline styles from reusable utility objects:
163
+
164
+ ```javascript
165
+ // Generate and inject a stylesheet
166
+ bw.injectCSS(bw.css({
167
+ '.my-card': { padding: '1rem', borderRadius: '8px' }
168
+ }));
169
+
170
+ // Compose inline styles from objects
171
+ { t: 'div', a: { style: bw.s({ display: 'flex' }, { gap: '1rem' }, { padding: '1rem' }) } }
172
+
173
+ // Responsive breakpoints
174
+ bw.responsive('.hero', {
175
+ base: { fontSize: '1.5rem' },
176
+ md: { fontSize: '2.5rem' }
177
+ });
178
+ ```
179
+
127
180
  ## Theming
128
181
 
129
- Generate a complete theme from two seed colors. All components — buttons, alerts, badges, cards, forms, tables are styled automatically:
182
+ `bw.loadStyles()` derives a complete design system -- buttons, alerts, badges, cards, forms, tables, hover states, focus rings -- from two seed colors. Styles can be scoped to DOM subtrees, so different sections of a page can use different themes. `bw.toggleStyles()` switches between primary and alternate palettes:
130
183
 
131
184
  ```javascript
132
- bw.generateTheme('my-theme', {
185
+ bw.loadStyles({
133
186
  primary: '#336699',
134
187
  secondary: '#cc6633'
135
188
  });
136
189
 
137
- bw.toggleTheme(); // switch between primary and alternate palettes
190
+ bw.toggleStyles(); // switch between primary and alternate palettes
138
191
  ```
139
192
 
193
+
140
194
  ## Core API
141
195
 
142
196
  | Function | Description |
143
197
  |---|---|
144
- | `bw.html(obj)` | Convert an object to an HTML string |
145
- | `bw.DOM(selector, obj)` | Mount an object to a DOM element |
146
- | `bw.component(taco)` | Wrap a TACO in a ComponentHandle with `.get()/.set()` reactive API |
198
+ | `bw.html(obj)` | Convert a TACO to an HTML string |
199
+ | `bw.DOM(selector, obj)` | Mount a TACO to a DOM element |
200
+ | `bw.mount(selector, obj)` | Like `bw.DOM()` but returns the root element for `el.bw` access |
201
+ | `bw.raw(str)` | Mark a string as pre-escaped HTML (no double-escaping) |
147
202
  | `bw.css(rules)` | Generate CSS from a JS object |
148
- | `bw.loadDefaultStyles()` | Inject the built-in stylesheet |
149
- | `bw.generateTheme(name, config)` | Generate a scoped theme from seed colors |
150
- | `bw.patch(id, content)` | Update a specific element by UUID |
203
+ | `bw.s(...objs)` | Compose inline style objects into a style string |
204
+ | `bw.responsive(sel, breakpoints)` | Generate `@media` CSS rules from JS |
205
+ | `bw.loadStyles(config?)` | Load structural CSS (no args) or generate + apply a theme from seed colors |
206
+ | `bw.makeStyles(config)` | Generate a theme from seed colors (returns styles object) |
207
+ | `bw.applyStyles(styles)` | Inject a generated styles object's CSS into the document |
208
+ | `bw.toggleStyles()` | Switch between primary and alternate palettes |
209
+ | `bw.clearStyles()` | Remove injected theme styles |
210
+ | `bw.patch(id, content)` | Update a specific element by id or UUID |
151
211
  | `bw.update(el)` | Re-render via the element's `o.render` function |
152
- | `bw.message(target, action, data)` | Send a message to a component by tag name |
212
+ | `bw.message(target, action, data)` | Dispatch a method call to a component's `el.bw` handle |
153
213
  | `bw.pub(topic, detail)` | Publish a message to subscribers |
154
214
  | `bw.sub(topic, handler)` | Subscribe to a topic; returns an unsub function |
155
- | `bw.inspect(target)` | Debug a component in the browser console |
156
- | `bw.clientConnect(url, opts)` | Connect to a bwserve SSE endpoint |
157
- | `bw.clientApply(msg)` | Apply a bwserve protocol message to the DOM |
158
- | `bw.clientParse(str)` | Parse strict or r-prefix relaxed JSON |
215
+ | `bw.inspect(target)` | Debug a component's state, handles, and metadata in the console |
216
+ | `bw.apply(msg)` | Apply a bwserve protocol message to the DOM |
159
217
 
160
218
  See the full [API Reference](https://deftio.github.io/bitwrench/pages/08-api-reference.html) for all functions.
161
219
 
@@ -178,7 +236,7 @@ Flags: `--output/-o`, `--standalone/-s`, `--cdn`, `--theme/-t`, `--css/-c`, `--t
178
236
 
179
237
  ### Pipe Server
180
238
 
181
- `bwcli serve` turns any language into a bwserve backend send JSON protocol messages via HTTP POST or stdin, and connected browsers update in real time:
239
+ `bwcli serve` turns any language into a bwserve backend -- send JSON protocol messages via HTTP POST or stdin, and connected browsers update in real time:
182
240
 
183
241
  ```bash
184
242
  bwcli serve --port 8080 --input-port 9000
@@ -198,39 +256,75 @@ All formats include source maps. A separate CSS file (`bitwrench.css`) is also a
198
256
 
199
257
  ## Documentation
200
258
 
201
- **Guides** (in `docs/`):
259
+ **Start here:**
260
+
261
+ - **[Thinking in Bitwrench](docs/thinking-in-bitwrench.md)** -- the complete guide. Covers TACO, styling (`bw.css`, `bw.s`, `bw.responsive`), composition, events, the three-level component model, bwserve, and common patterns
262
+ - **[LLM Guide](docs/llm-bitwrench-guide.md)** -- compact single-file reference with all APIs, patterns, and rules. Designed for AI-assisted development but works as a cheat sheet for anyone
263
+
264
+ **Reference guides** (in `docs/`):
202
265
 
203
- - [TACO Format](docs/taco-format.md) the `{t, a, c, o}` object format
204
- - [State Management](docs/state-management.md) three-level component model, ComponentHandle, reactive state
205
- - [Component Library](docs/component-library.md) all 50+ `make*()` functions with signatures and examples
206
- - [Theming](docs/theming.md) palette-driven theme generation, presets, design tokens
207
- - [CLI](docs/cli.md) the `bwcli` command for file conversion and pipe server
208
- - [bwserve](docs/bwserve.md) server-driven UI protocol (SSE, actions, embedded devices)
209
- - [LLM Guide](docs/llm-bitwrench-guide.md) — compact single-file reference for AI-assisted development
266
+ - [TACO Format](docs/taco-format.md) -- the `{t, a, c, o}` object format
267
+ - [State Management](docs/state-management.md) -- three-level component model, stateful TACO, reactive state
268
+ - [Component Library](docs/component-library.md) -- all 50+ `make*()` functions with signatures and examples
269
+ - [Theming](docs/theming.md) -- palette-driven theme generation, presets, design tokens
270
+ - [CLI](docs/cli.md) -- the `bwcli` command for file conversion and pipe server
271
+ - [bwserve](docs/bwserve.md) -- server-driven UI protocol (SSE, actions, embedded devices)
210
272
 
211
273
  **Tutorials:**
212
274
 
213
- - [Build a Website](docs/tutorial-website.md) multi-section landing page from TACO objects
214
- - [bwserve Dashboard](docs/tutorial-bwserve.md) Streamlit-style server-push dashboard
215
- - [ESP32 IoT Dashboard](docs/tutorial-embedded.md) embedded sensor dashboard with C macros
275
+ - [Build a Website](docs/tutorial-website.md) -- multi-section landing page from TACO objects
276
+ - [bwserve Dashboard](docs/tutorial-bwserve.md) -- Streamlit-style server-push dashboard
277
+ - [ESP32 IoT Dashboard](docs/tutorial-embedded.md) -- embedded sensor dashboard with C macros
216
278
 
217
279
  **Interactive demos** (live site):
218
280
 
219
- - [Quick Start](https://deftio.github.io/bitwrench/pages/00-quick-start.html) first steps with `bw.DOM()`
220
- - [Components](https://deftio.github.io/bitwrench/pages/01-components.html) buttons, cards, alerts, badges, navbars
221
- - [Styling & Theming](https://deftio.github.io/bitwrench/pages/03-styling.html) CSS generation and theming strategies
222
- - [State & Interactivity](https://deftio.github.io/bitwrench/pages/05-state.html) state patterns and ComponentHandle
223
- - [Tic Tac Toe Tutorial](https://deftio.github.io/bitwrench/pages/06-tic-tac-toe-tutorial.html) step-by-step game with state management
224
- - [Framework Comparison](https://deftio.github.io/bitwrench/pages/07-framework-comparison.html) bitwrench vs React, Vue, Svelte
225
- - [Themes](https://deftio.github.io/bitwrench/pages/10-themes.html) interactive theme generator with presets and CSS export
281
+ - [Quick Start](https://deftio.github.io/bitwrench/pages/00-quick-start.html) -- first steps with `bw.DOM()`
282
+ - [Components](https://deftio.github.io/bitwrench/pages/01-components.html) -- all 50+ UI components with live demos
283
+ - [Styling & Theming](https://deftio.github.io/bitwrench/pages/03-styling.html) -- CSS generation, `bw.s()`, and theming strategies
284
+ - [State & Interactivity](https://deftio.github.io/bitwrench/pages/05-state.html) -- state patterns and stateful TACO
285
+ - [Tic Tac Toe Tutorial](https://deftio.github.io/bitwrench/pages/06-tic-tac-toe-tutorial.html) -- step-by-step game with state management
286
+ - [Framework Comparison](https://deftio.github.io/bitwrench/pages/07-framework-comparison.html) -- bitwrench vs React, Vue, Svelte
287
+ - [Themes](https://deftio.github.io/bitwrench/pages/10-themes.html) -- interactive theme generator with presets and CSS export
288
+
289
+ **Example apps** (in `examples/`):
290
+
291
+ - [Ember & Oak Coffee Co.](examples/ember-and-oak/) -- full landing page: theme, cart, search, charts, accordion, timeline
292
+ - [SunForge Landing Page](examples/landing-page/) -- polished marketing page with zero reactive state, pure BCCL composition
293
+ - [Todo App](examples/todo-app/) -- stateful TACO with pub/sub
294
+ - [Metrics Dashboard](examples/dashboard/) -- live stat cards, bar chart, pub/sub, responsive layout
295
+ - [Signup Wizard](examples/wizard/) -- multi-step form, state transitions, bw.raw()
296
+ - [Live Feed](examples/live-feed/) -- real-time stream, bw.patch(), slide-in animation
297
+ - [IoT Dashboard](examples/embedded/) -- ESP32-style sensor dashboard with SSE
298
+ - [bwserve Counter](examples/client-server/) -- server-driven UI demo
299
+ - [LLM Chat](examples/llm-chat/) -- streaming chat via bwserve + Ollama/OpenAI
300
+
301
+ ## FAQ
302
+
303
+ **Is this a framework?** -- No. Bitwrench is a library (~38KB gzipped). No lifecycle to learn, no project structure to follow. Import it, call functions, done.
304
+
305
+ **Does it scale to large apps?** -- Bitwrench targets single-page tools, dashboards, prototypes, embedded UIs, and content sites -- apps where a single HTML file or a handful of files is the right form factor. For a 500-route SPA with team-scale state management, React or Vue is a better fit.
306
+
307
+ **How does bitwrench compare to React/Vue?** -- They solve different problems at different scales. React and Vue provide a component model, virtual DOM, and ecosystem for large team-built SPAs. Bitwrench provides rendering and state primitives in a single file with no build step, aimed at single-page tools, dashboards, embedded devices, and server-driven UIs. They coexist fine -- use whichever fits the job.
308
+
309
+ **How does CSS work?** -- Bitwrench doesn't own your CSS. Use any external stylesheet, Tailwind, or CSS file you want -- bitwrench doesn't interfere. On top of that, `bw.css()` generates CSS from JS objects (with `@media`, `@keyframes`, pseudo-classes), `bw.s()` composes inline style objects, and `bw.loadStyles()` derives a complete design system from 2 seed colors. You can use all three together or none at all.
310
+
311
+ **What's the difference between `bw.DOM()` and `bw.html()`?** -- Same TACO input, two outputs. `bw.DOM('#app', taco)` mounts live DOM elements in a browser. `bw.html(taco)` returns an HTML string -- use it in Node.js scripts, email generators, static site builds, or anywhere you need markup without a browser. One object format, two rendering modes.
312
+
313
+ **What is bwserve?** -- bwserve lets any server push UI updates to a browser over SSE. The server sends TACO objects as JSON; the browser renders them. It's language-agnostic -- the server can be Python, Go, Rust, C, or a shell script. Anything that can write JSON to an HTTP response can drive a bitwrench UI. See the [bwserve docs](docs/bwserve.md).
314
+
315
+ **Can I use bitwrench on embedded devices?** -- Yes -- this is a primary use case. An ESP32 or Raspberry Pi serves one HTML page with bitwrench loaded, then pushes sensor data as JSON patches over SSE. The device never generates HTML. See the [ESP32 tutorial](docs/tutorial-embedded.md).
316
+
317
+ **Can I use it with TypeScript?** -- Yes. Type declarations are included. TACO objects are plain JSON-compatible objects that TypeScript infers naturally.
318
+
319
+ **What about accessibility?** -- BCCL components emit semantic HTML with ARIA attributes where applicable. You can add any `aria-*` attribute via `a: { 'aria-label': '...' }`.
226
320
 
227
321
  ## Development
228
322
 
229
323
  ```bash
230
324
  npm install # install dev dependencies
231
325
  npm run build # build all dist formats (UMD, ESM, CJS, ES5)
232
- npm test # run unit tests (1000+ tests)
233
- npm run test:cli # run CLI tests (49 tests)
326
+ npm test # run unit tests (1400+ tests, 96% coverage)
327
+ npm run test:cli # run CLI tests
234
328
  npm run test:e2e # run Playwright browser tests
235
329
  npm run lint # run ESLint
236
330
  npm run cleanbuild # full production build with SRI hashes
@@ -238,4 +332,4 @@ npm run cleanbuild # full production build with SRI hashes
238
332
 
239
333
  ## License
240
334
 
241
- [BSD-2-Clause](./LICENSE.txt) (c) M. A. Chatterjee / [deftio](https://github.com/deftio)
335
+ [BSD-2-Clause](./LICENSE.txt) -- (c) M. A. Chatterjee / [deftio](https://github.com/deftio)