@nifrajs/web 2.14.1 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/dist/boundary.d.ts +158 -0
  2. package/dist/boundary.d.ts.map +1 -0
  3. package/dist/boundary.js +237 -0
  4. package/dist/boundary.js.map +1 -0
  5. package/dist/build-plan.d.ts +228 -0
  6. package/dist/build-plan.d.ts.map +1 -0
  7. package/dist/build-plan.js +514 -0
  8. package/dist/build-plan.js.map +1 -0
  9. package/dist/build-vite.d.ts +2 -1
  10. package/dist/build-vite.d.ts.map +1 -1
  11. package/dist/build-vite.js +5 -3
  12. package/dist/build-vite.js.map +1 -1
  13. package/dist/build.d.ts +2 -197
  14. package/dist/build.d.ts.map +1 -1
  15. package/dist/build.js +92 -515
  16. package/dist/build.js.map +1 -1
  17. package/dist/chunk-names.d.ts.map +1 -1
  18. package/dist/chunk-names.js +3 -2
  19. package/dist/chunk-names.js.map +1 -1
  20. package/dist/dev-ssr-graph.d.ts.map +1 -1
  21. package/dist/dev-ssr-graph.js +63 -28
  22. package/dist/dev-ssr-graph.js.map +1 -1
  23. package/dist/diagnostic.d.ts.map +1 -1
  24. package/dist/diagnostic.js +9 -2
  25. package/dist/diagnostic.js.map +1 -1
  26. package/dist/fonts-google.d.ts.map +1 -1
  27. package/dist/fonts-google.js +3 -1
  28. package/dist/fonts-google.js.map +1 -1
  29. package/dist/fs.d.ts.map +1 -1
  30. package/dist/fs.js +2 -1
  31. package/dist/fs.js.map +1 -1
  32. package/dist/index.d.ts +16 -589
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +23 -1824
  35. package/dist/index.js.map +1 -1
  36. package/dist/internal/codegen.d.ts +68 -0
  37. package/dist/internal/codegen.d.ts.map +1 -0
  38. package/dist/internal/codegen.js +317 -0
  39. package/dist/internal/codegen.js.map +1 -0
  40. package/dist/internal/fetcher-runtime.d.ts +19 -0
  41. package/dist/internal/fetcher-runtime.d.ts.map +1 -0
  42. package/dist/internal/fetcher-runtime.js +26 -0
  43. package/dist/internal/fetcher-runtime.js.map +1 -0
  44. package/dist/internal/head-merge.d.ts +2 -0
  45. package/dist/internal/head-merge.d.ts.map +1 -1
  46. package/dist/internal/head-merge.js +17 -1
  47. package/dist/internal/head-merge.js.map +1 -1
  48. package/dist/internal/identity-policy.d.ts +51 -0
  49. package/dist/internal/identity-policy.d.ts.map +1 -0
  50. package/dist/internal/identity-policy.js +67 -0
  51. package/dist/internal/identity-policy.js.map +1 -0
  52. package/dist/internal/parity.d.ts +104 -8
  53. package/dist/internal/parity.d.ts.map +1 -1
  54. package/dist/internal/parity.js +472 -56
  55. package/dist/internal/parity.js.map +1 -1
  56. package/dist/internal/query-runtime.d.ts +8 -0
  57. package/dist/internal/query-runtime.d.ts.map +1 -0
  58. package/dist/internal/query-runtime.js +29 -0
  59. package/dist/internal/query-runtime.js.map +1 -0
  60. package/dist/internal/render-document.d.ts +372 -0
  61. package/dist/internal/render-document.d.ts.map +1 -0
  62. package/dist/internal/render-document.js +744 -0
  63. package/dist/internal/render-document.js.map +1 -0
  64. package/dist/internal/runtime-contract.d.ts +48 -0
  65. package/dist/internal/runtime-contract.d.ts.map +1 -0
  66. package/dist/internal/runtime-contract.js +27 -0
  67. package/dist/internal/runtime-contract.js.map +1 -0
  68. package/dist/internal/web-app.d.ts +171 -0
  69. package/dist/internal/web-app.d.ts.map +1 -0
  70. package/dist/internal/web-app.js +844 -0
  71. package/dist/internal/web-app.js.map +1 -0
  72. package/dist/islands.d.ts +50 -2
  73. package/dist/islands.d.ts.map +1 -1
  74. package/dist/islands.js +96 -36
  75. package/dist/islands.js.map +1 -1
  76. package/dist/manifest.d.ts +41 -6
  77. package/dist/manifest.d.ts.map +1 -1
  78. package/dist/manifest.js.map +1 -1
  79. package/dist/module-graph.d.ts.map +1 -1
  80. package/dist/module-graph.js +22 -9
  81. package/dist/module-graph.js.map +1 -1
  82. package/dist/nano.d.ts +125 -0
  83. package/dist/nano.d.ts.map +1 -0
  84. package/dist/nano.js +190 -0
  85. package/dist/nano.js.map +1 -0
  86. package/dist/plugins/css-modules.js +2 -2
  87. package/dist/plugins/css-modules.js.map +1 -1
  88. package/dist/plugins/kit.d.ts +12 -0
  89. package/dist/plugins/kit.d.ts.map +1 -1
  90. package/dist/plugins/kit.js +62 -12
  91. package/dist/plugins/kit.js.map +1 -1
  92. package/dist/plugins/postcss.js +2 -2
  93. package/dist/plugins/postcss.js.map +1 -1
  94. package/dist/plugins/scss.js +2 -2
  95. package/dist/plugins/scss.js.map +1 -1
  96. package/dist/plugins/stylex.d.ts +70 -0
  97. package/dist/plugins/stylex.d.ts.map +1 -0
  98. package/dist/plugins/stylex.js +166 -0
  99. package/dist/plugins/stylex.js.map +1 -0
  100. package/dist/plugins/svg.js +2 -2
  101. package/dist/plugins/svg.js.map +1 -1
  102. package/dist/render-seam.d.ts +5 -0
  103. package/dist/render-seam.d.ts.map +1 -1
  104. package/dist/render-seam.js +10 -0
  105. package/dist/render-seam.js.map +1 -1
  106. package/dist/router.d.ts +11 -1
  107. package/dist/router.d.ts.map +1 -1
  108. package/dist/router.js +254 -47
  109. package/dist/router.js.map +1 -1
  110. package/dist/vite.d.ts.map +1 -1
  111. package/dist/vite.js +34 -16
  112. package/dist/vite.js.map +1 -1
  113. package/package.json +49 -2
  114. package/src/boundary.ts +407 -0
  115. package/src/build-plan.ts +741 -0
  116. package/src/build-vite.ts +6 -7
  117. package/src/build.ts +120 -730
  118. package/src/chunk-names.ts +3 -2
  119. package/src/dev-ssr-graph.ts +63 -28
  120. package/src/diagnostic.ts +14 -2
  121. package/src/fonts-google.ts +3 -1
  122. package/src/fs.ts +2 -1
  123. package/src/index.ts +107 -2553
  124. package/src/internal/codegen.ts +400 -0
  125. package/src/internal/fetcher-runtime.ts +36 -0
  126. package/src/internal/head-merge.ts +19 -1
  127. package/src/internal/identity-policy.ts +94 -0
  128. package/src/internal/parity.ts +603 -71
  129. package/src/internal/query-runtime.ts +31 -0
  130. package/src/internal/render-document.ts +1116 -0
  131. package/src/internal/runtime-contract.ts +54 -0
  132. package/src/internal/web-app.ts +1114 -0
  133. package/src/islands.ts +106 -40
  134. package/src/manifest.ts +50 -3
  135. package/src/module-graph.ts +23 -9
  136. package/src/nano.ts +246 -0
  137. package/src/plugins/css-modules.ts +2 -2
  138. package/src/plugins/kit.ts +65 -12
  139. package/src/plugins/postcss.ts +2 -2
  140. package/src/plugins/scss.ts +2 -2
  141. package/src/plugins/stylex.ts +298 -0
  142. package/src/plugins/svg.ts +2 -2
  143. package/src/render-seam.ts +6 -0
  144. package/src/router.ts +293 -51
  145. package/src/vite.ts +41 -15
