sibujs 4.12.0 → 4.13.1

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 (74) hide show
  1. package/dist/browser.cjs +71 -18
  2. package/dist/browser.js +4 -4
  3. package/dist/build.cjs +6618 -6178
  4. package/dist/build.d.cts +554 -415
  5. package/dist/build.d.ts +554 -415
  6. package/dist/build.js +2091 -1735
  7. package/dist/cdn.dev.global.js +12 -12
  8. package/dist/cdn.full.dev.global.js +13 -13
  9. package/dist/cdn.full.global.js +12 -12
  10. package/dist/cdn.global.js +12 -12
  11. package/dist/{chunk-WFRQ6D7H.js → chunk-22OPSWMF.js} +1 -1
  12. package/dist/{chunk-ZJCHY2IB.js → chunk-2NC56RGY.js} +1 -1
  13. package/dist/{chunk-NB7TFSJE.js → chunk-2O6JJCUR.js} +4 -4
  14. package/dist/{chunk-B2Y5BJSP.js → chunk-4UTGDVSA.js} +70 -16
  15. package/dist/{chunk-NAVLCP4S.js → chunk-5RIBLY2N.js} +4 -4
  16. package/dist/{chunk-T5O2CUHV.js → chunk-5XUGJM3J.js} +1 -1
  17. package/dist/{chunk-HXT2RNH5.js → chunk-ADZHPN2B.js} +1 -1
  18. package/dist/chunk-B36ADEIR.js +21 -0
  19. package/dist/{chunk-DFZL3AX7.js → chunk-C73VBPEF.js} +9 -5
  20. package/dist/{chunk-WH4U2VUE.js → chunk-CPQKWCJ2.js} +13 -5
  21. package/dist/{chunk-LEUEKK4G.js → chunk-EU7T7EB3.js} +2 -2
  22. package/dist/{chunk-QLG5IK7F.js → chunk-G3Z2FEBR.js} +4 -4
  23. package/dist/{chunk-ZPY2UAKM.js → chunk-J4X7ICH4.js} +3 -3
  24. package/dist/{chunk-XX4BRMWF.js → chunk-K4LNUT5L.js} +1 -1
  25. package/dist/{chunk-CI4W6XAU.js → chunk-KC62VURU.js} +3 -3
  26. package/dist/chunk-N5TBYXHW.js +17 -0
  27. package/dist/{chunk-653KGQS2.js → chunk-OIKD7YDY.js} +2 -2
  28. package/dist/{chunk-LYTUTXQP.js → chunk-PBJYCE2Z.js} +46 -4
  29. package/dist/{chunk-EMB5PG7V.js → chunk-QC3NP47A.js} +1 -1
  30. package/dist/{chunk-IHA62NGJ.js → chunk-QKFVMIAV.js} +1 -1
  31. package/dist/{chunk-LXBMVGVB.js → chunk-QZ47OZ25.js} +3 -3
  32. package/dist/{chunk-ZTYCCBU3.js → chunk-VFPLWUT7.js} +44 -26
  33. package/dist/{chunk-RK7EPQPG.js → chunk-YFTBCCVH.js} +1 -1
  34. package/dist/data.cjs +71 -18
  35. package/dist/data.js +5 -5
  36. package/dist/datePicker-DxuxWpgF.d.cts +285 -0
  37. package/dist/datePicker-DxuxWpgF.d.ts +285 -0
  38. package/dist/devtools.cjs +71 -18
  39. package/dist/devtools.js +4 -4
  40. package/dist/ecosystem.cjs +82 -21
  41. package/dist/ecosystem.js +7 -7
  42. package/dist/extras.cjs +131 -23
  43. package/dist/extras.d.cts +2 -2
  44. package/dist/extras.d.ts +2 -2
  45. package/dist/extras.js +21 -20
  46. package/dist/index.cjs +115 -37
  47. package/dist/index.d.cts +59 -5
  48. package/dist/index.d.ts +59 -5
  49. package/dist/index.js +10 -10
  50. package/dist/motion.cjs +69 -16
  51. package/dist/motion.js +3 -3
  52. package/dist/patterns.cjs +71 -18
  53. package/dist/patterns.js +5 -5
  54. package/dist/performance.cjs +69 -16
  55. package/dist/performance.js +4 -4
  56. package/dist/plugins.cjs +1421 -996
  57. package/dist/plugins.d.cts +132 -3
  58. package/dist/plugins.d.ts +132 -3
  59. package/dist/plugins.js +262 -11
  60. package/dist/routeMiddleware-B1sp4P7a.d.ts +688 -0
  61. package/dist/routeMiddleware-CedQTsLK.d.cts +688 -0
  62. package/dist/ssr.cjs +3607 -3524
  63. package/dist/ssr.d.cts +20 -671
  64. package/dist/ssr.d.ts +20 -671
  65. package/dist/ssr.js +15 -7
  66. package/dist/testing.cjs +71 -18
  67. package/dist/testing.js +2 -2
  68. package/dist/ui.cjs +78 -18
  69. package/dist/ui.js +8 -7
  70. package/dist/widgets.cjs +1352 -952
  71. package/dist/widgets.d.cts +100 -268
  72. package/dist/widgets.d.ts +100 -268
  73. package/dist/widgets.js +316 -7
  74. package/package.json +9 -1
