sibujs 1.0.3 → 1.0.4

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 (41) hide show
  1. package/LICENSE +21 -21
  2. package/dist/build.cjs +20 -0
  3. package/dist/build.js +1 -1
  4. package/dist/cdn.global.js +4 -4
  5. package/dist/{chunk-MEZVEBPN.js → chunk-32ZISOLJ.js} +22 -0
  6. package/dist/{chunk-7TQKR4PP.js → chunk-AZ3ISID5.js} +4 -0
  7. package/dist/{chunk-3CRQALYP.js → chunk-DKOHBI74.js} +49 -2
  8. package/dist/{chunk-DTCOOBMX.js → chunk-OF7UZIVB.js} +1 -1
  9. package/dist/{chunk-N6IZB6KJ.js → chunk-PBHF5WKN.js} +56 -7
  10. package/dist/{customElement-BKQfbSZQ.d.ts → customElement-yz8uyk-0.d.cts} +52 -6
  11. package/dist/{customElement-BKQfbSZQ.d.cts → customElement-yz8uyk-0.d.ts} +52 -6
  12. package/dist/extras.cjs +111 -9
  13. package/dist/extras.d.cts +3 -2
  14. package/dist/extras.d.ts +3 -2
  15. package/dist/extras.js +9 -5
  16. package/dist/index.cjs +22 -0
  17. package/dist/index.d.cts +27 -2
  18. package/dist/index.d.ts +27 -2
  19. package/dist/index.js +5 -1
  20. package/dist/patterns.d.cts +8 -2
  21. package/dist/patterns.d.ts +8 -2
  22. package/dist/plugins.cjs +142 -1
  23. package/dist/plugins.d.cts +39 -3
  24. package/dist/plugins.d.ts +39 -3
  25. package/dist/plugins.js +119 -3
  26. package/dist/{ssr-WKUPVSSK.js → ssr-6GIMY5MX.js} +5 -3
  27. package/dist/ssr-BA6sxxUd.d.cts +135 -0
  28. package/dist/ssr-BA6sxxUd.d.ts +135 -0
  29. package/dist/ssr.cjs +5 -0
  30. package/dist/ssr.d.cts +3 -113
  31. package/dist/ssr.d.ts +3 -113
  32. package/dist/ssr.js +4 -2
  33. package/dist/ui.cjs +50 -2
  34. package/dist/ui.d.cts +1 -1
  35. package/dist/ui.d.ts +1 -1
  36. package/dist/ui.js +3 -1
  37. package/dist/widgets.cjs +56 -7
  38. package/dist/widgets.d.cts +4 -2
  39. package/dist/widgets.d.ts +4 -2
  40. package/dist/widgets.js +1 -1
  41. package/package.json +139 -139
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Converts an HTMLElement tree to an HTML string for server-side rendering.
3
+ */
4
+ declare function renderToString(element: HTMLElement | DocumentFragment | Node): string;
5
+ /**
6
+ * Hydrates a server-rendered DOM tree by attaching event listeners
7
+ * and activating reactive bindings.
8
+ */
9
+ declare function hydrate(component: () => HTMLElement, container: HTMLElement): void;
10
+ /**
11
+ * Branded type for raw HTML that has been explicitly marked as trusted.
12
+ * Use `trustHTML()` to create a value of this type. This prevents
13
+ * accidental injection of unsanitized user input into `headExtra`.
14
+ */
15
+ type TrustedHTML = string & {
16
+ readonly __brand: "TrustedHTML";
17
+ };
18
+ /**
19
+ * Mark an HTML string as trusted for use in contexts that accept raw HTML
20
+ * (e.g. `renderToDocument({ headExtra })`). Only call this on
21
+ * developer-controlled strings — never on user input.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * const extra = trustHTML('<link rel="preconnect" href="https://fonts.googleapis.com">');
26
+ * renderToDocument(App, { headExtra: extra });
27
+ * ```
28
+ */
29
+ declare function trustHTML(html: string): TrustedHTML;
30
+ /**
31
+ * Renders a component to a full HTML document string.
32
+ *
33
+ * `headExtra` requires a `TrustedHTML` value created via `trustHTML()`.
34
+ * This prevents accidental injection of unsanitized user input.
35
+ */
36
+ declare function renderToDocument(component: () => HTMLElement, options?: {
37
+ title?: string;
38
+ meta?: Record<string, string>[];
39
+ links?: Record<string, string>[];
40
+ scripts?: string[];
41
+ bodyAttrs?: Record<string, string>;
42
+ /**
43
+ * Raw HTML injected into `<head>`. Must be wrapped in `trustHTML()`
44
+ * to confirm the content is developer-controlled.
45
+ */
46
+ headExtra?: TrustedHTML;
47
+ }): string;
48
+ /**
49
+ * Renders a component tree to an async iterable of HTML chunks.
50
+ * Enables progressive server-side rendering — the consumer can write
51
+ * each chunk to a response stream as it becomes available.
52
+ */
53
+ declare function renderToStream(element: HTMLElement | DocumentFragment | Node): AsyncGenerator<string>;
54
+ /**
55
+ * Collects the full output of renderToStream into a string.
56
+ */
57
+ declare function collectStream(stream: AsyncGenerator<string> | AsyncIterable<string>): Promise<string>;
58
+ /**
59
+ * Renders a component tree to a Web ReadableStream<string>.
60
+ * Compatible with Node 18+, Deno, and edge runtimes.
61
+ * Uses pull-based backpressure — chunks are produced on demand.
62
+ */
63
+ declare function renderToReadableStream(element: HTMLElement | DocumentFragment | Node): ReadableStream<string>;
64
+ /**
65
+ * Marks an element as a hydration island. During partial hydration
66
+ * only elements marked with `data-sibu-island` will be hydrated.
67
+ */
68
+ declare function island(id: string, component: () => HTMLElement): HTMLElement;
69
+ /**
70
+ * Hydrate only elements marked as islands (`data-sibu-island`).
71
+ * Non-island content keeps its server-rendered HTML untouched.
72
+ */
73
+ declare function hydrateIslands(container: HTMLElement, islands: Record<string, () => HTMLElement>): void;
74
+ /**
75
+ * Progressively hydrate islands only when they enter the viewport.
76
+ * Uses IntersectionObserver to defer hydration of off-screen islands,
77
+ * reducing initial JavaScript execution cost.
78
+ *
79
+ * Returns a cleanup function that disconnects all observers.
80
+ */
81
+ declare function hydrateProgressively(container: HTMLElement, islands: Record<string, () => HTMLElement>, options?: IntersectionObserverInit): () => void;
82
+ /**
83
+ * Reset SSR state between requests. Call at the start of each SSR render
84
+ * to prevent ID drift in long-lived server processes.
85
+ */
86
+ declare function resetSSRState(): void;
87
+ /**
88
+ * Create a suspense boundary for SSR streaming.
89
+ * Renders fallback HTML inline and returns a promise for the resolved content.
90
+ *
91
+ * The returned element contains the fallback UI with a `data-sibu-suspense-id`
92
+ * marker. The promise resolves to `{ id, html }` once async content is ready.
93
+ */
94
+ declare function ssrSuspense(props: {
95
+ fallback: () => HTMLElement;
96
+ content: () => Promise<HTMLElement>;
97
+ }): {
98
+ element: HTMLElement;
99
+ promise: Promise<{
100
+ id: string;
101
+ html: string;
102
+ }>;
103
+ };
104
+ /**
105
+ * Generate an inline script that swaps a suspense fallback with resolved content.
106
+ * The id is escaped for both JS string and HTML attribute contexts to prevent injection.
107
+ */
108
+ declare function suspenseSwapScript(id: string, nonce?: string): string;
109
+ /**
110
+ * Renders a component tree with suspense boundaries as a stream.
111
+ * Yields the main tree HTML first (including fallback content for suspended
112
+ * boundaries), then flushes resolved content with inline swap scripts.
113
+ */
114
+ declare function renderToSuspenseStream(element: HTMLElement | DocumentFragment | Node, pendingBoundaries?: Promise<{
115
+ id: string;
116
+ html: string;
117
+ }>[]): AsyncGenerator<string>;
118
+ /**
119
+ * Serialize application state into an HTML script tag for SSR.
120
+ * The serialized data is embedded in the document and picked up
121
+ * on the client with `deserializeState()`.
122
+ */
123
+ declare function serializeState(state: Record<string, unknown>, nonce?: string): string;
124
+ /**
125
+ * Retrieve state that was embedded by `serializeState()` during SSR.
126
+ *
127
+ * When a `validate` function is provided, it acts as a type guard —
128
+ * only data that passes validation is returned. This prevents
129
+ * tampered SSR payloads from being trusted by the client.
130
+ *
131
+ * @param validate Optional type guard to verify data integrity
132
+ */
133
+ declare function deserializeState<T = Record<string, unknown>>(validate?: (data: unknown) => data is T): T | undefined;
134
+
135
+ export { type TrustedHTML as T, hydrateIslands as a, hydrateProgressively as b, collectStream as c, deserializeState as d, renderToReadableStream as e, renderToStream as f, renderToString as g, hydrate as h, island as i, renderToSuspenseStream as j, resetSSRState as k, ssrSuspense as l, suspenseSwapScript as m, renderToDocument as r, serializeState as s, trustHTML as t };
package/dist/ssr.cjs CHANGED
@@ -55,6 +55,7 @@ __export(ssr_exports, {
55
55
  setStructuredData: () => setStructuredData,
56
56
  ssrSuspense: () => ssrSuspense,
57
57
  suspenseSwapScript: () => suspenseSwapScript,
58
+ trustHTML: () => trustHTML,
58
59
  wasm: () => wasm,
59
60
  worker: () => worker,
60
61
  workerFn: () => workerFn
@@ -156,6 +157,9 @@ function hydrateNode(serverNode, clientNode) {
156
157
  hydrateNode(serverChildren[i2], clientChildren[i2]);
157
158
  }
158
159
  }
160
+ function trustHTML(html2) {
161
+ return html2;
162
+ }
159
163
  function renderToDocument(component, options = {}) {
160
164
  let content;
161
165
  try {
@@ -1836,6 +1840,7 @@ function isWasmCached(key) {
1836
1840
  setStructuredData,
1837
1841
  ssrSuspense,
1838
1842
  suspenseSwapScript,
1843
+ trustHTML,
1839
1844
  wasm,
1840
1845
  worker,
1841
1846
  workerFn
package/dist/ssr.d.cts CHANGED
@@ -1,3 +1,5 @@
1
+ export { T as TrustedHTML, c as collectStream, d as deserializeState, h as hydrate, a as hydrateIslands, b as hydrateProgressively, i as island, r as renderToDocument, e as renderToReadableStream, f as renderToStream, g as renderToString, j as renderToSuspenseStream, k as resetSSRState, s as serializeState, l as ssrSuspense, m as suspenseSwapScript, t as trustHTML } from './ssr-BA6sxxUd.cjs';
2
+
1
3
  interface HeadProps {
2
4
  title?: string | (() => string);
3
5
  meta?: Record<string, string | (() => string)>[];
@@ -23,118 +25,6 @@ declare function setStructuredData(data: Record<string, unknown>): void;
23
25
  */
24
26
  declare function setCanonical(url: string): void;
25
27
 
26
- /**
27
- * Converts an HTMLElement tree to an HTML string for server-side rendering.
28
- */
29
- declare function renderToString(element: HTMLElement | DocumentFragment | Node): string;
30
- /**
31
- * Hydrates a server-rendered DOM tree by attaching event listeners
32
- * and activating reactive bindings.
33
- */
34
- declare function hydrate(component: () => HTMLElement, container: HTMLElement): void;
35
- /**
36
- * Renders a component to a full HTML document string.
37
- *
38
- * **Security warning:** `headExtra` is injected as raw HTML into the document head.
39
- * Never pass unsanitized user input to `headExtra` — it is intended for trusted,
40
- * developer-controlled content only (e.g. inline styles, custom meta tags).
41
- */
42
- declare function renderToDocument(component: () => HTMLElement, options?: {
43
- title?: string;
44
- meta?: Record<string, string>[];
45
- links?: Record<string, string>[];
46
- scripts?: string[];
47
- bodyAttrs?: Record<string, string>;
48
- /** Raw HTML injected into <head>. Must not contain unsanitized user input. */
49
- headExtra?: string;
50
- }): string;
51
- /**
52
- * Renders a component tree to an async iterable of HTML chunks.
53
- * Enables progressive server-side rendering — the consumer can write
54
- * each chunk to a response stream as it becomes available.
55
- */
56
- declare function renderToStream(element: HTMLElement | DocumentFragment | Node): AsyncGenerator<string>;
57
- /**
58
- * Collects the full output of renderToStream into a string.
59
- */
60
- declare function collectStream(stream: AsyncGenerator<string> | AsyncIterable<string>): Promise<string>;
61
- /**
62
- * Renders a component tree to a Web ReadableStream<string>.
63
- * Compatible with Node 18+, Deno, and edge runtimes.
64
- * Uses pull-based backpressure — chunks are produced on demand.
65
- */
66
- declare function renderToReadableStream(element: HTMLElement | DocumentFragment | Node): ReadableStream<string>;
67
- /**
68
- * Marks an element as a hydration island. During partial hydration
69
- * only elements marked with `data-sibu-island` will be hydrated.
70
- */
71
- declare function island(id: string, component: () => HTMLElement): HTMLElement;
72
- /**
73
- * Hydrate only elements marked as islands (`data-sibu-island`).
74
- * Non-island content keeps its server-rendered HTML untouched.
75
- */
76
- declare function hydrateIslands(container: HTMLElement, islands: Record<string, () => HTMLElement>): void;
77
- /**
78
- * Progressively hydrate islands only when they enter the viewport.
79
- * Uses IntersectionObserver to defer hydration of off-screen islands,
80
- * reducing initial JavaScript execution cost.
81
- *
82
- * Returns a cleanup function that disconnects all observers.
83
- */
84
- declare function hydrateProgressively(container: HTMLElement, islands: Record<string, () => HTMLElement>, options?: IntersectionObserverInit): () => void;
85
- /**
86
- * Reset SSR state between requests. Call at the start of each SSR render
87
- * to prevent ID drift in long-lived server processes.
88
- */
89
- declare function resetSSRState(): void;
90
- /**
91
- * Create a suspense boundary for SSR streaming.
92
- * Renders fallback HTML inline and returns a promise for the resolved content.
93
- *
94
- * The returned element contains the fallback UI with a `data-sibu-suspense-id`
95
- * marker. The promise resolves to `{ id, html }` once async content is ready.
96
- */
97
- declare function ssrSuspense(props: {
98
- fallback: () => HTMLElement;
99
- content: () => Promise<HTMLElement>;
100
- }): {
101
- element: HTMLElement;
102
- promise: Promise<{
103
- id: string;
104
- html: string;
105
- }>;
106
- };
107
- /**
108
- * Generate an inline script that swaps a suspense fallback with resolved content.
109
- * The id is escaped for both JS string and HTML attribute contexts to prevent injection.
110
- */
111
- declare function suspenseSwapScript(id: string, nonce?: string): string;
112
- /**
113
- * Renders a component tree with suspense boundaries as a stream.
114
- * Yields the main tree HTML first (including fallback content for suspended
115
- * boundaries), then flushes resolved content with inline swap scripts.
116
- */
117
- declare function renderToSuspenseStream(element: HTMLElement | DocumentFragment | Node, pendingBoundaries?: Promise<{
118
- id: string;
119
- html: string;
120
- }>[]): AsyncGenerator<string>;
121
- /**
122
- * Serialize application state into an HTML script tag for SSR.
123
- * The serialized data is embedded in the document and picked up
124
- * on the client with `deserializeState()`.
125
- */
126
- declare function serializeState(state: Record<string, unknown>, nonce?: string): string;
127
- /**
128
- * Retrieve state that was embedded by `serializeState()` during SSR.
129
- *
130
- * When a `validate` function is provided, it acts as a type guard —
131
- * only data that passes validation is returned. This prevents
132
- * tampered SSR payloads from being trusted by the client.
133
- *
134
- * @param validate Optional type guard to verify data integrity
135
- */
136
- declare function deserializeState<T = Record<string, unknown>>(validate?: (data: unknown) => data is T): T | undefined;
137
-
138
28
  interface UseWorkerReturn<TInput, TOutput> {
139
29
  post(data: TInput): void;
140
30
  result: () => TOutput | null;
@@ -481,4 +371,4 @@ declare function createMiddlewareChain(): {
481
371
  }) => Promise<void>;
482
372
  };
483
373
 
484
- export { type ActionFn, type ActionResult, Head, type ISROptions, type MicroApp, type MicroAppConfig, type MiddlewareFn, type SSGOptions, type SSGResult, type ScrollRestorationOptions, type ServiceWorkerState, type SharedScope, type UseWorkerFnReturn, type UseWorkerReturn, type WasmConfig, type WasmModuleState, type WorkerPool, clearWasmCache, collectStream, composeMiddleware, createAction, createISR, createMicroApp, createMiddlewareChain, createSharedScope, createWasmBridge, createWorkerPool, defineRemoteComponent, deserializeState, generateStaticSite, hydrate, hydrateIslands, hydrateProgressively, isWasmCached, island, loadRemoteModule, loadWasmModule, preloadWasm, renderToDocument, renderToReadableStream, renderToStream, renderToString, renderToSuspenseStream, resetSSRState, scrollRestoration, serializeState, serviceWorker, setCanonical, setStructuredData, ssrSuspense, suspenseSwapScript, wasm, worker, workerFn };
374
+ export { type ActionFn, type ActionResult, Head, type ISROptions, type MicroApp, type MicroAppConfig, type MiddlewareFn, type SSGOptions, type SSGResult, type ScrollRestorationOptions, type ServiceWorkerState, type SharedScope, type UseWorkerFnReturn, type UseWorkerReturn, type WasmConfig, type WasmModuleState, type WorkerPool, clearWasmCache, composeMiddleware, createAction, createISR, createMicroApp, createMiddlewareChain, createSharedScope, createWasmBridge, createWorkerPool, defineRemoteComponent, generateStaticSite, isWasmCached, loadRemoteModule, loadWasmModule, preloadWasm, scrollRestoration, serviceWorker, setCanonical, setStructuredData, wasm, worker, workerFn };
package/dist/ssr.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ export { T as TrustedHTML, c as collectStream, d as deserializeState, h as hydrate, a as hydrateIslands, b as hydrateProgressively, i as island, r as renderToDocument, e as renderToReadableStream, f as renderToStream, g as renderToString, j as renderToSuspenseStream, k as resetSSRState, s as serializeState, l as ssrSuspense, m as suspenseSwapScript, t as trustHTML } from './ssr-BA6sxxUd.js';
2
+
1
3
  interface HeadProps {
2
4
  title?: string | (() => string);
3
5
  meta?: Record<string, string | (() => string)>[];
@@ -23,118 +25,6 @@ declare function setStructuredData(data: Record<string, unknown>): void;
23
25
  */
24
26
  declare function setCanonical(url: string): void;
25
27
 
26
- /**
27
- * Converts an HTMLElement tree to an HTML string for server-side rendering.
28
- */
29
- declare function renderToString(element: HTMLElement | DocumentFragment | Node): string;
30
- /**
31
- * Hydrates a server-rendered DOM tree by attaching event listeners
32
- * and activating reactive bindings.
33
- */
34
- declare function hydrate(component: () => HTMLElement, container: HTMLElement): void;
35
- /**
36
- * Renders a component to a full HTML document string.
37
- *
38
- * **Security warning:** `headExtra` is injected as raw HTML into the document head.
39
- * Never pass unsanitized user input to `headExtra` — it is intended for trusted,
40
- * developer-controlled content only (e.g. inline styles, custom meta tags).
41
- */
42
- declare function renderToDocument(component: () => HTMLElement, options?: {
43
- title?: string;
44
- meta?: Record<string, string>[];
45
- links?: Record<string, string>[];
46
- scripts?: string[];
47
- bodyAttrs?: Record<string, string>;
48
- /** Raw HTML injected into <head>. Must not contain unsanitized user input. */
49
- headExtra?: string;
50
- }): string;
51
- /**
52
- * Renders a component tree to an async iterable of HTML chunks.
53
- * Enables progressive server-side rendering — the consumer can write
54
- * each chunk to a response stream as it becomes available.
55
- */
56
- declare function renderToStream(element: HTMLElement | DocumentFragment | Node): AsyncGenerator<string>;
57
- /**
58
- * Collects the full output of renderToStream into a string.
59
- */
60
- declare function collectStream(stream: AsyncGenerator<string> | AsyncIterable<string>): Promise<string>;
61
- /**
62
- * Renders a component tree to a Web ReadableStream<string>.
63
- * Compatible with Node 18+, Deno, and edge runtimes.
64
- * Uses pull-based backpressure — chunks are produced on demand.
65
- */
66
- declare function renderToReadableStream(element: HTMLElement | DocumentFragment | Node): ReadableStream<string>;
67
- /**
68
- * Marks an element as a hydration island. During partial hydration
69
- * only elements marked with `data-sibu-island` will be hydrated.
70
- */
71
- declare function island(id: string, component: () => HTMLElement): HTMLElement;
72
- /**
73
- * Hydrate only elements marked as islands (`data-sibu-island`).
74
- * Non-island content keeps its server-rendered HTML untouched.
75
- */
76
- declare function hydrateIslands(container: HTMLElement, islands: Record<string, () => HTMLElement>): void;
77
- /**
78
- * Progressively hydrate islands only when they enter the viewport.
79
- * Uses IntersectionObserver to defer hydration of off-screen islands,
80
- * reducing initial JavaScript execution cost.
81
- *
82
- * Returns a cleanup function that disconnects all observers.
83
- */
84
- declare function hydrateProgressively(container: HTMLElement, islands: Record<string, () => HTMLElement>, options?: IntersectionObserverInit): () => void;
85
- /**
86
- * Reset SSR state between requests. Call at the start of each SSR render
87
- * to prevent ID drift in long-lived server processes.
88
- */
89
- declare function resetSSRState(): void;
90
- /**
91
- * Create a suspense boundary for SSR streaming.
92
- * Renders fallback HTML inline and returns a promise for the resolved content.
93
- *
94
- * The returned element contains the fallback UI with a `data-sibu-suspense-id`
95
- * marker. The promise resolves to `{ id, html }` once async content is ready.
96
- */
97
- declare function ssrSuspense(props: {
98
- fallback: () => HTMLElement;
99
- content: () => Promise<HTMLElement>;
100
- }): {
101
- element: HTMLElement;
102
- promise: Promise<{
103
- id: string;
104
- html: string;
105
- }>;
106
- };
107
- /**
108
- * Generate an inline script that swaps a suspense fallback with resolved content.
109
- * The id is escaped for both JS string and HTML attribute contexts to prevent injection.
110
- */
111
- declare function suspenseSwapScript(id: string, nonce?: string): string;
112
- /**
113
- * Renders a component tree with suspense boundaries as a stream.
114
- * Yields the main tree HTML first (including fallback content for suspended
115
- * boundaries), then flushes resolved content with inline swap scripts.
116
- */
117
- declare function renderToSuspenseStream(element: HTMLElement | DocumentFragment | Node, pendingBoundaries?: Promise<{
118
- id: string;
119
- html: string;
120
- }>[]): AsyncGenerator<string>;
121
- /**
122
- * Serialize application state into an HTML script tag for SSR.
123
- * The serialized data is embedded in the document and picked up
124
- * on the client with `deserializeState()`.
125
- */
126
- declare function serializeState(state: Record<string, unknown>, nonce?: string): string;
127
- /**
128
- * Retrieve state that was embedded by `serializeState()` during SSR.
129
- *
130
- * When a `validate` function is provided, it acts as a type guard —
131
- * only data that passes validation is returned. This prevents
132
- * tampered SSR payloads from being trusted by the client.
133
- *
134
- * @param validate Optional type guard to verify data integrity
135
- */
136
- declare function deserializeState<T = Record<string, unknown>>(validate?: (data: unknown) => data is T): T | undefined;
137
-
138
28
  interface UseWorkerReturn<TInput, TOutput> {
139
29
  post(data: TInput): void;
140
30
  result: () => TOutput | null;
@@ -481,4 +371,4 @@ declare function createMiddlewareChain(): {
481
371
  }) => Promise<void>;
482
372
  };
483
373
 
484
- export { type ActionFn, type ActionResult, Head, type ISROptions, type MicroApp, type MicroAppConfig, type MiddlewareFn, type SSGOptions, type SSGResult, type ScrollRestorationOptions, type ServiceWorkerState, type SharedScope, type UseWorkerFnReturn, type UseWorkerReturn, type WasmConfig, type WasmModuleState, type WorkerPool, clearWasmCache, collectStream, composeMiddleware, createAction, createISR, createMicroApp, createMiddlewareChain, createSharedScope, createWasmBridge, createWorkerPool, defineRemoteComponent, deserializeState, generateStaticSite, hydrate, hydrateIslands, hydrateProgressively, isWasmCached, island, loadRemoteModule, loadWasmModule, preloadWasm, renderToDocument, renderToReadableStream, renderToStream, renderToString, renderToSuspenseStream, resetSSRState, scrollRestoration, serializeState, serviceWorker, setCanonical, setStructuredData, ssrSuspense, suspenseSwapScript, wasm, worker, workerFn };
374
+ export { type ActionFn, type ActionResult, Head, type ISROptions, type MicroApp, type MicroAppConfig, type MiddlewareFn, type SSGOptions, type SSGResult, type ScrollRestorationOptions, type ServiceWorkerState, type SharedScope, type UseWorkerFnReturn, type UseWorkerReturn, type WasmConfig, type WasmModuleState, type WorkerPool, clearWasmCache, composeMiddleware, createAction, createISR, createMicroApp, createMiddlewareChain, createSharedScope, createWasmBridge, createWorkerPool, defineRemoteComponent, generateStaticSite, isWasmCached, loadRemoteModule, loadWasmModule, preloadWasm, scrollRestoration, serviceWorker, setCanonical, setStructuredData, wasm, worker, workerFn };
package/dist/ssr.js CHANGED
@@ -38,8 +38,9 @@ import {
38
38
  resetSSRState,
39
39
  serializeState,
40
40
  ssrSuspense,
41
- suspenseSwapScript
42
- } from "./chunk-7TQKR4PP.js";
41
+ suspenseSwapScript,
42
+ trustHTML
43
+ } from "./chunk-AZ3ISID5.js";
43
44
  import "./chunk-EWFVA3TJ.js";
44
45
  import "./chunk-MDVXJWFN.js";
45
46
  import "./chunk-SDLZDHKP.js";
@@ -84,6 +85,7 @@ export {
84
85
  setStructuredData,
85
86
  ssrSuspense,
86
87
  suspenseSwapScript,
88
+ trustHTML,
87
89
  wasm,
88
90
  worker,
89
91
  workerFn
package/dist/ui.cjs CHANGED
@@ -29,6 +29,7 @@ __export(ui_exports, {
29
29
  bindAttrs: () => bindAttrs,
30
30
  bindBoolAttr: () => bindBoolAttr,
31
31
  bindData: () => bindData,
32
+ bindField: () => bindField,
32
33
  composable: () => composable,
33
34
  compose: () => compose,
34
35
  createGuard: () => createGuard,
@@ -448,6 +449,34 @@ function max(maxVal, message) {
448
449
  function custom(fn, message) {
449
450
  return (value) => fn(value) ? null : message;
450
451
  }
452
+ function bindField(field, extras) {
453
+ const fieldOn = {
454
+ input: (e) => {
455
+ const target = e.target;
456
+ if (target.type === "checkbox") {
457
+ field.set(target.checked);
458
+ } else {
459
+ field.set(target.value);
460
+ }
461
+ },
462
+ change: (e) => {
463
+ const target = e.target;
464
+ if ("checked" in target && target.type === "checkbox") {
465
+ field.set(target.checked);
466
+ } else {
467
+ field.set(target.value);
468
+ }
469
+ },
470
+ blur: () => field.touch()
471
+ };
472
+ const { on: extraOn, value: _ignoreValue, ...restExtras } = extras ?? {};
473
+ const mergedOn = extraOn && typeof extraOn === "object" ? { ...fieldOn, ...extraOn } : fieldOn;
474
+ return {
475
+ value: field.value,
476
+ on: mergedOn,
477
+ ...restExtras
478
+ };
479
+ }
451
480
  function form(config) {
452
481
  const fieldEntries = Object.entries(config);
453
482
  const fieldMap = {};
@@ -862,10 +891,19 @@ function announce(message, priority = "polite") {
862
891
 
863
892
  // src/ui/scopedStyle.ts
864
893
  var scopeCounter = 0;
894
+ function sanitizeCSS(css) {
895
+ let sanitized = css.replace(/@import\s+[^;]+;/gi, "/* @import removed */");
896
+ sanitized = sanitized.replace(/url\s*\(\s*(?:"[^"]*"|'[^']*'|[^)]*)\s*\)/gi, "/* url() removed */");
897
+ sanitized = sanitized.replace(/expression\s*\(\s*(?:"[^"]*"|'[^']*'|[^)]*)\s*\)/gi, "/* expression() removed */");
898
+ sanitized = sanitized.replace(/-moz-binding\s*:[^;]+;/gi, "/* -moz-binding removed */");
899
+ sanitized = sanitized.replace(/behavior\s*:[^;]+;/gi, "/* behavior removed */");
900
+ return sanitized;
901
+ }
865
902
  function scopedStyle(css) {
866
903
  const id = `sibu-s${scopeCounter++}`;
867
904
  const attr = `data-${id}`;
868
- const scopedCSS = css.replace(/([^\r\n,{}]+)(,(?=[^}]*{)|\s*{)/g, (match, selector, delimiter) => {
905
+ const safeCss = sanitizeCSS(css);
906
+ const scopedCSS = safeCss.replace(/([^\r\n,{}]+)(,(?=[^}]*{)|\s*{)/g, (match, selector, delimiter) => {
869
907
  const trimmed = selector.trim();
870
908
  if (trimmed.startsWith("@") || trimmed.startsWith("from") || trimmed.startsWith("to") || /^\d+%$/.test(trimmed)) {
871
909
  return match;
@@ -1091,7 +1129,16 @@ function toast(options) {
1091
1129
  timers.delete(id);
1092
1130
  }
1093
1131
  }
1094
- return { toasts, show, dismiss, dismissAll };
1132
+ return {
1133
+ toasts,
1134
+ show,
1135
+ info: (message) => show(message, "info"),
1136
+ success: (message) => show(message, "success"),
1137
+ error: (message) => show(message, "error"),
1138
+ warning: (message) => show(message, "warning"),
1139
+ dismiss,
1140
+ dismissAll
1141
+ };
1095
1142
  }
1096
1143
 
1097
1144
  // src/ui/infiniteScroll.ts
@@ -1509,6 +1556,7 @@ function createGuard(validator) {
1509
1556
  bindAttrs,
1510
1557
  bindBoolAttr,
1511
1558
  bindData,
1559
+ bindField,
1512
1560
  composable,
1513
1561
  compose,
1514
1562
  createGuard,
package/dist/ui.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- export { C as CustomElementOptions, F as FieldConfig, a as FocusTrap, b as FormConfig, c as FormField, d as FormReturn, I as IntersectionResult, M as MaskOptions, T as Toast, V as ValidatorFn, e as VirtualList, f as VirtualListProps, g as announce, h as aria, i as bindAttrs, j as bindBoolAttr, k as bindData, l as creditCardMask, m as custom, n as dateMask, o as defineElement, p as dialog, q as email, r as eventBus, s as focus, t as form, u as hotkey, v as infiniteScroll, w as inputMask, x as intersection, y as lazyLoad, z as matchesPattern, A as max, B as maxLength, D as min, E as minLength, G as pagination, H as phoneMask, J as removeScopedStyle, K as required, L as scopedStyle, N as ssnMask, O as svgElement, P as timeMask, Q as toast, R as withScopedStyle, S as zipMask } from './customElement-BKQfbSZQ.cjs';
1
+ export { B as BoundFieldProps, C as CustomElementOptions, F as FieldConfig, a as FocusTrap, b as FormConfig, c as FormField, d as FormReturn, I as IntersectionResult, M as MaskOptions, T as Toast, e as ToastInstance, V as ValidatorFn, f as VirtualList, g as VirtualListProps, h as announce, i as aria, j as bindAttrs, k as bindBoolAttr, l as bindData, m as bindField, n as creditCardMask, o as custom, p as dateMask, q as defineElement, r as dialog, s as email, t as eventBus, u as focus, v as form, w as hotkey, x as infiniteScroll, y as inputMask, z as intersection, A as lazyLoad, D as matchesPattern, E as max, G as maxLength, H as min, J as minLength, K as pagination, L as phoneMask, N as removeScopedStyle, O as required, P as scopedStyle, Q as ssnMask, R as svgElement, S as timeMask, U as toast, W as withScopedStyle, X as zipMask } from './customElement-yz8uyk-0.cjs';
2
2
  export { C as ComponentProps, P as PropDef, a as PropSchema, R as RenderProp, V as Validator, b as assertType, c as composable, d as compose, e as createGuard, f as createSlots, g as defineComponent, h as defineSlottedComponent, i as defineStrictComponent, v as validateProps, j as validators, w as withBoundary, k as withDefaults, l as withProps, m as withWrapper } from './contracts-DOrhwbke.cjs';
3
3
 
4
4
  /**
package/dist/ui.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { C as CustomElementOptions, F as FieldConfig, a as FocusTrap, b as FormConfig, c as FormField, d as FormReturn, I as IntersectionResult, M as MaskOptions, T as Toast, V as ValidatorFn, e as VirtualList, f as VirtualListProps, g as announce, h as aria, i as bindAttrs, j as bindBoolAttr, k as bindData, l as creditCardMask, m as custom, n as dateMask, o as defineElement, p as dialog, q as email, r as eventBus, s as focus, t as form, u as hotkey, v as infiniteScroll, w as inputMask, x as intersection, y as lazyLoad, z as matchesPattern, A as max, B as maxLength, D as min, E as minLength, G as pagination, H as phoneMask, J as removeScopedStyle, K as required, L as scopedStyle, N as ssnMask, O as svgElement, P as timeMask, Q as toast, R as withScopedStyle, S as zipMask } from './customElement-BKQfbSZQ.js';
1
+ export { B as BoundFieldProps, C as CustomElementOptions, F as FieldConfig, a as FocusTrap, b as FormConfig, c as FormField, d as FormReturn, I as IntersectionResult, M as MaskOptions, T as Toast, e as ToastInstance, V as ValidatorFn, f as VirtualList, g as VirtualListProps, h as announce, i as aria, j as bindAttrs, k as bindBoolAttr, l as bindData, m as bindField, n as creditCardMask, o as custom, p as dateMask, q as defineElement, r as dialog, s as email, t as eventBus, u as focus, v as form, w as hotkey, x as infiniteScroll, y as inputMask, z as intersection, A as lazyLoad, D as matchesPattern, E as max, G as maxLength, H as min, J as minLength, K as pagination, L as phoneMask, N as removeScopedStyle, O as required, P as scopedStyle, Q as ssnMask, R as svgElement, S as timeMask, U as toast, W as withScopedStyle, X as zipMask } from './customElement-yz8uyk-0.js';
2
2
  export { C as ComponentProps, P as PropDef, a as PropSchema, R as RenderProp, V as Validator, b as assertType, c as composable, d as compose, e as createGuard, f as createSlots, g as defineComponent, h as defineSlottedComponent, i as defineStrictComponent, v as validateProps, j as validators, w as withBoundary, k as withDefaults, l as withProps, m as withWrapper } from './contracts-DOrhwbke.js';
3
3
 
4
4
  /**
package/dist/ui.js CHANGED
@@ -6,6 +6,7 @@ import {
6
6
  bindAttrs,
7
7
  bindBoolAttr,
8
8
  bindData,
9
+ bindField,
9
10
  creditCardMask,
10
11
  custom,
11
12
  dateMask,
@@ -36,7 +37,7 @@ import {
36
37
  toast,
37
38
  withScopedStyle,
38
39
  zipMask
39
- } from "./chunk-3CRQALYP.js";
40
+ } from "./chunk-DKOHBI74.js";
40
41
  import {
41
42
  RenderProp,
42
43
  assertType,
@@ -106,6 +107,7 @@ export {
106
107
  bindAttrs,
107
108
  bindBoolAttr,
108
109
  bindData,
110
+ bindField,
109
111
  composable,
110
112
  compose,
111
113
  createGuard,
package/dist/widgets.cjs CHANGED
@@ -824,26 +824,75 @@ function fileUpload(options) {
824
824
  function contentEditable() {
825
825
  const [content, setContent] = signal("");
826
826
  const [isFocused, setFocused] = signal(false);
827
- function execCommand(command, value) {
828
- if (typeof document !== "undefined" && document.execCommand) {
829
- document.execCommand(command, false, value ?? "");
827
+ function wrapSelection(tagName) {
828
+ if (typeof window === "undefined") return;
829
+ const selection = window.getSelection();
830
+ if (!selection || selection.rangeCount === 0 || selection.isCollapsed) return;
831
+ const range = selection.getRangeAt(0);
832
+ const ancestor = range.commonAncestorContainer;
833
+ const existingWrap = findAncestorByTag(
834
+ ancestor instanceof HTMLElement ? ancestor : ancestor.parentElement,
835
+ tagName
836
+ );
837
+ let targetNode = null;
838
+ if (existingWrap) {
839
+ const parent = existingWrap.parentNode;
840
+ if (parent) {
841
+ const firstChild = existingWrap.firstChild;
842
+ const lastChild = existingWrap.lastChild;
843
+ while (existingWrap.firstChild) {
844
+ parent.insertBefore(existingWrap.firstChild, existingWrap);
845
+ }
846
+ parent.removeChild(existingWrap);
847
+ if (firstChild && lastChild) {
848
+ const newRange = document.createRange();
849
+ newRange.setStartBefore(firstChild);
850
+ newRange.setEndAfter(lastChild);
851
+ selection.removeAllRanges();
852
+ selection.addRange(newRange);
853
+ return;
854
+ }
855
+ }
856
+ } else {
857
+ const wrapper = document.createElement(tagName);
858
+ try {
859
+ range.surroundContents(wrapper);
860
+ } catch {
861
+ const fragment = range.extractContents();
862
+ wrapper.appendChild(fragment);
863
+ range.insertNode(wrapper);
864
+ }
865
+ targetNode = wrapper;
866
+ }
867
+ if (targetNode) {
868
+ selection.removeAllRanges();
869
+ const newRange = document.createRange();
870
+ newRange.selectNodeContents(targetNode);
871
+ selection.addRange(newRange);
872
+ }
873
+ }
874
+ function findAncestorByTag(el, tagName) {
875
+ const upper = tagName.toUpperCase();
876
+ while (el) {
877
+ if (el.tagName === upper) return el;
878
+ el = el.parentElement;
830
879
  }
880
+ return null;
831
881
  }
832
882
  function bold() {
833
- execCommand("bold");
883
+ wrapSelection("strong");
834
884
  }
835
885
  function italic() {
836
- execCommand("italic");
886
+ wrapSelection("em");
837
887
  }
838
888
  function underline() {
839
- execCommand("underline");
889
+ wrapSelection("u");
840
890
  }
841
891
  return {
842
892
  content,
843
893
  setContent,
844
894
  isFocused,
845
895
  setFocused,
846
- execCommand,
847
896
  bold,
848
897
  italic,
849
898
  underline