bitwrench 2.0.32 → 2.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.
Files changed (126) hide show
  1. package/README.md +210 -125
  2. package/dist/bitwrench-bccl.cjs.js +349 -188
  3. package/dist/bitwrench-bccl.cjs.min.js +2 -39
  4. package/dist/bitwrench-bccl.cjs.min.js.gz +0 -0
  5. package/dist/bitwrench-bccl.esm.js +349 -188
  6. package/dist/bitwrench-bccl.esm.min.js +2 -39
  7. package/dist/bitwrench-bccl.esm.min.js.gz +0 -0
  8. package/dist/bitwrench-bccl.umd.js +349 -188
  9. package/dist/bitwrench-bccl.umd.min.js +2 -39
  10. package/dist/bitwrench-bccl.umd.min.js.gz +0 -0
  11. package/dist/bitwrench-code-edit.cjs.js +17 -6
  12. package/dist/bitwrench-code-edit.cjs.min.js +2 -20
  13. package/dist/bitwrench-code-edit.es5.js +8 -3
  14. package/dist/bitwrench-code-edit.es5.min.js +2 -19
  15. package/dist/bitwrench-code-edit.esm.js +17 -6
  16. package/dist/bitwrench-code-edit.esm.min.js +2 -19
  17. package/dist/bitwrench-code-edit.umd.js +17 -6
  18. package/dist/bitwrench-code-edit.umd.min.js +2 -19
  19. package/dist/bitwrench-code-edit.umd.min.js.gz +0 -0
  20. package/dist/bitwrench-debug.js +1 -1
  21. package/dist/bitwrench-debug.min.js +1 -1
  22. package/dist/bitwrench-lean.cjs.js +2492 -1628
  23. package/dist/bitwrench-lean.cjs.min.js +2 -80
  24. package/dist/bitwrench-lean.cjs.min.js.gz +0 -0
  25. package/dist/bitwrench-lean.es5.js +2740 -1838
  26. package/dist/bitwrench-lean.es5.min.js +2 -49
  27. package/dist/bitwrench-lean.es5.min.js.gz +0 -0
  28. package/dist/bitwrench-lean.esm.js +2492 -1628
  29. package/dist/bitwrench-lean.esm.min.js +2 -80
  30. package/dist/bitwrench-lean.esm.min.js.gz +0 -0
  31. package/dist/bitwrench-lean.umd.js +2492 -1628
  32. package/dist/bitwrench-lean.umd.min.js +2 -80
  33. package/dist/bitwrench-lean.umd.min.js.gz +0 -0
  34. package/dist/bitwrench-util-color.cjs.js +251 -0
  35. package/dist/bitwrench-util-color.cjs.min.js +3 -0
  36. package/dist/bitwrench-util-color.es5.js +256 -0
  37. package/dist/bitwrench-util-color.es5.min.js +3 -0
  38. package/dist/bitwrench-util-color.esm.js +241 -0
  39. package/dist/bitwrench-util-color.esm.min.js +3 -0
  40. package/dist/bitwrench-util-color.umd.js +257 -0
  41. package/dist/bitwrench-util-color.umd.min.js +3 -0
  42. package/dist/bitwrench-util-css.cjs.js +2 -1
  43. package/dist/bitwrench-util-css.cjs.min.js +2 -21
  44. package/dist/bitwrench-util-css.es5.js +2 -1
  45. package/dist/bitwrench-util-css.es5.min.js +2 -20
  46. package/dist/bitwrench-util-css.esm.js +2 -1
  47. package/dist/bitwrench-util-css.esm.min.js +1 -19
  48. package/dist/bitwrench-util-css.umd.js +2 -1
  49. package/dist/bitwrench-util-css.umd.min.js +2 -20
  50. package/dist/bitwrench-util-css.umd.min.js.gz +0 -0
  51. package/dist/bitwrench.cjs.js +2826 -1801
  52. package/dist/bitwrench.cjs.min.js +2 -99
  53. package/dist/bitwrench.cjs.min.js.gz +0 -0
  54. package/dist/bitwrench.css +403 -479
  55. package/dist/bitwrench.d.ts +70 -73
  56. package/dist/bitwrench.es5.js +3106 -2020
  57. package/dist/bitwrench.es5.min.js +2 -67
  58. package/dist/bitwrench.es5.min.js.gz +0 -0
  59. package/dist/bitwrench.esm.js +2826 -1801
  60. package/dist/bitwrench.esm.min.js +2 -99
  61. package/dist/bitwrench.esm.min.js.gz +0 -0
  62. package/dist/bitwrench.min.css +1 -1
  63. package/dist/bitwrench.umd.js +2826 -1801
  64. package/dist/bitwrench.umd.min.js +2 -99
  65. package/dist/bitwrench.umd.min.js.gz +0 -0
  66. package/dist/builds.json +222 -134
  67. package/dist/bwserve.cjs.js +289 -282
  68. package/dist/bwserve.d.ts +157 -0
  69. package/dist/bwserve.esm.js +290 -283
  70. package/dist/sri.json +54 -46
  71. package/docs/README.md +6 -3
  72. package/docs/app-patterns.md +7 -6
  73. package/docs/bitwrench-for-wasm.md +53 -54
  74. package/docs/bitwrench-mcp.md +2 -2
  75. package/docs/bitwrench-northstar-principles.md +406 -0
  76. package/docs/bitwrench-taco-schema-discussion.md +2 -2
  77. package/docs/bitwrench_api.md +191 -106
  78. package/docs/bitwrench_typescript_usage.md +5 -5
  79. package/docs/bw-attach.md +29 -75
  80. package/docs/bwserve.md +200 -168
  81. package/docs/cli.md +36 -12
  82. package/docs/component-cheatsheet.md +2 -2
  83. package/docs/component-library.md +4 -4
  84. package/docs/component-lifecycle.md +234 -0
  85. package/docs/drift-lint.md +268 -0
  86. package/docs/framework-translation-table.md +4 -4
  87. package/docs/llm-bitwrench-guide.md +60 -50
  88. package/docs/routing.md +11 -13
  89. package/docs/state-management.md +110 -109
  90. package/docs/taco-format.md +13 -14
  91. package/docs/theming.md +13 -3
  92. package/docs/thinking-in-bitwrench.md +858 -983
  93. package/docs/tutorial-bwserve.md +37 -36
  94. package/docs/tutorial-embedded.md +10 -21
  95. package/docs/tutorial-website.md +2 -2
  96. package/package.json +38 -7
  97. package/readme.html +262 -160
  98. package/src/bitwrench-bccl-entry.js +2 -2
  99. package/src/bitwrench-bccl.js +346 -185
  100. package/src/bitwrench-code-edit.js +16 -5
  101. package/src/bitwrench-color-utils.js +117 -181
  102. package/src/bitwrench-file-ops.js +2 -2
  103. package/src/bitwrench-lean.js +4 -3
  104. package/src/bitwrench-router.js +5 -2
  105. package/src/bitwrench-styles.js +420 -504
  106. package/src/bitwrench-util-color.js +240 -0
  107. package/src/bitwrench-util-css.js +1 -0
  108. package/src/bitwrench-utils.js +4 -0
  109. package/src/bitwrench.d.ts +70 -73
  110. package/src/bitwrench.h +5 -0
  111. package/src/bitwrench.js +1939 -933
  112. package/src/bwserve/attach.js +0 -1
  113. package/src/bwserve/bwclient.js +172 -32
  114. package/src/bwserve/bwshell.js +0 -4
  115. package/src/bwserve/client.js +59 -220
  116. package/src/bwserve/index.js +59 -26
  117. package/src/bwserve.d.ts +157 -0
  118. package/src/bwserve.h +5 -0
  119. package/src/cli/attach.js +12 -75
  120. package/src/cli/convert.js +2 -2
  121. package/src/cli/serve.js +37 -35
  122. package/src/generate-css.js +1 -1
  123. package/src/mcp/knowledge.js +4 -4
  124. package/src/mcp/live.js +21 -13
  125. package/src/mcp/tools.js +0 -1
  126. package/src/version.js +3 -7