package/dist/index.d.ts CHANGED
@@ -7,597 +7,15 @@
7
7
  * the adapter interprets them. That keeps this package both framework-agnostic and free
8
8
  * of DOM types: it is pure server orchestration + string building.
9
9
  */
10
- import { type ServerOptions, server } from "@nifrajs/core/server";
11
- import { type Deferred, defer } from "./deferred.js";
12
- import { mergeHeads, resolveMeta } from "./internal/head-merge.js";
13
- import type { LinkDescriptor, Manifest, Meta, MetaDescriptor, ScriptDescriptor, UnsafeScriptDescriptor } from "./manifest.js";
14
- import type { RenderAdapter } from "./render-seam.js";
10
+ export { assertStaticBoundaryImports, type Boundary, type BoundaryDescriptor, type BoundaryError, type BoundaryMode, type BoundaryRegistration, type BoundaryRequestCtx, type BoundaryState, type BoundaryStates, type BoundaryStatus, boundaryDescriptors, boundaryModeKey, type DynamicBoundary, type DynamicBoundaryBatch, type InterceptBoundary, MemoryStaticBoundaryCache, type PendingBoundary, resolveDynamicBoundaries, resolveStaticBoundaries, type StaticBoundary, type StaticBoundaryCache, type StaticBoundaryImportEdge, type StaticBoundaryRoot, type StaticCtx, startDynamicBoundaries, } from "./boundary.js";
11
+ export { assertRenderAdapterConformance, RenderAdapterConformanceError, type RenderAdapterConformanceFixture, } from "./conformance.js";
12
+ export { type Deferred, defer } from "./deferred.js";
15
13
  export { DRAFT_COOKIE, type DraftCookieControls, disableDraft, type EnableDraftOptions, enableDraft, isDraftEnabled, type PreviewEndpointOptions, previewEndpoint, } from "./draft.js";
16
14
  export { type FontDisplay, type FontFace, type FontPreloadInput, type FontSource, fontFace, fontPreload, } from "./fonts.js";
