/** * `@nifrajs/web/route-manifest` - what each route actually DOES, as one artifact. * * The facts are already in the route modules: `prerender`, `getStaticPaths`, `revalidate`, `hydrate`. * What has never existed is anywhere to read them together. To answer "which pages are static?", "which * ones revalidate, and how often?", "which ship no JS?", you open every route file and hold the answer in * your head - and the answer changes on the target you deploy to, which is nowhere near the route file. * * That gap is not just inconvenient. The interesting cases are the ones where a route's declaration and * its deploy target disagree, and there is currently nothing that can notice: an ISR route on a target * with no revalidation story regenerates on every request; a `static` build containing a route that was * never prerenderable ships a page that 404s. Both are silent, and both are decided at build time by * information no single place holds. * * So this derives one record per route - render mode, hydration, cache policy - resolves it against the * target, and reports what the target cannot honour. Pure and fs-free: it takes an already-built * `Manifest` so it runs at build time, in `nifra routes`, and in a test with a hand-built manifest. */ import type { Manifest, RouteModule } from "./manifest.js"; /** * How a route produces its HTML. * * - `static` - prerendered at build; served as a file, no server render at request time. * - `isr` - server-rendered, then cached and revalidated on a timer (`export const revalidate`). * - `ssr` - server-rendered per request. The default, and the only mode that needs a live server. */ export type RenderMode = "static" | "isr" | "ssr"; /** What a route needs from its host in order to behave as declared. */ export type RouteCapability = "server" | "revalidation"; /** One route's resolved behaviour. */ export interface RouteManifestEntry { /** The route's id (its key in the build manifest and in `routes`). */ readonly id: string; /** The matching pattern, e.g. `/blog/:slug`. */ readonly pattern: string; readonly mode: RenderMode; /** Whether the full-document client is shipped. `false` means the page loads no framework JS. */ readonly hydrate: boolean; /** Revalidation window in seconds. Present only for `isr`. */ readonly revalidate?: number; /** Bounded tags that can purge this route from a shared ISR store. */ readonly revalidateTags?: readonly string[]; /** * Concrete paths prerendered at build. Present for `static` routes: a single path for a static route, * one per `getStaticPaths` entry for a dynamic one. Absent means "no path was enumerated", which for a * dynamic route is exactly the condition that makes it unprerenderable. */ readonly prerenderedPaths?: readonly string[]; /** What this route needs from the host to behave as declared. */ readonly requires: readonly RouteCapability[]; } /** A route whose declaration the chosen target cannot honour, and what actually happens if it ships. */ export interface RouteManifestConflict { readonly id: string; readonly pattern: string; readonly capability: RouteCapability; /** What goes wrong on this target - the consequence, not the rule that was broken. */ readonly consequence: string; } /** The whole artifact: every route's behaviour, plus anything the target cannot honour. */ export interface RouteManifest { /** The deploy target this was resolved against, when one was given. */ readonly target?: string; readonly routes: readonly RouteManifestEntry[]; readonly conflicts: readonly RouteManifestConflict[]; /** Route counts by mode - the summary a report leads with. */ readonly totals: Readonly>; } /** * Derive one route's behaviour from its module exports. * * `prerender`/`getStaticPaths` win over `revalidate`: a page rendered at build time is not revalidated at * runtime, so if a route declares both, the build-time answer is the one that describes what ships. That * combination is worth surfacing rather than silently resolving, which is what `conflicts` is for once a * target is known. */ export declare function deriveRouteEntry(id: string, pattern: string, module: Pick, prerenderedPaths?: readonly string[]): RouteManifestEntry; /** * Build the route manifest for a discovered app, optionally resolved against a deploy target. * * `prerendered` maps a route id to the concrete paths the build actually emitted for it - pass what * `prerenderRoutes` produced. Without it, dynamic routes are reported by their declaration alone, which * is the right answer before a build has run and the wrong one after. */ export declare function buildRouteManifest(manifest: Manifest, options?: { readonly target?: string; readonly prerendered?: Readonly>; /** Runtime capabilities supplied outside generated entries (for example an explicit `withISR`). */ readonly capabilities?: readonly RouteCapability[]; }): Promise; /** Render the manifest as a readable report - the `nifra routes --modes` output. */ export declare function renderRouteManifest(manifest: RouteManifest): string; //# sourceMappingURL=route-manifest.d.ts.map