zero-query 1.1.1 → 1.2.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 (154) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +2 -0
  3. package/cli/args.js +33 -33
  4. package/cli/commands/build-api.js +443 -442
  5. package/cli/commands/build.js +254 -247
  6. package/cli/commands/bundle.js +1228 -1224
  7. package/cli/commands/create.js +137 -121
  8. package/cli/commands/dev/devtools/index.js +56 -56
  9. package/cli/commands/dev/devtools/js/components.js +49 -49
  10. package/cli/commands/dev/devtools/js/core.js +423 -423
  11. package/cli/commands/dev/devtools/js/elements.js +421 -421
  12. package/cli/commands/dev/devtools/js/network.js +166 -166
  13. package/cli/commands/dev/devtools/js/performance.js +73 -73
  14. package/cli/commands/dev/devtools/js/router.js +105 -105
  15. package/cli/commands/dev/devtools/js/source.js +132 -132
  16. package/cli/commands/dev/devtools/js/stats.js +35 -35
  17. package/cli/commands/dev/devtools/js/tabs.js +79 -79
  18. package/cli/commands/dev/devtools/panel.html +95 -95
  19. package/cli/commands/dev/devtools/styles.css +244 -244
  20. package/cli/commands/dev/index.js +107 -107
  21. package/cli/commands/dev/logger.js +75 -75
  22. package/cli/commands/dev/overlay.js +858 -858
  23. package/cli/commands/dev/server.js +220 -220
  24. package/cli/commands/dev/validator.js +94 -94
  25. package/cli/commands/dev/watcher.js +172 -172
  26. package/cli/help.js +114 -112
  27. package/cli/index.js +52 -52
  28. package/cli/scaffold/default/LICENSE +21 -21
  29. package/cli/scaffold/default/app/app.js +207 -207
  30. package/cli/scaffold/default/app/components/about.js +201 -201
  31. package/cli/scaffold/default/app/components/api-demo.js +143 -143
  32. package/cli/scaffold/default/app/components/contact-card.js +231 -231
  33. package/cli/scaffold/default/app/components/contacts/contacts.css +706 -706
  34. package/cli/scaffold/default/app/components/contacts/contacts.html +200 -200
  35. package/cli/scaffold/default/app/components/contacts/contacts.js +196 -196
  36. package/cli/scaffold/default/app/components/counter.js +127 -127
  37. package/cli/scaffold/default/app/components/home.js +249 -249
  38. package/cli/scaffold/default/app/components/not-found.js +16 -16
  39. package/cli/scaffold/default/app/components/playground/playground.css +115 -115
  40. package/cli/scaffold/default/app/components/playground/playground.html +161 -161
  41. package/cli/scaffold/default/app/components/playground/playground.js +116 -116
  42. package/cli/scaffold/default/app/components/todos.js +225 -225
  43. package/cli/scaffold/default/app/components/toolkit/toolkit.css +97 -97
  44. package/cli/scaffold/default/app/components/toolkit/toolkit.html +146 -146
  45. package/cli/scaffold/default/app/components/toolkit/toolkit.js +280 -280
  46. package/cli/scaffold/default/app/routes.js +15 -15
  47. package/cli/scaffold/default/app/store.js +101 -101
  48. package/cli/scaffold/default/global.css +552 -552
  49. package/cli/scaffold/default/index.html +99 -99
  50. package/cli/scaffold/minimal/app/app.js +85 -85
  51. package/cli/scaffold/minimal/app/components/about.js +68 -68
  52. package/cli/scaffold/minimal/app/components/counter.js +122 -122
  53. package/cli/scaffold/minimal/app/components/home.js +68 -68
  54. package/cli/scaffold/minimal/app/components/not-found.js +16 -16
  55. package/cli/scaffold/minimal/app/routes.js +9 -9
  56. package/cli/scaffold/minimal/app/store.js +36 -36
  57. package/cli/scaffold/minimal/global.css +300 -300
  58. package/cli/scaffold/minimal/index.html +44 -44
  59. package/cli/scaffold/ssr/app/app.js +41 -41
  60. package/cli/scaffold/ssr/app/components/about.js +55 -55
  61. package/cli/scaffold/ssr/app/components/blog/index.js +65 -65
  62. package/cli/scaffold/ssr/app/components/blog/post.js +86 -86
  63. package/cli/scaffold/ssr/app/components/home.js +37 -37
  64. package/cli/scaffold/ssr/app/components/not-found.js +15 -15
  65. package/cli/scaffold/ssr/app/routes.js +8 -8
  66. package/cli/scaffold/ssr/global.css +228 -228
  67. package/cli/scaffold/ssr/index.html +37 -37
  68. package/cli/scaffold/ssr/package.json +8 -8
  69. package/cli/scaffold/ssr/server/data/posts.js +144 -144
  70. package/cli/scaffold/ssr/server/index.js +213 -213
  71. package/cli/scaffold/webrtc/app/app.js +11 -0
  72. package/cli/scaffold/webrtc/app/components/video-room.js +295 -0
  73. package/cli/scaffold/webrtc/app/lib/room.js +252 -0
  74. package/cli/scaffold/webrtc/assets/.gitkeep +0 -0
  75. package/cli/scaffold/webrtc/global.css +250 -0
  76. package/cli/scaffold/webrtc/index.html +21 -0
  77. package/cli/utils.js +305 -287
  78. package/dist/API.md +661 -0
  79. package/dist/zquery.dist.zip +0 -0
  80. package/dist/zquery.js +10313 -6614
  81. package/dist/zquery.min.js +8 -631
  82. package/index.d.ts +570 -371
  83. package/index.js +311 -240
  84. package/package.json +76 -70
  85. package/src/component.js +1709 -1691
  86. package/src/core.js +921 -921
  87. package/src/diff.js +497 -497
  88. package/src/errors.js +209 -209
  89. package/src/expression.js +922 -922
  90. package/src/http.js +242 -242
  91. package/src/package.json +1 -1
  92. package/src/reactive.js +255 -255
  93. package/src/router.js +843 -843
  94. package/src/ssr.js +418 -418
  95. package/src/store.js +318 -318
  96. package/src/utils.js +515 -515
  97. package/src/webrtc/e2ee.js +351 -0
  98. package/src/webrtc/errors.js +116 -0
  99. package/src/webrtc/ice.js +301 -0
  100. package/src/webrtc/index.js +131 -0
  101. package/src/webrtc/joinToken.js +119 -0
  102. package/src/webrtc/observe.js +172 -0
  103. package/src/webrtc/peer.js +351 -0
  104. package/src/webrtc/reactive.js +268 -0
  105. package/src/webrtc/room.js +625 -0
  106. package/src/webrtc/sdp.js +302 -0
  107. package/src/webrtc/sfu/index.js +43 -0
  108. package/src/webrtc/sfu/livekit.js +131 -0
  109. package/src/webrtc/sfu/mediasoup.js +150 -0
  110. package/src/webrtc/signaling.js +373 -0
  111. package/src/webrtc/turn.js +237 -0
  112. package/tests/_helpers/webrtcFakes.js +289 -0
  113. package/tests/audit.test.js +4158 -4158
  114. package/tests/cli.test.js +1136 -1103
  115. package/tests/compare.test.js +497 -486
  116. package/tests/component.test.js +3969 -3938
  117. package/tests/core.test.js +1910 -1910
  118. package/tests/dev-server.test.js +489 -489
  119. package/tests/diff.test.js +1416 -1416
  120. package/tests/docs.test.js +1664 -1650
  121. package/tests/electron-features.test.js +864 -864
  122. package/tests/errors.test.js +619 -619
  123. package/tests/expression.test.js +1056 -1056
  124. package/tests/http.test.js +648 -648
  125. package/tests/reactive.test.js +819 -819
  126. package/tests/router.test.js +2327 -2327
  127. package/tests/ssr.test.js +870 -870
  128. package/tests/store.test.js +830 -830
  129. package/tests/test-minifier.js +153 -153
  130. package/tests/test-ssr.js +27 -27
  131. package/tests/utils.test.js +1377 -1377
  132. package/tests/webrtc/e2ee.test.js +283 -0
  133. package/tests/webrtc/ice.test.js +202 -0
  134. package/tests/webrtc/joinToken.test.js +89 -0
  135. package/tests/webrtc/observe.test.js +111 -0
  136. package/tests/webrtc/peer.test.js +373 -0
  137. package/tests/webrtc/reactive.test.js +235 -0
  138. package/tests/webrtc/room.test.js +406 -0
  139. package/tests/webrtc/sdp.test.js +151 -0
  140. package/tests/webrtc/sfu-livekit.test.js +119 -0
  141. package/tests/webrtc/sfu.test.js +160 -0
  142. package/tests/webrtc/signaling.test.js +251 -0
  143. package/tests/webrtc/turn.test.js +256 -0
  144. package/types/collection.d.ts +383 -383
  145. package/types/component.d.ts +186 -186
  146. package/types/errors.d.ts +135 -135
  147. package/types/http.d.ts +92 -92
  148. package/types/misc.d.ts +201 -201
  149. package/types/reactive.d.ts +98 -98
  150. package/types/router.d.ts +190 -190
  151. package/types/ssr.d.ts +102 -102
  152. package/types/store.d.ts +146 -146
  153. package/types/utils.d.ts +245 -245
  154. package/types/webrtc.d.ts +653 -0