17
- export { type CachedResponse, type CacheStore, ISR_REVALIDATE_HEADER, ISR_REVALIDATE_TAGS_HEADER, ISR_STATUS_HEADER, type ISRApp, type ISROptions, type ISRPlatform, KVCacheStore, type KVCacheStoreOptions, type KVNamespaceLike, MemoryCacheStore, type MemoryCacheStoreOptions, type RevalidateEndpointOptions, revalidateEndpoint, withISR, } from "./isr.js";
18
- export { type Action, buildManifest, enumerateStaticRoutes, filePathToPattern, filePathToPatterns, type GetStaticPaths, type InertScriptType, type LayoutEntry, type LinkDescriptor, type Loader, type LoaderContext, type Manifest, type Meta, type MetaArgs, type MetaDescriptor, type MetaInput, type RouteEntry, type RouteModule, type ScriptDescriptor, type StaticPath, type StaticPaths, type StaticRoutes, type UnsafeScriptDescriptor, } from "./manifest.js";
19
- export { type Blocker, type BlockerController, type BlockerFunction, type BlockerLocation, type BlockerState, type BrowserNavigate, getBrowserNavigate, IDLE_BLOCKER, type NavigateFunction, type NavigateOptions, type NavigateSearchOf, type NavigateTargetInput, type RouteSearch, registerBlocker, resolveNavigate, setBlockerController, setBrowserNavigate, } from "./navigation.js";
20
- export { type PublicDirCache, resolvePublicPath, type ServePublicDirOptions, servePublicDir, } from "./public-dir.js";
21
- export { createMutation, createQueryClient, type DehydratedState, hashQueryKey, type InfiniteData, type InfiniteQueryHandle, type InfiniteQueryOptions, type MutationCallbacks, type MutationHandle, type MutationState, type MutationStatus, type QueryClient, type QueryClientOptions, type QueryHandle, type QueryOptions, type QueryState, type QueryStatus, } from "./query.js";
22
- export { type ClientRouter, type ClientRouterOptions, createClientRouter, createMatcher, DATA_HEADER, type Fetcher, type FetcherState, type FetchRouteData, type MountRouterOptions, NAV_FROM_HEADER, REDIRECT_HEADER, RETAIN_HEADER, REVALIDATE_HEADER, type RouteMatch, type RoutePattern, type RouterState, STATUS_HEADER, type Submission, type SubmitOptions, } from "./router.js";
23
- export { type Deferred, defer, mergeHeads, resolveMeta };
24
- /** Phantom brand key for {@link ServerOnly}. A unique symbol so the brand can't be forged by a plain
25
- * object literal; `unique symbol` keys never appear in the emitted JS, so the brand is purely
26
- * type-level (zero runtime cost). The property is optional + `never`-typed, so a `ServerOnly<T>`
27
- * stays assignment-compatible with `T` - it documents intent without obstructing real use. */
28
- declare const SERVER_ONLY_BRAND: unique symbol;
29
- /**
30
- * Type-level intent marker for a value that must only exist on the server - a secret, a DB handle, a
31
- * server-only client. `ServerOnly<T>` is structurally `T` (the brand is an optional phantom field, so
32
- * existing code keeps type-checking), but it advertises to readers + the compiler that the value is
33
- * not meant to cross to the browser. It is **purely type-level** and erases at build - it does NOT,
34
- * by itself, keep the value out of the client bundle.
35
- *
36
- * The enforcement is two runtime conventions:
37
- * - add the side-effect import `import "@nifrajs/web/server-only"` at the top of the module - the
38
- * client build ({@link buildClient}) fails loud, with the import chain, if it reaches a browser
39
- * chunk (the poison-import marker);
40
- * - or name the file `*.server.ts` - the `.server` convention empties it in the client build.
41
- *
42
- * Use this brand to express the intent in the types; pair it with one of those runtime markers so a
43
- * leak is caught at build time rather than shipping a secret to the client.
44
- *
45
- * @example
46
- * import "@nifrajs/web/server-only"
47
- * import type { ServerOnly } from "@nifrajs/web"
48
- * export const apiKey: ServerOnly<string> = process.env.SECRET_API_KEY!
49
- */
50
- export type ServerOnly<T> = T & {
51
- readonly [SERVER_ONLY_BRAND]?: never;
52
- };
53
- export { assertRenderAdapterConformance, RenderAdapterConformanceError, type RenderAdapterConformanceFixture, } from "./conformance.js";
54
- export { ACTION_GLOBAL, DATA_GLOBAL, LAYOUT_DATA_GLOBAL, type RenderAdapter, type RenderProps, ROOT_ATTRIBUTE, ROUTE_GLOBAL, type SsrModuleLoader, setSsrModuleLoader, ssrModuleLoader, } from "./render-seam.js";
55
- export { type SearchOf, searchOf, searchOfChain, serializeSearch } from "./search.js";
56
- /**
57
- * Pre-hydration form guard - a tiny inline script flushed in `<head>` (it runs in the window between
58
- * first paint and the island bundle taking over). It neutralizes the one real hydration footgun: a
59
- * JS-only form (a hand-wired `onSubmit` with no native fallback) submitting *natively* before its
60
- * handler is attached, which navigates the browser to a broken `?field=…` GET of the current page.
61
- *
62
- * It blocks ONLY that shape - an effective-GET form whose action targets the current document - and
63
- * only until hydration commits (`data-nifra-hydrated`, set by the client entry). Method-`post` forms
64
- * (progressive enhancement: the native POST hits the route `action`) and GET forms with a real action
65
- * (a search box → `/search`) pass through untouched. Opt out per-form with `data-native`. Static text
66
- * (no interpolation), so it can't carry injected markup. See the Hydration guide.
67
- */
68
- export declare const PRE_HYDRATION_GUARD: string;
69
- /**
70
- * The single default port for the dev server (`@nifrajs/web/dev`, `@nifrajs/web/vite`) **and**
71
- * `nifra start`. Deliberately uncommon: `3000`/`5173`/`8080` collide with whatever else is running
72
- * (Next, Vite, a stray Node API). `4321` rarely is - and being the *same* constant across `nifra dev`
73
- * and `nifra start` means a project's URL doesn't change between commands. Override per-run with
74
- * `--port <n>` or the `PORT` env var. */
75
- export declare const DEFAULT_DEV_PORT = 4321;
76
- type MaybePromise<T> = T | Promise<T>;
77
- declare const RESPONSE_RESULT: unique symbol;
78
- export interface RenderedPage {
79
- readonly [RESPONSE_RESULT]: true;
80
- toResponse(): Response;
81
- toNodeBody?(): {
82
- readonly status: number;
83
- readonly headers: Readonly<Record<string, string | readonly string[]>> | undefined;
84
- readonly body: string | Uint8Array;
85
- };
86
- }
87
- export interface RenderPageOptions {
88
- readonly adapter: RenderAdapter;
89
- /** The layout chain to render - outermost layout → page (opaque; the adapter renders it). */
90
- readonly chain: readonly unknown[];
91
- /** The loader output for this request. */
92
- readonly data: unknown;
93
- /** An action's data return (POST only) - surfaced to the page as `actionData` + serialized
94
- * for the client so post-POST hydration matches. Omit on GETs. */
95
- readonly actionData?: unknown;
96
- /**
97
- * URL of the built client entry (loaded as a module script).
98
- *
99
- * Optional ONLY on a `hydrate: false` page, where there is no client takeover to feed and this value
100
- * reaches no output at all. The union below is what enforces that: omitting it on a hydrating page
101
- * stays a compile error rather than rendering `src=""`.
102
- */
103
- readonly clientEntry?: string;
104
- /** Chunk URLs for the **matched** route (its layout chain + own chunk) to `modulepreload` in the
105
- * shell - so the route code downloads in parallel with the entry instead of after it
106
- * (`buildClient`'s per-route map). Empty/omitted ⇒ only the entry is preloaded (unchanged). */
107
- readonly preload?: readonly string[];
108
- /** Stylesheet URLs for the **matched** route (its layout chain + own CSS, from `buildClient`'s
109
- * `BuildManifest.css`) - injected as `<link rel="stylesheet">` in `<head>` so styles arrive with the
110
- * first paint (no FOUC). Rendered even on non-hydrated pages. Empty/omitted ⇒ none (unchanged). */
111
- readonly styles?: readonly string[];
112
- /** SSG: the prerendered-path set, serialized to `window.__NIFRA_PRERENDERED__` so the client fetches
113
- * a static `_data.json` on soft-nav into a prerendered route. Empty/omitted ⇒ not injected. */
114
- readonly prerenderedPaths?: readonly string[];
115
- /** ISR: route freshness in seconds, emitted as the `x-nifra-isr-revalidate` header for a `withISR`
116
- * wrapper to read. Omit ⇒ no header (the wrapper's default TTL applies). */
117
- readonly revalidate?: number;
118
- /** ISR invalidation tags emitted as a bounded `x-nifra-isr-tags` header. */
119
- readonly revalidateTags?: readonly string[];
120
- /** Matched route id; written to `window.__NIFRA_ROUTE__` so the client hydrates this chain. */
121
- readonly routeId?: string;
122
- /** The matched route's decoded path params - surfaced to the page as `params` (via {@link RenderProps})
123
- * so an adapter's `useParams` is SSR-correct. Omit ⇒ `{}` (a route with no dynamic segments, or an
124
- * error/404 render). */
125
- readonly params?: Readonly<Record<string, string>>;
126
- /** The request's `pathname + search` - surfaced as `path` (via {@link RenderProps}) so an adapter's
127
- * `useLocation`/`useSearchParams` render the right URL server-side and hydrate without drift. Omit ⇒
128
- * `""`. */
129
- readonly path?: string;
130
- /** The route's validated search (`searchOf(mod.searchSchema, url.search)`, the same value handed to
131
- * the loader as `ctx.search`), surfaced as `search` (via {@link RenderProps}) so an adapter's
132
- * `useSearch` is SSR-correct. Omit ⇒ `{}` (a render with no search context). */
133
- readonly search?: Record<string, unknown>;
134
- /** Per-layout loader data, forwarded to the adapter as `RenderProps.layoutData`. Aligned with the
135
- * chain's layout prefix; omitted when no layout in the chain has a loader. */
136
- readonly layoutData?: readonly unknown[];
137
- /** HTTP status for the response (default 200; e.g. 404 for a not-found page). */
138
- readonly status?: number;
139
- /** Extra response headers - e.g. the `cache-control` a terminal status page wants. `content-type`
140
- * is ignored (the document is always HTML) and the ISR freshness header is applied after these,
141
- * so neither can be overridden from here. */
142
- readonly headers?: HeadersLike;
143
- /** Document title (fallback when `head.title` is unset). */
144
- readonly title?: string;
145
- /** Resolved route head - `title` overrides `title` above; `meta`/`link` render as managed
146
- * (`data-nifra`) tags the client updates on navigation.
147
- *
148
- * **Head contract (the layout chain contributes).** `createWebApp` resolves this via
149
- * {@link mergeHeads}: a route's head is its **layout chain's** `meta`/`head` exports merged with the
150
- * page's. A `_layout.tsx` may `export const meta` (or `export function meta(args)`) - its tags land
151
- * on every page below it (the home for `hreflang`, `preconnect`, a section-default `<title>`). The
152
- * merge is **nearest-wins for scalars** (the page's `title` overrides an inner layout's, which
153
- * overrides an outer one; an undefined page title keeps the layout's) and **concatenated for the
154
- * `meta`/`link` arrays** (outermost layout first, page last). `<meta>`/`<link>` attributes pass a
155
- * shared tag-specific allowlist (including inert `data-*` metadata) and values are escaped. */
156
- readonly head?: Meta;
157
- /** Id of the container wrapping the app markup (default `"root"`). A non-default id also gets
158
- * {@link ROOT_ATTRIBUTE}, which is how the generated client entry finds the container to hydrate -
159
- * the entry is built once and cannot know what a given render chose. */
160
- readonly rootId?: string;
161
- /** When `false`, emit a complete but **non-hydrated** document - no client entry script, data
162
- * globals, or modulepreloads. Used for server-rendered `_error` pages: a terminal state that needs no
163
- * client takeover, and it sidesteps an SSR/hydrate mismatch (the server rendered the boundary, not
164
- * the page the client manifest maps this route id to). Default `true`. */
165
- readonly hydrate?: boolean;
166
- /** Island client bundles (`@nifrajs/web/islands`) to load as `<script type="module">` in the document
167
- * tail - emitted **regardless of `hydrate`**, so a static (`hydrate: false`) page can still mount
168
- * no-framework islands. URLs are attribute-escaped. Empty/omitted ⇒ none (unchanged output). */
169
- readonly islandScripts?: readonly string[];
170
- /** CSP nonce applied to every framework-owned executable script in this document. */
171
- readonly nonce?: string;
172
- /**
173
- * Advanced: a per-route slot the renderer fills with the request-invariant document pieces (shell
174
- * prefix/suffix, tail statics) on the first render and reuses afterwards, skipping their re-assembly.
175
- *
176
- * Only pass a cache when every shell-shaping input is IDENTICAL across the requests sharing it:
177
- * same `head` content (a static meta chain - never a `meta(data)` function), `title`, `styles`,
178
- * `preload`, `islandScripts`, `clientEntry`, `rootId`, `hydrate`, and `prerenderedPaths`. Per-request
179
- * values (`data`, `params`, `search`, `actionData`, `layoutData`, deferred state) are always assembled
180
- * fresh and safe. A per-request `nonce` disables the cache automatically. `createWebApp` wires this
181
- * per route, gated on the route + layout metas being static.
182
- */
183
- readonly assemblyCache?: RenderAssemblyCache;
184
- }
185
- /** The mutable per-route slot {@link RenderPageOptions.assemblyCache} fills. Opaque - create as `{}`. */
186
- export interface RenderAssemblyCache {
187
- /** Shell up to (not including) the deferred-runtime insertion point. */
188
- shellPre?: string;
189
- /** Shell from after the deferred-runtime insertion point through the open `#root` container. */
190
- shellPost?: string;
191
- /** Tail opener: the inline script open tag + the route-id global (before the action global). */
192
- tailPre?: string;
193
- /** Tail mid: the prerendered-paths global (between the action and layout-data globals). */
194
- tailMid?: string;
195
- /** Tail data prefix: the `window.<data global>=` assignment head. */
196
- tailData?: string;
197
- /** Tail from after the serialized data through `</html>`. */
198
- tailPost?: string;
199
- }
200
- /**
201
- * `renderPage` input. A hydrating page (the default) must supply `clientEntry`, because the document
202
- * loads it as a module script; a `hydrate: false` page may omit it, because nothing in the emitted
203
- * document references it. Expressed as a union so the compiler enforces the pairing rather than the
204
- * renderer discovering an empty `src` at runtime.
205
- */
206
- export type RenderPageInput = RenderPageOptions & ({
207
- readonly hydrate?: true;
208
- readonly clientEntry: string;
209
- } | {
210
- readonly hydrate: false;
211
- });
212
- /**
213
- * Server: render a full HTML document for a page - the adapter's hydration head + the SSR
214
- * markup (**streamed**) + the serialized loader data + the client module - as a `Response`.
215
- * The shell (`<head>` + the open container) flushes first, the adapter's app stream follows,
216
- * then the tail (data globals + client entry). Pure Web Standards, so it returns straight from
217
- * a nifra route handler and streams on any fetch runtime (Bun/Node/Deno/Workers).
218
- */
219
- export declare function renderPage(options: RenderPageInput): MaybePromise<Response>;
220
- export declare function renderPageResult(options: RenderPageInput): MaybePromise<RenderedPage>;
221
- /** Options for {@link redirect}. */
222
- export interface RedirectOptions {
223
- /** HTTP status (default 303 See Other; pass 307/308 to preserve the method). */
224
- readonly status?: number;
225
- /** Allow an off-origin / absolute destination. Off by default: only a same-origin path (a single
226
- * leading `/`) is permitted, so an action can't be turned into an open redirect by passing
227
- * attacker-controlled input straight through. Set `true` for a deliberate external redirect. */
228
- readonly external?: boolean;
229
- }
230
- /**
231
- * Build a redirect `Response` - return it from a route `action` for the Post/Redirect/Get
232
- * pattern (POST mutates, 303 sends the browser to a fresh GET, so a reload doesn't re-submit).
233
- * Defaults to 303 (See Other); pass `{ status: 307 }` or `{ status: 308 }` to preserve the method.
234
- *
235
- * **Secure by default:** `location` must be a same-origin path (begins with `/`, not `//`). An
236
- * off-origin/absolute destination throws unless you pass `{ external: true }` - this closes the
237
- * open-redirect footgun of `return redirect(formData.get("next"))` on the no-JS (native-form) path,
238
- * which returns the action's `Response` verbatim.
239
- *
240
- * @param options redirect status and whether an off-origin destination is intentional.
241
- */
242
- export declare function redirect(location: string, options?: RedirectOptions): Response;
243
- /**
244
- * Brand marking a `Response` as a **terminal-status signal** rather than a response to serve verbatim.
245
- *
246
- * A loader that throws a bare `Response` has always been passed straight through - that is how
247
- * `throw redirect(...)` works, and apps rely on it. So "render the `_404` boundary at 404" cannot be
248
- * expressed by throwing a plain `Response`: the framework would have no way to tell it apart from a
249
- * hand-rolled body the app wants served exactly as written. The brand is that distinction, and
250
- * checking it *before* the pass-through is what keeps every existing throw working unchanged.
251
- *
252
- * `Symbol.for` matches `RESPONSE_RESULT` above: a registry symbol survives two copies of this module,
253
- * which a `unique symbol` would not - and a duplicate-install turning a 404 into a raw 404 body would
254
- * be a maddening bug to trace.
255
- */
256
- /** Derived from the `Headers` constructor rather than the DOM lib's `HeadersInit`: `@nifrajs/web`
257
- * is consumed from DOM-free programs (the root tsconfig runs `types: ["bun"]`), and naming the DOM
258
- * type here would break their build. Same workaround as `SSEInit.headers` in core. */
259
- type HeadersLike = ConstructorParameters<typeof Headers>[0];
260
- /** Options shared by {@link notFound}, {@link gone}, and {@link statusPage}. */
261
- export interface StatusPageOptions {
262
- /**
263
- * Extra headers for the rendered response - `cache-control` above all.
264
- *
265
- * The defaults differ by status for a reason: a 404 may be a race with publication, so it wants a
266
- * short TTL, while a 410 is a promise that the URL is permanently gone and can be cached hard.
267
- * Getting this wrong is the difference between a crawler dropping a dead URL and re-fetching it
268
- * for weeks.
269
- */
270
- readonly headers?: HeadersLike;
271
- }
272
- /**
273
- * Render the nearest `_404` page at status **404**. `throw` it from a loader when the record does not
274
- * exist.
275
- *
276
- * This is the fix for the soft 404: a matched route whose loader finds nothing has otherwise no way to
277
- * answer 404, so the path of least resistance is to return empty data and render "not found" inside a
278
- * **200**. That looks correct in a browser and is invisible in review, which is why it ships and stays
279
- * shipped - while search engines penalise it and keep the dead URL indexed.
280
- *
281
- * Returns `never`: these throw, so a loader narrows without a redundant `return`, and the type states
282
- * the thing the "loaders `throw` redirect, actions `return` it" rule already trips people on.
283
- */
284
- export declare function notFound(options?: StatusPageOptions): never;
285
- /**
286
- * Render a terminal page at status **410 Gone**. `throw` it from a loader for a record that existed and
287
- * was deliberately removed - a withdrawn listing, a deleted post.
288
- *
289
- * 410 is not a pedantic 404: it tells a crawler to **drop** the URL rather than re-fetch it for weeks
290
- * on the assumption the 404 was transient. Uses `_410.tsx` if the app has one, otherwise `_404`.
291
- */
292
- export declare function gone(options?: StatusPageOptions): never;
293
- /**
294
- * Render a terminal page at any 4xx/5xx status - the escape hatch behind {@link notFound} and
295
- * {@link gone} (402, 451, …). Uses `_<status>.tsx` if present, otherwise `_404`.
296
- */
297
- export declare function statusPage(status: number, options?: StatusPageOptions): never;
298
- /** The wrapper `revalidate()` returns: the action's `data` plus the paths it changed. A plain tagged
299
- * shape (not a class) so `@nifrajs/client`'s `ActionData` can unwrap it structurally without importing
300
- * from `@nifrajs/web`. `createWebApp` strips the wrapper - the client receives `data` as the body and
301
- * the paths via the `X-Nifra-Revalidate` header. */
302
- export interface RevalidateResult<T> {
303
- readonly __nifraRevalidate: readonly string[];
304
- readonly data: T;
305
- }
306
- /**
307
- * Return this from an action to declare which routes the mutation changed (alongside the action's
308
- * `data`). `createWebApp` sets the `X-Nifra-Revalidate` response header; after the submit the client
309
- * marks those cached routes stale - refetching the active one and any mounted fetcher showing them -
310
- * so a mutation can refresh views beyond the one that was submitted. `data` is still surfaced to the
311
- * component as `actionData` (the wrapper is transparent to `ActionData<typeof action>`).
312
- */
313
- export declare function revalidate<T>(paths: readonly string[], data: T): RevalidateResult<T>;
314
- /**
315
- * Serialize loader data for embedding inside an inline `<script>`. `JSON.stringify` alone
316
- * is NOT safe there: a string containing `</script>` or `<!--` would break out of the
317
- * script element (an XSS vector). Escape `<`/`>` to `\uXXXX`, plus the U+2028/U+2029
318
- * separators.
319
- */
320
- export declare function serializeData(data: unknown): string;
321
- /**
322
- * A `<link rel="canonical">` descriptor for a route's `meta.link`. The canonical URL tells search
323
- * engines which URL is authoritative for a page (deduping query-string / tracking variants).
324
- *
325
- * ```ts
326
- * export const meta = (a) => ({ link: [canonical(`https://site.com/posts/${a.params.slug}`)] })
327
- * ```
328
- */
329
- export declare function canonical(href: string): LinkDescriptor;
330
- /** Inputs for {@link openGraph} - the common Open Graph properties. All optional; only the provided
331
- * ones become tags. `type` defaults to `"website"`. */
332
- export interface OpenGraphInput {
333
- readonly title?: string;
334
- readonly description?: string;
335
- /** Absolute URL of the share image (`og:image`). */
336
- readonly image?: string;
337
- /** Canonical URL of the page (`og:url`). */
338
- readonly url?: string;
339
- /** Object type (`og:type`) - `"website"`, `"article"`, … Default `"website"`. */
340
- readonly type?: string;
341
- }
342
- /**
343
- * Build the Open Graph `<meta property="og:*">` entries for a route's `meta.meta`. Returns only the
344
- * properties you supplied (plus `og:type`, defaulting to `"website"`), so it composes with other meta.
345
- *
346
- * ```ts
347
- * export const meta = { meta: [...openGraph({ title: "Nifra", image: "https://site.com/og.png" })] }
348
- * ```
349
- */
350
- export declare function openGraph(input: OpenGraphInput): MetaDescriptor[];
351
- /**
352
- * Build a JSON-LD `<script type="application/ld+json">` entry for a route's `meta.script` from a plain
353
- * object. `JSON.stringify` produces the body; the head renderer breakout-escapes it (see
354
- * `escapeScriptContent`), so a string field containing `</script>` is embedded safely.
355
- *
356
- * ```ts
357
- * export const meta = {
358
- * script: [jsonLd({ "@context": "https://schema.org", "@type": "Article", headline: "Hi" })],
359
- * }
360
- * ```
361
- */
362
- export declare function jsonLd(data: Record<string, unknown>): ScriptDescriptor;
363
- /**
364
- * Deliberately unsafe escape hatch for executable inline code. The required nonce keeps the result
365
- * compatible with a strict CSP and makes the security-sensitive choice visible at the call site.
366
- */
367
- export declare function unsafeInlineScript(content: string, options: {
368
- readonly nonce: string;
369
- readonly type?: "module" | "text/javascript";
370
- }): UnsafeScriptDescriptor;
371
- export interface CreateWebAppOptions<Env = unknown> {
372
- readonly adapter: RenderAdapter;
373
- readonly manifest: Manifest;
374
- /** URL of the built client entry (module script) injected into every page. */
375
- readonly clientEntry: string;
376
- /** Default document title for all pages. */
377
- readonly title?: string;
378
- /**
379
- * Options for the underlying `server()` - `requestTimeoutMs`, `admission`, `gracefulSignals`, and
380
- * the rest of {@link ServerOptions}.
381
- *
382
- * Needed because the `Server` is constructed in here, so a caller has no other way to reach its
383
- * constructor: a page app could set no request timeout and no capacity gate, which are exactly the
384
- * two knobs a production readiness check looks for. An SSR app wants them MORE than a backend does -
385
- * a render is slow and allocation-heavy, so a burst that a JSON API would absorb is the one that
386
- * exhausts the pod.
387
- *
388
- * Applies to the whole app, {@link mounts} and the {@link api} auto-mount included: the capacity gate
389
- * sits at the fetch entry, ahead of the request hooks those are dispatched from.
390
- */
391
- readonly server?: ServerOptions;
392
- /**
393
- * Runs against the app BEFORE any page route is registered - the seam for `securityHeaders()`,
394
- * `requestId()`, `logger()`, a rate limit, or anything else applied with `use`.
395
- *
396
- * ```ts
397
- * createWebApp({
398
- * …,
399
- * use: (app) => {
400
- * app.use(securityHeaders())
401
- * app.use(requestId())
402
- * },
403
- * })
404
- * ```
405
- *
406
- * A callback rather than an array because `use` is overloaded - `Middleware`, `IdentityPlugin`,
407
- * `ContextPlugin` - and only the real call site instantiates the right overload. The return value
408
- * is ignored: this is for cross-cutting concerns, not for declaring routes (declare those on the
409
- * returned app, where they get their types).
410
- *
411
- * **Why the timing matters.** `beforeHandle`, `afterHandle`, `around`, `derive`/`decorate`, and
412
- * `onError` are snapshotted into each route AS IT IS DECLARED, and `createWebApp` declares every
413
- * page (plus the `/*` catch-all) before it returns - so a caller's `app.use(…)` afterwards binds
414
- * them to nothing, silently. `requestId()` is exactly that case: it is a `derive`, so applied late
415
- * it leaves every page without `c.requestId`. Route assurance evidence is order-scoped the same
416
- * way, so a late `securityHeaders()` leaves the pages unable to PROVE the header to `nifra assure`
417
- * even though it does still set it.
418
- *
419
- * `onRequest`/`onResponse` (and the response header/body hooks) are app-global arrays read at
420
- * request time, so those alone DO work when added late. Using this seam for everything avoids
421
- * having to remember which is which.
422
- *
423
- * Runs ahead of the {@link mounts} / {@link api} request hooks, so an `onRequest` middleware guards
424
- * a mounted auth handler too.
425
- *
426
- * A `ContextPlugin` applied here takes runtime effect but cannot widen the declared return type of
427
- * this function, so `c.requestId` is not typed on routes you declare afterwards. Named plugins are
428
- * idempotent, so `app.use(requestId())` on the returned app recovers the TYPE without applying the
429
- * plugin a second time.
430
- */
431
- readonly use?: (app: ReturnType<typeof server<Env>>) => void;
432
- /** Injected into each loader's `ctx.api` - typically an `inProcessClient(app)` (typed
433
- * per-route via `@nifrajs/client`'s `createRoutes`). Opaque to the core.
434
- *
435
- * **Auto-mount.** Every `inProcessClient(backend)` exposes the symbol-keyed platform-aware backend
436
- * mount interface from `@nifrajs/core/mount`; `createWebApp` also serves that backend over HTTP at
437
- * {@link apiPrefix} (default `/api`): a request whose pathname starts with the prefix is dispatched
438
- * before page routing with the same `env`/`waitUntil` platform context, and the backend's `Response`
439
- * is returned untouched. The mount runs in `nifra dev` too. Pass `apiPrefix: ""` to disable it. */
440
- readonly api?: unknown;
441
- /** HTTP path prefix the {@link api} backend is auto-mounted at (default `"/api"`). A request whose
442
- * pathname is exactly the prefix or starts with `prefix + "/"` is dispatched to the backend before
443
- * page routing; the backend therefore defines its routes at the **full** path (`server().post("/api/
444
- * sync", …)`), matching the in-process `inProcessClient` call sites. Set to `""` to disable the
445
- * auto-mount entirely (the app serves pages only and `api` stays a loader-only `ctx.api`). Mounting
446
- * is also a no-op when `api` does not expose the symbol mount. */
447
- readonly apiPrefix?: string;
448
- /**
449
- * Strip {@link apiPrefix} from the pathname before dispatching to `api` (default `false`).
450
- *
451
- * The default suits a backend that declares FULL paths (`server().post("/api/sync", …)`), which is
452
- * right when it is only ever mounted here. Set this when the backend declares its routes WITHOUT the
453
- * prefix because it also runs standalone behind its own shell, so its paths cannot carry a prefix that
454
- * only exists when it is mounted. Without it every request 404s inside the backend, and the workaround
455
- * is a `Proxy` that rewrites each URL.
456
- */
457
- readonly apiStrip?: boolean;
458
- /**
459
- * Sub-apps mounted ahead of page routing - an auth handler, a webhook receiver, a stack's routes.
460
- *
461
- * Structural on purpose: anything with `{ path, app: { fetch } }` fits, so a library that exposes its
462
- * routes as such a list mounts as `mounts: theirRoutes` without `@nifrajs/web` taking a dependency on
463
- * it. `better-auth` is the motivating case - it is not a `backend` route, so `/api/auth/*` used to 404
464
- * silently.
465
- *
466
- * Tried longest-path-first and BEFORE the `api` mount, so a mount at `/api/auth` wins over a backend
467
- * at `/api` no matter which was declared first. `stripPrefix` is the per-mount form of {@link apiStrip}:
468
- * leave it off to pass the full path through.
469
- */
470
- readonly mounts?: ReadonlyArray<{
471
- readonly path: string;
472
- readonly app: {
473
- fetch(request: Request): Response | Promise<Response>;
474
- };
475
- readonly stripPrefix?: boolean;
476
- }>;
477
- /** Secret for **draft / preview mode** (see `enableDraft`). When set, a request carrying a valid
478
- * signed `__nifra_draft` cookie gets `ctx.draft === true` in loaders/actions (else always `false`).
479
- * Pair with `withISR({ draftSecret })` so editors bypass the cache. Omit to disable draft mode. */
480
- readonly draftSecret?: string;
481
- /** Per-route chunk URLs (`buildClient`'s `BuildManifest.routes`) - `routeId → [layout chunks…, own
482
- * chunk]`. When present, each page `modulepreload`s its matched route's chunks alongside the entry,
483
- * so the route code downloads in parallel (no entry→route-chunk waterfall). Omit ⇒ entry-only. */
484
- readonly routePreload?: Readonly<Record<string, readonly string[]>>;
485
- /** The app's bundled stylesheet URLs (`buildClient`'s `BuildManifest.css`) - the aggregate, injected
486
- * as `<link rel="stylesheet">` in a page's `<head>`. Used as the fallback for any route absent from
487
- * {@link routeStyles}. Omit ⇒ no links (dev, where Vite injects CSS, or a CSS-free app). */
488
- readonly styles?: readonly string[];
489
- /** Per-route stylesheet URLs (`buildClient`'s `BuildManifest.routeStyles`) - `routeId → [chain CSS]`.
490
- * When a matched route has an entry here, only those (its layout chain + own CSS) are linked instead
491
- * of the aggregate `styles`, so a page ships only the CSS it uses. An empty array ⇒ no `<link>` (the
492
- * page imports no CSS). Routes absent here fall back to `styles`. Omit ⇒ always use `styles`. */
493
- readonly routeStyles?: Readonly<Record<string, readonly string[]>>;
494
- /** SSG: the prerendered-path set (e.g. `enumerateStaticRoutes(routes).paths` or the build's
495
- * `prerendered.json`). Injected as `window.__NIFRA_PRERENDERED__` on every page so a client soft-nav
496
- * into a prerendered route fetches its static `_data.json` instead of hitting the worker. */
497
- readonly prerenderedPaths?: readonly string[];
498
- /** Publish the project's `AGENTS.md` inside `/llms.txt` and `/llms-full.txt`. **Off by default**:
499
- * those endpoints are public and unauthenticated, while `AGENTS.md` is a repo file written for the
500
- * team - unreleased feature names, internal hostnames, and "don't touch X yet" notes live there
501
- * routinely. Turn it on only for a repo whose guidelines you would publish as a page. */
502
- readonly publishLocalGuidelines?: boolean;
503
- /** SSG: per dynamic route pattern, its `getStaticPaths` `fallback` (from `enumerateStaticRoutes` or
504
- * the build's `prerendered.json`). A route mapped to `"404"` rejects any path NOT in
505
- * `prerenderedPaths` with the 404 page - the unlisted path simply doesn't exist. `"ssr"` (the
506
- * default for unmapped routes) renders unlisted paths on-demand. */
507
- readonly staticFallbacks?: Readonly<Record<string, "ssr" | "404">>;
508
- /** Observe every loader/action failure - for error-reporting plugins (Sentry-style). Called for
509
- * real throws (not control-flow `Response`s like `redirect`), **before** the nearest `_error`
510
- * boundary renders / a soft-nav 500 / a rethrow - so it sees errors that the boundary would
511
- * otherwise hide. Observation only; its own throws are swallowed so a faulty reporter can't break
512
- * rendering. (`beforeLoader` is intentionally omitted - the core HTTP hooks already cover
513
- * pre-request work.) */
514
- readonly onLoaderError?: (error: unknown, ctx: {
515
- readonly request: Request;
516
- readonly params: Readonly<Record<string, string>>;
517
- readonly route: string;
518
- }) => void;
519
- }
520
- /**
521
- * Build a nifra app from a route manifest: every route SSRs its layout chain via `renderPage`,
522
- * and a wildcard catch-all renders `_404` (or a plain 404). Reuses @nifrajs/core's router +
523
- * lifecycle, so matching, params, and precedence are battle-tested. fs-free - feed it a
524
- * manifest from `discoverRoutes` (`@nifrajs/web/fs`) at startup, so the served app stays portable.
525
- *
526
- * **Typed platform bindings.** Pass `Env` - `createWebApp<Env>({ … })` - to declare the app's Workers
527
- * bindings ONCE. It seeds the returned `Server`'s context with `{ env: Env }` (exactly as the backend's
528
- * `server<Env>()` does), so `app.fetch(req, { env })` / `toFetchHandler(app)` type-check the `env`
529
- * argument against the declared shape - no per-binding cast at the edge entry. Per-route loaders/actions
530
- * stay typed independently of this call: annotate them with `@nifrajs/client`'s `LoaderArgs<Api, Env>`
531
- * (same `Env`) so `ctx.env.MY_KV` is typed there too. Omit the parameter and `Env` is `unknown` - the
532
- * secure default; validate at the trust boundary before use.
533
- */
534
- export declare function createWebApp<Env = unknown>(options: CreateWebAppOptions<Env>): ReturnType<typeof server<Env>>;
535
- export interface GenerateClientEntryOptions {
536
- /**
537
- * Module specifier for the adapter's client runtime, e.g. `"@nifrajs/web-solid/client"`.
538
- *
539
- * **Contract:** the module MUST export `mountRouter({ router, routes, container })`. The generated
540
- * bootstrap imports the specifier and calls it - so a self-executing entry that mounts on import
541
- * builds cleanly and then does nothing, which is the trap this contract exists to name. The type is
542
- * a bare `string` because a specifier is resolved by the bundler, not the type system, so the
543
- * requirement is enforced by the bootstrap instead: it throws immediately, naming this module and
544
- * the missing export, rather than failing later as `mountRouter is not a function`.
545
- */
546
- readonly clientModule: string;
547
- /** Turn a route/layout source file (relative to the routes dir) into an import specifier. */
548
- readonly resolve: (file: string) => string;
549
- }
550
- /**
551
- * Codegen: emit a client-entry module (as source) that lazily imports each route's layout chain
552
- * (so `Bun.build` with `splitting` code-splits one chunk per route), builds a `patterns` list,
553
- * then creates the agnostic router store (with a `loadModule` hook), installs history + form
554
- * interception, loads the initial route's chunk, and hydrates the adapter's stateful Router. The
555
- * initial route is derived from the URL (falling back to the server-injected route id, e.g.
556
- * `_404`), so after hydration the Router owns navigation and swaps routes without full reloads.
557
- * Bun has no `import.meta.glob`, so file-based routing needs this. Write the result to a file and
558
- * bundle it with `buildClient` / `Bun.build` (+ the adapter's transform).
559
- */
560
- export declare function generateClientEntry(manifest: Manifest, options: GenerateClientEntryOptions): string;
561
- export interface GenerateRouteSearchTypesOptions {
562
- /** Turn a route source file into a module specifier for a `typeof import(...)` type - the same contract
563
- * as `generateClientEntry`'s `resolve`, but WITHOUT a file extension (a `.d.ts` imports a module, not a
564
- * path). Relative to wherever the emitted `.d.ts` is written. */
565
- readonly resolve: (file: string) => string;
566
- /** The module whose `RouteSearch` interface is augmented (default `"@nifrajs/web"`). Every adapter's
567
- * `NavigateTarget` reads `@nifrajs/web`'s `RouteSearch`, so the default types `navigate` on all of them. */
568
- readonly module?: string;
569
- }
570
- /**
571
- * Codegen: emit a `.d.ts` that types cross-route `navigate({ to, search })` against each route's
572
- * `searchSchema`. It augments the {@link RouteSearch} map with `"<pattern>": SearchOf<typeof import(...)>`
573
- * for every **static** route (one with no `:param`/`*` segment - a concrete `to` a caller can pass; a
574
- * dynamic route's concrete path can't match its pattern key, so those keep the loose object form). Written
575
- * by `nifra sync-routes` next to the route tree and included in the app's `tsconfig`; because it is
576
- * regenerated from the route files, a `navigate` whose `search` no longer matches the route's schema
577
- * becomes a `tsc` error - the same drift guarantee as nifra's typed client, no hand-maintained map.
578
- */
579
- export declare function generateRouteSearchTypes(manifest: Manifest, options: GenerateRouteSearchTypesOptions): string;
580
- export interface GenerateServerManifestOptions {
581
- /** Turn a route/layout source file (relative to the routes dir) into an import specifier -
582
- * same contract as `generateClientEntry`'s `resolve`. */
583
- readonly resolve: (file: string) => string;
584
- /** The content-hashed client entry URL (from `buildClient`'s manifest), **baked** into the emitted
585
- * module - a disk-less worker can't read `manifest.json` at runtime. */
586
- readonly clientEntry: string;
587
- /** The app's aggregate stylesheet URLs (`buildClient`'s `BuildManifest.css`) - baked as
588
- * `export const styles` so the server entry can hand them to `createWebApp` (→ `<link rel="stylesheet">`
589
- * in `<head>`). Without this the built SSR page ships no CSS link and renders unstyled. */
590
- readonly styles?: readonly string[] | undefined;
591
- /** Per-route stylesheet URLs (`buildClient`'s `BuildManifest.routeStyles`) - baked as
592
- * `export const routeStyles` so a page links only the CSS its route chain uses. */
593
- readonly routeStyles?: Readonly<Record<string, readonly string[]>> | undefined;
594
- /** Emit **lazy** per-route loaders (`() => import("./routes/x")`, a static specifier) instead of
595
- * eager `import * as`, so a bundler with code-splitting emits one chunk per route - loaded on the
596
- * first request to it, not all at boot (smaller cold-start parse). Default `false` (eager). Both
597
- * modes are fs-free with statically-analyzable specifiers; only the *when* differs. */
598
- readonly lazy?: boolean;
599
- }
600
- export declare function generateServerManifest(manifest: Manifest, options: GenerateServerManifestOptions): string;
15
+ export { type GenerateClientEntryOptions, type GenerateRouteSearchTypesOptions, type GenerateServerManifestOptions, generateClientEntry, generateRouteSearchTypes, generateServerManifest, } from "./internal/codegen.js";
16
+ export { mergeHeads, resolveMeta } from "./internal/head-merge.js";
17
+ export { canonical, gone, jsonLd, notFound, type OpenGraphInput, openGraph, type RedirectOptions, type RenderAssemblyCache, type RenderedPage, type RenderPageInput, type RenderPageOptions, type RevalidateResult, redirect, renderPage, renderPageResult, revalidate, type StatusPageOptions, serializeData, statusPage, unsafeInlineScript, } from "./internal/render-document.js";
18
+ export { DEFAULT_DEV_PORT, PRE_HYDRATION_GUARD, type ServerOnly, } from "./internal/runtime-contract.js";
601
19
  /**
602
20
  * The two file-name conventions that decide what never reaches a browser: a `*.server` module is
603
21
  * EMPTIED in the client build, a `*.fn` module is REPLACED with client stubs.
@@ -609,4 +27,13 @@ export declare function generateServerManifest(manifest: Manifest, options: Gene
609
27
  * server-only" should import the matcher rather than re-encode it.
610
28
  */
