zero-query 1.2.3 → 1.2.5

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/dist/API.md CHANGED
@@ -25,7 +25,7 @@ Complete API documentation for every module, method, option, and type in zQuery.
25
25
  - [Navigation Guards](#navigation-guards)
26
26
  - [Change Listener](#change-listener)
27
27
  - [Current Route State](#current-route-state)
28
- - [matchRoute()](#matchroute)
28
+ - [matchRoute()](#match-route)
29
29
  - [Dynamic Route Management](#dynamic-route-management)
30
30
  - [Hash Fragments](#hash-fragments)
31
31
  - [Sub-Route History Substates](#sub-route-history-substates)
@@ -39,28 +39,28 @@ Complete API documentation for every module, method, option, and type in zQuery.
39
39
  - [Computed Properties](#computed-properties)
40
40
  - [Watchers](#watchers)
41
41
  - [Templates](#templates)
42
- - [Events & Forms](#events-forms)
42
+ - [Events & Forms](#events)
43
43
  - [Lifecycle](#lifecycle)
44
44
  - [Props & Communication](#props-communication)
45
- - [Reactive Props Schema](#reactive-props-schema)
45
+ - [Reactive Props Schema](#reactive-props)
46
46
  - [Store Connectors](#store-connectors)
47
47
  - [Scoped Styles](#scoped-styles)
48
48
  - [DOM Morphing](#dom-morphing)
49
49
  - [Transitions](#transitions)
50
50
  - [Mounting & Instance API](#mounting-instance-api)
51
- - [Quick Reference](#quick-reference)
51
+ - [Quick Reference](#component-quick-reference)
52
52
  - [Directives](#directives)
53
- - [Quick Reference](#quick-reference)
54
- - [z-if / z-else-if / z-else](#z-if-z-else-if-z-else)
53
+ - [Quick Reference](#directive-quick-reference)
54
+ - [z-if / z-else-if / z-else](#z-if-z-else)
55
55
  - [z-for](#z-for)
56
56
  - [z-key](#z-key)
57
57
  - [z-show](#z-show)
58
- - [z-bind / :attr](#z-bind-attr)
58
+ - [z-bind / :attr](#z-bind)
59
59
  - [z-class](#z-class)
60
60
  - [z-style](#z-style)
61
61
  - [z-html & z-text](#z-html-z-text)
62
- - [Event Binding (@event)](#event-binding-event)
63
- - [z-model](#z-model)
62
+ - [Event Binding (@event)](#event-binding)
63
+ - [z-model](#z-model-directive)
64
64
  - [z-ref](#z-ref)
65
65
  - [z-cloak](#z-cloak)
66
66
  - [z-pre](#z-pre)
@@ -70,7 +70,7 @@ Complete API documentation for every module, method, option, and type in zQuery.
70
70
  - [External Templates](#external-templates)
71
71
  - [Processing Order](#processing-order)
72
72
  - [Store](#store)
73
- - [Setup](#setup)
73
+ - [Setup](#store-setup)
74
74
  - [Dispatching Actions](#dispatching-actions)
75
75
  - [Reading State & Getters](#reading-state-getters)
76
76
  - [Subscriptions](#subscriptions)
@@ -81,35 +81,35 @@ Complete API documentation for every module, method, option, and type in zQuery.
81
81
  - [Batch Updates](#batch-updates)
82
82
  - [Checkpoint / Undo / Redo](#checkpoint-undo-redo)
83
83
  - [State Utilities](#state-utilities)
84
- - [Error Resilience](#error-resilience)
85
- - [Using Store in Components](#using-store-in-components)
86
- - [connectStore()](#connectstore)
87
- - [Quick Reference](#quick-reference)
88
- - [HTTP Client](#http-client)
84
+ - [Error Resilience](#store-error-resilience)
85
+ - [Using Store in Components](#store-in-components)
86
+ - [connectStore()](#connect-store)
87
+ - [Quick Reference](#store-quick-reference)
88
+ - [HTTP Client](#http)
89
89
  - [Request Methods](#request-methods)
90
- - [Configuration](#configuration)
90
+ - [Configuration](#http-configuration)
91
91
  - [Response Object](#response-object)
92
92
  - [Auto-Parsing](#auto-parsing)
93
93
  - [Interceptors](#interceptors)
94
94
  - [Abort / Cancel](#abort-cancel)
95
- - [FormData & String Bodies](#formdata-string-bodies)
96
- - [Error Handling](#error-handling)
95
+ - [FormData & String Bodies](#formdata)
96
+ - [Error Handling](#http-error-handling)
97
97
  - [Per-Request Options](#per-request-options)
98
98
  - [Parallel Requests](#parallel-requests)
99
- - [Raw Fetch Passthrough](#raw-fetch-passthrough)
99
+ - [Raw Fetch Passthrough](#raw-fetch)
100
100
  - [Reactive](#reactive)
101
- - [$.reactive()](#reactive)
102
- - [$.Signal](#signal)
103
- - [$.signal()](#signal)
104
- - [$.computed()](#computed)
105
- - [$.effect()](#effect)
101
+ - [$.reactive()](#reactive-proxy)
102
+ - [$.Signal](#signal-class)
103
+ - [$.signal()](#signals)
104
+ - [$.computed()](#computed-signals)
105
+ - [$.effect()](#effects)
106
106
  - [$.batch()](#batch)
107
107
  - [$.untracked()](#untracked)
108
- - [Summary](#summary)
109
- - [How Auto-Tracking Works](#how-auto-tracking-works)
110
- - [Error Resilience](#error-resilience)
111
- - [Quick Reference](#quick-reference)
112
- - [Selectors & Collections](#selectors-collections)
108
+ - [Summary](#reactive-summary)
109
+ - [How Auto-Tracking Works](#how-tracking-works)
110
+ - [Error Resilience](#reactive-error-resilience)
111
+ - [Quick Reference](#reactive-quick-reference)
112
+ - [Selectors & Collections](#selectors)
113
113
  - [$() Main Selector](#main-selector)
114
114
  - [Raw-Element Shortcuts](#raw-element-shortcuts)
115
115
  - [Multi-Element Shortcuts](#multi-element-shortcuts)
@@ -117,9 +117,9 @@ Complete API documentation for every module, method, option, and type in zQuery.
117
117
  - [Element Creation](#element-creation)
118
118
  - [Animations](#animations)
119
119
  - [Form Helpers](#form-helpers)
120
- - [DOM Ready & Plugins](#dom-ready-plugins)
120
+ - [DOM Ready & Plugins](#plugins)
121
121
  - [Native DOM Equivalents](#native-dom-equivalents)
122
- - [Utilities](#utilities)
122
+ - [Utilities](#utils)
123
123
  - [Function Utilities](#function-utilities)
124
124
  - [String Utilities](#string-utilities)
125
125
  - [Object Utilities](#object-utilities)
@@ -139,53 +139,53 @@ Complete API documentation for every module, method, option, and type in zQuery.
139
139
  - [Dismissing & Auto-Clear](#dismissing-auto-clear)
140
140
  - [Programmatic Error Handling](#programmatic-error-handling)
141
141
  - [Error Utilities](#error-utilities)
142
- - [formatError()](#formaterror)
143
- - [guardAsync()](#guardasync)
142
+ - [formatError()](#format-error)
143
+ - [guardAsync()](#guard-async)
144
144
  - [All Error Codes](#all-error-codes)
145
- - [Server-Side Rendering (SSR)](#server-side-rendering-ssr)
146
- - [Overview](#overview)
145
+ - [Server-Side Rendering (SSR)](#ssr)
146
+ - [Overview](#ssr-overview)
147
147
  - [SSR Scaffold](#ssr-scaffold)
148
- - [createSSRApp()](#createssrapp)
149
- - [Registering Components](#registering-components)
150
- - [renderToString()](#rendertostring)
151
- - [renderPage()](#renderpage)
152
- - [renderBatch()](#renderbatch)
153
- - [renderShell()](#rendershell)
154
- - [Hydration](#hydration)
155
- - [Error Handling in SSR](#error-handling-in-ssr)
156
- - [escapeHtml()](#escapehtml)
157
- - [matchRoute()](#matchroute)
148
+ - [createSSRApp()](#create-ssr-app)
149
+ - [Registering Components](#register-components)
150
+ - [renderToString()](#render-to-string)
151
+ - [renderPage()](#render-page)
152
+ - [renderBatch()](#render-batch)
153
+ - [renderShell()](#render-shell)
154
+ - [Hydration](#ssr-hydration)
155
+ - [Error Handling in SSR](#ssr-error-handling)
156
+ - [escapeHtml()](#ssr-escape-html)
157
+ - [matchRoute()](#ssr-match-route)
158
158
  - [Security](#security)
159
- - [Overview](#overview)
160
- - [Template Expression Escaping](#template-expression-escaping)
159
+ - [Overview](#security-overview)
160
+ - [Template Expression Escaping](#template-escaping)
161
161
  - [z-html & Trusted HTML](#z-html-trusted-html)
162
162
  - [Expression Sandbox](#expression-sandbox)
163
- - [Prototype Pollution Prevention](#prototype-pollution-prevention)
163
+ - [Prototype Pollution Prevention](#prototype-pollution)
164
164
  - [Route Link Validation](#route-link-validation)
165
165
  - [SSR Error Sanitization](#ssr-error-sanitization)
166
- - [Best Practices](#best-practices)
167
- - [Quick Reference](#quick-reference)
168
- - [Environment Detection](#environment-detection)
166
+ - [Best Practices](#security-best-practices)
167
+ - [Quick Reference](#security-quick-reference)
168
+ - [Environment Detection](#environment)
169
169
  - [Environment Properties](#environment-properties)
170
170
  - [Platform Detection](#platform-detection)
171
- - [Quick Reference](#quick-reference)
171
+ - [Quick Reference](#environment-quick-reference)
172
172
  - [WebRTC](#webrtc)
173
- - [Overview](#overview)
174
- - [Surface Status](#surface-status)
175
- - [Quick Start](#quick-start)
176
- - [SignalingClient](#signalingclient)
177
- - [Peer (Perfect Negotiation)](#peer-perfect-negotiation)
178
- - [Room](#room)
179
- - [Reactive Composables](#reactive-composables)
180
- - [z-stream Directive](#z-stream-directive)
181
- - [TURN Credentials](#turn-credentials)
182
- - [End-to-End Encryption (SFrame)](#end-to-end-encryption-sframe)
183
- - [SFU Adapters](#sfu-adapters)
184
- - [Join Tokens](#join-tokens)
185
- - [Observability (getStats)](#observability-getstats)
186
- - [SDP + ICE Helpers](#sdp-ice-helpers)
187
- - [Error Family](#error-family)
188
- - [Wire Protocol](#wire-protocol)
173
+ - [Overview](#webrtc-overview)
174
+ - [Surface Status](#webrtc-status)
175
+ - [Quick Start](#webrtc-quickstart)
176
+ - [SignalingClient](#webrtc-signaling)
177
+ - [Peer (Perfect Negotiation)](#webrtc-peer)
178
+ - [Room](#webrtc-room)
179
+ - [Reactive Composables](#webrtc-composables)
180
+ - [z-stream Directive](#webrtc-z-stream)
181
+ - [TURN Credentials](#webrtc-turn)
182
+ - [End-to-End Encryption (SFrame)](#webrtc-e2ee)
183
+ - [SFU Adapters](#webrtc-sfu)
184
+ - [Join Tokens](#webrtc-jointoken)
185
+ - [Observability (getStats)](#webrtc-observe)
186
+ - [SDP + ICE Helpers](#webrtc-sdp-ice)
187
+ - [Error Family](#webrtc-errors)
188
+ - [Wire Protocol](#webrtc-wire)
189
189
 
190
190
  ---
191
191
 
@@ -195,6 +195,7 @@ Complete API documentation for every module, method, option, and type in zQuery.
195
195
  Client-side SPA router with history and hash mode, dynamic params, query strings, navigation guards, lazy loading, and lifecycle hooks. Handles `z-link` interception, `popstate`/`hashchange` events, and component mounting automatically.
196
196
 
197
197
 
198
+
198
199
  ### Setup
199
200
 
200
201
 
@@ -225,6 +226,7 @@ const router = $.router({
225
226
  > **Tip:** **Recommended:** Use `` in your HTML rather than passing `el` in JavaScript. The router auto-detects it, keeping your JS cleaner and your outlet visible in markup. You can still pass `el` to override if needed.
226
227
 
227
228
 
229
+
228
230
  ### Config Options
229
231
 
230
232
 
@@ -237,6 +239,7 @@ const router = $.router({
237
239
  | `fallback` | `string \| null` | `null` | Component name to mount when no route matches (404 page) |
238
240
 
239
241
 
242
+
240
243
  ### Routing Modes
241
244
 
242
245
 
@@ -271,6 +274,7 @@ $.router({ el: '#my-container', routes: [...] });
271
274
  ```
272
275
 
273
276
 
277
+
274
278
  ### Route Definitions
275
279
 
276
280
 
@@ -299,6 +303,7 @@ $.router({ el: '#my-container', routes: [...] });
299
303
  ```
300
304
 
301
305
 
306
+
302
307
  ### Keep-Alive Routes
303
308
 
304
309
 
@@ -357,6 +362,7 @@ $.component('code-editor', {
357
362
  > **Warning:** Keep-alive components are never destroyed until the router itself is destroyed. Use `deactivated()` to release resources (WebSocket connections, intervals) that shouldn’t run while hidden.
358
363
 
359
364
 
365
+
360
366
  ### Route Matching
361
367
 
362
368
 
@@ -377,6 +383,7 @@ Routes are tested in **registration order** — the first match wins. Place spec
377
383
  When no route matches, the `fallback` component is mounted (your 404 page). If no fallback is configured, the outlet is left empty.
378
384
 
379
385
 
386
+
380
387
  ### Navigation
381
388
 
382
389
 
@@ -445,6 +452,7 @@ router.add({ path: '/new', component: 'new-page' }).navigate('/new');
445
452
  ```
446
453
 
447
454
 
455
+
448
456
  ### Navigation Links — `z-link`
449
457
 
450
458
 
@@ -484,6 +492,7 @@ Add `z-link` to any element for SPA navigation. Clicks are intercepted and route
484
492
  > **Warning:** **Internal routes only:** `z-link` accepts only internal route paths. Protocol schemes like `http:`, `javascript:`, and `data:` are automatically rejected. Use regular `` tags for external links.
485
493
 
486
494
 
495
+
487
496
  ### Scroll to Top — `z-to-top`
488
497
 
489
498
 
@@ -498,6 +507,7 @@ Add `z-to-top` to a `z-link` to scroll to the top after navigation. Defaults to
498
507
  ```
499
508
 
500
509
 
510
+
501
511
  ### Active Route — `z-active-route`
502
512
 
503
513
 
@@ -549,6 +559,7 @@ Automatically toggle a CSS class on elements based on whether their route matche
549
559
  > **Tip:** Unlike Angular’s `routerLinkActive` which infers the route from `routerLink`, zQuery uses an explicit path in `z-active-route`. This lets you apply the active class to *any* element, not just links.
550
560
 
551
561
 
562
+
552
563
  ### Route Params & Query
553
564
 
554
565
 
@@ -590,6 +601,7 @@ $.component('user-page', {
590
601
  ```
591
602
 
592
603
 
604
+
593
605
  ### Lazy Loading
594
606
 
595
607
 
@@ -616,6 +628,7 @@ const router = $.router({
616
628
  > **Tip:** **Code-splitting tip:** Each `import()` becomes a separate chunk when you bundle. Group related components into one file or split every page — whatever fits your app size.
617
629
 
618
630
 
631
+
619
632
  ### Render Functions
620
633
 
621
634
 
@@ -642,6 +655,7 @@ const router = $.router({
642
655
  > **No lifecycle:** Render functions inject raw HTML into the outlet — no `mounted`, `destroyed`, or reactive state. Use them for static preview pages, simple redirects, or placeholder content. For anything interactive, use a registered component.
643
656
 
644
657
 
658
+
645
659
  ### Navigation Guards
646
660
 
647
661
 
@@ -688,6 +702,7 @@ Both callbacks receive `(to, from)` objects with `{ path, params, query, route }
688
702
  > **Warning:** **Redirect loop protection:** If guards redirect more than **10 times** in a single navigation cycle, the router bails out to prevent infinite loops. If your guard throws an error, it is caught automatically — the navigation is cancelled but the router keeps running.
689
703
 
690
704
 
705
+
691
706
  ### Change Listener
692
707
 
693
708
 
@@ -706,6 +721,7 @@ unsub();
706
721
  ```
707
722
 
708
723
 
724
+
709
725
  ### Current Route State
710
726
 
711
727
 
@@ -740,6 +756,7 @@ router.resolve('/'); // → '/my-app'
740
756
  ```
741
757
 
742
758
 
759
+
743
760
  ### matchRoute()
744
761
 
745
762
 
@@ -801,6 +818,7 @@ async function render(pathname) {
801
818
  ```
802
819
 
803
820
 
821
+
804
822
  ### Dynamic Route Management
805
823
 
806
824
 
@@ -832,6 +850,7 @@ router
832
850
  > **Tip:** Routes added via `add()` are appended to the end of the route list. Since matching is first-match-wins, they won’t shadow existing routes with the same pattern.
833
851
 
834
852
 
853
+
835
854
  ### Hash Fragments
836
855
 
837
856
 
@@ -854,6 +873,7 @@ router.navigate('/docs#api');
854
873
  ```
855
874
 
856
875
 
876
+
857
877
  ### Sub-Route History Substates
858
878
 
859
879
 
@@ -920,6 +940,7 @@ unsub();
920
940
  > **Tip:** **Use cases:** modals, side panels, multi-step forms, tab switches, expandable detail views, and any inner-component navigation where "back" should undo a UI action instead of leaving the page entirely.
921
941
 
922
942
 
943
+
923
944
  ### Cleanup & Destroy
924
945
 
925
946
 
@@ -942,6 +963,7 @@ router.destroy();
942
963
  | Substate tracking | The internal `_inSubstate` flag is reset |
943
964
 
944
965
 
966
+
945
967
  ### How Navigation Works
946
968
 
947
969
 
@@ -964,6 +986,7 @@ Every route change — whether from a click, `navigate()`, or the back button
964
986
  > **Re-entrancy safe:** If a guard or listener triggers another navigation, the current resolution is completed first — no double-mounts or race conditions.
965
987
 
966
988
 
989
+
967
990
  ### Full Example
968
991
 
969
992
 
@@ -1015,6 +1038,7 @@ document.querySelector('#go').addEventListener('click', () => {
1015
1038
  Components are the core building block in zQuery. Each one is a self-contained unit with its own state, template, lifecycle, and scoped styles — all defined in a single `$.component()` call.
1016
1039
 
1017
1040
 
1041
+
1018
1042
  ### Your First Component
1019
1043
 
1020
1044
 
@@ -1044,6 +1068,7 @@ Drop `` anywhere in your HTML and it just works.
1044
1068
  > **Tip:** If you come from React, think of `$.component()` as a combination of `useState`, `useEffect`, and JSX — with no build step. If you come from Vue, it's very close to the Options API.
1045
1069
 
1046
1070
 
1071
+
1047
1072
  ### Anatomy of a Component
1048
1073
 
1049
1074
 
@@ -1065,6 +1090,7 @@ Every component is an object passed to `$.component(name, options)`. Here’s ho
1065
1090
  > The `state` key is special — it creates a deeply reactive proxy. Mutate properties and the component re-renders automatically. You never call a `setState()` or `forceUpdate()`.
1066
1091
 
1067
1092
 
1093
+
1068
1094
  ### State & Reactivity
1069
1095
 
1070
1096
 
@@ -1094,6 +1120,7 @@ $.component('notification-badge', {
1094
1120
  > **Tip:** Use a factory function `state: () => ({ ... })` when the same component appears more than once on a page. An object literal is shared across instances, which can cause unexpected coupling.
1095
1121
 
1096
1122
 
1123
+
1097
1124
  ### Computed Properties
1098
1125
 
1099
1126
 
@@ -1110,6 +1137,7 @@ $.component('cart-summary', {
1110
1137
  formatted(){ return '
1111
1138
 
1112
1139
 
1140
+
1113
1141
  ### Watchers
1114
1142
 
1115
1143
 
@@ -1142,6 +1170,7 @@ $.component('theme-switcher', {
1142
1170
  ```
1143
1171
 
1144
1172
 
1173
+
1145
1174
  ### Templates
1146
1175
 
1147
1176
 
@@ -1292,6 +1321,7 @@ templateUrl: { main: 'main.html', sidebar: 'sidebar.html' }
1292
1321
  ```
1293
1322
 
1294
1323
 
1324
+
1295
1325
  ### Events & Forms
1296
1326
 
1297
1327
 
@@ -1323,6 +1353,7 @@ $.component('contact-form', {
1323
1353
  > **Tip:** See Directives › Event Binding for modifiers, argument passing, and `$event`. See Directives › z-model for the full form element & modifier reference.
1324
1354
 
1325
1355
 
1356
+
1326
1357
  ### Lifecycle
1327
1358
 
1328
1359
 
@@ -1361,6 +1392,7 @@ $.component('live-clock', {
1361
1392
  > **Warning:** Always clean up in `destroyed()`. Timers, event listeners, and store subscriptions that outlive their component cause memory leaks.
1362
1393
 
1363
1394
 
1395
+
1364
1396
  ### Props & Communication
1365
1397
 
1366
1398
 
@@ -1478,6 +1510,7 @@ $.component('modal-dialog', {
1478
1510
  > **Tip:** If you need to query projected content, do so in `updated()` or with a `requestAnimationFrame` in `mounted()`.
1479
1511
 
1480
1512
 
1513
+
1481
1514
  ### Reactive Props Schema
1482
1515
 
1483
1516
 
@@ -1533,6 +1566,7 @@ $.component('user-badge', {
1533
1566
  > **Tip:** You can also use the shorthand `{ name: String }` which is equivalent to `{ name: { type: String } }`.
1534
1567
 
1535
1568
 
1569
+
1536
1570
  ### Store Connectors
1537
1571
 
1538
1572
 
@@ -1564,6 +1598,7 @@ The `stores` config creates automatic multi-key subscriptions. When any listed k
1564
1598
  > **Tip:** See Store › connectStore() for full details on the connector API.
1565
1599
 
1566
1600
 
1601
+
1567
1602
  ### Scoped Styles
1568
1603
 
1569
1604
 
@@ -1631,6 +1666,7 @@ $.style(['reset.css', 'typography.css', 'layout.css']);
1631
1666
  > **Tip:** Duplicate URLs are ignored — calling `$.style("theme.css")` twice only loads it once.
1632
1667
 
1633
1668
 
1669
+
1634
1670
  ### DOM Morphing
1635
1671
 
1636
1672
 
@@ -1749,6 +1785,7 @@ $.morphElement($.id('panel'), newEl);
1749
1785
  **Auto-Key Detection:** zQuery automatically detects `z-key` attributes in child lists and switches to keyed reconciliation. If any child has `z-key`, the entire sibling group is reconciled as a keyed list.
1750
1786
 
1751
1787
 
1788
+
1752
1789
  ### Transitions
1753
1790
 
1754
1791
 
@@ -1826,6 +1863,7 @@ $.component('fade-panel', {
1826
1863
  > **Tip:** See Directives › z-transition for the directive reference.
1827
1864
 
1828
1865
 
1866
+
1829
1867
  ### Mounting & Instance API
1830
1868
 
1831
1869
 
@@ -1858,6 +1896,7 @@ $.mount('#header', 'user-badge', { name: 'Alice' });
1858
1896
  | `this.emit(event, detail)` | Dispatch a CustomEvent from the host element (bubbles) |
1859
1897
 
1860
1898
 
1899
+
1861
1900
  ### Quick Reference
1862
1901
 
1863
1902
 
@@ -1894,6 +1933,7 @@ $.mount('#header', 'user-badge', { name: 'Alice' });
1894
1933
  ```
1895
1934
 
1896
1935
 
1936
+
1897
1937
  ### Watchers
1898
1938
 
1899
1939
 
@@ -1911,6 +1951,7 @@ React to specific state changes with `watch`. Each watcher receives the new and
1911
1951
  __CODEBLOCK_3__
1912
1952
 
1913
1953
 
1954
+
1914
1955
  ### Templates
1915
1956
 
1916
1957
 
@@ -1961,6 +2002,7 @@ __CODEBLOCK_6__
1961
2002
  __CODEBLOCK_7__
1962
2003
 
1963
2004
 
2005
+
1964
2006
  ### Events & Forms
1965
2007
 
1966
2008
 
@@ -1976,6 +2018,7 @@ __CODEBLOCK_9__
1976
2018
  > **Tip:** See Directives › Event Binding for modifiers, argument passing, and `$event`. See Directives › z-model for the full form element & modifier reference.
1977
2019
 
1978
2020
 
2021
+
1979
2022
  ### Lifecycle
1980
2023
 
1981
2024
 
@@ -1998,6 +2041,7 @@ __CODEBLOCK_10__
1998
2041
  > **Warning:** Always clean up in `destroyed()`. Timers, event listeners, and store subscriptions that outlive their component cause memory leaks.
1999
2042
 
2000
2043
 
2044
+
2001
2045
  ### Props & Communication
2002
2046
 
2003
2047
 
@@ -2058,6 +2102,7 @@ __CODEBLOCK_15__
2058
2102
  > **Tip:** If you need to query projected content, do so in `updated()` or with a `requestAnimationFrame` in `mounted()`.
2059
2103
 
2060
2104
 
2105
+
2061
2106
  ### Reactive Props Schema
2062
2107
 
2063
2108
 
@@ -2093,6 +2138,7 @@ __CODEBLOCK_17__
2093
2138
  > **Tip:** You can also use the shorthand `{ name: String }` which is equivalent to `{ name: { type: String } }`.
2094
2139
 
2095
2140
 
2141
+
2096
2142
  ### Store Connectors
2097
2143
 
2098
2144
 
@@ -2108,6 +2154,7 @@ The `stores` config creates automatic multi-key subscriptions. When any listed k
2108
2154
  > **Tip:** See Store › connectStore() for full details on the connector API.
2109
2155
 
2110
2156
 
2157
+
2111
2158
  ### Scoped Styles
2112
2159
 
2113
2160
 
@@ -2141,6 +2188,7 @@ __CODEBLOCK_21__
2141
2188
  > **Tip:** Duplicate URLs are ignored — calling `$.style("theme.css")` twice only loads it once.
2142
2189
 
2143
2190
 
2191
+
2144
2192
  ### DOM Morphing
2145
2193
 
2146
2194
 
@@ -2222,6 +2270,7 @@ __CODEBLOCK_24__
2222
2270
  **Auto-Key Detection:** zQuery automatically detects `z-key` attributes in child lists and switches to keyed reconciliation. If any child has `z-key`, the entire sibling group is reconciled as a keyed list.
2223
2271
 
2224
2272
 
2273
+
2225
2274
  ### Transitions
2226
2275
 
2227
2276
 
@@ -2263,6 +2312,7 @@ __CODEBLOCK_27__
2263
2312
  > **Tip:** See Directives › z-transition for the directive reference.
2264
2313
 
2265
2314
 
2315
+
2266
2316
  ### Mounting & Instance API
2267
2317
 
2268
2318
 
@@ -2285,6 +2335,7 @@ __CODEBLOCK_28__
2285
2335
  | `this.emit(event, detail)` | Dispatch a CustomEvent from the host element (bubbles) |
2286
2336
 
2287
2337
 
2338
+
2288
2339
  ### Quick Reference
2289
2340
 
2290
2341
 
@@ -2322,6 +2373,7 @@ __CODEBLOCK_28__
2322
2373
  Directives are special HTML attributes that add reactive behavior to your templates. They’re processed after every render and morph pass.
2323
2374
 
2324
2375
 
2376
+
2325
2377
  ### Quick Reference
2326
2378
 
2327
2379
 
@@ -2350,6 +2402,7 @@ Directives are special HTML attributes that add reactive behavior to your templa
2350
2402
  | `z-link` | | Client-side SPA link — see **Router** section |
2351
2403
 
2352
2404
 
2405
+
2353
2406
  ### z-if / z-else-if / z-else
2354
2407
 
2355
2408
 
@@ -2392,6 +2445,7 @@ $.component('status-display', {
2392
2445
  | Transitions | Triggers mount/destroy | CSS transitions work naturally |
2393
2446
 
2394
2447
 
2448
+
2395
2449
  ### z-for
2396
2450
 
2397
2451
 
@@ -2444,6 +2498,7 @@ $.component('todo-list', {
2444
2498
  > **Tip:** Always add `z-key` when using `z-for` with items that can be reordered or removed. This enables LIS-based reconciliation for minimal DOM operations.
2445
2499
 
2446
2500
 
2501
+
2447
2502
  ### z-key
2448
2503
 
2449
2504
 
@@ -2492,6 +2547,7 @@ $.component('task-list', {
2492
2547
  > **Tip:** Never use the loop index as a key on mutable lists — it defeats the purpose of keyed reconciliation. Use a stable unique identifier like a database ID.
2493
2548
 
2494
2549
 
2550
+
2495
2551
  ### z-show
2496
2552
 
2497
2553
 
@@ -2521,6 +2577,7 @@ $.component('toggle-panel', {
2521
2577
  ```
2522
2578
 
2523
2579
 
2580
+
2524
2581
  ### z-bind / `:attr`
2525
2582
 
2526
2583
 
@@ -2565,6 +2622,7 @@ $.component('dynamic-link', {
2565
2622
  > **Tip:** Boolean attributes (`disabled`, `hidden`, `checked`, etc.) are removed from the DOM when the expression is falsy, and added when truthy.
2566
2623
 
2567
2624
 
2625
+
2568
2626
  ### z-class
2569
2627
 
2570
2628
 
@@ -2608,6 +2666,7 @@ $.component('tab-button', {
2608
2666
  > **Tip:** Static classes on the same element are preserved. `z-class` only manages the classes it controls — it won’t remove classes you set in plain `class="..."`.
2609
2667
 
2610
2668
 
2669
+
2611
2670
  ### z-style
2612
2671
 
2613
2672
 
@@ -2647,6 +2706,7 @@ $.component('color-picker', {
2647
2706
  > **Tip:** Object syntax merges with existing inline styles. Use camelCase property names (`fontSize`) — they’re converted to kebab-case (`font-size`) automatically.
2648
2707
 
2649
2708
 
2709
+
2650
2710
  ### z-html & z-text
2651
2711
 
2652
2712
 
@@ -2682,6 +2742,7 @@ $.component('article-view', {
2682
2742
  > **Tip:** `z-text` is morph-friendly and will not disrupt focus or selection. Prefer it over `{{}}` interpolation for text-only content that changes frequently.
2683
2743
 
2684
2744
 
2745
+
2685
2746
  ### Event Binding — `@event`
2686
2747
 
2687
2748
 
@@ -2846,6 +2907,7 @@ Modifiers chain with dots — no manual `e.preventDefault()` calls needed:
2846
2907
  > **Tip:** The `.outside` modifier installs a document-level listener (cleaned up on destroy) so clicks anywhere outside the element trigger the handler — ideal for dropdowns, modals, and popovers.
2847
2908
 
2848
2909
 
2910
+
2849
2911
  ### z-model
2850
2912
 
2851
2913
 
@@ -2962,6 +3024,7 @@ $.component('signup-form', {
2962
3024
  ```
2963
3025
 
2964
3026
 
3027
+
2965
3028
  ### z-ref
2966
3029
 
2967
3030
 
@@ -2989,6 +3052,7 @@ $.component('focus-input', {
2989
3052
  ```
2990
3053
 
2991
3054
 
3055
+
2992
3056
  ### z-cloak
2993
3057
 
2994
3058
 
@@ -3010,6 +3074,7 @@ Prevents flash of uncompiled template. The attribute is removed once the compone
3010
3074
  > **Tip:** zQuery automatically injects the `[z-cloak]` CSS rule, so you usually don’t need to add it yourself.
3011
3075
 
3012
3076
 
3077
+
3013
3078
  ### z-pre
3014
3079
 
3015
3080
 
@@ -3025,6 +3090,7 @@ Skip directive processing for an element and all its children:
3025
3090
  ```
3026
3091
 
3027
3092
 
3093
+
3028
3094
  ### z-skip
3029
3095
 
3030
3096
 
@@ -3045,6 +3111,7 @@ Tell the morph engine to skip this subtree entirely during re-renders:
3045
3111
  > `z-to-top` and `z-link` are router attributes — see the **Router** documentation section for full usage, values, and examples.
3046
3112
 
3047
3113
 
3114
+
3048
3115
  ### z-transition
3049
3116
 
3050
3117
 
@@ -3089,6 +3156,7 @@ Classes are removed automatically on `transitionend` or `animationend`. Works wi
3089
3156
  > **Tip:** See Components › Transitions for the component-level transition config alternative.
3090
3157
 
3091
3158
 
3159
+
3092
3160
  ### Expression Context
3093
3161
 
3094
3162
 
@@ -3105,6 +3173,7 @@ Expressions inside directives are evaluated in a sandboxed scope with access to:
3105
3173
  | `$event` | `$event` | Native DOM event object (in `@event`) |
3106
3174
 
3107
3175
 
3176
+
3108
3177
  ### External Templates
3109
3178
 
3110
3179
 
@@ -3137,6 +3206,7 @@ $.component('my-page', {
3137
3206
  ```
3138
3207
 
3139
3208
 
3209
+
3140
3210
  ### Processing Order
3141
3211
 
3142
3212
 
@@ -3173,6 +3243,7 @@ Global state management with actions, getters, subscriptions, and middleware. In
3173
3243
  > **Data flow:** Component dispatches `action` → middleware pipeline → action mutates `state` → getters recompute → subscribers notified → UI updates
3174
3244
 
3175
3245
 
3246
+
3176
3247
  ### Setup
3177
3248
 
3178
3249
 
@@ -3208,6 +3279,7 @@ const store = $.store({
3208
3279
  | `maxUndo` | number | Maximum undo checkpoint stack size (default `50`) |
3209
3280
 
3210
3281
 
3282
+
3211
3283
  ### Dispatching Actions
3212
3284
 
3213
3285
 
@@ -3228,6 +3300,7 @@ const result = store.dispatch('compute');
3228
3300
  > **Tip:** `dispatch()` returns whatever the action function returns. This is useful for actions that compute a value or return a status.
3229
3301
 
3230
3302
 
3303
+
3231
3304
  ### Reading State & Getters
3232
3305
 
3233
3306
 
@@ -3243,6 +3316,7 @@ console.log(store.getters.displayName); // 'Guest'
3243
3316
  ```
3244
3317
 
3245
3318
 
3319
+
3246
3320
  ### Subscriptions
3247
3321
 
3248
3322
 
@@ -3289,6 +3363,7 @@ unsubMulti();
3289
3363
  ```
3290
3364
 
3291
3365
 
3366
+
3292
3367
  ### Multi-Key Subscriptions
3293
3368
 
3294
3369
 
@@ -3311,6 +3386,7 @@ store.dispatch('login', 'Alice'); // → callback does NOT fire
3311
3386
  > **Tip:** Multi-key subscriptions are implemented as filtered wildcard listeners — lightweight and efficient. The unsubscribe function works exactly like single-key subscriptions.
3312
3387
 
3313
3388
 
3389
+
3314
3390
  ### Middleware
3315
3391
 
3316
3392
 
@@ -3361,6 +3437,7 @@ store
3361
3437
  ```
3362
3438
 
3363
3439
 
3440
+
3364
3441
  ### Named Stores
3365
3442
 
3366
3443
 
@@ -3384,6 +3461,7 @@ const nope = $.getStore('nonexistent'); // null
3384
3461
  > **Tip:** If no name is passed to `$.store(config)`, the store is registered under `"default"`. Retrieve it with `$.getStore()` (no argument).
3385
3462
 
3386
3463
 
3464
+
3387
3465
  ### Async Actions
3388
3466
 
3389
3467
 
@@ -3411,6 +3489,7 @@ await store.dispatch('fetchData', '/api/users');
3411
3489
  > **Tip:** Because `dispatch()` returns the action's return value, async actions naturally return a Promise you can `await`, chain with `.then()`, or ignore for fire-and-forget.
3412
3490
 
3413
3491
 
3492
+
3414
3493
  ### Batch Updates
3415
3494
 
3416
3495
 
@@ -3448,6 +3527,7 @@ store.batch(state => {
3448
3527
  > **Tip:** Use `batch()` when updating multiple state keys inside a loop or complex handler. This prevents intermediate states from triggering wasted renders.
3449
3528
 
3450
3529
 
3530
+
3451
3531
  ### Checkpoint / Undo / Redo
3452
3532
 
3453
3533
 
@@ -3504,6 +3584,7 @@ document.querySelector('#redo').addEventListener('click', () => {
3504
3584
  > **Tip:** The undo stack is capped at `maxUndo` (default 50). When exceeded, the oldest checkpoint is discarded. Set `maxUndo` in the store config to tune.
3505
3585
 
3506
3586
 
3587
+
3507
3588
  ### State Utilities
3508
3589
 
3509
3590
 
@@ -3546,6 +3627,7 @@ console.log(store.history);
3546
3627
  > **Tip:** `store.reset()` with no arguments uses a deep copy of the original initial state you passed at store creation — no need to keep a reference to it yourself.
3547
3628
 
3548
3629
 
3630
+
3549
3631
  ### Error Resilience
3550
3632
 
3551
3633
 
@@ -3563,6 +3645,7 @@ The store catches and reports errors in subscribers, actions, and middleware so
3563
3645
  > **Tip:** All store errors use the `STORE_ACTION`, `STORE_SUBSCRIBE`, or `STORE_MIDDLEWARE` error codes. See the *Error Handling → All Error Codes* section for details.
3564
3646
 
3565
3647
 
3648
+
3566
3649
  ### Using Store in Components
3567
3650
 
3568
3651
 
@@ -3596,6 +3679,7 @@ $.component('user-status', {
3596
3679
  > **Warning:** Always call the unsubscribe function in `destroyed()` to avoid memory leaks.
3597
3680
 
3598
3681
 
3682
+
3599
3683
  ### connectStore()
3600
3684
 
3601
3685
 
@@ -3639,6 +3723,7 @@ $.component('file-list', {
3639
3723
  > **Tip:** Access connected store data in templates via `this.stores.app.files`. The connector uses multi-key subscriptions under the hood, so the component only re-renders when the listed keys change.
3640
3724
 
3641
3725
 
3726
+
3642
3727
  ### Quick Reference
3643
3728
 
3644
3729
 
@@ -3674,6 +3759,7 @@ $.component('file-list', {
3674
3759
  A lightweight `fetch`-based HTTP client with automatic JSON parsing, interceptors, abort support, and a clean chainable API.
3675
3760
 
3676
3761
 
3762
+
3677
3763
  ### Request Methods
3678
3764
 
3679
3765
 
@@ -3720,6 +3806,7 @@ console.log(check.headers); // { 'content-length': '1234', ... }
3720
3806
  ```
3721
3807
 
3722
3808
 
3809
+
3723
3810
  ### Configuration
3724
3811
 
3725
3812
 
@@ -3759,6 +3846,7 @@ console.log(cfg.headers); // { 'Content-Type': '...', 'Authorization': '...' }
3759
3846
  > **Tip:** Per-request config overrides defaults: `$.http.get('/api/data', null, { timeout: 10000 })`. Set `timeout: 0` to disable the timeout entirely.
3760
3847
 
3761
3848
 
3849
+
3762
3850
  ### Response Object
3763
3851
 
3764
3852
 
@@ -3786,6 +3874,7 @@ console.log(res.response); // raw fetch Response (for advanced use)
3786
3874
  ```
3787
3875
 
3788
3876
 
3877
+
3789
3878
  ### Auto-Parsing
3790
3879
 
3791
3880
 
@@ -3817,6 +3906,7 @@ const url = URL.createObjectURL(img.data);
3817
3906
  ```
3818
3907
 
3819
3908
 
3909
+
3820
3910
  ### Interceptors
3821
3911
 
3822
3912
 
@@ -3871,6 +3961,7 @@ $.http.clearInterceptors('response');
3871
3961
  ```
3872
3962
 
3873
3963
 
3964
+
3874
3965
  ### Abort / Cancel
3875
3966
 
3876
3967
 
@@ -3903,6 +3994,7 @@ setTimeout(() => controller.abort(), 2000);
3903
3994
  | User calls `controller.abort()` | `Request aborted: GET /api/slow` |
3904
3995
 
3905
3996
 
3997
+
3906
3998
  ### FormData & String Bodies
3907
3999
 
3908
4000
 
@@ -3934,6 +4026,7 @@ await $.http.post('/api/users', { name: 'Alice' });
3934
4026
  > **Tip:** For GET and HEAD requests, object data is serialized as query parameters instead of a request body.
3935
4027
 
3936
4028
 
4029
+
3937
4030
  ### Error Handling
3938
4031
 
3939
4032
 
@@ -3973,6 +4066,7 @@ try {
3973
4066
  > **Tip:** The `err.response` property is only present for server errors (4xx/5xx). Network failures, timeouts, and aborts produce a plain `Error` without `.response`.
3974
4067
 
3975
4068
 
4069
+
3976
4070
  ### Per-Request Options
3977
4071
 
3978
4072
 
@@ -4008,6 +4102,7 @@ await $.http.get('/api/me', null, {
4008
4102
  ```
4009
4103
 
4010
4104
 
4105
+
4011
4106
  ### Parallel Requests
4012
4107
 
4013
4108
 
@@ -4037,6 +4132,7 @@ try {
4037
4132
  > **Tip:** `$.http.all()` is a convenience wrapper around `Promise.all` that keeps your HTTP operations in a single namespace.
4038
4133
 
4039
4134
 
4135
+
4040
4136
  ### Raw Fetch Passthrough
4041
4137
 
4042
4138
 
@@ -4073,6 +4169,7 @@ Standalone reactivity primitives you can use anywhere — inside or outside comp
4073
4169
  > **Signal flow:** `$.signal()` / `$.reactive()` → `$.computed()` derives → `$.effect()` runs side-effects
4074
4170
 
4075
4171
 
4172
+
4076
4173
  ### $.reactive()
4077
4174
 
4078
4175
 
@@ -4125,6 +4222,7 @@ $.reactive(null, fn); // → null
4125
4222
  > **Tip:** `delete obj.key` triggers the callback with `(key, undefined, oldValue)` — useful for clearing optional properties.
4126
4223
 
4127
4224
 
4225
+
4128
4226
  ### $.Signal
4129
4227
 
4130
4228
 
@@ -4148,6 +4246,7 @@ console.log(same instanceof $.Signal); // true
4148
4246
  > **Tip:** `$.signal(val)` is the recommended shorthand. `$.Signal` is mainly useful for type checks and advanced patterns.
4149
4247
 
4150
4248
 
4249
+
4151
4250
  ### $.signal()
4152
4251
 
4153
4252
 
@@ -4176,6 +4275,7 @@ unsub(); // unsubscribe
4176
4275
  | `.toString()` | Returns `String(.value)` |
4177
4276
 
4178
4277
 
4278
+
4179
4279
  ### $.computed()
4180
4280
 
4181
4281
 
@@ -4209,6 +4309,7 @@ console.log(quadrupled.value); // 12
4209
4309
  ```
4210
4310
 
4211
4311
 
4312
+
4212
4313
  ### $.effect()
4213
4314
 
4214
4315
 
@@ -4245,6 +4346,7 @@ $.effect(() => {
4245
4346
  > **Tip:** Effects automatically clean up stale dependencies on each re-run. If a conditional branch stops reading a signal, the effect unsubscribes from it. This prevents memory leaks and unnecessary re-runs.
4246
4347
 
4247
4348
 
4349
+
4248
4350
  ### $.batch()
4249
4351
 
4250
4352
 
@@ -4293,6 +4395,7 @@ console.log(result); // 300
4293
4395
  > **Tip:** Use `$.batch()` when updating multiple related signals in one operation — such as form resets or API response hydration — to avoid intermediate renders.
4294
4396
 
4295
4397
 
4398
+
4296
4399
  ### $.untracked()
4297
4400
 
4298
4401
 
@@ -4327,6 +4430,7 @@ a.value = 2; // effect re-runs → logs 22 (reads updated b)
4327
4430
  > **Tip:** Use `$.untracked()` to read "reference data" (e.g. a config signal) without subscribing to its changes. This is especially useful when one signal is used only for its current snapshot.
4328
4431
 
4329
4432
 
4433
+
4330
4434
  ### Summary
4331
4435
 
4332
4436
 
@@ -4343,6 +4447,7 @@ a.value = 2; // effect re-runs → logs 22 (reads updated b)
4343
4447
  > **Tip:** Use `signals` for individual values that change independently. Use `$.reactive()` when you have a config object or deeply nested state that needs unified change detection.
4344
4448
 
4345
4449
 
4450
+
4346
4451
  ### How Auto-Tracking Works
4347
4452
 
4348
4453
 
@@ -4376,6 +4481,7 @@ a.value = 'A2'; // does NOT re-run (a is no longer tracked)
4376
4481
  > **Key concept:** Dependencies are dynamic. An effect only tracks signals it actually reads during its most recent execution. This is why `peek()` is useful — it reads a value without becoming a dependency.
4377
4482
 
4378
4483
 
4484
+
4379
4485
  ### Error Resilience
4380
4486
 
4381
4487
 
@@ -4394,6 +4500,7 @@ All reactive callbacks are wrapped in try/catch. A single error never crashes th
4394
4500
  > **Tip:** Reactive errors use the `REACTIVE_CALLBACK`, `SIGNAL_CALLBACK`, and `EFFECT_EXEC` error codes. See the *Error Handling → All Error Codes* section for details.
4395
4501
 
4396
4502
 
4503
+
4397
4504
  ### Quick Reference
4398
4505
 
4399
4506
 
@@ -4421,6 +4528,7 @@ All reactive callbacks are wrapped in try/catch. A single error never crashes th
4421
4528
  zQuery ships a jQuery-style `$()` selector that returns a `ZQueryCollection` — an array-like wrapper with chainable DOM manipulation methods, plus a handful of global helpers on `$` itself.
4422
4529
 
4423
4530
 
4531
+
4424
4532
  ### $() Main Selector
4425
4533
 
4426
4534
 
@@ -4454,6 +4562,7 @@ $(document.querySelectorAll('input')).val('');
4454
4562
  ```
4455
4563
 
4456
4564
 
4565
+
4457
4566
  ### Raw-Element Shortcuts
4458
4567
 
4459
4568
 
@@ -4493,6 +4602,7 @@ console.log(links.length);
4493
4602
  ```
4494
4603
 
4495
4604
 
4605
+
4496
4606
  ### Multi-Element Shortcuts
4497
4607
 
4498
4608
 
@@ -4527,6 +4637,7 @@ $.children('sidebar').addClass('nav-item');
4527
4637
  ```
4528
4638
 
4529
4639
 
4640
+
4530
4641
  ### Collection Methods
4531
4642
 
4532
4643
 
@@ -4849,6 +4960,7 @@ $(window).on('scroll', () => {
4849
4960
  ```
4850
4961
 
4851
4962
 
4963
+
4852
4964
  ### Element Creation — `$.create()`
4853
4965
 
4854
4966
 
@@ -4888,6 +5000,7 @@ const rawEl = $.create('input', { type: 'text' })[0];
4888
5000
  Additional arguments after `attrs` are appended as children (strings become text nodes, elements are appended directly).
4889
5001
 
4890
5002
 
5003
+
4891
5004
  ### Animations
4892
5005
 
4893
5006
 
@@ -4928,6 +5041,7 @@ $('.row.removing').remove();
4928
5041
  ```
4929
5042
 
4930
5043
 
5044
+
4931
5045
  ### Form Helpers
4932
5046
 
4933
5047
 
@@ -4954,6 +5068,7 @@ $('form').eq(0).find('input, textarea').val('');
4954
5068
  ```
4955
5069
 
4956
5070
 
5071
+
4957
5072
  ### DOM Ready & Plugins
4958
5073
 
4959
5074
 
@@ -4985,6 +5100,7 @@ $('#settings-form select').disable();
4985
5100
  ```
4986
5101
 
4987
5102
 
5103
+
4988
5104
  ### Native DOM Equivalents
4989
5105
 
4990
5106
 
@@ -5024,6 +5140,7 @@ For raw elements (`$.id`, `$.class`, `$.qs`, `$.qsa`) you use the native DOM API
5024
5140
  Quality-of-life helpers available on the global `$` object. Every function is also a named export from `src/utils.js`, making them tree-shakeable when imported selectively.
5025
5141
 
5026
5142
 
5143
+
5027
5144
  ### Function Utilities
5028
5145
 
5029
5146
 
@@ -5073,6 +5190,7 @@ lookup.clear(); // flush the cache
5073
5190
  > **Warning:** By default `$.memoize` uses only the **first argument** as cache key. For multi-argument functions, pass a custom key function as the second parameter.
5074
5191
 
5075
5192
 
5193
+
5076
5194
  ### String Utilities
5077
5195
 
5078
5196
 
@@ -5121,6 +5239,7 @@ $.truncate('A really long sentence here', 15, '...');
5121
5239
  ```
5122
5240
 
5123
5241
 
5242
+
5124
5243
  ### Object Utilities
5125
5244
 
5126
5245
 
@@ -5177,6 +5296,7 @@ $.isEmpty(false); // false
5177
5296
  > **Tip:** The fallback clone (when `structuredClone` is unavailable) manually handles `Date`, `RegExp`, `Map`, `Set`, `ArrayBuffer`, typed arrays, and circular references. It preserves `undefined` values and prototype chains — no data loss compared to the JSON round-trip approach.
5178
5297
 
5179
5298
 
5299
+
5180
5300
  ### Array Utilities
5181
5301
 
5182
5302
 
@@ -5215,6 +5335,7 @@ $.groupBy(items, i => i.type);
5215
5335
  > **Tip:** `$.range` returns an empty array if `step` is `0` or goes in the wrong direction relative to start/end.
5216
5336
 
5217
5337
 
5338
+
5218
5339
  ### Number Utilities
5219
5340
 
5220
5341
 
@@ -5233,6 +5354,7 @@ $.clamp(100, 0, 100); // 100 (boundary)
5233
5354
  ```
5234
5355
 
5235
5356
 
5357
+
5236
5358
  ### Async Utilities
5237
5359
 
5238
5360
 
@@ -5275,6 +5397,7 @@ await $.timeout(longTask(), 5000, 'Task exceeded 5 s limit');
5275
5397
  > **Tip:** `$.timeout` automatically clears its internal timer via `.finally()`, so there is no risk of lingering timers.
5276
5398
 
5277
5399
 
5400
+
5278
5401
  ### URL Utilities
5279
5402
 
5280
5403
 
@@ -5294,6 +5417,7 @@ $.param({ page: 2, sort: 'name' });
5294
5417
  ```
5295
5418
 
5296
5419
 
5420
+
5297
5421
  ### Storage Wrappers
5298
5422
 
5299
5423
 
@@ -5329,6 +5453,7 @@ $.session.clear();
5329
5453
  > **Tip:** Values are JSON-serialized automatically. Unlike raw `localStorage.getItem()`, you get proper types back — numbers stay numbers, objects stay objects.
5330
5454
 
5331
5455
 
5456
+
5332
5457
  ### Event Bus
5333
5458
 
5334
5459
 
@@ -5372,6 +5497,7 @@ formBus.clear(); // only clears formBus
5372
5497
  ```
5373
5498
 
5374
5499
 
5500
+
5375
5501
  ### Global Helpers
5376
5502
 
5377
5503
 
@@ -5406,6 +5532,7 @@ styles.remove();
5406
5532
  ```
5407
5533
 
5408
5534
 
5535
+
5409
5536
  ### Quick Reference
5410
5537
 
5411
5538
 
@@ -5432,6 +5559,7 @@ All 37 utility exports at a glance, grouped by category:
5432
5559
  During development, zQuery catches errors **before they bury themselves in the console** and shows them right in the browser as a full-screen overlay. Syntax mistakes, runtime crashes, and framework-level `ZQueryError` exceptions all appear in the same place — color-coded so you can tell at a glance what went wrong and where.
5433
5560
 
5434
5561
 
5562
+
5435
5563
  ### What Gets Caught
5436
5564
 
5437
5565
 
@@ -5445,6 +5573,7 @@ The dev server watches for three categories of errors:
5445
5573
  | **ZQueryError** | Framework-level errors raised by the router, components, store, reactive system, etc. | A **color-coded error code badge**, the message, any context metadata (component name, directive, expression…), and a stack trace. |
5446
5574
 
5447
5575
 
5576
+
5448
5577
  ### Syntax Error Code Frames
5449
5578
 
5450
5579
 
@@ -5465,6 +5594,7 @@ When a syntax error is caught on save, the overlay shows the surrounding source
5465
5594
  Fix the error and save again — the overlay clears automatically and the page reloads.
5466
5595
 
5467
5596
 
5597
+
5468
5598
  ### Framework Error Codes
5469
5599
 
5470
5600
 
@@ -5486,6 +5616,7 @@ Every `ZQueryError` carries a code prefixed by the subsystem that raised it. The
5486
5616
  Syntax/parse errors without a `ZQ_` code get a red badge; everything else defaults to orange.
5487
5617
 
5488
5618
 
5619
+
5489
5620
  ### Context Metadata
5490
5621
 
5491
5622
 
@@ -5500,6 +5631,7 @@ When a `ZQueryError` includes a `context` object, its key/value pairs are shown
5500
5631
  This tells you exactly which part of your app triggered the error without having to dig through a stack trace.
5501
5632
 
5502
5633
 
5634
+
5503
5635
  ### Dismissing & Auto-Clear
5504
5636
 
5505
5637
 
@@ -5516,6 +5648,7 @@ The overlay disappears on its own when you fix the error and save — no manual
5516
5648
  > **Production safety.** The error reporting script is **never** written to disk and is **not** included in `zquery bundle` builds. Your shipped code is completely clean.
5517
5649
 
5518
5650
 
5651
+
5519
5652
  ### Programmatic Error Handling
5520
5653
 
5521
5654
 
@@ -5549,6 +5682,7 @@ $.onError(null);
5549
5682
  | `err.cause` | Error? | Original error if wrapping another |
5550
5683
 
5551
5684
 
5685
+
5552
5686
  ### Error Utilities
5553
5687
 
5554
5688
 
@@ -5586,6 +5720,7 @@ $.validate(el, 'target'); // throws if null/undefined
5586
5720
  > **Tip:** `guardCallback` is used internally by zQuery for all lifecycle hooks and directive callbacks. `guardAsync` is the async equivalent — use it for fetch handlers, timers, or any async code where a rejection shouldn’t crash the entire flow.
5587
5721
 
5588
5722
 
5723
+
5589
5724
  ### formatError()
5590
5725
 
5591
5726
 
@@ -5620,6 +5755,7 @@ const nested = $.formatError(new Error('outer', { cause: new TypeError('inner')
5620
5755
  | `cause` | object \| null | Recursively formatted cause chain |
5621
5756
 
5622
5757
 
5758
+
5623
5759
  ### guardAsync()
5624
5760
 
5625
5761
 
@@ -5646,6 +5782,7 @@ const data = await safeFetch('/api/data');
5646
5782
  > **Tip:** `guardAsync` returns `undefined` on failure, so always check the return value. The error is still reported to all `$.onError` handlers and logged to the console.
5647
5783
 
5648
5784
 
5785
+
5649
5786
  ### All Error Codes
5650
5787
 
5651
5788
 
@@ -5694,6 +5831,7 @@ The full list of error codes available on `$.ErrorCode` (28 total, frozen at loa
5694
5831
  zQuery includes a lightweight SSR module for rendering components to HTML strings in **Node.js**. Use it for SEO, faster initial page loads, static site generation, or API-driven HTML responses. No DOM required — it runs entirely on the server.
5695
5832
 
5696
5833
 
5834
+
5697
5835
  ### Overview
5698
5836
 
5699
5837
 
@@ -5726,6 +5864,7 @@ const html = await app.renderToString('hello-world');
5726
5864
  > **Node.js only.** The SSR module is a separate import (`zero-query/ssr`) and does not run in the browser. Your client-side app uses the normal `$` global as usual.
5727
5865
 
5728
5866
 
5867
+
5729
5868
  ### SSR Scaffold
5730
5869
 
5731
5870
 
@@ -5781,6 +5920,7 @@ node server/index.js
5781
5920
  ```
5782
5921
 
5783
5922
 
5923
+
5784
5924
  ### createSSRApp()
5785
5925
 
5786
5926
 
@@ -5808,6 +5948,7 @@ The returned `app` object has these methods:
5808
5948
  | `app.renderShell(shell, opts?)` | Render a component into an existing HTML shell template (your `index.html`) |
5809
5949
 
5810
5950
 
5951
+
5811
5952
  ### Registering Components
5812
5953
 
5813
5954
 
@@ -5862,6 +6003,7 @@ app.component('user-card', {
5862
6003
  > **Validation:** Component names must be non-empty strings and definitions must be objects. Invalid arguments throw a `ZQueryError` with code `ZQ_SSR_COMPONENT`.
5863
6004
 
5864
6005
 
6006
+
5865
6007
  ### renderToString()
5866
6008
 
5867
6009
 
@@ -5905,6 +6047,7 @@ const html = renderToString({
5905
6047
  ```
5906
6048
 
5907
6049
 
6050
+
5908
6051
  ### renderPage()
5909
6052
 
5910
6053
 
@@ -5952,6 +6095,7 @@ res.send(page);
5952
6095
  | `head.og` | object | Open Graph `` tags — any key/value pairs |
5953
6096
 
5954
6097
 
6098
+
5955
6099
  ### renderBatch()
5956
6100
 
5957
6101
 
@@ -5978,6 +6122,7 @@ const combined = results.join('\n');
5978
6122
  | `options` | object | Same options as `renderToString` (optional) |
5979
6123
 
5980
6124
 
6125
+
5981
6126
  ### renderShell()
5982
6127
 
5983
6128
 
@@ -6052,6 +6197,7 @@ async function render(pathname) {
6052
6197
  ```
6053
6198
 
6054
6199
 
6200
+
6055
6201
  ### Hydration
6056
6202
 
6057
6203
 
@@ -6070,6 +6216,7 @@ When the client-side app loads, it can detect these markers and take over the ex
6070
6216
  > **Tip:** Set `{ hydrate: false }` in render options for purely static HTML that doesn’t need client-side interactivity (e.g. email templates, static pages, RSS feeds).
6071
6217
 
6072
6218
 
6219
+
6073
6220
  ### Error Handling in SSR
6074
6221
 
6075
6222
 
@@ -6111,6 +6258,7 @@ onError((err) => {
6111
6258
  ```
6112
6259
 
6113
6260
 
6261
+
6114
6262
  ### escapeHtml()
6115
6263
 
6116
6264
 
@@ -6129,6 +6277,7 @@ const safe = escapeHtml('<script>alert("xss")</script>');
6129
6277
  This is the same function used internally by the SSR expression interpolator to prevent XSS in `{{...}}` output.
6130
6278
 
6131
6279
 
6280
+
6132
6281
  ### matchRoute()
6133
6282
 
6134
6283
 
@@ -6172,6 +6321,7 @@ Uses the same matching rules as the client-side router: `:param` segments, `*` w
6172
6321
  zQuery applies defense-in-depth across templates, expressions, state utilities, routing, and SSR. This page summarizes the built-in protections and explains how to keep your app safe.
6173
6322
 
6174
6323
 
6324
+
6175
6325
  ### Overview
6176
6326
 
6177
6327
 
@@ -6185,6 +6335,7 @@ zQuery applies defense-in-depth across templates, expressions, state utilities,
6185
6335
  | `z-html` | Inserts raw HTML — only use with trusted content |
6186
6336
 
6187
6337
 
6338
+
6188
6339
  ### Template Expression Escaping
6189
6340
 
6190
6341
 
@@ -6212,6 +6363,7 @@ state.name = '<img src=x onerror=alert(1)>';
6212
6363
  > Both `{{expression}}` and `z-text` are XSS-safe. Only `z-html` inserts raw HTML.
6213
6364
 
6214
6365
 
6366
+
6215
6367
  ### z-html & Trusted HTML
6216
6368
 
6217
6369
 
@@ -6237,6 +6389,7 @@ The `z-html` directive sets `innerHTML` directly — equivalent to Vue’s `v-ht
6237
6389
  > **Tip:** If you need to render user HTML, sanitize it server-side (e.g. with DOMPurify) before storing it. Then use `z-html` only on the sanitized output.
6238
6390
 
6239
6391
 
6392
+
6240
6393
  ### Expression Sandbox
6241
6394
 
6242
6395
 
@@ -6273,6 +6426,7 @@ encodeURIComponent, decodeURIComponent
6273
6426
  > **Tip:** The sandbox also blocks property access to `__defineGetter__` and other internal properties. If an expression tries to access a blocked identifier or property, it silently returns `undefined`.
6274
6427
 
6275
6428
 
6429
+
6276
6430
  ### Prototype Pollution Prevention
6277
6431
 
6278
6432
 
@@ -6300,6 +6454,7 @@ $.setPath({}, 'user.name', 'Alice'); // { user: { name: 'Alice' } } ✓
6300
6454
  > **Why this matters:** If your app merges untrusted JSON (e.g. from an API or user input) into state objects, prototype pollution could inject properties onto `Object.prototype`, affecting every object in the application. The blocked-key guard prevents this attack vector.
6301
6455
 
6302
6456
 
6457
+
6303
6458
  ### Route Link Validation
6304
6459
 
6305
6460
 
@@ -6319,9 +6474,10 @@ The `z-link` click handler rejects any value that looks like a protocol scheme.
6319
6474
  ```
6320
6475
 
6321
6476
 
6322
- > **Tip:** For external links, use a regular `` tag. `z-link` is designed exclusively for SPA route navigation.
6477
+ > **Tip:** For external links, use a regular `[` tag. `z-link` is designed exclusively for SPA route navigation.
6323
6478
 
6324
6479
 
6480
+ ](https://...)
6325
6481
  ### SSR Error Sanitization
6326
6482
 
6327
6483
 
@@ -6349,6 +6505,7 @@ The actual error details (message, stack trace, file paths) are reported via `$.
6349
6505
  | XSS via title / description / OG values | All injected text is HTML-escaped via `escapeHtml()` |
6350
6506
 
6351
6507
 
6508
+
6352
6509
  ### Best Practices
6353
6510
 
6354
6511
 
@@ -6453,6 +6610,7 @@ zQuery’s SSR already strips error details from HTML output. Apply the same pri
6453
6610
  > **Tip:** Following these practices plus the built-in protections gives you a strong defense-in-depth posture. The library handles the framework layer so you can focus on application-level validation.
6454
6611
 
6455
6612
 
6613
+
6456
6614
  ### Quick Reference
6457
6615
 
6458
6616
 
@@ -6475,6 +6633,7 @@ zQuery’s SSR already strips error details from HTML output. Apply the same pri
6475
6633
  zQuery exposes runtime environment properties on the global `$` object for Electron, browser, and Node.js detection. These are set once at initialization and are read-only.
6476
6634
 
6477
6635
 
6636
+
6478
6637
  ### Environment Properties
6479
6638
 
6480
6639
 
@@ -6491,6 +6650,7 @@ console.log($.platform); // 'electron', 'browser', or 'node'
6491
6650
  ```
6492
6651
 
6493
6652
 
6653
+
6494
6654
  ### Platform Detection
6495
6655
 
6496
6656
 
@@ -6524,6 +6684,7 @@ const API_BASE = $.platform === 'electron'
6524
6684
  > **Tip:** These properties are available immediately — no async detection or initialization needed. They are set when zQuery loads.
6525
6685
 
6526
6686
 
6687
+
6527
6688
  ### Quick Reference
6528
6689
 
6529
6690
 
@@ -6540,6 +6701,7 @@ const API_BASE = $.platform === 'electron'
6540
6701
  zQuery ships a complete WebRTC client that speaks the wire protocol of `@zero-server/webrtc` — from a low-level `SignalingClient` + perfect-negotiation `Peer` up to a reactive multi-peer `Room` with composables, TURN credential rotation, SFrame end-to-end encryption, mediasoup & LiveKit SFU adapters, join-token decoding, and `getStats()` observability. The `z-stream` directive binds remote `MediaStream`s straight to `` / `` elements — no `URL.createObjectURL` dance.
6541
6702
 
6542
6703
 
6704
+
6543
6705
  ### Overview
6544
6706
 
6545
6707
 
@@ -6558,6 +6720,7 @@ The WebRTC surface is layered — pick the level you need:
6558
6720
  > **Tip:** Want a working starting point? Run `npx zero-query create my-app --webrtc-demo` (alias `-w`) to scaffold a one-page video room with mic / camera / screen-share toggles, a reactive roster, and a chat data channel. The scaffold installs [zero-server](https://github.com/tonywied17/zero-server), launches the signaling + static server on `http://localhost:3000`, and opens your browser - one command, no extra setup. Camera and microphone stay off until the user opts in.
6559
6721
 
6560
6722
 
6723
+
6561
6724
  ### Surface Status
6562
6725
 
6563
6726
 
@@ -6581,6 +6744,7 @@ Everything in the table below is shipping today. Green dots mean stable + tested
6581
6744
  | `WebRtcError` family (Signaling / Ice / Sdp / Turn / E2ee / Sfu) | Shipping | Stable string codes; flows through `$.onError` |
6582
6745
 
6583
6746
 
6747
+
6584
6748
  ### Quick Start
6585
6749
 
6586
6750
 
@@ -6623,6 +6787,7 @@ $.component('video-room', {
6623
6787
  > **Tip:** `$.webrtc.join()` is the one-liner that bundles `new SignalingClient(…)` + `connect()` + `send('join')` + `Room` wiring. Use it whenever you don't need raw control of the JSEP loop.
6624
6788
 
6625
6789
 
6790
+
6626
6791
  ### SignalingClient
6627
6792
 
6628
6793
 
@@ -6671,6 +6836,7 @@ client.close();
6671
6836
  > All signaling errors derive from `SignalingError`: `ZQ_WEBRTC_SIGNALING_BAD_URL`, `ZQ_WEBRTC_SIGNALING_BAD_HANDSHAKE`, `ZQ_WEBRTC_SIGNALING_BAD_FRAME`, `ZQ_WEBRTC_SIGNALING_NOT_CONNECTED`, `ZQ_WEBRTC_SIGNALING_CLOSED`.
6672
6837
 
6673
6838
 
6839
+
6674
6840
  ### Peer (Perfect Negotiation)
6675
6841
 
6676
6842
 
@@ -6724,6 +6890,7 @@ signaling.on('peer-left', ({ id }) => peers.get(id)?.close());
6724
6890
  > **Tip:** mDNS (`*.local`) candidates are filtered before send, and trickled candidates are capped per-peer so we stay inside the server's `a=candidate:` ceiling.
6725
6891
 
6726
6892
 
6893
+
6727
6894
  ### Room
6728
6895
 
6729
6896
 
@@ -6770,6 +6937,7 @@ await room.leave();
6770
6937
  | `room.leave()` | `Promise` | Send `leave`, close every peer and the socket. Idempotent |
6771
6938
 
6772
6939
 
6940
+
6773
6941
  ### Reactive Composables
6774
6942
 
6775
6943
 
@@ -6821,6 +6989,7 @@ quality.dispose();
6821
6989
  > **Warning:** Forgetting `dispose()` on unmount leaks getStats intervals and signal subscriptions — `useConnectionQuality` in particular keeps a 2-second timer alive until disposed.
6822
6990
 
6823
6991
 
6992
+
6824
6993
  ### z-stream Directive
6825
6994
 
6826
6995
 
@@ -6845,6 +7014,7 @@ tile.instance.state.stream = peerInfo.stream;
6845
7014
  > **Tip:** `z-stream` tolerates plain `MediaStream`s, anything with `.stream`, or any object that exposes `getTracks()`. Reassign the expression to `null` to detach without removing the element.
6846
7015
 
6847
7016
 
7017
+
6848
7018
  ### TURN Credentials
6849
7019
 
6850
7020
 
@@ -6890,6 +7060,7 @@ turn.stop(); // cancel timer on unmount
6890
7060
  > All TURN errors derive from `TurnError`: `ZQ_WEBRTC_TURN_BAD_URL`, `ZQ_WEBRTC_TURN_NO_FETCH`, `ZQ_WEBRTC_TURN_NETWORK`, `ZQ_WEBRTC_TURN_HTTP`, `ZQ_WEBRTC_TURN_BAD_JSON`, `ZQ_WEBRTC_TURN_BAD_BODY`.
6891
7061
 
6892
7062
 
7063
+
6893
7064
  ### End-to-End Encryption (SFrame)
6894
7065
 
6895
7066
 
@@ -6935,6 +7106,7 @@ import { deriveSFrameKey, SFrameContext, attachE2ee, join } from 'zero-query/web
6935
7106
  > All E2EE errors derive from `E2eeError`: `ZQ_WEBRTC_E2EE_NO_WEBCRYPTO`, `ZQ_WEBRTC_E2EE_NO_RANDOM`, `ZQ_WEBRTC_E2EE_BAD_PASSPHRASE`, `ZQ_WEBRTC_E2EE_BAD_SALT`, `ZQ_WEBRTC_E2EE_BAD_INPUT`, `ZQ_WEBRTC_E2EE_BAD_CTX`, `ZQ_WEBRTC_E2EE_NO_KEY`, `ZQ_WEBRTC_E2EE_SHORT_FRAME`, `ZQ_WEBRTC_E2EE_UNKNOWN_EPOCH`, `ZQ_WEBRTC_E2EE_AUTH_FAILED`.
6936
7107
 
6937
7108
 
7109
+
6938
7110
  ### SFU Adapters
6939
7111
 
6940
7112
 
@@ -6971,6 +7143,7 @@ import { loadSfuAdapter } from 'zero-query/webrtc';
6971
7143
  > All SFU errors derive from `SfuError`: `ZQ_WEBRTC_SFU_UNKNOWN`, `ZQ_WEBRTC_SFU_PEER_MISSING`, `ZQ_WEBRTC_SFU_BAD_MODULE`, `ZQ_WEBRTC_SFU_DEVICE_FAILED`, `ZQ_WEBRTC_SFU_ROOM_FAILED`, `ZQ_WEBRTC_SFU_BAD_RTP_CAPS`, `ZQ_WEBRTC_SFU_BAD_URL`, `ZQ_WEBRTC_SFU_BAD_TOKEN`, `ZQ_WEBRTC_SFU_LOAD_FAILED`, `ZQ_WEBRTC_SFU_CONNECT_FAILED`, `ZQ_WEBRTC_SFU_NOT_LOADED`, `ZQ_WEBRTC_SFU_JOIN_UNAVAILABLE`.
6972
7144
 
6973
7145
 
7146
+
6974
7147
  ### Join Tokens
6975
7148
 
6976
7149
 
@@ -7002,6 +7175,7 @@ import { decodeJoinToken, isJoinTokenExpired } from 'zero-query';
7002
7175
  > Errors derive from `WebRtcError`: `ZQ_WEBRTC_TOKEN_BAD_INPUT`, `ZQ_WEBRTC_TOKEN_BAD_SHAPE`, `ZQ_WEBRTC_TOKEN_BAD_PAYLOAD`.
7003
7176
 
7004
7177
 
7178
+
7005
7179
  ### Observability (getStats)
7006
7180
 
7007
7181
 
@@ -7039,6 +7213,7 @@ import { samplePeerStats, createStatsSampler, classifyStats } from 'zero-query';
7039
7213
  > Errors derive from `WebRtcError`: `ZQ_WEBRTC_OBSERVE_BAD_PC`, `ZQ_WEBRTC_OBSERVE_GETSTATS_FAILED`.
7040
7214
 
7041
7215
 
7216
+
7042
7217
  ### SDP + ICE Helpers
7043
7218
 
7044
7219
 
@@ -7083,6 +7258,7 @@ if (isMdnsHostname(c.address)) console.log('mDNS - skip');
7083
7258
  | `isPrivateIp / isLoopbackIp / isLinkLocalIp / isMdnsHostname` | `boolean` | — |
7084
7259
 
7085
7260
 
7261
+
7086
7262
  ### Error Family
7087
7263
 
7088
7264
 
@@ -7121,6 +7297,7 @@ try {
7121
7297
  > **Tip:** Use `$.onError(handler)` to centralize WebRTC error reporting alongside HTTP / router / component errors. Every WebRTC error code starts with `ZQ_WEBRTC_` so a single prefix check picks them all out.
7122
7298
 
7123
7299
 
7300
+
7124
7301
  ### Wire Protocol
7125
7302
 
7126
7303