@@ -0,0 +1,688 @@
1
+ import { C as Component } from './types-CJFViL6Q.cjs';
2
+
3
+ interface HeadProps {
4
+ title?: string | (() => string);
5
+ meta?: Record<string, string | (() => string)>[];
6
+ /**
7
+ * `<link>` elements to add to `<head>`.
8
+ *
9
+ * TRUST BOUNDARY for stylesheets: `{ rel: "stylesheet", href }` is the
10
+ * framework's explicit API for a stylesheet whose URL is a runtime value.
11
+ * The generic writers refuse to let a runtime `href` become an applied
12
+ * stylesheet at all (see `utils/elementPolicy.ts`), because a well-formed
13
+ * URL is not trusted CSS. Naming it here is the trust decision: first-party
14
+ * or pinned URLs only, and a CSP `style-src` as the second layer.
15
+ */
16
+ link?: Record<string, string>[];
17
+ /**
18
+ * External scripts to add to `<head>`.
19
+ *
20
+ * TRUST BOUNDARY: this is the framework's explicit API for loading a script
21
+ * whose URL is a runtime value, and naming it here IS the trust decision —
22
+ * the URL passes the scheme allowlist, but an allowed `https:` URL is still a
23
+ * program that runs with the page's full authority. Pass only URLs you
24
+ * control or pin (a first-party path, a CDN URL with `integrity`). The
25
+ * generic writers refuse to let a runtime value choose a `<script>` source
26
+ * at all; see `docs/architecture/attribute-security.md` § Trust model.
27
+ */
28
+ script?: Record<string, string>[];
29
+ /**
30
+ * The document `<base>`.
31
+ *
32
+ * TRUST BOUNDARY: `href` passes the scheme allowlist, but an allowed `https:`
33
+ * base still re-homes every relative URL on the page — relative `<script
34
+ * src>`, stylesheets, form actions and `fetch("/api")` alike. Treat it like a
35
+ * script URL: first-party values only.
36
+ */
37
+ base?: {
38
+ href?: string;
39
+ target?: string;
40
+ };
41
+ }
42
+ /**
43
+ * Head() manages document <head> tags reactively.
44
+ *
45
+ * META SECURITY: each meta entry is committed TRANSACTIONALLY. All of its
46
+ * attributes — static and reactive — are resolved into one snapshot, duplicate
47
+ * case-insensitive names are rejected, and the assembled snapshot is validated
48
+ * against the shared meta-refresh policy before anything reaches the DOM. An
49
+ * approved snapshot is then materialised on a fresh `<meta>` element while it is
50
+ * still detached and swapped in with a single `replaceWith()`, so no partially
51
+ * updated element is ever connected. A snapshot that fails validation withdraws
52
+ * the element entirely. See `utils/metaRefresh.ts`; the same policy governs SSR.
53
+ *
54
+ * NATIVE REFRESH DIRECTIVES MUST BE STATIC. A browser processes a meta refresh
55
+ * when the element is INSERTED — it records the pending navigation there and
56
+ * then, and removing or replacing the element afterwards is not a defined way to
57
+ * cancel it. `Head()` therefore never publishes a snapshot whose effective
58
+ * `http-equiv` is `refresh` from an entry that contains any reactive attribute,
59
+ * even when the destination is allowed: what cannot be withdrawn must not be
60
+ * handed over. Static refresh directives work as before, and every other
61
+ * reactive meta entry — description, keywords, Open Graph, non-refresh
62
+ * `http-equiv` — is unaffected.
63
+ *
64
+ * Supports dynamic title, meta tags, link tags, and structured data.
65
+ * Each instance tracks its own elements and effects for independent cleanup.
66
+ */
67
+ declare function Head(props: HeadProps): Comment;
68
+ /**
69
+ * Sets structured data (JSON-LD) for SEO.
70
+ *
71
+ * Security: the serialized JSON is passed through `escapeScriptJsonLocal`
72
+ * which unicode-escapes `<`, `>`, `&`, `U+2028`, and `U+2029`. This is
73
+ * defense-in-depth: when the element is inserted via `document.createElement`
74
+ * + `textContent` the browser will NOT re-parse the body, so `</script>`
75
+ * cannot break out of the tag at insertion time. However, tools that
76
+ * later serialize `document.head.innerHTML` DO re-parse, and the server
77
+ * side of any SSR roundtrip would see the raw text. Escaping here makes
78
+ * both paths safe.
79
+ */
80
+ declare function setStructuredData(data: Record<string, unknown>): void;
81
+ /**
82
+ * Sets the canonical URL for the page.
83
+ */
84
+ declare function setCanonical(url: string): void;
85
+
86
+ interface UseWorkerReturn<TInput, TOutput> {
87
+ post(data: TInput): void;
88
+ result: () => TOutput | null;
89
+ error: () => Error | null;
90
+ loading: () => boolean;
91
+ terminate(): void;
92
+ }
93
+ /**
94
+ * worker creates a Web Worker from an inline function and provides
95
+ * reactive state for its result, error, and loading status.
96
+ *
97
+ * The workerFn receives messages via the standard `onmessage` handler
98
+ * and should call `postMessage` to send results back. It is serialized
99
+ * into a Blob URL, so it must be self-contained (no closures).
100
+ *
101
+ * **CSP Warning:** This function serializes the provided function via `.toString()`
102
+ * and executes it inside a `blob:` URL Worker. This is equivalent to `eval()` and
103
+ * is incompatible with strict Content Security Policies that restrict
104
+ * `worker-src 'self'` or block `blob:` URLs. Additionally:
105
+ * - Minifiers may break captured variable references (closures silently fail).
106
+ * - Module-level imports are NOT accessible inside the worker.
107
+ * - Never pass user-controlled or dynamically constructed functions — this
108
+ * would be equivalent to `eval()` on untrusted input.
109
+ *
110
+ * @param workerFn The function body to run inside the worker.
111
+ * It receives `self` as the worker global scope.
112
+ * @returns An object with post, result, error, loading, and terminate.
113
+ */
114
+ declare function worker<TInput = unknown, TOutput = unknown>(workerFn: (e: MessageEvent<TInput>) => void): UseWorkerReturn<TInput, TOutput>;
115
+ interface UseWorkerFnReturn<TArgs extends unknown[], TResult> {
116
+ run(...args: TArgs): Promise<TResult>;
117
+ loading: () => boolean;
118
+ terminate(): void;
119
+ }
120
+ /**
121
+ * workerFn wraps a pure function so it runs inside a Web Worker.
122
+ *
123
+ * The function must be self-contained -- it cannot reference variables
124
+ * from the outer scope. Arguments are serialized via postMessage.
125
+ *
126
+ * **Trust boundary:** the function's source is evaluated in a `blob:` worker,
127
+ * which is equivalent to `eval()`. Only a function object is accepted — never
128
+ * a string, and never a function built from untrusted input.
129
+ *
130
+ * @param fn A pure function to execute in a worker thread.
131
+ * @returns An object with run, loading, and terminate.
132
+ */
133
+ declare function workerFn<TArgs extends unknown[], TResult>(fn: (...args: TArgs) => TResult): UseWorkerFnReturn<TArgs, TResult>;
134
+ interface WorkerPool<TInput, TOutput> {
135
+ execute(data: TInput): Promise<TOutput>;
136
+ terminate(): void;
137
+ }
138
+ /**
139
+ * createWorkerPool creates a pool of workers for parallel task execution.
140
+ *
141
+ * Tasks are distributed across workers using round-robin scheduling.
142
+ * Each worker is created from the same inline function.
143
+ *
144
+ * **Trust boundary:** as with `worker()`, the function's source is evaluated in
145
+ * a `blob:` worker. Only a function object is accepted, never a string.
146
+ *
147
+ * @param workerFn The function body to run inside each worker.
148
+ * @param poolSize Number of workers in the pool (defaults to navigator.hardwareConcurrency or 4).
149
+ * @returns An object with execute and terminate.
150
+ */
151
+ declare function createWorkerPool<TInput = unknown, TOutput = unknown>(workerFn: (e: MessageEvent<TInput>) => void, poolSize?: number): WorkerPool<TInput, TOutput>;
152
+
153
+ /**
154
+ * WebAssembly integration for SibuJS.
155
+ * Provides hooks and utilities to load, cache, and use WASM modules
156
+ * for performance-critical operations.
157
+ */
158
+ interface WasmModuleState<T extends object = Record<string, unknown>> {
159
+ /** The instantiated WASM module exports, null until loaded */
160
+ instance: T | null;
161
+ /** Loading state */
162
+ loading: boolean;
163
+ /** Error if loading failed */
164
+ error: Error | null;
165
+ /** Whether the module has been loaded successfully */
166
+ ready: boolean;
167
+ }
168
+ /**
169
+ * Configuration for the `wasm()` reactive wrapper.
170
+ *
171
+ * Deliberately the SAME option bag as the underlying `loadWasmModule()`
172
+ * primitive rather than a hand-copied subset. The primitive REQUIRES an
173
+ * explicit origin policy for URL sources (`allowedOrigins`, or an explicit
174
+ * `unsafelyAllowAnyOrigin` opt-in), and the wrapper previously had no way to
175
+ * express one — so `wasm("/math.wasm")` could only ever reject, and the public
176
+ * convenience API was unusable for its documented primary use case. Extending
177
+ * the primitive's type keeps the two from drifting again.
178
+ */
179
+ interface WasmConfig extends LoadWasmOptions {
180
+ }
181
+ /**
182
+ * Hook to load and use a WebAssembly module reactively.
183
+ * Returns reactive state that updates when the module loads.
184
+ *
185
+ * A URL source needs an explicit origin policy — WASM is compiled code with
186
+ * imports into JS memory, so fetching it from an unvetted URL is a supply-chain
187
+ * risk equivalent to importing a remote module (CWE-829). Pass `allowedOrigins`,
188
+ * or `unsafelyAllowAnyOrigin: true` to opt out deliberately. An `ArrayBuffer` /
189
+ * `Uint8Array` source needs neither: the bytes are already in hand.
190
+ *
191
+ * @example
192
+ * ```ts
193
+ * const math = wasm<{ add: (a: number, b: number) => number }>(
194
+ * 'https://cdn.example.com/math.wasm',
195
+ * { allowedOrigins: ['https://cdn.example.com'] },
196
+ * );
197
+ * // In reactive context:
198
+ * if (math.ready()) {
199
+ * const result = math.instance()!.add(1, 2);
200
+ * }
201
+ * ```
202
+ *
203
+ * @example Same-origin asset — still an explicit decision.
204
+ * ```ts
205
+ * const math = wasm('/math.wasm', { allowedOrigins: [location.origin] });
206
+ * ```
207
+ */
208
+ declare function wasm<T extends object = Record<string, unknown>>(source: string | ArrayBuffer | Uint8Array, config?: WasmConfig): {
209
+ instance: () => T | null;
210
+ loading: () => boolean;
211
+ error: () => Error | null;
212
+ ready: () => boolean;
213
+ reload: () => Promise<void>;
214
+ };
215
+ /**
216
+ * Load and instantiate a WebAssembly module.
217
+ * Supports loading from URL, ArrayBuffer, or Uint8Array.
218
+ *
219
+ * Caching: keyed by `cacheKey` (or, for a URL source, the URL itself). A keyed
220
+ * load is memoized as a **singleton instance** — every caller with the same key
221
+ * receives the *same* `WebAssembly.Instance`, which shares one linear memory and
222
+ * mutable globals. This is intentional (load-once / reuse), but it means callers
223
+ * that need isolated state must use distinct cache keys, or pass a non-URL source
224
+ * with no `cacheKey` (which instantiates fresh every call). Compiled modules are
225
+ * immutable and always safe to share.
226
+ */
227
+ interface LoadWasmOptions {
228
+ imports?: WebAssembly.Imports;
229
+ cacheKey?: string;
230
+ allowedOrigins?: string[];
231
+ /** Required when source is a URL and allowedOrigins is empty. WASM is
232
+ * compiled code with imports into JS memory — fetching from any URL is
233
+ * a supply-chain risk equivalent to remote module import (CWE-829). */
234
+ unsafelyAllowAnyOrigin?: boolean;
235
+ }
236
+ /**
237
+ * Load and instantiate a WebAssembly module — **positional/legacy form**.
238
+ *
239
+ * The second parameter is always `WebAssembly.Imports` and the third is always
240
+ * the cache key. There is no structural guessing, so a module namespace legally
241
+ * named `imports` or `cacheKey` is passed through unharmed.
242
+ *
243
+ * It previously accepted `WebAssembly.Imports | LoadWasmOptions` and decided
244
+ * between them at runtime by probing for `allowedOrigins` /
245
+ * `unsafelyAllowAnyOrigin`. That discriminator was unsound in both directions:
246
+ * an options bag carrying only `imports`/`cacheKey` was read as an import
247
+ * namespace (so `cacheKey` was dropped and the documented keyed-singleton
248
+ * guarantee silently did not hold), while a genuine namespace *named*
249
+ * `allowedOrigins` would have been read as options. No structural test can
250
+ * separate the two, because both are plain objects with caller-chosen keys — so
251
+ * the union was removed rather than re-guessed.
252
+ *
253
+ * For anything beyond imports and a cache key — notably the origin policy a URL
254
+ * source requires — use {@link loadWasmModuleWithOptions}.
255
+ *
256
+ * @see loadWasmModuleWithOptions
257
+ */
258
+ declare function loadWasmModule(source: string | ArrayBuffer | Uint8Array, imports?: WebAssembly.Imports, cacheKey?: string): Promise<WebAssembly.Instance>;
259
+ /**
260
+ * Load and instantiate a WebAssembly module — **options form**.
261
+ *
262
+ * Unambiguous by construction: options live in their own parameter, so a WASM
263
+ * module namespace named `imports`, `cacheKey`, or `allowedOrigins` is just a
264
+ * namespace and nothing has to be inferred from object shape.
265
+ *
266
+ * This is the form to use for a URL source, since the origin policy
267
+ * (`allowedOrigins`, or an explicit `unsafelyAllowAnyOrigin`) can only be
268
+ * expressed here.
269
+ *
270
+ * @example
271
+ * ```ts
272
+ * const instance = await loadWasmModuleWithOptions("https://cdn.example.com/math.wasm", {
273
+ * allowedOrigins: ["https://cdn.example.com"],
274
+ * imports: { env: { log: console.log } },
275
+ * cacheKey: "math",
276
+ * });
277
+ * ```
278
+ */
279
+ declare function loadWasmModuleWithOptions(source: string | ArrayBuffer | Uint8Array, opts?: LoadWasmOptions): Promise<WebAssembly.Instance>;
280
+ /**
281
+ * Preload and compile a WASM module without instantiating it.
282
+ * The compiled module is cached for instant instantiation later.
283
+ */
284
+ declare function preloadWasm(url: string, options?: {
285
+ allowedOrigins?: string[];
286
+ unsafelyAllowAnyOrigin?: boolean;
287
+ }): Promise<void>;
288
+ /**
289
+ * Create a type-safe bridge to a WASM module with automatic memory management.
290
+ * Provides helpers for passing strings and arrays between JS and WASM.
291
+ */
292
+ declare function createWasmBridge<T extends object>(instance: WebAssembly.Instance): {
293
+ exports: T;
294
+ memory: WebAssembly.Memory;
295
+ /** Allocate bytes in WASM memory (requires WASM to export malloc) */
296
+ alloc: (size: number) => number;
297
+ /** Free allocated memory (requires WASM to export free) */
298
+ free: (ptr: number) => void;
299
+ /** Write a string to WASM memory, returns pointer */
300
+ writeString: (str: string) => {
301
+ ptr: number;
302
+ len: number;
303
+ };
304
+ /** Read a string from WASM memory */
305
+ readString: (ptr: number, len: number) => string;
306
+ /** Write a typed array to WASM memory, returns pointer */
307
+ writeArray: (arr: ArrayLike<number>) => {
308
+ ptr: number;
309
+ len: number;
310
+ };
311
+ /** Read a Float64Array from WASM memory */
312
+ readF64Array: (ptr: number, len: number) => Float64Array;
313
+ };
314
+ /**
315
+ * Invalidate the module, instance, and in-flight WASM cache generations.
316
+ *
317
+ * CONTRACT: work already started may still resolve to the callers that started
318
+ * it, but must never repopulate the caches after the clear. A load in flight
319
+ * across this call therefore still returns its instance to whoever awaited it,
320
+ * while the cache stays empty and the next load for that key compiles and
321
+ * instantiates afresh.
322
+ *
323
+ * This is an invalidation BARRIER, not a `Map.clear()`: emptying the maps alone
324
+ * would let the invalidated work write its results straight back in.
325
+ */
326
+ declare function clearWasmCache(): void;
327
+ /**
328
+ * Check if a WASM module is cached.
329
+ */
330
+ declare function isWasmCached(key: string): boolean;
331
+
332
+ interface MicroAppConfig {
333
+ /** Unique name for this micro-frontend instance */
334
+ name: string;
335
+ /** Optional host element to mount into. Defaults to a new div. */
336
+ container?: HTMLElement;
337
+ /** If true, use Shadow DOM for style isolation */
338
+ shadow?: boolean;
339
+ }
340
+ interface MicroApp {
341
+ /** Mount a component into this micro-app container */
342
+ mount(component: () => HTMLElement): void;
343
+ /** Unmount the currently rendered component and clean up */
344
+ unmount(): void;
345
+ /** The outer host element */
346
+ element: HTMLElement;
347
+ }
348
+ interface SharedScope<T extends object> {
349
+ /** Get the current value for a key */
350
+ get<K extends keyof T>(key: K): T[K];
351
+ /** Set a value for a key, notifying all subscribers */
352
+ set<K extends keyof T>(key: K, value: T[K]): void;
353
+ /** Subscribe to changes on a specific key. Returns an unsubscribe function. */
354
+ subscribe<K extends keyof T>(key: K, callback: (value: T[K]) => void): () => void;
355
+ }
356
+ /**
357
+ * Creates an isolated micro-frontend container.
358
+ *
359
+ * Each micro-app gets its own DOM boundary. When `shadow: true` is set the
360
+ * component renders inside a Shadow DOM root so its styles are fully isolated
361
+ * from the host page.
362
+ *
363
+ * @example
364
+ * ```ts
365
+ * const app = createMicroApp({ name: "widget", shadow: true });
366
+ * document.body.appendChild(app.element);
367
+ *
368
+ * app.mount(() => div("Hello from micro-app!"));
369
+ *
370
+ * // Later, tear it down:
371
+ * app.unmount();
372
+ * ```
373
+ */
374
+ declare function createMicroApp(config: MicroAppConfig): MicroApp;
375
+ /**
376
+ * Dynamically load a remote ES module by URL.
377
+ *
378
+ * Modules are cached by URL so repeated calls with the same URL return the
379
+ * same promise without issuing another network request.
380
+ *
381
+ * An origin policy is REQUIRED: importing a remote module is remote code
382
+ * execution, so the call is refused unless you either restrict it with
383
+ * `allowedOrigins` or opt out deliberately with `unsafelyAllowAnyOrigin`
384
+ * (CWE-829).
385
+ *
386
+ * @example
387
+ * ```ts
388
+ * const charts = await loadRemoteModule("https://cdn.example.com/charts.js", {
389
+ * allowedOrigins: ["https://cdn.example.com"],
390
+ * });
391
+ * const el = charts.BarChart({ data: [1, 2, 3] });
392
+ * ```
393
+ */
394
+ interface LoadRemoteModuleOptions {
395
+ allowedOrigins?: string[];
396
+ /** Required when allowedOrigins is empty. Forces a deliberate decision
397
+ * to import code from any URL — equivalent to remote eval (CWE-829). */
398
+ unsafelyAllowAnyOrigin?: boolean;
399
+ }
400
+ declare function loadRemoteModule(url: string, optionsOrAllowedOrigins?: string[] | LoadRemoteModuleOptions): Promise<unknown>;
401
+ /**
402
+ * Loads the remote module whose `default` export is the component. Its root may
403
+ * be any `Element` — an SVG root included — using the public `Component` type
404
+ * rather than a private `() => HTMLElement` that forced a cast.
405
+ */
406
+ type RemoteLoader<R extends Element = HTMLElement> = () => Promise<{
407
+ default: Component<void, R>;
408
+ }>;
409
+ /**
410
+ * Register a remote component that loads on demand.
411
+ *
412
+ * Returns a component factory function. On first call it shows a loading
413
+ * placeholder, fetches the remote module, then swaps in the real component.
414
+ * Subsequent calls render instantly from the cached module.
415
+ *
416
+ * The load is owner-scoped: if the container is disposed before the module
417
+ * arrives, the module is still cached (it is shared and expensive to fetch) but
418
+ * the component is NOT instantiated and nothing is written into the dead
419
+ * container.
420
+ *
421
+ * @example
422
+ * ```ts
423
+ * const RemoteHeader = defineRemoteComponent(
424
+ * "remote-header",
425
+ * () =>
426
+ * loadRemoteModule("https://cdn.example.com/header.js", {
427
+ * allowedOrigins: ["https://cdn.example.com"],
428
+ * })
429
+ * );
430
+ *
431
+ * // Use it like any local component
432
+ * document.body.appendChild(RemoteHeader());
433
+ * ```
434
+ */
435
+ declare function defineRemoteComponent<R extends Element = HTMLElement>(name: string, loader: RemoteLoader<R>): Component<void, R | HTMLElement>;
436
+ /**
437
+ * Create a shared state scope that enables communication between independent
438
+ * micro-frontend instances.
439
+ *
440
+ * Each key in the scope can be read, written, and subscribed to independently.
441
+ * This is intentionally kept simpler than a full global store so micro-apps
442
+ * can share data with minimal coupling.
443
+ *
444
+ * @example
445
+ * ```ts
446
+ * const shared = createSharedScope({ user: null, theme: "light" });
447
+ *
448
+ * // Micro-app A sets a value
449
+ * shared.set("user", { name: "Alice" });
450
+ *
451
+ * // Micro-app B subscribes to changes
452
+ * const unsub = shared.subscribe("user", (user) => {
453
+ * console.log("User changed:", user);
454
+ * });
455
+ *
456
+ * // Later
457
+ * unsub();
458
+ * ```
459
+ */
460
+ declare function createSharedScope<T extends object>(initialState: T): SharedScope<T>;
461
+
462
+ interface ServiceWorkerState {
463
+ registration: () => ServiceWorkerRegistration | null;
464
+ isReady: () => boolean;
465
+ isUpdateAvailable: () => boolean;
466
+ error: () => Error | null;
467
+ update: () => Promise<void>;
468
+ unregister: () => Promise<boolean>;
469
+ }
470
+ /**
471
+ * serviceWorker registers and manages a service worker.
472
+ *
473
+ * TRUST BOUNDARY: `scriptUrl` is CODE. A service worker runs with authority
474
+ * over every page in its scope and persists across reloads, so this is the
475
+ * strongest code-loading primitive in the framework. The browser enforces
476
+ * same-origin, a secure context and a JavaScript MIME type — it does NOT
477
+ * protect against a same-origin URL that serves attacker-influenced content
478
+ * (a JSONP endpoint, an upload directory). Pass only a literal path to a worker
479
+ * script you ship; never a value derived from the URL, storage or an API
480
+ * response.
481
+ *
482
+ * LIFECYCLE CONTRACT
483
+ * ------------------
484
+ * Registration is asynchronous and `unregister()` can be called at any point
485
+ * during it, so this tracks four distinct situations rather than one boolean:
486
+ *
487
+ * registering register() in flight, nothing to unregister yet
488
+ * active registration adopted, listeners attached
489
+ * unregister asked requested before the registration resolved — the arriving
490
+ * registration is unregistered rather than adopted, so the
491
+ * browser never keeps a worker SibuJS has forgotten
492
+ * unregistered terminal, and only entered once unregister() actually
493
+ * RETURNED TRUE
494
+ *
495
+ * The last point is the important one. `ServiceWorkerRegistration.unregister()`
496
+ * returns `false` when the browser declined — the worker is still installed and
497
+ * still controlling pages. Treating that as teardown (detaching listeners,
498
+ * dropping the registration) left the wrapper permanently blind to a worker
499
+ * that was very much alive: no update tracking, no registration, no way back.
500
+ * A failed unregister therefore changes nothing.
501
+ */
502
+ declare function serviceWorker(scriptUrl: string, options?: RegistrationOptions): ServiceWorkerState;
503
+
504
+ interface SSGOptions {
505
+ routes: string[];
506
+ renderFn: (path: string) => Promise<string>;
507
+ outDir?: string;
508
+ }
509
+ interface SSGResult {
510
+ pages: Array<{
511
+ path: string;
512
+ html: string;
513
+ }>;
514
+ errors: Array<{
515
+ path: string;
516
+ error: Error;
517
+ }>;
518
+ }
519
+ /**
520
+ * Generate a static site by iterating over routes and collecting rendered HTML.
521
+ * This is a pure async function — it does NOT write files, only returns results.
522
+ */
523
+ declare function generateStaticSite(options: SSGOptions): Promise<SSGResult>;
524
+
525
+ interface ISROptions<T> {
526
+ revalidateAfter: number;
527
+ fetcher: (ctx?: {
528
+ signal: AbortSignal;
529
+ }) => Promise<T>;
530
+ initialData?: T;
531
+ }
532
+ /**
533
+ * Creates an Incremental Static Regeneration (ISR) resource.
534
+ * Data is fetched initially, then automatically revalidated once it goes stale.
535
+ *
536
+ * `isStale()` is a reactive signal: it flips to `true` when `revalidateAfter`
537
+ * elapses since the last successful fetch (effects re-run at that moment), stays
538
+ * `true` while a revalidation is pending or after one fails, and returns to
539
+ * `false` when a revalidation succeeds.
540
+ *
541
+ * `revalidate()` called while a revalidation is running joins it instead of
542
+ * starting another: the fetcher runs once, and every caller's promise settles
543
+ * — resolving, or rejecting with the same error — when that fetch does.
544
+ *
545
+ * @throws RangeError when `revalidateAfter` is not a positive finite number.
546
+ */
547
+ declare function createISR<T>(options: ISROptions<T>): {
548
+ data: () => T | undefined;
549
+ isStale: () => boolean;
550
+ revalidate: () => Promise<void>;
551
+ dispose: () => void;
552
+ };
553
+
554
+ type ActionFn<T = unknown> = (data: FormData | Record<string, unknown>) => Promise<T>;
555
+ interface ActionResult<T> {
556
+ data: () => T | undefined;
557
+ error: () => Error | undefined;
558
+ loading: () => boolean;
559
+ submit: (data: FormData | Record<string, unknown>) => Promise<T>;
560
+ }
561
+ /**
562
+ * Creates a managed action for handling POST/PUT/DELETE-style mutations.
563
+ * Provides reactive loading, error, and data state via signal.
564
+ * State updates are batched to avoid redundant notifications.
565
+ */
566
+ declare function createAction<T>(actionFn: ActionFn<T>): ActionResult<T>;
567
+
568
+ interface ScrollRestorationOptions {
569
+ /**
570
+ * `"auto"` (default) manages history-entry identity and restores the
571
+ * destination on `popstate`. It tags the entry the page started on, tags each
572
+ * entry you announce with `onNavigation()`, saves the outgoing position, and
573
+ * takes over `history.scrollRestoration` so the browser does not restore in
574
+ * parallel.
575
+ *
576
+ * What auto mode CANNOT do is notice a `history.pushState` it was not told
577
+ * about — no library can, short of monkey-patching `history` globally. Entries
578
+ * created without `onNavigation()` carry no identity and are simply not
579
+ * restored (a safe no-op, not a wrong position).
580
+ *
581
+ * `"manual"` attaches no listener, claims no native restoration, and tags
582
+ * nothing — you call `save()` / `restore()` yourself.
583
+ */
584
+ mode?: "auto" | "manual";
585
+ /**
586
+ * Identifies the entry the user is currently on. Called once at construction
587
+ * to seed the current entry, and consulted as a fallback when nothing has
588
+ * been saved yet.
589
+ *
590
+ * Point it at whatever your app treats as a history identity — e.g.
591
+ * `() => router.location().key`. Pathname alone is usually wrong: `?page=2`
592
+ * and `#section` are distinct scroll positions to a user.
593
+ */
594
+ getKey?: () => string | null;
595
+ /**
596
+ * History-state property used to tag entries so a `popstate` can name its
597
+ * DESTINATION. `popstate` reports the state of the entry being restored, and
598
+ * that is the only reliable way to know where the user just landed.
599
+ */
600
+ stateKey?: string;
601
+ }
602
+ /**
603
+ * Manages scroll position saving and restoration keyed by route/key.
604
+ *
605
+ * AUTO MODE
606
+ * ---------
607
+ * `"auto"` previously attached a `popstate` listener that only ever called
608
+ * `save()` — so the documented "save/restore on popstate" behaviour was half
609
+ * implemented, and going Back never returned the viewport anywhere. The whole
610
+ * point of the feature was the half that was missing.
611
+ *
612
+ * A real restore needs to know WHICH entry the user landed on, so auto mode
613
+ * tags history entries with their key (`stateKey`) and the `popstate` handler
614
+ * reads that tag off `event.state`. On each pop it:
615
+ *
616
+ * 1. saves the position of the entry being LEFT (unless it is also the
617
+ * destination — a same-key pop is not a departure, and saving there would
618
+ * overwrite the stored position with the current one, destroying exactly
619
+ * the value about to be restored)
620
+ * 2. restores the destination's saved position, if one exists
621
+ *
622
+ * An unknown or absent destination key is a safe SibuJS no-op: no guessed
623
+ * position is applied. Note this is not a hand-off to the browser — auto mode
624
+ * leases `history.scrollRestoration` to `"manual"` while active, so nothing
625
+ * else is restoring either. The viewport simply stays where the engine left it.
626
+ *
627
+ * WHAT "AUTO" MEANS, EXACTLY
628
+ * --------------------------
629
+ * Reacting to `popstate` automatically is not enough on its own: the handler
630
+ * can only restore an entry that HAS an identity, and originally nothing ever
631
+ * gave one to the entry the page started on. The first Back a user pressed
632
+ * therefore restored nothing. Auto mode now owns identity as well as reaction:
633
+ *
634
+ * - the INITIAL entry is tagged at construction, and
635
+ * - `onNavigation(key)` tags each entry the application creates.
636
+ *
637
+ * That second half is an explicit hook rather than magic, and deliberately so:
638
+ * a library cannot observe arbitrary `history.pushState` calls without patching
639
+ * `history` globally, which would surprise every other consumer of it. So the
640
+ * honest contract is:
641
+ *
642
+ * > Auto mode restores any entry it was given identity for, and never guesses
643
+ * > about entries it was not told about.
644
+ *
645
+ * Auto mode also leases `history.scrollRestoration = "manual"` while active, so
646
+ * the browser is not restoring the viewport at the same time SibuJS is. The
647
+ * previous value is restored when the last controller is disposed.
648
+ */
649
+ declare function scrollRestoration(options?: ScrollRestorationOptions): {
650
+ save: (key: string) => void;
651
+ restore: (key: string) => void;
652
+ /**
653
+ * Tell auto mode that the application created a new history entry.
654
+ *
655
+ * Records the outgoing entry's position, tags the new entry with `key`, and
656
+ * makes it current. Call it immediately after your `pushState` (before any
657
+ * scrolling), so the position captured is the one the user is leaving.
658
+ */
659
+ onNavigation: (key: string) => void;
660
+ getPosition: (key: string) => {
661
+ x: number;
662
+ y: number;
663
+ } | undefined;
664
+ dispose: () => void;
665
+ };
666
+
667
+ type MiddlewareFn = (context: {
668
+ path: string;
669
+ params: Record<string, string>;
670
+ }, next: () => void | Promise<void>) => void | Promise<void>;
671
+ /**
672
+ * Composes multiple middleware functions into a single middleware.
673
+ * Each middleware must call next() to proceed to the next one.
674
+ */
675
+ declare function composeMiddleware(...fns: MiddlewareFn[]): MiddlewareFn;
676
+ /**
677
+ * Creates a middleware chain with a builder API.
678
+ * Use `use()` to add middleware, and `run()` to execute the chain.
679
+ */
680
+ declare function createMiddlewareChain(): {
681
+ use: (fn: MiddlewareFn) => void;
682
+ run: (context: {
683
+ path: string;
684
+ params: Record<string, string>;
685
+ }) => Promise<void>;
686
+ };
687
+
688
+ export { type ActionFn as A, preloadWasm as B, scrollRestoration as C, serviceWorker as D, setCanonical as E, setStructuredData as F, wasm as G, Head as H, type ISROptions as I, worker as J, workerFn as K, type LoadRemoteModuleOptions as L, type MicroApp as M, type SSGOptions as S, type UseWorkerFnReturn as U, type WasmConfig as W, type ActionResult as a, type LoadWasmOptions as b, type MicroAppConfig as c, type MiddlewareFn as d, type SSGResult as e, type ScrollRestorationOptions as f, type ServiceWorkerState as g, type SharedScope as h, type UseWorkerReturn as i, type WasmModuleState as j, type WorkerPool as k, clearWasmCache as l, composeMiddleware as m, createAction as n, createISR as o, createMicroApp as p, createMiddlewareChain as q, createSharedScope as r, createWasmBridge as s, createWorkerPool as t, defineRemoteComponent as u, generateStaticSite as v, isWasmCached as w, loadRemoteModule as x, loadWasmModule as y, loadWasmModuleWithOptions as z };