611
29
  export { SERVER_FN_MODULE, SERVER_ONLY_MODULE } from "./internal/server-boundary.js";
30
+ export { type CreateWebAppOptions, createWebApp, } from "./internal/web-app.js";
31
+ export { type CachedResponse, type CacheStore, ISR_REVALIDATE_HEADER, ISR_REVALIDATE_TAGS_HEADER, ISR_STATUS_HEADER, type ISRApp, type ISROptions, type ISRPlatform, KVCacheStore, type KVCacheStoreOptions, type KVNamespaceLike, MemoryCacheStore, type MemoryCacheStoreOptions, type RevalidateEndpointOptions, revalidateEndpoint, withISR, } from "./isr.js";
32
+ export { type Action, buildManifest, type ClientAction, type ClientActionArgs, type ClientActionResult, type ClientLoader, type ClientLoaderArgs, type ClientRequestBody, type ClientRouteHooks, enumerateStaticRoutes, filePathToPattern, filePathToPatterns, type GetStaticPaths, type InertScriptType, type LayoutEntry, type LinkDescriptor, type Loader, type LoaderContext, type Manifest, type Meta, type MetaArgs, type MetaDescriptor, type MetaInput, type RouteEntry, type RouteModule, type ScriptDescriptor, type StaticPath, type StaticPaths, type StaticRoutes, type UnsafeScriptDescriptor, } from "./manifest.js";
33
+ export { type Blocker, type BlockerController, type BlockerFunction, type BlockerLocation, type BlockerState, type BrowserNavigate, getBrowserNavigate, IDLE_BLOCKER, type NavigateFunction, type NavigateOptions, type NavigateSearchOf, type NavigateTargetInput, type RouteSearch, registerBlocker, resolveNavigate, setBlockerController, setBrowserNavigate, } from "./navigation.js";
34
+ export { type PublicDirCache, resolvePublicPath, type ServePublicDirOptions, servePublicDir, } from "./public-dir.js";
35
+ export { createMutation, createQueryClient, type DehydratedState, hashQueryKey, type InfiniteData, type InfiniteQueryHandle, type InfiniteQueryOptions, type MutationCallbacks, type MutationHandle, type MutationState, type MutationStatus, type QueryClient, type QueryClientOptions, type QueryHandle, type QueryOptions, type QueryState, type QueryStatus, } from "./query.js";
36
+ export { ACTION_GLOBAL, BOUNDARY_GLOBAL, DATA_GLOBAL, LAYOUT_DATA_GLOBAL, type RenderAdapter, type RenderProps, ROOT_ATTRIBUTE, ROUTE_GLOBAL, type SsrModuleLoader, setSsrModuleLoader, ssrModuleLoader, } from "./render-seam.js";
37
+ export { type ClientRouter, type ClientRouterOptions, createClientRouter, createMatcher, DATA_HEADER, type Fetcher, type FetcherState, type FetchRouteData, type MountRouterOptions, NAV_FROM_HEADER, REDIRECT_HEADER, RETAIN_HEADER, REVALIDATE_HEADER, type RouteMatch, type RoutePattern, type RouterState, STATUS_HEADER, type Submission, type SubmitOptions, } from "./router.js";
38
+ export { type SearchOf, searchOf, searchOfChain, serializeSearch } from "./search.js";
612
39
  //# sourceMappingURL=index.d.ts.map