@@ -4,28 +4,28 @@
4
4
 
5
5
  | Field | Value |
6
6
  |-------|-------|
7
- | Version | 2.0.31 |
8
- | Generated | 2026-04-12 |
9
- | Total APIs | 105 |
7
+ | Version | 2.1.0 |
8
+ | Generated | 2026-07-15 |
9
+ | Total APIs | 112 |
10
10
  | Categories | 14 |
11
- | bitwrench.js | 4100 lines |
12
- | bitwrench-bccl.js | 3793 lines |
11
+ | bitwrench.js | 5106 lines |
12
+ | bitwrench-bccl.js | 3954 lines |
13
13
 
14
14
  ## Table of Contents
15
15
 
16
- - [Core](#core) (5)
17
- - [DOM Generation](#dom-generation) (10)
16
+ - [Core](#core) (3)
17
+ - [DOM Generation](#dom-generation) (17)
18
18
  - [DOM Selection](#dom-selection) (1)
19
19
  - [Identifiers](#identifiers) (4)
20
20
  - [State Management](#state-management) (3)
21
21
  - [Events (DOM)](#events-dom-) (2)
22
- - [Pub/Sub](#pub-sub) (4)
23
- - [CSS & Styling](#css-styling) (10)
22
+ - [Pub/Sub](#pub-sub) (5)
23
+ - [CSS & Styling](#css-styling) (12)
24
24
  - [Component Builders](#component-builders) (50)
25
25
  - [Browser Utilities](#browser-utilities) (4)
26
26
  - [Utilities](#utilities) (1)
27
27
  - [Function Registry](#function-registry) (5)
28
- - [Component](#component) (5)
28
+ - [Component](#component) (4)
29
29
  - [Data Utilities](#data-utilities) (1)
30
30
 
31
31
  ---
@@ -59,24 +59,6 @@ Parse a bwserve protocol message string, supporting both strict JSON and r-prefi
59
59
 
60
60
  ---
61
61
 
62
- ### `bw.apply(msg)`
63
-
64
- Apply a bwserve protocol message to the DOM. Dispatches one of 9 message types: replace — bw.DOM(target, node) append — target.appendChild(bw.createDOM(node)) remove — bw.cleanup(target); target.remove() patch — bw.patch(target, content, attr) batch — iterate ops, call bw.apply for each message — bw.message(target, action, data) register — store a named function for later call() call — invoke a registered function exec — execute arbitrary JS (requires allowExec) Target resolution: Starts with '#' or '.' → CSS selector (querySelector) Otherwise → getElementById, then bw._el fallback
65
-
66
- **Parameters:**
67
-
68
- | Name | Type | Description |
69
- |------|------|-------------|
70
- | `msg` | `Object` | - Protocol message |
71
-
72
- **Returns:** `boolean` — if the message was applied successfully
73
-
74
- ---
75
-
76
- ### `bw.colorInterp(x, in0, in1, colors, stretch)`
77
-
78
- ---
79
-
80
62
  ### `bw.makeDataTable(config)`
81
63
 
82
64
  Create a ready-to-use data table with title and responsive wrapper. Convenience wrapper around `bw.makeTable()` that adds a title heading, responsive horizontal scroll container, and defaults to striped + hover. Use this for the common case; use `bw.makeTable()` when you need a bare table element with no wrapper.
@@ -107,7 +89,7 @@ const table = bw.makeDataTable({ title: "Users", data: [{ name: "Alice", role: "
107
89
 
108
90
  ### `bw.raw(str)`
109
91
 
110
- Mark a string as raw HTML so it will not be escaped by bw.html() or bw.createDOM(). By default, bitwrench escapes all text content to prevent XSS. Use bw.raw() when you need to embed pre-sanitized HTML, entities, or inline markup.
92
+ Mark a string as raw HTML so it will not be escaped by bw.html() or bw.create(). By default, bitwrench escapes all text content to prevent XSS. Use bw.raw() when you need to embed pre-sanitized HTML, entities, or inline markup.
111
93
 
112
94
  **Parameters:**
113
95
 
@@ -115,7 +97,7 @@ Mark a string as raw HTML so it will not be escaped by bw.html() or bw.createDOM
115
97
  |------|------|-------------|
116
98
  | `str` | `string` | - HTML string to mark as raw |
117
99
 
118
- **Returns:** `Object` — object recognized by bw.html() and bw.createDOM()
100
+ **Returns:** `Object` — object recognized by bw.html() and bw.create()
119
101
 
120
102
  **Example:**
121
103
  ```javascript
@@ -173,9 +155,9 @@ bw.htmlPage({ title: 'My App', body: { t: 'h1', c: 'Hello World' }, runtime: 'sh
173
155
 
174
156
  ---
175
157
 
176
- ### `bw.createDOM(taco, options = {})`
158
+ ### `bw.create(taco, options)`
177
159
 
178
- Create a live DOM element from a TACO object (browser only). Unlike `bw.html()` which returns a string, this creates real DOM elements with event handlers, lifecycle hooks (mounted/unmount), and state. Used internally by `bw.DOM()`. Throws in Node.js use `bw.html()` instead.
160
+ Create a hydrated, detached DOM element from a TACO object (browser only). v2.1 Phase verb: the element is fully wired (state, handles, slots, events, unmount closure) but NOT registered and mounted() is NOT fired. Registration happens in mountTree(); mounted fires there too.
179
161
 
180
162
  **Parameters:**
181
163
 
@@ -184,114 +166,192 @@ Create a live DOM element from a TACO object (browser only). Unlike `bw.html()`
184
166
  | `taco` | `Object` | - TACO object with {t, a, c, o} |
185
167
  | `options` | `Object` | - Creation options |
186
168
 
187
- **Returns:** `Element|Text` — element or text node
169
+ **Returns:** `Element|Text|DocumentFragment` — element, text node, or fragment
188
170
 
189
- **Example:**
190
- ```javascript
191
- var el = bw.createDOM({ t: 'button', a: { class: 'bw_btn', onclick: () => alert('clicked') }, c: 'Click Me' }); document.body.appendChild(el);
192
- ```
171
+ ---
172
+
173
+ ### `bw.hydrate(el, taco)`
174
+
175
+ Wire lifecycle from taco.o onto an existing DOM node. Idempotent. Used for Path S adoption: html() output → mountTree → hydrate adds behavior.
176
+
177
+ **Parameters:**
178
+
179
+ | Name | Type | Description |
180
+ |------|------|-------------|
181
+ | `el` | `Element` | - Existing DOM element |
182
+ | `taco` | `Object` | - TACO object whose o.* to wire |
193
183
 
194
184
  ---
195
185
 
196
- ### `bw.DOM(target, taco, options = {})`
186
+ ### `bw.mountTree(el)`
197
187
 
198
- Mount a TACO object into a DOM element, replacing its contents (browser only). This is the primary way to render bitwrench UI to the page. It cleans up any existing children (calling unmount hooks), then renders the TACO into the target. The target element itself is preserved — only its children change.
188
+ Walk a subtree, register every addressable node, fire mounted() hooks. Idempotent: already-registered nodes (same element) are skipped silently. Mounted fires synchronously, parent before children.
199
189
 
200
190
  **Parameters:**
201
191
 
202
192
  | Name | Type | Description |
203
193
  |------|------|-------------|
204
- | `target` | `string|Element` | - CSS selector or DOM element to mount into |
205
- | `taco` | `Object` | - TACO object to render |
206
- | `options` | `Object` | - Mount options |
194
+ | `el` | `Element` | - Root of subtree to mount |
195
+
196
+ ---
207
197
 
208
- **Returns:** `Element` — element
198
+ ### `bw.unmount(el)`
209
199
 
210
- **Example:**
211
- ```javascript
212
- bw.DOM('#app', { t: 'div', a: { class: 'card' }, c: [ { t: 'h2', c: 'Hello' }, { t: 'p', c: 'Built with bitwrench.' } ] });
213
- ```
200
+ Unmount an element and its entire subtree. Fire unmount hooks self-first, then descendants in document order. Strip ALL bitwrench properties. Deregister from _nodeMap.
201
+
202
+ **Parameters:**
203
+
204
+ | Name | Type | Description |
205
+ |------|------|-------------|
206
+ | `el` | `Element` | - Element to unmount |
214
207
 
215
208
  ---
216
209
 
217
- ### `bw.mount(target, taco, options)`
210
+ ### `bw.unmountChildren(el)`
218
211
 
219
- Mount a TACO into a target element and return the created root element. Like bw.DOM() but returns the root element of the TACO (not the container), giving direct access to el.bw handle methods.
212
+ Unmount descendants only; the element's own state/subs/registration are untouched.
220
213
 
221
214
  **Parameters:**
222
215
 
223
216
  | Name | Type | Description |
224
217
  |------|------|-------------|
225
- | `target` | `string|Element` | - CSS selector or DOM element |
226
- | `taco` | `Object` | - TACO to render |
227
- | `options` | `Object` | - Mount options |
218
+ | `el` | `Element` | - Parent element whose children to unmount |
228
219
 
229
- **Returns:** `Element` — created root element
220
+ ---
230
221
 
231
- **Example:**
232
- ```javascript
233
- var el = bw.mount('#app', bw.makeCarousel({ items: slides })); el.bw.goToSlide(2); el.bw.next();
234
- ```
222
+ ### `bw.remove(ref)`
223
+
224
+ Remove an element from the DOM and clean it up. Convenience compound: unmount(el) + el.remove().
225
+
226
+ **Parameters:**
227
+
228
+ | Name | Type | Description |
229
+ |------|------|-------------|
230
+ | `ref` | `string|Element` | - Element reference |
235
231
 
236
232
  ---
237
233
 
238
- ### `bw.cleanup(element)`
234
+ ### `bw.detach(el)`
239
235
 
240
- Clean up a DOM element and all its children by calling unmount callbacks, removing pub/sub subscriptions, and clearing state/render references. Called automatically by `bw.DOM()` before re-rendering. Call manually when removing elements to prevent memory leaks from orphaned callbacks.
236
+ Detach an element from the DOM but keep it registered (keep-alive). The element stays addressable and its subscriptions keep delivering. Janitor will not reap detach-exempt elements.
241
237
 
242
238
  **Parameters:**
243
239
 
244
240
  | Name | Type | Description |
245
241
  |------|------|-------------|
246
- | `element` | `Element` | - DOM element to clean up |
242
+ | `el` | `Element` | - Element to detach |
247
243
 
248
- **Example:**
249
- ```javascript
250
- var el = document.querySelector('#my-widget'); bw.cleanup(el); // runs unmount hooks, clears _bw_state, _bw_render el.remove(); // safe to remove from DOM now
251
- ```
244
+ ---
245
+
246
+ ### `bw.mount(target, taco, options)`
247
+
248
+ Mount a TACO into a target element. Returns the root element (single root), first node (array), or null. This is the primary compound verb for putting UI on the page. Composes atomics: unmountChildren(target) → clear → create(content) → insert → mountTree(target).
249
+
250
+ **Parameters:**
251
+
252
+ | Name | Type | Description |
253
+ |------|------|-------------|
254
+ | `target` | `string|Element` | - CSS selector or DOM element to mount into |
255
+ | `taco` | `Object|Array` | - TACO object or array to render |
256
+ | `options` | `Object` | - Creation options |
257
+
258
+ **Returns:** `Element|null` — root element, or null
252
259
 
253
260
  ---
254
261
 
255
- ### `bw.render(element, position, taco)`
262
+ ### `bw.append(target, content, opts)`
256
263
 
257
- Render a TACO object into the DOM at a specific position, returning a component handle. The handle provides full lifecycle control: state management, re-rendering, class manipulation, show/hide, event binding, and destroy. Components are tracked in a registry for later retrieval via `bw.getComponent()`.
264
+ Append content to a target. create insert (respecting opts.before) mountTree. Returns the new child element.
258
265
 
259
266
  **Parameters:**
260
267
 
261
268
  | Name | Type | Description |
262
269
  |------|------|-------------|
263
- | `element` | `Element|string` | - Target element or CSS selector |
264
- | `position` | `string` | - Position: 'replace', 'prepend', 'append', 'before', 'after' |
265
- | `taco` | `Object` | - TACO object to render |
270
+ | `target` | `string|Element` | - Container |
271
+ | `content` | `Object` | - TACO to append |
272
+ | `opts` | `Object` | - {before: Element|number} for positioning |
266
273
 
267
- **Returns:** `Object` — handle with element, setState, update, destroy, etc.
274
+ **Returns:** `Element|null` — appended element
268
275
 
269
- **Example:**
270
- ```javascript
271
- var handle = bw.render('#app', 'append', { t: 'button', a: { class: 'bw_btn' }, c: 'Click Me', o: { state: { clicks: 0 } } }); handle.setState({ clicks: 1 }); handle.destroy();
272
- ```
276
+ ---
277
+
278
+ ### `bw.replace(ref, taco)`
279
+
280
+ Replace an existing element with new content. unmount(old) → create(taco) → insert at position → mountTree. Returns new element. null taco = remove.
281
+
282
+ **Parameters:**
283
+
284
+ | Name | Type | Description |
285
+ |------|------|-------------|
286
+ | `ref` | `Element` | - Element to replace |
287
+ | `taco` | `Object|null` | - Replacement TACO, or null to just remove |
288
+
289
+ **Returns:** `Element|null` — new element, or null
290
+
291
+ ---
292
+
293
+ ### `bw.refresh(ref)`
294
+
295
+ Refresh a component: unmountChildren → re-render → mountTree. Render throw propagates. Emits bw:refresh.
296
+
297
+ **Parameters:**
298
+
299
+ | Name | Type | Description |
300
+ |------|------|-------------|
301
+ | `ref` | `string|Element` | - Component to refresh |
302
+
303
+ **Returns:** `Element|null` — element
273
304
 
274
305
  ---
275
306
 
276
- ### `bw.getComponent(id)`
307
+ ### `bw.updateSlot(ref, name, value)`
277
308
 
278
- Get a component handle by its ID from the component registry.
309
+ Update a specific slot on a component by reference.
279
310
 
280
311
  **Parameters:**
281
312
 
282
313
  | Name | Type | Description |
283
314
  |------|------|-------------|
284
- | `id` | `string` | - Component ID (from bw.render) |
315
+ | `ref` | `string|Element` | - Component reference |
316
+ | `name` | `string` | - Slot name |
317
+ | `value` | `*` | - Value to set |
318
+
319
+ **Returns:** `boolean` — if slot was updated
320
+
321
+ ---
322
+
323
+ ### `bw.syncChildren(parentEl, items, opts)`
285
324
 
286
- **Returns:** `Object|null` handle or null if not found
325
+ Keyed reconciliation: match existing children by `el._bw_key`, move/add/remove to match `items` order. Moved nodes are the SAME DOM nodes (state/focus survives).
326
+
327
+ **Parameters:**
328
+
329
+ | Name | Type | Description |
330
+ |------|------|-------------|
331
+ | `parentEl` | `Element` | - Container element |
332
+ | `items` | `Array` | - Data array for desired children |
333
+ | `opts` | `Object` | - {key: fn(item)→string, create: fn(item)→TACO, update: fn(el, item)} |
287
334
 
288
335
  ---
289
336
 
290
- ### `bw.getAllComponents()`
337
+ ### `bw.render(target, position, taco)`
338
+
339
+ Render a TACO into the DOM at a specific position relative to a target. Thin convenience factory over `bw.append()` / `bw.replace()`. Every code path goes through the v2.1 lifecycle pipeline (create → insert → mountTree), so mounted/unmount hooks, state, handles, and the janitor all work automatically.
340
+
341
+ **Parameters:**
342
+
343
+ | Name | Type | Description |
344
+ |------|------|-------------|
345
+ | `target` | `Element|string` | - Target element or CSS selector |
346
+ | `position` | `string` | - 'append', 'prepend', 'replace', 'before', 'after' |
347
+ | `taco` | `Object` | - TACO object to render |
291
348
 
292
- Get all registered component handles as a Map.
349
+ **Returns:** `{ el: Element|null, ok: boolean, error: string|null }`
293
350
 
294
- **Returns:** `Map` — of componentId → component handle
351
+ **Example:**
352
+ ```javascript
353
+ var r = bw.render('#app', 'append', { t: 'button', a: { class: 'bw_btn' }, c: 'Click Me', o: { state: { clicks: 0 } } }); if (r.ok) r.el.bw.myMethod(); // use component handle
354
+ ```
295
355
 
296
356
  ---
297
357
 
@@ -299,7 +359,7 @@ Get all registered component handles as a Map.
299
359
 
300
360
  ### `bw.el(target, apply)`
301
361
 
302
- Look up a single DOM element by ID, CSS selector, UUID, or element ref. Optionally apply content or a function to the resolved element. Resolution order for string targets: 1. Check `bw._nodeMap[id]` cache (O(1), stale entries auto-pruned) 2. `document.getElementById(id)` 3. `document.querySelector(id)` for selectors starting with # or . 4. Class-based lookup for `bw_uuid_*` tokens With one argument, returns the element (or null). With two arguments, applies the second argument to the element and returns the element: - string/number: sets `el.textContent` - function: calls `apply(el)`, returns el - TACO object: clears children, mounts TACO via `bw.createDOM()` - array: clears children, appends each item (string -> text node, TACO -> element)
362
+ Look up a single DOM element by ID, CSS selector, UUID, or element ref. Optionally apply content or a function to the resolved element. Resolution order for string targets: 1. Check `bw._nodeMap[id]` cache (O(1), stale entries auto-pruned) 2. `document.getElementById(id)` 3. `document.querySelector(id)` for selectors starting with # or . 4. Class-based lookup for `bw_uuid_*` tokens With one argument, returns the element (or null). With two arguments, applies the second argument to the element and returns the element: - string/number: sets `el.textContent` - function: calls `apply(el)`, returns el - TACO object: clears children, mounts TACO via `bw.create()` - array: clears children, appends each item (string -> text node, TACO -> element)
303
363
 
304
364
  **Parameters:**
305
365
 
@@ -398,28 +458,24 @@ bw.escapeHTML('<b>Hello</b> & "world"') // => '&lt;b&gt;Hello&lt;&#x2F;b&gt; &am
398
458
 
399
459
  ## State Management
400
460
 
401
- ### `bw.update(target)`
461
+ ### `bw.update(ref, data)`
402
462
 
403
- Trigger re-render of a component by calling its stored `o.render` function. This is the recommended way to update a component after changing its state. Calls `el._bw_render(el, state)` and emits `bw:statechange` so other components can react without tight coupling.
463
+ Update a component by dispatching to el.bw.update(data) if defined. Emits bw:statechange. If no update handle, emits specific diag warning. NEVER falls back to refresh.
404
464
 
405
465
  **Parameters:**
406
466
 
407
467
  | Name | Type | Description |
408
468
  |------|------|-------------|
409
- | `target` | `string|Element` | - Element ID, bw_uuid_* class, CSS selector, or DOM element |
469
+ | `ref` | `string|Element` | - Component to update |
470
+ | `data` | `*` | - Data to pass to el.bw.update |
410
471
 
411
- **Returns:** `Element|null` — element, or null if not found / no render function
412
-
413
- **Example:**
414
- ```javascript
415
- // Given a counter element with o.render el._bw_state.count++; bw.update(el); // re-renders, emits bw:statechange
416
- ```
472
+ **Returns:** `Element|null` — element
417
473
 
418
474
  ---
419
475
 
420
476
  ### `bw.patch(id, content, attr)`
421
477
 
422
- Targeted DOM update by element ID — change one element's content or attribute without rebuilding the entire component tree. Use `bw.patch()` for lightweight value updates (scores, labels, counters) and `bw.update()` for full structural re-renders.
478
+ Targeted DOM update by element ID — change one element's content or attribute without rebuilding the entire component tree. Use `bw.patch()` for lightweight value updates (scores, labels, counters) and `bw.refresh()` for full structural re-renders.
423
479
 
424
480
  **Parameters:**
425
481
 
@@ -523,7 +579,7 @@ bw.pub('score:updated', { player: 'X', score: 10 }); // Wildcard subscribers mat
523
579
 
524
580
  ### `bw.sub(topic, handler, el)`
525
581
 
526
- Subscribe to a topic. Returns an unsub() function. Supports wildcard patterns: a topic ending in `*` matches any published topic that starts with the prefix before the `*`. For example, `'agui:*'` matches `'agui:ready'`, `'agui:error'`, etc. The handler receives `(detail, topic)` so it can distinguish which topic fired. Optional third argument ties the subscription to a DOM element's lifecycle -- when `bw.cleanup()` is called on that element, the subscription is automatically removed, preventing memory leaks.
582
+ Subscribe to a topic. Returns an unsub() function. Supports wildcard patterns: a topic ending in `*` matches any published topic that starts with the prefix before the `*`. For example, `'agui:*'` matches `'agui:ready'`, `'agui:error'`, etc. The handler receives `(detail, topic)` so it can distinguish which topic fired. Optional third argument ties the subscription to a DOM element's lifecycle -- when `bw.unmount()` is called on that element, the subscription is automatically removed, preventing memory leaks.
527
583
 
528
584
  **Parameters:**
529
585
 
@@ -578,6 +634,23 @@ bw.once('data:loaded', function(detail) { console.log('Received:', detail); // N
578
634
 
579
635
  ---
580
636
 
637
+ ### `bw.derive(inputs, fn, outTopic, opts)`
638
+
639
+ Declared dataflow: recompute fn(inputs...) on any input publish. Returns a disposer function. Optionally ties to an element lifecycle.
640
+
641
+ **Parameters:**
642
+
643
+ | Name | Type | Description |
644
+ |------|------|-------------|
645
+ | `inputs` | `Array<string>` | - Topic names to subscribe to |
646
+ | `fn` | `Function` | - Combiner: fn(...latestValues) → result |
647
+ | `outTopic` | `string` | - Topic to publish result on |
648
+ | `opts` | `Object` | - {seed: [], immediate: bool, el: Element} |
649
+
650
+ **Returns:** `Function`
651
+
652
+ ---
653
+
581
654
  ## CSS & Styling
582
655
 
583
656
  ### `bw.css(rules, options = {})`
@@ -726,6 +799,14 @@ bw.loadStyles(); // defaults, global bw
726
799
 
727
800
  ---
728
801
 
802
+ ### `bw.loadStructural()`
803
+
804
+ Inject structural (theme-independent) CSS only. Idempotent.
805
+
806
+ **Returns:** `Element|null` — `<style>` element, or null in Node.js
807
+
808
+ ---
809
+
729
810
  ### `bw.loadReset()`
730
811
 
731
812
  Inject the CSS reset (box-sizing, html/body font, reduced-motion). Idempotent — if already injected, returns the existing `<style>` element.
@@ -739,9 +820,24 @@ bw.loadReset(); // inject once, safe to call multiple times
739
820
 
740
821
  ---
741
822
 
823
+ ### `bw.setThemeMode(mode, scope)`
824
+
825
+ Set the theme mode on all matching elements.
826
+
827
+ **Parameters:**
828
+
829
+ | Name | Type | Description |
830
+ |------|------|-------------|
831
+ | `mode` | `string` | - 'primary' or 'alternate' |
832
+ | `scope` | `string` | - Selector. Omit for global (<html>). |
833
+
834
+ **Returns:** `Object` — mode, count } — the mode set and number of elements affected
835
+
836
+ ---
837
+
742
838
  ### `bw.toggleThemeMode(scope)`
743
839
 
744
- Toggle between primary and alternate theme palettes. Adds/removes the `bw_theme_alt` class on the scoping element(s). Without a scope, toggles on `<html>` (global). With a scope, toggles on ALL matching elements.
840
+ Toggle between primary and alternate theme palettes. Determines current mode from first matched element, then sets inverse on all.
745
841
 
746
842
  **Parameters:**
747
843
 
@@ -751,11 +847,6 @@ Toggle between primary and alternate theme palettes. Adds/removes the `bw_theme_
751
847
 
752
848
  **Returns:** `string` — mode after toggle: 'primary' or 'alternate' (based on first element)
753
849
 
754
- **Example:**
755
- ```javascript
756
- bw.toggleThemeMode(); // global toggle on <html> bw.toggleThemeMode('#my-dashboard'); // scoped toggle bw.toggleThemeMode('.panel'); // toggle on ALL .panel elements
757
- ```
758
-
759
850
  ---
760
851
 
761
852
  ### `bw.clearStyles(scope)`
@@ -1427,7 +1518,7 @@ Create a hero section for landing pages and headers Supports gradient background
1427
1518
 
1428
1519
  **Example:**
1429
1520
  ```javascript
1430
- const hero = makeHero({ title: "Welcome to Bitwrench", subtitle: "Build UIs with pure JavaScript", variant: "dark", actions: [ makeButton({ text: "Get Started", variant: "primary", size: "lg" }), makeButton({ text: "Learn More", variant: "outline-light", size: "lg" }) ] });
1521
+ const hero = makeHero({ title: "Welcome to Bitwrench", subtitle: "Build UIs with pure JavaScript", variant: "dark", actions: [ makeButton({ text: "Get Started", variant: "primary", size: "lg" }), makeButton({ text: "Learn More", variant: "outline_light", size: "lg" }) ] });
1431
1522
  ```
1432
1523
 
1433
1524
  ---
@@ -2230,12 +2321,6 @@ Get a shallow copy of the function registry for inspection.
2230
2321
 
2231
2322
  ## Component
2232
2323
 
2233
- ### `bw.flush()`
2234
-
2235
- No-op flush (ComponentHandle removed in v2.0.19). Kept as no-op for backward compatibility.
2236
-
2237
- ---
2238
-
2239
2324
  ### `bw.message(target, action, data)`
2240
2325
 
2241
2326
  Dispatch a message to a component by UUID, CSS class, or selector. Finds the element, looks up el.bw, and calls the named method. This is the bitwrench equivalent of Win32 SendMessage(hwnd, msg, wParam, lParam).
@@ -153,11 +153,11 @@ const counter: Taco = {
153
153
  handle: {
154
154
  increment: (el: HTMLElement) => {
155
155
  el._bw_state.count++;
156
- bw.update(el);
156
+ bw.refresh(el);
157
157
  },
158
158
  reset: (el: HTMLElement) => {
159
159
  el._bw_state.count = 0;
160
- bw.update(el);
160
+ bw.refresh(el);
161
161
  }
162
162
  },
163
163
  slots: {
@@ -248,8 +248,8 @@ const primaryBase: string = p.primary.base; // '#2563eb'
248
248
  const primaryHover: string = p.primary.hover; // derived shade
249
249
  const bg: string = p.background; // plain string (NOT an object)
250
250
 
251
- // Toggle dark/light
252
- bw.toggleStyles();
251
+ // Toggle between primary and alternate palettes (one-class toggle):
252
+ const mode: string = bw.toggleThemeMode(); // 'primary' | 'alternate'
253
253
 
254
254
  // Shorthand: generate + apply in one call
255
255
  bw.loadStyles({ primary: '#dc2626' });
@@ -419,7 +419,7 @@ dynamic and don't have specific types:
419
419
  - **`el.bw.*` methods** -- populated at runtime from `o.handle`/`o.slots`.
420
420
  Cast `el.bw` to a custom interface for your components.
421
421
  - **`bw.apply()` wire protocol messages** -- typed as `Record<string, any>`.
422
- The bwserve protocol is documented in `dev/bw-client-server.md`.
422
+ The bwserve protocol is documented in [docs/bwserve.md](bwserve.md).
423
423
  - **Less common `make*()` configs** -- typed as `ComponentConfig` (open
424
424
  object). The most-used components (Card, Button, Tabs, Accordion, Modal,
425
425
  Alert, Nav, Input, Carousel, Table) have specific config types.