@vertz/ui-server 0.2.24 → 0.2.26

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.
@@ -1,6 +1,6 @@
1
1
  type ErrorCategory = "build" | "resolve" | "runtime" | "ssr";
2
2
  import { CSSExtractionResult } from "@vertz/ui-compiler";
3
- type DebugCategory = "fields" | "manifest" | "plugin" | "ssr" | "watcher" | "ws";
3
+ type DebugCategory = "aot" | "fields" | "manifest" | "plugin" | "prefetch" | "ssr" | "watcher" | "ws";
4
4
  interface DebugLogger {
5
5
  log(category: DebugCategory, message: string, data?: Record<string, unknown>): void;
6
6
  isEnabled(category: DebugCategory): boolean;
@@ -13,6 +13,7 @@ interface VNode {
13
13
  * Base Node class for SSR — matches the browser's Node interface minimally
14
14
  */
15
15
  declare class SSRNode {
16
+ nodeType: number;
16
17
  childNodes: SSRNode[];
17
18
  parentNode: SSRNode | null;
18
19
  get firstChild(): SSRNode | null;
@@ -28,6 +29,7 @@ declare class SSRNode {
28
29
  * hydration cursor can claim during mount.
29
30
  */
30
31
  declare class SSRComment extends SSRNode {
32
+ nodeType: number;
31
33
  text: string;
32
34
  constructor(text: string);
33
35
  get data(): string;
@@ -37,6 +39,7 @@ declare class SSRComment extends SSRNode {
37
39
  * SSR text node
38
40
  */
39
41
  declare class SSRTextNode extends SSRNode {
42
+ nodeType: number;
40
43
  text: string;
41
44
  constructor(text: string);
42
45
  get data(): string;
@@ -46,6 +49,7 @@ declare class SSRTextNode extends SSRNode {
46
49
  * SSR document fragment
47
50
  */
48
51
  declare class SSRDocumentFragment extends SSRNode {
52
+ nodeType: number;
49
53
  children: (SSRElement | string)[];
50
54
  appendChild(child: SSRElement | SSRTextNode | SSRDocumentFragment): void;
51
55
  }
@@ -7,7 +7,7 @@ import {
7
7
  installDomShim,
8
8
  removeDomShim,
9
9
  toVNode
10
- } from "../shared/chunk-zs75v8qj.js";
10
+ } from "../shared/chunk-gcwqkynf.js";
11
11
  export {
12
12
  toVNode,
13
13
  removeDomShim,
package/dist/index.d.ts CHANGED
@@ -1,3 +1,16 @@
1
+ import { FallbackFontName as FallbackFontName2, FontFallbackMetrics as FontFallbackMetrics7 } from "@vertz/ui";
2
+ interface AotBuildComponentEntry {
3
+ tier: "static" | "data-driven" | "conditional" | "runtime-fallback";
4
+ holes: string[];
5
+ }
6
+ interface AotBuildManifest {
7
+ components: Record<string, AotBuildComponentEntry>;
8
+ classificationLog: string[];
9
+ }
10
+ /**
11
+ * Scan all TSX files in srcDir and generate an AOT build manifest.
12
+ */
13
+ declare function generateAotBuildManifest(srcDir: string): AotBuildManifest;
1
14
  /** A raw HTML string that bypasses escaping during serialization. */
2
15
  interface RawHtml {
3
16
  __raw: true;
@@ -80,7 +93,6 @@ declare function renderAssetTags(assets: AssetDescriptor[]): string;
80
93
  * Returns an empty string if the CSS is empty.
81
94
  */
82
95
  declare function inlineCriticalCss(css: string): string;
83
- import { FallbackFontName as FallbackFontName2, FontFallbackMetrics as FontFallbackMetrics5 } from "@vertz/ui";
84
96
  import { FallbackFontName, FontDescriptor, FontFallbackMetrics } from "@vertz/ui";
85
97
  /**
86
98
  * Auto-detect which system font to use as fallback base.
@@ -317,6 +329,85 @@ declare function resetSlotCounter(): void;
317
329
  declare function createSlotPlaceholder(fallback: VNode | string): VNode & {
318
330
  _slotId: number;
319
331
  };
332
+ /**
333
+ * SSR prefetch access rule evaluator.
334
+ *
335
+ * Evaluates serialized entity access rules against the current session
336
+ * to determine whether a query should be prefetched during SSR.
337
+ *
338
+ * The serialized rules come from the prefetch manifest (generated at build time).
339
+ * The session comes from the JWT decoded at request time.
340
+ */
341
+ /**
342
+ * Serialized access rule — the JSON-friendly format stored in the manifest.
343
+ * Mirrors SerializedRule from @vertz/server/auth/rules but defined here
344
+ * to avoid importing the server package into the SSR pipeline.
345
+ */
346
+ type SerializedAccessRule = {
347
+ type: "public";
348
+ } | {
349
+ type: "authenticated";
350
+ } | {
351
+ type: "role";
352
+ roles: string[];
353
+ } | {
354
+ type: "entitlement";
355
+ value: string;
356
+ } | {
357
+ type: "where";
358
+ conditions: Record<string, unknown>;
359
+ } | {
360
+ type: "all";
361
+ rules: SerializedAccessRule[];
362
+ } | {
363
+ type: "any";
364
+ rules: SerializedAccessRule[];
365
+ } | {
366
+ type: "fva";
367
+ maxAge: number;
368
+ } | {
369
+ type: "deny";
370
+ };
371
+ /**
372
+ * Minimal session shape needed for prefetch access evaluation.
373
+ * Extracted from the JWT at SSR request time.
374
+ */
375
+ type PrefetchSession = {
376
+ status: "authenticated";
377
+ roles?: string[];
378
+ entitlements?: Record<string, boolean>;
379
+ tenantId?: string;
380
+ } | {
381
+ status: "unauthenticated";
382
+ };
383
+ /**
384
+ * Convert SSRAuth (from the JWT/session resolver) to PrefetchSession
385
+ * for entity access evaluation during SSR prefetching.
386
+ */
387
+ declare function toPrefetchSession(ssrAuth: {
388
+ status: string;
389
+ user?: {
390
+ role?: string;
391
+ [key: string]: unknown;
392
+ };
393
+ } | undefined): PrefetchSession;
394
+ /**
395
+ * Evaluate a serialized access rule against the current session.
396
+ *
397
+ * Returns true if the query is eligible for prefetch (the user
398
+ * likely has access), false if it should be skipped.
399
+ *
400
+ * Design rationale for specific rule types:
401
+ * - `where` → true: row-level filter, not an access gate. The query
402
+ * always executes; it just returns fewer rows for non-owners.
403
+ * - `fva` → optimistic for authenticated users: MFA freshness is
404
+ * enforced on the actual API call. If the check fails server-side,
405
+ * the query returns an error result.
406
+ * - `deny` → false: explicitly denied operations are never prefetched.
407
+ * - Unknown types → false: fail-secure. Don't prefetch if we can't
408
+ * evaluate the rule.
409
+ */
410
+ declare function evaluateAccessRule(rule: SerializedAccessRule, session: PrefetchSession): boolean;
320
411
  import { AccessSet } from "@vertz/ui/auth";
321
412
  /**
322
413
  * Extract an AccessSet from a decoded JWT payload for SSR injection.
@@ -343,38 +434,114 @@ import { RenderAdapter } from "@vertz/ui/internals";
343
434
  * Replaces `installDomShim()` — no global mutation needed.
344
435
  */
345
436
  declare function createSSRAdapter(): RenderAdapter;
346
- import { AsyncLocalStorage } from "node:async_hooks";
347
- import { SSRQueryEntry, SSRRenderContext } from "@vertz/ui/internals";
348
- import { SSRQueryEntry as SSRQueryEntry2 } from "@vertz/ui/internals";
349
- declare const ssrStorage: AsyncLocalStorage<SSRRenderContext>;
350
- declare function isInSSR(): boolean;
351
- declare function getSSRUrl(): string | undefined;
352
- /**
353
- * Register an SSR query for awaiting before final render.
354
- * No-op when called outside an SSR context.
355
- */
356
- declare function registerSSRQuery(entry: SSRQueryEntry): void;
357
- /**
358
- * Get all registered SSR queries for the current render.
359
- * Returns an empty array when called outside an SSR context.
360
- */
361
- declare function getSSRQueries(): SSRRenderContext["queries"];
362
- /**
363
- * Set the global SSR timeout for queries that don't specify their own.
364
- * Called by the virtual SSR entry to propagate the plugin-level ssrTimeout.
365
- * Stored in the per-request SSR context (AsyncLocalStorage), not on globalThis.
366
- */
367
- declare function setGlobalSSRTimeout(timeout: number): void;
368
437
  /**
369
- * Clear the global SSR timeout (cleanup after render).
438
+ * AOT SSR Diagnostics
439
+ *
440
+ * Tracks AOT compilation results and provides a JSON snapshot
441
+ * for the `/__vertz_ssr_aot` dev endpoint.
370
442
  */
371
- declare function clearGlobalSSRTimeout(): void;
443
+ /** AOT tier classification (mirrored from @vertz/ui-compiler to avoid cross-package dependency). */
444
+ type AotTier = "static" | "data-driven" | "conditional" | "runtime-fallback";
445
+ /** Per-component diagnostic entry in the snapshot. */
446
+ interface AotComponentDiagnostic {
447
+ tier: AotTier;
448
+ holes: string[];
449
+ }
450
+ /** A recorded divergence between AOT and DOM shim output. */
451
+ interface AotDivergenceEntry {
452
+ component: string;
453
+ aotHtml: string;
454
+ domHtml: string;
455
+ timestamp: string;
456
+ }
457
+ /** JSON snapshot returned by the `/__vertz_ssr_aot` endpoint. */
458
+ interface AotDiagnosticsSnapshot {
459
+ components: Record<string, AotComponentDiagnostic>;
460
+ coverage: {
461
+ total: number;
462
+ aot: number;
463
+ runtime: number;
464
+ percentage: number;
465
+ };
466
+ divergences: AotDivergenceEntry[];
467
+ }
468
+ /** Input shape matching AotComponentInfo from @vertz/ui-compiler. */
469
+ interface ComponentInput {
470
+ name: string;
471
+ tier: AotTier;
472
+ holes: string[];
473
+ }
372
474
  /**
373
- * Get the global SSR timeout for the current SSR context.
374
- * Returns undefined if not set or outside SSR context.
475
+ * Collects AOT compilation diagnostics and produces JSON snapshots.
476
+ *
477
+ * Used by the dev server to power the `/__vertz_ssr_aot` endpoint
478
+ * and by the build pipeline for classification logging.
375
479
  */
376
- declare function getGlobalSSRTimeout(): number | undefined;
377
- import { FontFallbackMetrics as FontFallbackMetrics4 } from "@vertz/ui";
480
+ declare class AotDiagnostics {
481
+ private _components;
482
+ private _divergences;
483
+ /**
484
+ * Record components from an AOT compilation result.
485
+ * Called once per file during compilation or hot rebuild.
486
+ */
487
+ recordCompilation(components: ComponentInput[]): void;
488
+ /** Record a divergence between AOT and DOM shim HTML output. */
489
+ recordDivergence(component: string, aotHtml: string, domHtml: string): void;
490
+ /** Clear all recorded data (used during full rebuild). */
491
+ clear(): void;
492
+ /** Clear only component classifications (preserves divergences). */
493
+ clearComponents(): void;
494
+ /**
495
+ * Generate per-component classification log lines.
496
+ * Used by the build pipeline and VERTZ_DEBUG=aot logging.
497
+ *
498
+ * Returns lines like:
499
+ * - "Header: static"
500
+ * - "Dashboard: conditional, 1 hole (SidePanel)"
501
+ * - "Coverage: 3/4 components (75%)"
502
+ */
503
+ getClassificationLog(): string[];
504
+ /** Produce a JSON-serializable snapshot for the diagnostic endpoint. */
505
+ getSnapshot(): AotDiagnosticsSnapshot;
506
+ }
507
+ /** Per-component entry in the dev AOT manifest. */
508
+ interface AotDevComponentEntry {
509
+ tier: "static" | "data-driven" | "conditional" | "runtime-fallback";
510
+ holes: string[];
511
+ /** The file this component was compiled from. */
512
+ file: string;
513
+ }
514
+ /** Dev-mode AOT manifest — tracks all components across all files. */
515
+ interface AotDevManifest {
516
+ components: Record<string, AotDevComponentEntry>;
517
+ }
518
+ interface AotManifestSnapshot {
519
+ manifest: AotDevManifest | null;
520
+ rebuildCount: number;
521
+ lastRebuildMs: number | null;
522
+ lastRebuildAt: string | null;
523
+ }
524
+ interface AotManifestManagerOptions {
525
+ /** Read a file's contents. Returns undefined if file doesn't exist. */
526
+ readFile: (path: string) => string | undefined;
527
+ /** List all files in the source directory (absolute paths). */
528
+ listFiles: () => string[];
529
+ }
530
+ interface AotManifestManager {
531
+ /** Initial full build — compile all TSX files. */
532
+ build(): void;
533
+ /** Handle a file change — recompile a single file. */
534
+ onFileChange(filePath: string, sourceText: string): void;
535
+ /** Get the current manifest (atomic read). */
536
+ getManifest(): AotDevManifest | null;
537
+ /** Get diagnostic snapshot for endpoints. */
538
+ getSnapshot(): AotManifestSnapshot;
539
+ /** Get AotDiagnostics instance for the diagnostics endpoint. */
540
+ getDiagnostics(): AotDiagnostics;
541
+ }
542
+ declare function createAotManifestManager(options: AotManifestManagerOptions): AotManifestManager;
543
+ import { FontFallbackMetrics as FontFallbackMetrics5 } from "@vertz/ui";
544
+ import { SSRAuth as SSRAuth2 } from "@vertz/ui/internals";
378
545
  import { CompiledRoute, FontFallbackMetrics as FontFallbackMetrics3, Theme as Theme2 } from "@vertz/ui";
379
546
  import { SSRAuth as SSRAuth_jq1nwm } from "@vertz/ui/internals";
380
547
  interface SSRModule {
@@ -393,6 +560,8 @@ interface SSRModule {
393
560
  getInjectedCSS?: () => string[];
394
561
  /** Compiled routes exported from the app for build-time SSG with generateParams. */
395
562
  routes?: CompiledRoute[];
563
+ /** Code-generated API client for manifest-driven zero-discovery prefetching. */
564
+ api?: Record<string, Record<string, (...args: unknown[]) => unknown>>;
396
565
  }
397
566
  interface SSRRenderResult {
398
567
  html: string;
@@ -441,6 +610,206 @@ declare function ssrRenderToString(module: SSRModule, url: string, options?: {
441
610
  declare function ssrDiscoverQueries(module: SSRModule, url: string, options?: {
442
611
  ssrTimeout?: number;
443
612
  }): Promise<SSRDiscoverResult>;
613
+ import { FontFallbackMetrics as FontFallbackMetrics4 } from "@vertz/ui";
614
+ import { SSRAuth } from "@vertz/ui/internals";
615
+ import { ExtractedQuery } from "@vertz/ui-compiler";
616
+ /** Serialized entity access rules from the prefetch manifest. */
617
+ type EntityAccessMap = Record<string, Partial<Record<string, SerializedAccessRule>>>;
618
+ interface SSRPrefetchManifest {
619
+ /** Route patterns present in the manifest. */
620
+ routePatterns: string[];
621
+ /** Entity access rules keyed by entity name → operation → serialized rule. */
622
+ entityAccess?: EntityAccessMap;
623
+ /** Route entries with query binding metadata for zero-discovery prefetch. */
624
+ routeEntries?: Record<string, {
625
+ queries: ExtractedQuery[];
626
+ }>;
627
+ }
628
+ interface SSRSinglePassOptions {
629
+ ssrTimeout?: number;
630
+ /** Pre-computed font fallback metrics (computed at server startup). */
631
+ fallbackMetrics?: Record<string, FontFallbackMetrics4>;
632
+ /** Auth state resolved from session cookie. */
633
+ ssrAuth?: SSRAuth;
634
+ /** Set to false to fall back to two-pass rendering. Default: true. */
635
+ prefetch?: boolean;
636
+ /** Prefetch manifest for entity access filtering. */
637
+ manifest?: SSRPrefetchManifest;
638
+ /** Session data for access rule evaluation. */
639
+ prefetchSession?: PrefetchSession;
640
+ }
641
+ /**
642
+ * Render an SSR module in a single pass via discovery-only execution.
643
+ *
644
+ * 1. Discovery: Run the app factory to capture query registrations (no stream render)
645
+ * 2. Prefetch: Await all discovered queries with timeout
646
+ * 3. Render: Create a fresh context with pre-populated cache, render once
647
+ *
648
+ * Falls back to two-pass (`ssrRenderToString`) when:
649
+ * - `prefetch: false` is set
650
+ * - A redirect is detected during discovery
651
+ */
652
+ declare function ssrRenderSinglePass(module: SSRModule, url: string, options?: SSRSinglePassOptions): Promise<SSRRenderResult>;
653
+ /** Context passed to AOT render functions for accessing data and runtime holes. */
654
+ interface SSRAotContext {
655
+ /** Pre-generated closures for runtime-rendered components. */
656
+ holes: Record<string, () => string>;
657
+ /** Access query data by cache key. */
658
+ getData(key: string): unknown;
659
+ /** Auth session for conditional rendering. */
660
+ session: PrefetchSession | undefined;
661
+ /** Route params for the current request. */
662
+ params: Record<string, string>;
663
+ }
664
+ /** An AOT render function: takes props/data and context, returns HTML string. */
665
+ type AotRenderFn = (data: Record<string, unknown>, ctx: SSRAotContext) => string;
666
+ /** Per-route AOT entry in the manifest. */
667
+ interface AotRouteEntry {
668
+ /** The pre-compiled render function. */
669
+ render: AotRenderFn;
670
+ /** Component names that need runtime fallback (holes). */
671
+ holes: string[];
672
+ /** Query cache keys this route reads via ctx.getData(). */
673
+ queryKeys?: string[];
674
+ }
675
+ /**
676
+ * AOT manifest — maps route patterns to pre-compiled render functions.
677
+ *
678
+ * Generated at build time by the AOT compiler pipeline.
679
+ */
680
+ interface AotManifest {
681
+ /** Route pattern → AOT entry. */
682
+ routes: Record<string, AotRouteEntry>;
683
+ }
684
+ /** Options for `ssrRenderAot()`. */
685
+ interface SSRRenderAotOptions {
686
+ /** AOT manifest with pre-compiled render functions. */
687
+ aotManifest: AotManifest;
688
+ /** Prefetch manifest for route matching and data fetching. */
689
+ manifest?: SSRPrefetchManifest;
690
+ /** SSR timeout in ms. */
691
+ ssrTimeout?: number;
692
+ /** Pre-computed font fallback metrics. */
693
+ fallbackMetrics?: Record<string, FontFallbackMetrics5>;
694
+ /** Auth state resolved from session cookie. */
695
+ ssrAuth?: SSRAuth2;
696
+ /** Session data for access rule evaluation. */
697
+ prefetchSession?: PrefetchSession;
698
+ /** AOT diagnostics collector (dev mode). When provided with VERTZ_DEBUG=aot, enables dual rendering and divergence detection. */
699
+ diagnostics?: AotDiagnostics;
700
+ }
701
+ /**
702
+ * Create closure-based runtime fallback renderers for components
703
+ * that cannot be AOT-compiled.
704
+ *
705
+ * Each hole closure:
706
+ * 1. Runs inside `ssrStorage.run()` to provide SSRRenderContext
707
+ * 2. Calls the component factory via the SSR module
708
+ * 3. Converts the result to VNode and serializes to HTML string
709
+ * 4. Shares the query cache with the AOT function
710
+ *
711
+ * @param holeNames - Component names that need runtime rendering
712
+ * @param module - SSR module with component factories
713
+ * @param url - Request URL for context
714
+ * @param queryCache - Pre-populated query cache (shared with AOT)
715
+ * @param ssrAuth - Auth state for the request
716
+ */
717
+ declare function createHoles(holeNames: string[], module: SSRModule, url: string, queryCache: Map<string, unknown>, ssrAuth?: SSRAuth2): Record<string, () => string>;
718
+ /**
719
+ * Render a page using pre-compiled AOT string-builder functions.
720
+ *
721
+ * Falls back to `ssrRenderSinglePass()` when:
722
+ * - No route match in the AOT manifest
723
+ * - No prefetch manifest for route matching
724
+ *
725
+ * Pipeline:
726
+ * 1. Match URL to route pattern
727
+ * 2. Look up AOT entry in manifest
728
+ * 3. Prefetch query data (reuses single-pass prefetch logic)
729
+ * 4. Create runtime holes (closures for non-AOT components)
730
+ * 5. Call AOT render function with data + context
731
+ * 6. Collect CSS, ssrData, headTags
732
+ * 7. Return SSRRenderResult
733
+ */
734
+ declare function ssrRenderAot(module: SSRModule, url: string, options: SSRRenderAotOptions): Promise<SSRRenderResult>;
735
+ /** Check if VERTZ_DEBUG includes the 'aot' category. */
736
+ declare function isAotDebugEnabled(): boolean;
737
+ /**
738
+ * SSR AOT Runtime Helpers
739
+ *
740
+ * Lightweight runtime functions used by AOT-compiled SSR string-builder
741
+ * functions. These are injected at the top of compiled output and called
742
+ * inline during string concatenation.
743
+ *
744
+ * Design constraints:
745
+ * - Must produce identical output to html-serializer.ts escapeHtml/escapeAttr
746
+ * - Must be fast — called per-element, per-attribute during SSR
747
+ * - No dependencies beyond this file
748
+ */
749
+ type Renderable = any;
750
+ /**
751
+ * Escape HTML text content. Matches escapeHtml() from html-serializer.ts exactly.
752
+ *
753
+ * Handles: null, undefined, false → '', true → 'true', numbers → string,
754
+ * arrays → recursive join.
755
+ */
756
+ declare function __esc(value: Renderable): string;
757
+ /**
758
+ * Escape HTML attribute value. Matches escapeAttr() from html-serializer.ts exactly.
759
+ */
760
+ declare function __esc_attr(value: Renderable): string;
761
+ /**
762
+ * Render a props object as an HTML attribute string for spread attributes.
763
+ *
764
+ * - Skips null/undefined/false values
765
+ * - Skips event handlers (on* props)
766
+ * - Maps className → class
767
+ * - Boolean true → attribute name only (no value)
768
+ * - Escapes string values
769
+ */
770
+ declare function __ssr_spread(props: Record<string, Renderable>): string;
771
+ /**
772
+ * Convert a style object to a CSS string.
773
+ *
774
+ * - camelCase → kebab-case
775
+ * - Numeric values get 'px' appended for non-unitless properties
776
+ * - Zero is never suffixed with 'px'
777
+ * - Skips null, undefined, empty string values
778
+ * - Preserves CSS custom properties and vendor prefixes
779
+ */
780
+ declare function __ssr_style_object(style: Record<string, Renderable>): string;
781
+ import { AsyncLocalStorage } from "node:async_hooks";
782
+ import { SSRQueryEntry, SSRRenderContext as SSRRenderContext2 } from "@vertz/ui/internals";
783
+ import { SSRQueryEntry as SSRQueryEntry2 } from "@vertz/ui/internals";
784
+ declare const ssrStorage: AsyncLocalStorage<SSRRenderContext2>;
785
+ declare function isInSSR(): boolean;
786
+ declare function getSSRUrl(): string | undefined;
787
+ /**
788
+ * Register an SSR query for awaiting before final render.
789
+ * No-op when called outside an SSR context.
790
+ */
791
+ declare function registerSSRQuery(entry: SSRQueryEntry): void;
792
+ /**
793
+ * Get all registered SSR queries for the current render.
794
+ * Returns an empty array when called outside an SSR context.
795
+ */
796
+ declare function getSSRQueries(): SSRRenderContext2["queries"];
797
+ /**
798
+ * Set the global SSR timeout for queries that don't specify their own.
799
+ * Called by the virtual SSR entry to propagate the plugin-level ssrTimeout.
800
+ * Stored in the per-request SSR context (AsyncLocalStorage), not on globalThis.
801
+ */
802
+ declare function setGlobalSSRTimeout(timeout: number): void;
803
+ /**
804
+ * Clear the global SSR timeout (cleanup after render).
805
+ */
806
+ declare function clearGlobalSSRTimeout(): void;
807
+ /**
808
+ * Get the global SSR timeout for the current SSR context.
809
+ * Returns undefined if not set or outside SSR context.
810
+ */
811
+ declare function getGlobalSSRTimeout(): number | undefined;
812
+ import { FontFallbackMetrics as FontFallbackMetrics6 } from "@vertz/ui";
444
813
  import { AccessSet as AccessSet2 } from "@vertz/ui/auth";
445
814
  interface SessionData {
446
815
  user: {
@@ -502,7 +871,7 @@ interface SSRHandlerOptions {
502
871
  */
503
872
  nonce?: string;
504
873
  /** Pre-computed font fallback metrics (computed at server startup). */
505
- fallbackMetrics?: Record<string, FontFallbackMetrics4>;
874
+ fallbackMetrics?: Record<string, FontFallbackMetrics6>;
506
875
  /** Paths to inject as `<link rel="modulepreload">` in `<head>`. */
507
876
  modulepreload?: string[];
508
877
  /**
@@ -540,6 +909,69 @@ interface GenerateSSRHtmlOptions {
540
909
  * Generate a complete HTML document from SSR render results.
541
910
  */
542
911
  declare function generateSSRHtml(options: GenerateSSRHtmlOptions): string;
912
+ import { ExtractedQuery as ExtractedQuery2 } from "@vertz/ui-compiler";
913
+ interface ReconstructedDescriptor {
914
+ key: string;
915
+ fetch: () => Promise<unknown>;
916
+ }
917
+ /**
918
+ * Reconstruct QueryDescriptors from manifest metadata by calling the
919
+ * real API client factories. Returns descriptors with correct `_key`
920
+ * and `_fetch` for pre-populating the SSR query cache.
921
+ *
922
+ * Skips queries that:
923
+ * - Have no entity/operation (variable references)
924
+ * - Reference entities or operations not in the API client
925
+ * - Have unresolvable where bindings (null = dynamic value)
926
+ * - Reference route params not present in the URL
927
+ */
928
+ declare function reconstructDescriptors(queries: ExtractedQuery2[], routeParams: Record<string, string>, apiClient: Record<string, Record<string, (...args: unknown[]) => unknown>> | undefined): ReconstructedDescriptor[];
929
+ import { PrefetchManifest } from "@vertz/ui-compiler";
930
+ interface PrefetchManifestManagerOptions {
931
+ /** Absolute path to the router file. */
932
+ routerPath: string;
933
+ /** Read a file's contents. Returns undefined if file doesn't exist. */
934
+ readFile: (path: string) => string | undefined;
935
+ /** Resolve an import specifier from a given file to an absolute path. */
936
+ resolveImport: (specifier: string, fromFile: string) => string | undefined;
937
+ }
938
+ interface PrefetchManifestSnapshot {
939
+ manifest: PrefetchManifest | null;
940
+ rebuildCount: number;
941
+ lastRebuildMs: number | null;
942
+ lastRebuildAt: string | null;
943
+ }
944
+ interface PrefetchManifestManager {
945
+ /** Initial full manifest build. */
946
+ build(): void;
947
+ /** Handle a file change — incremental for components, full for router. */
948
+ onFileChange(filePath: string, sourceText: string): void;
949
+ /** Get the SSR manifest for rendering (atomic read). */
950
+ getSSRManifest(): SSRPrefetchManifest | undefined;
951
+ /** Get diagnostic snapshot for the `/__vertz_prefetch_manifest` endpoint. */
952
+ getSnapshot(): PrefetchManifestSnapshot;
953
+ }
954
+ declare function createPrefetchManifestManager(options: PrefetchManifestManagerOptions): PrefetchManifestManager;
955
+ /**
956
+ * SSR route matcher — matches URLs to manifest route patterns.
957
+ *
958
+ * Used by the single-pass SSR pipeline to look up which components
959
+ * and queries are expected for a given URL, enabling entity access
960
+ * filtering before discovery-only execution.
961
+ */
962
+ interface MatchedRoute {
963
+ /** The matched route pattern (e.g., '/projects/:projectId/board') */
964
+ pattern: string;
965
+ /** Extracted route parameter values (e.g., { projectId: 'abc123' }) */
966
+ params: Record<string, string>;
967
+ }
968
+ /**
969
+ * Match a URL path against a list of route patterns.
970
+ * Returns all matching patterns (layouts + page) ordered from most general to most specific.
971
+ *
972
+ * Patterns use Express-style `:param` syntax.
973
+ */
974
+ declare function matchUrlToPatterns(url: string, patterns: string[]): MatchedRoute[];
543
975
  /**
544
976
  * Serialize data to JSON with `<` escaped as `\u003c`.
545
977
  * Prevents `<\/script>` breakout and `<!--` injection in inline scripts.
@@ -590,4 +1022,4 @@ declare function collectStreamChunks(stream: ReadableStream<Uint8Array>): Promis
590
1022
  * @param nonce - Optional CSP nonce to add to the inline script tag.
591
1023
  */
592
1024
  declare function createTemplateChunk(slotId: number, resolvedHtml: string, nonce?: string): string;
593
- export { wrapWithHydrationMarkers, streamToString, ssrStorage, ssrRenderToString, ssrDiscoverQueries, setGlobalSSRTimeout, serializeToHtml, safeSerialize, resetSlotCounter, renderToStream, renderToHTMLStream, renderToHTML, renderPage, renderHeadToHtml, renderAssetTags, registerSSRQuery, rawHtml, isInSSR, inlineCriticalCss, getStreamingRuntimeScript, getSSRUrl, getSSRQueries, getGlobalSSRTimeout, getAccessSetForSSR, generateSSRHtml, extractFontMetrics, encodeChunk, detectFallbackFont, createTemplateChunk, createSlotPlaceholder, createSessionScript, createSSRHandler, createSSRDataChunk, createSSRAdapter, createAccessSetScript, collectStreamChunks, clearGlobalSSRTimeout, VNode, SessionResolver, SessionData, SSRSessionInfo, SSRRenderResult, SSRQueryEntry2 as SSRQueryEntry, SSRModule, SSRHandlerOptions, SSRDiscoverResult, RenderToStreamOptions, RenderToHTMLStreamOptions, RenderToHTMLOptions, RawHtml, PageOptions, HydrationOptions, HeadEntry, HeadCollector, GenerateSSRHtmlOptions, FontFallbackMetrics5 as FontFallbackMetrics, FallbackFontName2 as FallbackFontName, AssetDescriptor };
1025
+ export { wrapWithHydrationMarkers, toPrefetchSession, streamToString, ssrStorage, ssrRenderToString, ssrRenderSinglePass, ssrRenderAot, ssrDiscoverQueries, setGlobalSSRTimeout, serializeToHtml, safeSerialize, resetSlotCounter, renderToStream, renderToHTMLStream, renderToHTML, renderPage, renderHeadToHtml, renderAssetTags, registerSSRQuery, reconstructDescriptors, rawHtml, matchUrlToPatterns, isInSSR, isAotDebugEnabled, inlineCriticalCss, getStreamingRuntimeScript, getSSRUrl, getSSRQueries, getGlobalSSRTimeout, getAccessSetForSSR, generateSSRHtml, generateAotBuildManifest, extractFontMetrics, evaluateAccessRule, encodeChunk, detectFallbackFont, createTemplateChunk, createSlotPlaceholder, createSessionScript, createSSRHandler, createSSRDataChunk, createSSRAdapter, createPrefetchManifestManager, createHoles, createAotManifestManager, createAccessSetScript, collectStreamChunks, clearGlobalSSRTimeout, __ssr_style_object, __ssr_spread, __esc_attr, __esc, VNode, SessionResolver, SessionData, SerializedAccessRule, SSRSinglePassOptions, SSRSessionInfo, SSRRenderResult, SSRRenderAotOptions, SSRQueryEntry2 as SSRQueryEntry, SSRPrefetchManifest, SSRModule, SSRHandlerOptions, SSRDiscoverResult, SSRAotContext, RenderToStreamOptions, RenderToHTMLStreamOptions, RenderToHTMLOptions, ReconstructedDescriptor, RawHtml, PrefetchSession, PrefetchManifestSnapshot, PrefetchManifestManagerOptions, PrefetchManifestManager, PageOptions, MatchedRoute, HydrationOptions, HeadEntry, HeadCollector, GenerateSSRHtmlOptions, FontFallbackMetrics7 as FontFallbackMetrics, FallbackFontName2 as FallbackFontName, EntityAccessMap, AssetDescriptor, AotTier, AotRouteEntry, AotRenderFn, AotManifestSnapshot, AotManifestManagerOptions, AotManifestManager, AotManifest, AotDivergenceEntry, AotDiagnosticsSnapshot, AotDiagnostics, AotDevManifest, AotDevComponentEntry, AotComponentDiagnostic, AotBuildManifest, AotBuildComponentEntry };