@vertz/ui-server 0.2.29 → 0.2.30
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.
- package/dist/bun-dev-server.d.ts +24 -1
- package/dist/bun-dev-server.js +99 -68
- package/dist/bun-plugin/index.d.ts +2 -2
- package/dist/index.d.ts +21 -0
- package/dist/index.js +17 -476
- package/dist/shared/chunk-bd0sgykf.js +1468 -0
- package/dist/ssr/index.d.ts +75 -2
- package/dist/ssr/index.js +1 -1
- package/package.json +5 -5
- package/dist/shared/chunk-yr65qdge.js +0 -764
package/dist/bun-dev-server.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ interface SSRSessionInfo {
|
|
|
25
25
|
* Returns null when no valid session exists (expired, missing, or invalid cookie).
|
|
26
26
|
*/
|
|
27
27
|
type SessionResolver = (request: Request) => Promise<SSRSessionInfo | null>;
|
|
28
|
+
import { BunPlugin as BunPlugin_seob6 } from "bun";
|
|
28
29
|
/**
|
|
29
30
|
* Detect `public/favicon.svg` and return a `<link>` tag for it.
|
|
30
31
|
* Returns empty string when the file does not exist.
|
|
@@ -98,6 +99,21 @@ interface BunDevServerOptions {
|
|
|
98
99
|
* script restarts the process.
|
|
99
100
|
*/
|
|
100
101
|
onRestartNeeded?: () => void;
|
|
102
|
+
/**
|
|
103
|
+
* Enable progressive HTML streaming in the dev server. Default: false.
|
|
104
|
+
*
|
|
105
|
+
* When true, SSR responses stream `<head>` content before `<body>`
|
|
106
|
+
* rendering completes. Currently reserved for future use — the dev server
|
|
107
|
+
* always uses buffered rendering. The option is accepted to match the
|
|
108
|
+
* production handler's `progressiveHTML` option.
|
|
109
|
+
*/
|
|
110
|
+
progressiveHTML?: boolean;
|
|
111
|
+
/**
|
|
112
|
+
* Additional Bun plugins to register alongside the Vertz compiler plugin.
|
|
113
|
+
* Use this to add MDX compilation or other custom file type handling.
|
|
114
|
+
* Plugins are registered once (process-global) on the first `start()` call.
|
|
115
|
+
*/
|
|
116
|
+
plugins?: BunPlugin_seob6[];
|
|
101
117
|
}
|
|
102
118
|
interface ErrorDetail {
|
|
103
119
|
message: string;
|
|
@@ -110,6 +126,13 @@ interface ErrorDetail {
|
|
|
110
126
|
}
|
|
111
127
|
type ErrorCategory = "build" | "resolve" | "runtime" | "ssr";
|
|
112
128
|
declare function isStaleGraphError(message: string): boolean;
|
|
129
|
+
/**
|
|
130
|
+
* Detect Bun's reload stub — the response served when the dev bundler
|
|
131
|
+
* fails to compile a client module. The stub is literally:
|
|
132
|
+
* try{location.reload()}catch(_){}
|
|
133
|
+
* addEventListener("DOMContentLoaded",function(event){location.reload()})
|
|
134
|
+
*/
|
|
135
|
+
declare function isReloadStub(text: string): boolean;
|
|
113
136
|
/** A resolved stack frame for terminal logging. */
|
|
114
137
|
interface TerminalStackFrame {
|
|
115
138
|
functionName: string | null;
|
|
@@ -221,4 +244,4 @@ declare function clearSSRRequireCache(): number;
|
|
|
221
244
|
* SSR is always on. HMR always works. No mode toggle needed.
|
|
222
245
|
*/
|
|
223
246
|
declare function createBunDevServer(options: BunDevServerOptions): BunDevServer;
|
|
224
|
-
export { parseHMRAssets, isStaleGraphError, generateSSRPageHtml, formatTerminalRuntimeError, detectFaviconTag, createRuntimeErrorDeduplicator, createFetchInterceptor, createBunDevServer, clearSSRRequireCache, buildScriptTag, SSRPageHtmlOptions, HMRAssets, FetchInterceptorOptions, ErrorDetail, ErrorCategory, BunDevServerOptions, BunDevServer };
|
|
247
|
+
export { parseHMRAssets, isStaleGraphError, isReloadStub, generateSSRPageHtml, formatTerminalRuntimeError, detectFaviconTag, createRuntimeErrorDeduplicator, createFetchInterceptor, createBunDevServer, clearSSRRequireCache, buildScriptTag, SSRPageHtmlOptions, HMRAssets, FetchInterceptorOptions, ErrorDetail, ErrorCategory, BunDevServerOptions, BunDevServer };
|
package/dist/bun-dev-server.js
CHANGED
|
@@ -1790,6 +1790,15 @@ function safeSerialize(data) {
|
|
|
1790
1790
|
}
|
|
1791
1791
|
|
|
1792
1792
|
// src/ssr-render.ts
|
|
1793
|
+
var compiledThemeCache = new WeakMap;
|
|
1794
|
+
function compileThemeCached(theme, fallbackMetrics) {
|
|
1795
|
+
const cached = compiledThemeCache.get(theme);
|
|
1796
|
+
if (cached)
|
|
1797
|
+
return cached;
|
|
1798
|
+
const compiled = compileTheme(theme, { fallbackMetrics });
|
|
1799
|
+
compiledThemeCache.set(theme, compiled);
|
|
1800
|
+
return compiled;
|
|
1801
|
+
}
|
|
1793
1802
|
function createRequestContext(url) {
|
|
1794
1803
|
return {
|
|
1795
1804
|
url,
|
|
@@ -1855,9 +1864,7 @@ async function ssrRenderToString(module, url, options) {
|
|
|
1855
1864
|
let themePreloadTags = "";
|
|
1856
1865
|
if (module.theme) {
|
|
1857
1866
|
try {
|
|
1858
|
-
const compiled =
|
|
1859
|
-
fallbackMetrics: options?.fallbackMetrics
|
|
1860
|
-
});
|
|
1867
|
+
const compiled = compileThemeCached(module.theme, options?.fallbackMetrics);
|
|
1861
1868
|
themeCss = compiled.css;
|
|
1862
1869
|
themePreloadTags = compiled.preloadTags;
|
|
1863
1870
|
} catch (e) {
|
|
@@ -1914,10 +1921,7 @@ async function ssrRenderToString(module, url, options) {
|
|
|
1914
1921
|
const stream = renderToStream(vnode);
|
|
1915
1922
|
const html = await streamToString(stream);
|
|
1916
1923
|
const css = collectCSS(themeCss, module);
|
|
1917
|
-
const ssrData = resolvedQueries.length > 0 ? resolvedQueries.map(({ key, data }) => ({
|
|
1918
|
-
key,
|
|
1919
|
-
data: JSON.parse(JSON.stringify(data))
|
|
1920
|
-
})) : [];
|
|
1924
|
+
const ssrData = resolvedQueries.length > 0 ? resolvedQueries.map(({ key, data }) => ({ key, data })) : [];
|
|
1921
1925
|
return {
|
|
1922
1926
|
html,
|
|
1923
1927
|
css,
|
|
@@ -2003,7 +2007,7 @@ data: {}
|
|
|
2003
2007
|
return;
|
|
2004
2008
|
settled = true;
|
|
2005
2009
|
resolve(data);
|
|
2006
|
-
const entry = { key, data
|
|
2010
|
+
const entry = { key, data };
|
|
2007
2011
|
safeEnqueue(encoder2.encode(`event: data
|
|
2008
2012
|
data: ${safeSerialize(entry)}
|
|
2009
2013
|
|
|
@@ -2040,9 +2044,6 @@ function escapeAttr3(s) {
|
|
|
2040
2044
|
return s.replace(/[&"'<>]/g, (c) => `&#${c.charCodeAt(0)};`);
|
|
2041
2045
|
}
|
|
2042
2046
|
|
|
2043
|
-
// src/ssr-single-pass.ts
|
|
2044
|
-
import { compileTheme as compileTheme2 } from "@vertz/ui";
|
|
2045
|
-
|
|
2046
2047
|
// src/ssr-manifest-prefetch.ts
|
|
2047
2048
|
function reconstructDescriptors(queries, routeParams, apiClient) {
|
|
2048
2049
|
if (!apiClient)
|
|
@@ -2179,54 +2180,7 @@ async function ssrRenderSinglePass(module, url, options) {
|
|
|
2179
2180
|
if (zeroDiscoveryData) {
|
|
2180
2181
|
return renderWithPrefetchedData(module, normalizedUrl, zeroDiscoveryData, options);
|
|
2181
2182
|
}
|
|
2182
|
-
const
|
|
2183
|
-
if (options?.ssrAuth) {
|
|
2184
|
-
discoveryCtx.ssrAuth = options.ssrAuth;
|
|
2185
|
-
}
|
|
2186
|
-
const discoveredData = await ssrStorage.run(discoveryCtx, async () => {
|
|
2187
|
-
try {
|
|
2188
|
-
setGlobalSSRTimeout(ssrTimeout);
|
|
2189
|
-
const createApp = resolveAppFactory2(module);
|
|
2190
|
-
createApp();
|
|
2191
|
-
if (discoveryCtx.ssrRedirect) {
|
|
2192
|
-
return { redirect: discoveryCtx.ssrRedirect };
|
|
2193
|
-
}
|
|
2194
|
-
if (discoveryCtx.pendingRouteComponents?.size) {
|
|
2195
|
-
const entries = Array.from(discoveryCtx.pendingRouteComponents.entries());
|
|
2196
|
-
const results = await Promise.allSettled(entries.map(([route, promise]) => Promise.race([
|
|
2197
|
-
promise.then((mod) => ({ route, factory: mod.default })),
|
|
2198
|
-
new Promise((_, reject) => setTimeout(() => reject(new Error("lazy route timeout")), ssrTimeout))
|
|
2199
|
-
])));
|
|
2200
|
-
discoveryCtx.resolvedComponents = new Map;
|
|
2201
|
-
for (const result of results) {
|
|
2202
|
-
if (result.status === "fulfilled") {
|
|
2203
|
-
const { route, factory } = result.value;
|
|
2204
|
-
discoveryCtx.resolvedComponents.set(route, factory);
|
|
2205
|
-
}
|
|
2206
|
-
}
|
|
2207
|
-
discoveryCtx.pendingRouteComponents = undefined;
|
|
2208
|
-
}
|
|
2209
|
-
const queries = getSSRQueries();
|
|
2210
|
-
const eligibleQueries = filterByEntityAccess(queries, options?.manifest?.entityAccess, options?.prefetchSession);
|
|
2211
|
-
const resolvedQueries = [];
|
|
2212
|
-
if (eligibleQueries.length > 0) {
|
|
2213
|
-
await Promise.allSettled(eligibleQueries.map(({ promise, timeout, resolve, key }) => Promise.race([
|
|
2214
|
-
promise.then((data) => {
|
|
2215
|
-
resolve(data);
|
|
2216
|
-
resolvedQueries.push({ key, data });
|
|
2217
|
-
return "resolved";
|
|
2218
|
-
}),
|
|
2219
|
-
new Promise((r) => setTimeout(r, timeout || ssrTimeout)).then(() => "timeout")
|
|
2220
|
-
])));
|
|
2221
|
-
}
|
|
2222
|
-
return {
|
|
2223
|
-
resolvedQueries,
|
|
2224
|
-
resolvedComponents: discoveryCtx.resolvedComponents
|
|
2225
|
-
};
|
|
2226
|
-
} finally {
|
|
2227
|
-
clearGlobalSSRTimeout();
|
|
2228
|
-
}
|
|
2229
|
-
});
|
|
2183
|
+
const discoveredData = await runDiscoveryPhase(normalizedUrl, ssrTimeout, module, options);
|
|
2230
2184
|
if ("redirect" in discoveredData) {
|
|
2231
2185
|
return {
|
|
2232
2186
|
html: "",
|
|
@@ -2252,9 +2206,7 @@ async function ssrRenderSinglePass(module, url, options) {
|
|
|
2252
2206
|
let themePreloadTags = "";
|
|
2253
2207
|
if (module.theme) {
|
|
2254
2208
|
try {
|
|
2255
|
-
const compiled =
|
|
2256
|
-
fallbackMetrics: options?.fallbackMetrics
|
|
2257
|
-
});
|
|
2209
|
+
const compiled = compileThemeCached(module.theme, options?.fallbackMetrics);
|
|
2258
2210
|
themeCss = compiled.css;
|
|
2259
2211
|
themePreloadTags = compiled.preloadTags;
|
|
2260
2212
|
} catch (e) {
|
|
@@ -2268,7 +2220,7 @@ async function ssrRenderSinglePass(module, url, options) {
|
|
|
2268
2220
|
const css = collectCSS2(themeCss, module);
|
|
2269
2221
|
const ssrData = discoveredData.resolvedQueries.map(({ key, data }) => ({
|
|
2270
2222
|
key,
|
|
2271
|
-
data
|
|
2223
|
+
data
|
|
2272
2224
|
}));
|
|
2273
2225
|
return {
|
|
2274
2226
|
html,
|
|
@@ -2283,6 +2235,56 @@ async function ssrRenderSinglePass(module, url, options) {
|
|
|
2283
2235
|
}
|
|
2284
2236
|
});
|
|
2285
2237
|
}
|
|
2238
|
+
async function runDiscoveryPhase(normalizedUrl, ssrTimeout, module, options) {
|
|
2239
|
+
const discoveryCtx = createRequestContext(normalizedUrl);
|
|
2240
|
+
if (options?.ssrAuth) {
|
|
2241
|
+
discoveryCtx.ssrAuth = options.ssrAuth;
|
|
2242
|
+
}
|
|
2243
|
+
return ssrStorage.run(discoveryCtx, async () => {
|
|
2244
|
+
try {
|
|
2245
|
+
setGlobalSSRTimeout(ssrTimeout);
|
|
2246
|
+
const createApp = resolveAppFactory2(module);
|
|
2247
|
+
createApp();
|
|
2248
|
+
if (discoveryCtx.ssrRedirect) {
|
|
2249
|
+
return { redirect: discoveryCtx.ssrRedirect };
|
|
2250
|
+
}
|
|
2251
|
+
if (discoveryCtx.pendingRouteComponents?.size) {
|
|
2252
|
+
const entries = Array.from(discoveryCtx.pendingRouteComponents.entries());
|
|
2253
|
+
const results = await Promise.allSettled(entries.map(([route, promise]) => Promise.race([
|
|
2254
|
+
promise.then((mod) => ({ route, factory: mod.default })),
|
|
2255
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error("lazy route timeout")), ssrTimeout))
|
|
2256
|
+
])));
|
|
2257
|
+
discoveryCtx.resolvedComponents = new Map;
|
|
2258
|
+
for (const result of results) {
|
|
2259
|
+
if (result.status === "fulfilled") {
|
|
2260
|
+
const { route, factory } = result.value;
|
|
2261
|
+
discoveryCtx.resolvedComponents.set(route, factory);
|
|
2262
|
+
}
|
|
2263
|
+
}
|
|
2264
|
+
discoveryCtx.pendingRouteComponents = undefined;
|
|
2265
|
+
}
|
|
2266
|
+
const queries = getSSRQueries();
|
|
2267
|
+
const eligibleQueries = filterByEntityAccess(queries, options?.manifest?.entityAccess, options?.prefetchSession);
|
|
2268
|
+
const resolvedQueries = [];
|
|
2269
|
+
if (eligibleQueries.length > 0) {
|
|
2270
|
+
await Promise.allSettled(eligibleQueries.map(({ promise, timeout, resolve, key }) => Promise.race([
|
|
2271
|
+
promise.then((data) => {
|
|
2272
|
+
resolve(data);
|
|
2273
|
+
resolvedQueries.push({ key, data });
|
|
2274
|
+
return "resolved";
|
|
2275
|
+
}),
|
|
2276
|
+
new Promise((r) => setTimeout(r, timeout || ssrTimeout)).then(() => "timeout")
|
|
2277
|
+
])));
|
|
2278
|
+
}
|
|
2279
|
+
return {
|
|
2280
|
+
resolvedQueries,
|
|
2281
|
+
resolvedComponents: discoveryCtx.resolvedComponents
|
|
2282
|
+
};
|
|
2283
|
+
} finally {
|
|
2284
|
+
clearGlobalSSRTimeout();
|
|
2285
|
+
}
|
|
2286
|
+
});
|
|
2287
|
+
}
|
|
2286
2288
|
function attemptZeroDiscovery(url, module, options, ssrTimeout) {
|
|
2287
2289
|
const manifest = options?.manifest;
|
|
2288
2290
|
if (!manifest?.routeEntries || !module.api)
|
|
@@ -2345,9 +2347,7 @@ async function renderWithPrefetchedData(module, normalizedUrl, prefetchedData, o
|
|
|
2345
2347
|
let themePreloadTags = "";
|
|
2346
2348
|
if (module.theme) {
|
|
2347
2349
|
try {
|
|
2348
|
-
const compiled =
|
|
2349
|
-
fallbackMetrics: options?.fallbackMetrics
|
|
2350
|
-
});
|
|
2350
|
+
const compiled = compileThemeCached(module.theme, options?.fallbackMetrics);
|
|
2351
2351
|
themeCss = compiled.css;
|
|
2352
2352
|
themePreloadTags = compiled.preloadTags;
|
|
2353
2353
|
} catch (e) {
|
|
@@ -2372,7 +2372,7 @@ async function renderWithPrefetchedData(module, normalizedUrl, prefetchedData, o
|
|
|
2372
2372
|
const css = collectCSS2(themeCss, module);
|
|
2373
2373
|
const ssrData = data.resolvedQueries.map(({ key, data: d }) => ({
|
|
2374
2374
|
key,
|
|
2375
|
-
data:
|
|
2375
|
+
data: d
|
|
2376
2376
|
}));
|
|
2377
2377
|
return {
|
|
2378
2378
|
html,
|
|
@@ -2553,6 +2553,9 @@ var STALE_GRAPH_PATTERNS = [
|
|
|
2553
2553
|
function isStaleGraphError(message) {
|
|
2554
2554
|
return STALE_GRAPH_PATTERNS.some((pattern) => pattern.test(message));
|
|
2555
2555
|
}
|
|
2556
|
+
function isReloadStub(text) {
|
|
2557
|
+
return text.trimStart().startsWith("try{location.reload()}");
|
|
2558
|
+
}
|
|
2556
2559
|
var MAX_TERMINAL_STACK_FRAMES = 5;
|
|
2557
2560
|
function formatTerminalRuntimeError(errors, parsedStack) {
|
|
2558
2561
|
const primary = errors[0];
|
|
@@ -2881,9 +2884,13 @@ var BUILD_ERROR_LOADER = [
|
|
|
2881
2884
|
"if(t.trimStart().startsWith('try{location.reload()}')){",
|
|
2882
2885
|
"fetch('/__vertz_build_check').then(function(r){return r.json()}).then(function(j){",
|
|
2883
2886
|
"if(j.errors&&j.errors.length>0){showOverlay('Build failed',formatErrors(j.errors),j)}",
|
|
2887
|
+
"else{var V2=window.__vertz_overlay;",
|
|
2888
|
+
"if(V2&&V2._autoRestart&&V2._canAutoRestart&&V2._canAutoRestart()){",
|
|
2889
|
+
"V2._autoRestart();sessionStorage.removeItem('__vertz_stub_retry');",
|
|
2890
|
+
`showOverlay('Restarting dev server','<p style="margin:0;color:#666;font-size:12px">Dev bundler appears stale after adding new files. Restarting...</p>')}`,
|
|
2884
2891
|
"else{var rk='__vertz_stub_retry',rc=+(sessionStorage.getItem(rk)||0);",
|
|
2885
2892
|
"if(rc<3){sessionStorage.setItem(rk,String(rc+1));setTimeout(function(){location.reload()},2000)}",
|
|
2886
|
-
`else{sessionStorage.removeItem(rk);showOverlay('Build failed','<p style="margin:0;color:#666;font-size:12px">Could not load client bundle. Try
|
|
2893
|
+
`else{sessionStorage.removeItem(rk);showOverlay('Build failed','<p style="margin:0;color:#666;font-size:12px">Could not load client bundle. Try restarting the dev server.</p>',null,null,true)}}}`,
|
|
2887
2894
|
"}).catch(function(){",
|
|
2888
2895
|
`showOverlay('Build failed','<p style="margin:0;color:#666;font-size:12px">Check your terminal for details.</p>')})}`,
|
|
2889
2896
|
"else{sessionStorage.removeItem('__vertz_stub_retry');var s=document.createElement('script');s.type='module';s.crossOrigin='';s.src=src;document.body.appendChild(s)}",
|
|
@@ -3277,6 +3284,11 @@ function createBunDevServer(options) {
|
|
|
3277
3284
|
plugin(serverPlugin);
|
|
3278
3285
|
stableUpdateManifest = updateManifest;
|
|
3279
3286
|
}
|
|
3287
|
+
if (!pluginsRegistered && options.plugins) {
|
|
3288
|
+
for (const userPlugin of options.plugins) {
|
|
3289
|
+
plugin(userPlugin);
|
|
3290
|
+
}
|
|
3291
|
+
}
|
|
3280
3292
|
pluginsRegistered = true;
|
|
3281
3293
|
const updateServerManifest = stableUpdateManifest;
|
|
3282
3294
|
let ssrMod;
|
|
@@ -3897,6 +3909,24 @@ data: {}
|
|
|
3897
3909
|
if (bundledScriptUrl !== prevUrl)
|
|
3898
3910
|
break;
|
|
3899
3911
|
}
|
|
3912
|
+
if (bundledScriptUrl && server && !isRestarting) {
|
|
3913
|
+
try {
|
|
3914
|
+
const bundleRes = await fetch(`http://${host}:${server.port}${bundledScriptUrl}`);
|
|
3915
|
+
const bundleText = await bundleRes.text();
|
|
3916
|
+
if (isReloadStub(bundleText)) {
|
|
3917
|
+
if (canAutoRestart()) {
|
|
3918
|
+
autoRestartTimestamps.push(Date.now());
|
|
3919
|
+
if (logRequests) {
|
|
3920
|
+
console.log("[Server] Dev bundler serving reload stub after successful build \u2014 restarting");
|
|
3921
|
+
}
|
|
3922
|
+
devServer.restart();
|
|
3923
|
+
return;
|
|
3924
|
+
} else if (logRequests) {
|
|
3925
|
+
console.log("[Server] Dev bundler stale but auto-restart cap reached");
|
|
3926
|
+
}
|
|
3927
|
+
}
|
|
3928
|
+
} catch {}
|
|
3929
|
+
}
|
|
3900
3930
|
clearErrorForFileChange();
|
|
3901
3931
|
}
|
|
3902
3932
|
} catch {}
|
|
@@ -4110,6 +4140,7 @@ data: {}
|
|
|
4110
4140
|
export {
|
|
4111
4141
|
parseHMRAssets,
|
|
4112
4142
|
isStaleGraphError,
|
|
4143
|
+
isReloadStub,
|
|
4113
4144
|
generateSSRPageHtml,
|
|
4114
4145
|
formatTerminalRuntimeError,
|
|
4115
4146
|
detectFaviconTag,
|
|
@@ -133,7 +133,7 @@ declare class DiagnosticsCollector {
|
|
|
133
133
|
recordFieldMiss(type: string, id: string, field: string, querySource: string): void;
|
|
134
134
|
getSnapshot(): DiagnosticsSnapshot;
|
|
135
135
|
}
|
|
136
|
-
import { BunPlugin as
|
|
136
|
+
import { BunPlugin as BunPlugin_seob62 } from "bun";
|
|
137
137
|
interface VertzBunPluginOptions {
|
|
138
138
|
/** Regex filter for files to transform. Defaults to .tsx files. */
|
|
139
139
|
filter?: RegExp;
|
|
@@ -187,7 +187,7 @@ interface ManifestUpdateResult {
|
|
|
187
187
|
}
|
|
188
188
|
interface VertzBunPluginResult {
|
|
189
189
|
/** The Bun plugin to pass to Bun.build or bunfig.toml. */
|
|
190
|
-
plugin:
|
|
190
|
+
plugin: BunPlugin_seob62;
|
|
191
191
|
/** CSS extractions for all transformed files (for production dead CSS elimination). */
|
|
192
192
|
fileExtractions: FileExtractionsMap;
|
|
193
193
|
/** Map of source file to CSS sidecar file path (for debugging). */
|
package/dist/index.d.ts
CHANGED
|
@@ -901,6 +901,27 @@ interface SSRHandlerOptions {
|
|
|
901
901
|
* optionally `window.__VERTZ_ACCESS_SET__` for instant auth hydration.
|
|
902
902
|
*/
|
|
903
903
|
sessionResolver?: SessionResolver;
|
|
904
|
+
/**
|
|
905
|
+
* Prefetch manifest for single-pass SSR optimization.
|
|
906
|
+
*
|
|
907
|
+
* When provided with route entries and an API client export, enables
|
|
908
|
+
* zero-discovery rendering — queries are prefetched from the manifest
|
|
909
|
+
* without executing the component tree, then a single render pass
|
|
910
|
+
* produces the HTML. Without a manifest, SSR still uses the single-pass
|
|
911
|
+
* discovery-then-render approach (cheaper than two-pass).
|
|
912
|
+
*/
|
|
913
|
+
manifest?: SSRPrefetchManifest;
|
|
914
|
+
/**
|
|
915
|
+
* Enable progressive HTML streaming. Default: false.
|
|
916
|
+
*
|
|
917
|
+
* When true, the Response body is a ReadableStream that sends `<head>`
|
|
918
|
+
* content (CSS, preloads, fonts) before `<body>` rendering is complete.
|
|
919
|
+
* This improves TTFB and FCP.
|
|
920
|
+
*
|
|
921
|
+
* Has no effect on zero-discovery routes (manifest with routeEntries),
|
|
922
|
+
* which always use buffered rendering.
|
|
923
|
+
*/
|
|
924
|
+
progressiveHTML?: boolean;
|
|
904
925
|
}
|
|
905
926
|
declare function createSSRHandler(options: SSRHandlerOptions): (request: Request) => Promise<Response>;
|
|
906
927
|
interface GenerateSSRHtmlOptions {
|