package/types/http.d.ts CHANGED
@@ -1,92 +1,92 @@
1
- /**
2
- * HTTP Client - fetch-based wrapper with interceptors and auto-JSON.
3
- *
4
- * @module http
5
- */
6
-
7
- /** The response object resolved by all HTTP request methods (except `raw`). */
8
- export interface HttpResponse<T = any> {
9
- /** `true` if status 200-299. */
10
- ok: boolean;
11
- /** HTTP status code. */
12
- status: number;
13
- /** HTTP status text. */
14
- statusText: string;
15
- /** Response headers as a plain object. */
16
- headers: Record<string, string>;
17
- /** Auto-parsed body (JSON, text, or Blob depending on content type). */
18
- data: T;
19
- /** Raw `fetch` Response object. */
20
- response: Response;
21
- }
22
-
23
- /** Per-request options passed to HTTP methods. */
24
- export interface HttpRequestOptions extends Omit<RequestInit, 'body' | 'method'> {
25
- /** Additional headers (merged with defaults). */
26
- headers?: Record<string, string>;
27
- /** Override default timeout (ms). */
28
- timeout?: number;
29
- /** Abort signal for cancellation. */
30
- signal?: AbortSignal;
31
- }
32
-
33
- /** Global HTTP configuration options. */
34
- export interface HttpConfigureOptions {
35
- /** Prepended to non-absolute URLs. */
36
- baseURL?: string;
37
- /** Default headers (merged, not replaced). */
38
- headers?: Record<string, string>;
39
- /** Default timeout in ms (default 30 000). Set `0` to disable. */
40
- timeout?: number;
41
- }
42
-
43
- /** Request interceptor function. */
44
- export type HttpRequestInterceptor = (
45
- fetchOpts: RequestInit & { headers: Record<string, string> },
46
- url: string,
47
- ) => void | false | { url?: string; options?: RequestInit } | Promise<void | false | { url?: string; options?: RequestInit }>;
48
-
49
- /** Response interceptor function. */
50
- export type HttpResponseInterceptor = (result: HttpResponse) => void | Promise<void>;
51
-
52
- /** The `$.http` namespace. */
53
- export interface HttpClient {
54
- /** GET request. `params` appended as query string. */
55
- get<T = any>(url: string, params?: Record<string, any> | null, opts?: HttpRequestOptions): Promise<HttpResponse<T>>;
56
- /** POST request. `data` sent as JSON body (or FormData). */
57
- post<T = any>(url: string, data?: any, opts?: HttpRequestOptions): Promise<HttpResponse<T>>;
58
- /** PUT request. */
59
- put<T = any>(url: string, data?: any, opts?: HttpRequestOptions): Promise<HttpResponse<T>>;
60
- /** PATCH request. */
61
- patch<T = any>(url: string, data?: any, opts?: HttpRequestOptions): Promise<HttpResponse<T>>;
62
- /** DELETE request. */
63
- delete<T = any>(url: string, data?: any, opts?: HttpRequestOptions): Promise<HttpResponse<T>>;
64
- /** HEAD request - no body, useful for checking resource existence or headers. */
65
- head<T = any>(url: string, opts?: HttpRequestOptions): Promise<HttpResponse<T>>;
66
-
67
- /** Update default configuration for all subsequent requests. */
68
- configure(options: HttpConfigureOptions): void;
69
-
70
- /** Read-only snapshot of the current configuration. Returns a shallow copy. */
71
- getConfig(): { baseURL: string; headers: Record<string, string>; timeout: number };
72
-
73
- /** Add a request interceptor (called before every request). Returns an unsubscribe function. */
74
- onRequest(fn: HttpRequestInterceptor): () => void;
75
-
76
- /** Add a response interceptor (called after every response, before error check). Returns an unsubscribe function. */
77
- onResponse(fn: HttpResponseInterceptor): () => void;
78
-
79
- /** Clear interceptors. No args = all; `'request'` or `'response'` for one type. */
80
- clearInterceptors(type?: 'request' | 'response'): void;
81
-
82
- /** Run multiple request promises in parallel via `Promise.all`. */
83
- all<T extends readonly Promise<HttpResponse<any>>[]>(requests: T): Promise<{ -readonly [K in keyof T]: Awaited<T[K]> }>;
84
-
85
- /** Create a new `AbortController` for manual request cancellation. */
86
- createAbort(): AbortController;
87
-
88
- /** Direct passthrough to native `fetch()` - no JSON handling, no interceptors. */
89
- raw(url: string, opts?: RequestInit): Promise<Response>;
90
- }
91
-
92
- export declare const http: HttpClient;
1
+ /**
2
+ * HTTP Client - fetch-based wrapper with interceptors and auto-JSON.
3
+ *
4
+ * @module http
5
+ */
6
+
7
+ /** The response object resolved by all HTTP request methods (except `raw`). */
8
+ export interface HttpResponse<T = any> {
9
+ /** `true` if status 200-299. */
10
+ ok: boolean;
11
+ /** HTTP status code. */
12
+ status: number;
13
+ /** HTTP status text. */
14
+ statusText: string;
15
+ /** Response headers as a plain object. */
16
+ headers: Record<string, string>;
17
+ /** Auto-parsed body (JSON, text, or Blob depending on content type). */
18
+ data: T;
19
+ /** Raw `fetch` Response object. */
20
+ response: Response;
21
+ }
22
+
23
+ /** Per-request options passed to HTTP methods. */
24
+ export interface HttpRequestOptions extends Omit<RequestInit, 'body' | 'method'> {
25
+ /** Additional headers (merged with defaults). */
26
+ headers?: Record<string, string>;
27
+ /** Override default timeout (ms). */
28
+ timeout?: number;
29
+ /** Abort signal for cancellation. */
30
+ signal?: AbortSignal;
31
+ }
32
+
33
+ /** Global HTTP configuration options. */
34
+ export interface HttpConfigureOptions {
35
+ /** Prepended to non-absolute URLs. */
36
+ baseURL?: string;
37
+ /** Default headers (merged, not replaced). */
38
+ headers?: Record<string, string>;
39
+ /** Default timeout in ms (default 30 000). Set `0` to disable. */
40
+ timeout?: number;
41
+ }
42
+
43
+ /** Request interceptor function. */
44
+ export type HttpRequestInterceptor = (
45
+ fetchOpts: RequestInit & { headers: Record<string, string> },
46
+ url: string,
47
+ ) => void | false | { url?: string; options?: RequestInit } | Promise<void | false | { url?: string; options?: RequestInit }>;
48
+
49
+ /** Response interceptor function. */
50
+ export type HttpResponseInterceptor = (result: HttpResponse) => void | Promise<void>;
51
+
52
+ /** The `$.http` namespace. */
53
+ export interface HttpClient {
54
+ /** GET request. `params` appended as query string. */
55
+ get<T = any>(url: string, params?: Record<string, any> | null, opts?: HttpRequestOptions): Promise<HttpResponse<T>>;
56
+ /** POST request. `data` sent as JSON body (or FormData). */
57
+ post<T = any>(url: string, data?: any, opts?: HttpRequestOptions): Promise<HttpResponse<T>>;
58
+ /** PUT request. */
59
+ put<T = any>(url: string, data?: any, opts?: HttpRequestOptions): Promise<HttpResponse<T>>;
60
+ /** PATCH request. */
61
+ patch<T = any>(url: string, data?: any, opts?: HttpRequestOptions): Promise<HttpResponse<T>>;
62
+ /** DELETE request. */
63
+ delete<T = any>(url: string, data?: any, opts?: HttpRequestOptions): Promise<HttpResponse<T>>;
64
+ /** HEAD request - no body, useful for checking resource existence or headers. */
65
+ head<T = any>(url: string, opts?: HttpRequestOptions): Promise<HttpResponse<T>>;
66
+
67
+ /** Update default configuration for all subsequent requests. */
68
+ configure(options: HttpConfigureOptions): void;
69
+
70
+ /** Read-only snapshot of the current configuration. Returns a shallow copy. */
71
+ getConfig(): { baseURL: string; headers: Record<string, string>; timeout: number };
72
+
73
+ /** Add a request interceptor (called before every request). Returns an unsubscribe function. */
74
+ onRequest(fn: HttpRequestInterceptor): () => void;
75
+
76
+ /** Add a response interceptor (called after every response, before error check). Returns an unsubscribe function. */
77
+ onResponse(fn: HttpResponseInterceptor): () => void;
78
+
79
+ /** Clear interceptors. No args = all; `'request'` or `'response'` for one type. */
80
+ clearInterceptors(type?: 'request' | 'response'): void;
81
+
82
+ /** Run multiple request promises in parallel via `Promise.all`. */
83
+ all<T extends readonly Promise<HttpResponse<any>>[]>(requests: T): Promise<{ -readonly [K in keyof T]: Awaited<T[K]> }>;
84
+
85
+ /** Create a new `AbortController` for manual request cancellation. */
86
+ createAbort(): AbortController;
87
+
88
+ /** Direct passthrough to native `fetch()` - no JSON handling, no interceptors. */
89
+ raw(url: string, opts?: RequestInit): Promise<Response>;
90
+ }
91
+
92
+ export declare const http: HttpClient;
package/types/misc.d.ts CHANGED
@@ -1,201 +1,201 @@
1
- /**
2
- * DOM diffing, safe expression evaluator, and directive metadata.
3
- *
4
- * @module misc
5
- */
6
-
7
- // ---------------------------------------------------------------------------
8
- // DOM Diffing (Morphing)
9
- // ---------------------------------------------------------------------------
10
-
11
- /**
12
- * Morph an existing DOM element's children to match new HTML.
13
- * Only touches nodes that actually differ - preserves focus, scroll
14
- * positions, video playback, and other live DOM state.
15
- *
16
- * Use `z-key="uniqueId"` attributes on list items for keyed reconciliation.
17
- * Elements with `id`, `data-id`, or `data-key` attributes are auto-keyed.
18
- *
19
- * @param rootEl The live DOM container to patch.
20
- * @param newHTML The desired HTML string.
21
- */
22
- export function morph(rootEl: Element, newHTML: string): void;
23
-
24
- /**
25
- * Morph a single element in place - diffs attributes and children
26
- * without replacing the node reference. If the tag name matches, the
27
- * element is patched in place (preserving identity). If the tag differs,
28
- * the element is replaced.
29
- *
30
- * @param oldEl The live DOM element to patch.
31
- * @param newHTML HTML string for the replacement element.
32
- * @returns The resulting element (same ref if morphed, new if replaced).
33
- */
34
- export function morphElement(oldEl: Element, newHTML: string): Element;
35
-
36
- // ---------------------------------------------------------------------------
37
- // Safe Expression Evaluator
38
- // ---------------------------------------------------------------------------
39
-
40
- /**
41
- * CSP-safe expression evaluator. Parses and evaluates JS expressions
42
- * without `eval()` or `new Function()`. Used internally by directives.
43
- *
44
- * @param expr Expression string.
45
- * @param scope Array of scope objects checked in order for identifier resolution.
46
- * @returns Evaluation result, or `undefined` on error.
47
- */
48
- export function safeEval(expr: string, scope: object[]): any;
49
-
50
- // ---------------------------------------------------------------------------
51
- // Directive System
52
- // ---------------------------------------------------------------------------
53
- //
54
- // Directives are special attributes processed by zQuery's component renderer.
55
- // They work in both `render()` template literals and external `templateUrl`
56
- // HTML files. All expressions evaluate in the component's state context
57
- // (bare names resolve to `this.state.*`; `props` and `refs` also available).
58
- //
59
- // --- Structural Directives ----------------------------------------------
60
- //
61
- // z-if="expression" Conditional rendering - element removed when falsy.
62
- // z-else-if="expression" Else-if branch (must be immediate sibling of z-if).
63
- // z-else Default branch (must follow z-if or z-else-if).
64
- //
65
- // z-for="item in items" List rendering - repeats the element per item.
66
- // {{item.prop}} Use double-brace interpolation for item data.
67
- // (item, index) in items Destructured index support.
68
- // n in 5 Number range → [1, 2, 3, 4, 5].
69
- // (val, key) in object Object iteration → {key, value} entries.
70
- //
71
- // z-key="uniqueId" Keyed reconciliation for list items.
72
- // Preserves DOM nodes across reorders. Use inside
73
- // z-for to give each item a stable identity.
74
- // Example: <li z-for="item in items" z-key="{{item.id}}">
75
- //
76
- // z-show="expression" Toggle `display: none` (element stays in DOM).
77
- //
78
- // --- Attribute Directives -----------------------------------------------
79
- //
80
- // z-bind:attr="expression" Dynamic attribute binding.
81
- // :attr="expression" Shorthand for z-bind:attr.
82
- // false/null/undefined → removes the attribute.
83
- // true → sets empty attribute (e.g. disabled="").
84
- //
85
- // z-class="expression" Dynamic class binding.
86
- // String: space-separated class names.
87
- // Array: list of class names (falsy filtered).
88
- // Object: { className: condition } map.
89
- //
90
- // z-style="expression" Dynamic inline styles.
91
- // String: appended to existing cssText.
92
- // Object: { property: value } map (camelCase keys).
93
- //
94
- // z-html="expression" Set innerHTML from expression (use trusted content only).
95
- // z-text="expression" Set textContent from expression (safe, no HTML).
96
- //
97
- // --- Form & Reference Directives ----------------------------------------
98
- //
99
- // z-model="stateKey" Two-way binding for form elements.
100
- // Supports: input, textarea, select, select[multiple], contenteditable.
101
- // Nested keys: z-model="user.name" → this.state.user.name.
102
- // Modifiers (boolean attributes on same element):
103
- // z-lazy - update on 'change' instead of 'input' (update on blur).
104
- // z-trim - auto .trim() whitespace before writing to state.
105
- // z-number - force Number() conversion regardless of input type.
106
- //
107
- // z-ref="name" Element reference → this.refs.name.
108
- //
109
- // --- Event Directives ---------------------------------------------------
110
- //
111
- // @event="method" Event binding with delegation (shorthand).
112
- // z-on:event="method" Event binding with delegation (full syntax).
113
- // @event="method(args)" Pass arguments: strings, numbers, booleans,
114
- // null, $event, state.key references.
115
- //
116
- // Event Modifiers (chainable with dots):
117
- // .prevent event.preventDefault()
118
- // .stop event.stopPropagation()
119
- // .self Only fire if event.target === element itself.
120
- // .once Handler fires at most once per element.
121
- // .capture addEventListener with { capture: true }.
122
- // .passive addEventListener with { passive: true }.
123
- // .debounce.{ms} Debounce: delay until {ms}ms idle (default 250).
124
- // .throttle.{ms} Throttle: invoke at most once per {ms}ms (default 250).
125
- //
126
- // --- Special Directives -------------------------------------------------
127
- //
128
- // z-cloak Hidden until rendered (auto-removed after mount).
129
- // Global CSS: [z-cloak] { display: none !important }.
130
- // Also injects: *, *::before, *::after { -webkit-tap-highlight-color: transparent }.
131
- //
132
- // z-pre Skip all directive processing for this element
133
- // and its descendants.
134
- //
135
- // --- Slot System --------------------------------------------------------
136
- //
137
- // <slot> Default slot - replaced with child content
138
- // passed by the parent component.
139
- // <slot name="header"> Named slot - replaced with child content that
140
- // has a matching slot="header" attribute.
141
- // <slot>fallback</slot> Fallback content shown when no slot content provided.
142
- //
143
- // Parent usage:
144
- // <my-component>
145
- // <h1 slot="header">Title</h1> (→ named slot "header")
146
- // <p>Body text</p> (→ default slot)
147
- // </my-component>
148
- //
149
- // --- Processing Order ---------------------------------------------------
150
- //
151
- // 1. z-for (pre-innerHTML expansion)
152
- // 2. z-if chain (DOM removal)
153
- // 3. z-show (display toggle)
154
- // 4. z-bind / : (dynamic attributes)
155
- // 5. z-class (dynamic classes)
156
- // 6. z-style (dynamic styles)
157
- // 7. z-html/text (content injection)
158
- // 8. @/z-on (event binding)
159
- // 9. z-ref (element references)
160
- // 10. z-model (two-way binding)
161
- // 11. z-cloak (attribute removal)
162
- //
163
- // ---------------------------------------------------------------------------
164
-
165
- /**
166
- * Supported event modifier strings for `@event` and `z-on:event` bindings.
167
- * Modifiers are appended to the event name with dots, e.g. `@click.prevent.stop`.
168
- *
169
- * **Key modifiers** — named shortcuts (`.enter`, `.escape`, `.tab`, `.space`,
170
- * `.delete`, `.up`, `.down`, `.left`, `.right`) plus any arbitrary key matched
171
- * case-insensitively against `KeyboardEvent.key` (e.g. `.a`, `.f1`, `.+`).
172
- *
173
- * **System modifiers** — `.ctrl`, `.shift`, `.alt`, `.meta` require the
174
- * corresponding modifier key to be held.
175
- */
176
- export type EventModifier =
177
- | 'prevent'
178
- | 'stop'
179
- | 'self'
180
- | 'once'
181
- | 'outside'
182
- | 'capture'
183
- | 'passive'
184
- | `debounce`
185
- | `debounce.${number}`
186
- | `throttle`
187
- | `throttle.${number}`
188
- | 'enter'
189
- | 'escape'
190
- | 'tab'
191
- | 'space'
192
- | 'delete'
193
- | 'up'
194
- | 'down'
195
- | 'left'
196
- | 'right'
197
- | 'ctrl'
198
- | 'shift'
199
- | 'alt'
200
- | 'meta'
201
- | (string & {});
1
+ /**
2
+ * DOM diffing, safe expression evaluator, and directive metadata.
3
+ *
4
+ * @module misc
5
+ */
6
+
7
+ // ---------------------------------------------------------------------------
8
+ // DOM Diffing (Morphing)
9
+ // ---------------------------------------------------------------------------
10
+
11
+ /**
12
+ * Morph an existing DOM element's children to match new HTML.
13
+ * Only touches nodes that actually differ - preserves focus, scroll
14
+ * positions, video playback, and other live DOM state.
15
+ *
16
+ * Use `z-key="uniqueId"` attributes on list items for keyed reconciliation.
17
+ * Elements with `id`, `data-id`, or `data-key` attributes are auto-keyed.
18
+ *
19
+ * @param rootEl The live DOM container to patch.
20
+ * @param newHTML The desired HTML string.
21
+ */
22
+ export function morph(rootEl: Element, newHTML: string): void;
23
+
24
+ /**
25
+ * Morph a single element in place - diffs attributes and children
26
+ * without replacing the node reference. If the tag name matches, the
27
+ * element is patched in place (preserving identity). If the tag differs,
28
+ * the element is replaced.
29
+ *
30
+ * @param oldEl The live DOM element to patch.
31
+ * @param newHTML HTML string for the replacement element.
32
+ * @returns The resulting element (same ref if morphed, new if replaced).
33
+ */
34
+ export function morphElement(oldEl: Element, newHTML: string): Element;
35
+
36
+ // ---------------------------------------------------------------------------
37
+ // Safe Expression Evaluator
38
+ // ---------------------------------------------------------------------------
39
+
40
+ /**
41
+ * CSP-safe expression evaluator. Parses and evaluates JS expressions
42
+ * without `eval()` or `new Function()`. Used internally by directives.
43
+ *
44
+ * @param expr Expression string.
45
+ * @param scope Array of scope objects checked in order for identifier resolution.
46
+ * @returns Evaluation result, or `undefined` on error.
47
+ */
48
+ export function safeEval(expr: string, scope: object[]): any;
49
+
50
+ // ---------------------------------------------------------------------------
51
+ // Directive System
52
+ // ---------------------------------------------------------------------------
53
+ //
54
+ // Directives are special attributes processed by zQuery's component renderer.
55
+ // They work in both `render()` template literals and external `templateUrl`
56
+ // HTML files. All expressions evaluate in the component's state context
57
+ // (bare names resolve to `this.state.*`; `props` and `refs` also available).
58
+ //
59
+ // --- Structural Directives ----------------------------------------------
60
+ //
61
+ // z-if="expression" Conditional rendering - element removed when falsy.
62
+ // z-else-if="expression" Else-if branch (must be immediate sibling of z-if).
63
+ // z-else Default branch (must follow z-if or z-else-if).
64
+ //
65
+ // z-for="item in items" List rendering - repeats the element per item.
66
+ // {{item.prop}} Use double-brace interpolation for item data.
67
+ // (item, index) in items Destructured index support.
68
+ // n in 5 Number range → [1, 2, 3, 4, 5].
69
+ // (val, key) in object Object iteration → {key, value} entries.
70
+ //
71
+ // z-key="uniqueId" Keyed reconciliation for list items.
72
+ // Preserves DOM nodes across reorders. Use inside
73
+ // z-for to give each item a stable identity.
74
+ // Example: <li z-for="item in items" z-key="{{item.id}}">
75
+ //
76
+ // z-show="expression" Toggle `display: none` (element stays in DOM).
77
+ //
78
+ // --- Attribute Directives -----------------------------------------------
79
+ //
80
+ // z-bind:attr="expression" Dynamic attribute binding.
81
+ // :attr="expression" Shorthand for z-bind:attr.
82
+ // false/null/undefined → removes the attribute.
83
+ // true → sets empty attribute (e.g. disabled="").
84
+ //
85
+ // z-class="expression" Dynamic class binding.
86
+ // String: space-separated class names.
87
+ // Array: list of class names (falsy filtered).
88
+ // Object: { className: condition } map.
89
+ //
90
+ // z-style="expression" Dynamic inline styles.
91
+ // String: appended to existing cssText.
92
+ // Object: { property: value } map (camelCase keys).
93
+ //
94
+ // z-html="expression" Set innerHTML from expression (use trusted content only).
95
+ // z-text="expression" Set textContent from expression (safe, no HTML).
96
+ //
97
+ // --- Form & Reference Directives ----------------------------------------
98
+ //
99
+ // z-model="stateKey" Two-way binding for form elements.
100
+ // Supports: input, textarea, select, select[multiple], contenteditable.
101
+ // Nested keys: z-model="user.name" → this.state.user.name.
102
+ // Modifiers (boolean attributes on same element):
103
+ // z-lazy - update on 'change' instead of 'input' (update on blur).
104
+ // z-trim - auto .trim() whitespace before writing to state.
105
+ // z-number - force Number() conversion regardless of input type.
106
+ //
107
+ // z-ref="name" Element reference → this.refs.name.
108
+ //
109
+ // --- Event Directives ---------------------------------------------------
110
+ //
111
+ // @event="method" Event binding with delegation (shorthand).
112
+ // z-on:event="method" Event binding with delegation (full syntax).
113
+ // @event="method(args)" Pass arguments: strings, numbers, booleans,
114
+ // null, $event, state.key references.
115
+ //
116
+ // Event Modifiers (chainable with dots):
117
+ // .prevent event.preventDefault()
118
+ // .stop event.stopPropagation()
119
+ // .self Only fire if event.target === element itself.
120
+ // .once Handler fires at most once per element.
121
+ // .capture addEventListener with { capture: true }.
122
+ // .passive addEventListener with { passive: true }.
123
+ // .debounce.{ms} Debounce: delay until {ms}ms idle (default 250).
124
+ // .throttle.{ms} Throttle: invoke at most once per {ms}ms (default 250).
125
+ //
126
+ // --- Special Directives -------------------------------------------------
127
+ //
128
+ // z-cloak Hidden until rendered (auto-removed after mount).
129
+ // Global CSS: [z-cloak] { display: none !important }.
130
+ // Also injects: *, *::before, *::after { -webkit-tap-highlight-color: transparent }.
131
+ //
132
+ // z-pre Skip all directive processing for this element
133
+ // and its descendants.
134
+ //
135
+ // --- Slot System --------------------------------------------------------
136
+ //
137
+ // <slot> Default slot - replaced with child content
138
+ // passed by the parent component.
139
+ // <slot name="header"> Named slot - replaced with child content that
140
+ // has a matching slot="header" attribute.
141
+ // <slot>fallback</slot> Fallback content shown when no slot content provided.
142
+ //
143
+ // Parent usage:
144
+ // <my-component>
145
+ // <h1 slot="header">Title</h1> (→ named slot "header")
146
+ // <p>Body text</p> (→ default slot)
147
+ // </my-component>
148
+ //
149
+ // --- Processing Order ---------------------------------------------------
150
+ //
151
+ // 1. z-for (pre-innerHTML expansion)
152
+ // 2. z-if chain (DOM removal)
153
+ // 3. z-show (display toggle)
154
+ // 4. z-bind / : (dynamic attributes)
155
+ // 5. z-class (dynamic classes)
156
+ // 6. z-style (dynamic styles)
157
+ // 7. z-html/text (content injection)
158
+ // 8. @/z-on (event binding)
159
+ // 9. z-ref (element references)
160
+ // 10. z-model (two-way binding)
161
+ // 11. z-cloak (attribute removal)
162
+ //
163
+ // ---------------------------------------------------------------------------
164
+
165
+ /**
166
+ * Supported event modifier strings for `@event` and `z-on:event` bindings.
167
+ * Modifiers are appended to the event name with dots, e.g. `@click.prevent.stop`.
168
+ *
169
+ * **Key modifiers** — named shortcuts (`.enter`, `.escape`, `.tab`, `.space`,
170
+ * `.delete`, `.up`, `.down`, `.left`, `.right`) plus any arbitrary key matched
171
+ * case-insensitively against `KeyboardEvent.key` (e.g. `.a`, `.f1`, `.+`).
172
+ *
173
+ * **System modifiers** — `.ctrl`, `.shift`, `.alt`, `.meta` require the
174
+ * corresponding modifier key to be held.
175
+ */
176
+ export type EventModifier =
177
+ | 'prevent'
178
+ | 'stop'
179
+ | 'self'
180
+ | 'once'
181
+ | 'outside'
182
+ | 'capture'
183
+ | 'passive'
184
+ | `debounce`
185
+ | `debounce.${number}`
186
+ | `throttle`
187
+ | `throttle.${number}`
188
+ | 'enter'
189
+ | 'escape'
190
+ | 'tab'
191
+ | 'space'
192
+ | 'delete'
193
+ | 'up'
194
+ | 'down'
195
+ | 'left'
196
+ | 'right'
197
+ | 'ctrl'
198
+ | 'shift'
199
+ | 'alt'
200
+ | 'meta'
201
+ | (string & {});