@rsc-kit/core 0.17.0 → 0.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/dist/barrelImports.d.ts +6 -0
  2. package/dist/barrelImports.js +93 -0
  3. package/dist/barrelImports.js.map +1 -0
  4. package/dist/events.d.ts +57 -0
  5. package/dist/events.js +113 -0
  6. package/dist/events.js.map +1 -0
  7. package/dist/host.d.ts +16 -6
  8. package/dist/host.js +219 -124
  9. package/dist/host.js.map +1 -1
  10. package/dist/hostCalls.d.ts +27 -0
  11. package/dist/hostCalls.js +127 -12
  12. package/dist/hostCalls.js.map +1 -1
  13. package/dist/hostRouting.d.ts +53 -0
  14. package/dist/hostRouting.js +100 -0
  15. package/dist/hostRouting.js.map +1 -0
  16. package/dist/js/DefaultRouteError.d.ts +3 -0
  17. package/dist/js/DefaultRouteError.js +61 -0
  18. package/dist/js/DefaultRouteError.js.map +1 -0
  19. package/dist/js/LoadingBoundary.d.ts +5 -0
  20. package/dist/js/LoadingBoundary.js +19 -0
  21. package/dist/js/LoadingBoundary.js.map +1 -0
  22. package/dist/js/fallbackReport.js +10 -8
  23. package/dist/js/fallbackReport.js.map +1 -1
  24. package/dist/js/queryClient.d.ts +2 -1
  25. package/dist/js/queryClient.js +0 -12
  26. package/dist/js/queryClient.js.map +1 -1
  27. package/dist/js/router.d.ts +2 -2
  28. package/dist/js/router.js.map +1 -1
  29. package/dist/js/useEvents.d.ts +25 -0
  30. package/dist/js/useEvents.js +80 -0
  31. package/dist/js/useEvents.js.map +1 -0
  32. package/dist/js/usePolling.d.ts +29 -0
  33. package/dist/js/usePolling.js +142 -0
  34. package/dist/js/usePolling.js.map +1 -0
  35. package/dist/manifest.d.ts +18 -1
  36. package/dist/manifest.js.map +1 -1
  37. package/dist/metadataRoutes.d.ts +20 -0
  38. package/dist/metadataRoutes.js +35 -0
  39. package/dist/metadataRoutes.js.map +1 -1
  40. package/dist/prerender.js +2 -0
  41. package/dist/prerender.js.map +1 -1
  42. package/dist/redirect.d.ts +16 -2
  43. package/dist/redirect.js +10 -19
  44. package/dist/redirect.js.map +1 -1
  45. package/dist/revalidate.d.ts +6 -4
  46. package/dist/revalidate.js +6 -5
  47. package/dist/revalidate.js.map +1 -1
  48. package/dist/routeSchema.d.ts +49 -0
  49. package/dist/routeSchema.js.map +1 -1
  50. package/dist/routes.d.ts +16 -3
  51. package/dist/routes.js +5 -5
  52. package/dist/routes.js.map +1 -1
  53. package/dist/routing.d.ts +2 -2
  54. package/dist/routing.js +47 -25
  55. package/dist/routing.js.map +1 -1
  56. package/dist/testing.d.ts +8 -0
  57. package/dist/testing.js +27 -3
  58. package/dist/testing.js.map +1 -1
  59. package/dist/vite.d.ts +53 -2
  60. package/dist/vite.js +503 -38
  61. package/dist/vite.js.map +1 -1
  62. package/package.json +15 -3
@@ -1 +1 @@
1
- {"version":3,"file":"metadataRoutes.js","sourceRoot":"","sources":["../src/metadataRoutes.ts"],"names":[],"mappings":"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","sourcesContent":["// robots.txt, sitemap.xml and llms.txt, from a file beside the root layout.\n//\n// Each convention file becomes an api route the build synthesises - so a\n// sitemap that reads nothing per request is stored at build like any frozen\n// route, one that reads the request stays dynamic, and the build's table says\n// which. What lives here is the formatting: the value the app's function\n// returns, written the way the crawler expects it.\n\nimport type { MetadataRoute, RobotsRule, SitemapEntry } from \"./metadata.js\";\n\nexport const METADATA_ROUTES = {\n robots: { file: \"robots.txt\", type: \"text/plain; charset=utf-8\" },\n sitemap: { file: \"sitemap.xml\", type: \"application/xml; charset=utf-8\" },\n llms: { file: \"llms.txt\", type: \"text/plain; charset=utf-8\" },\n \"llms-full\": { file: \"llms-full.txt\", type: \"text/plain; charset=utf-8\" },\n} as const;\n\nexport type MetadataRouteKind = keyof typeof METADATA_ROUTES;\n\n/**\n * Files an app may drop beside the root layout to be served at the root as\n * they are: the same three, hand-written, and the handful of other files a\n * site is asked for at its root.\n */\nexport const ROOT_FILES =\n /^(?:robots\\.txt|sitemap(?:-[\\w.-]+)?\\.xml|llms(?:-full)?\\.txt|humans\\.txt|security\\.txt|ads\\.txt|app-ads\\.txt)$/;\n\nexport function rootFileType(name: string): string {\n return name.endsWith(\".xml\")\n ? \"application/xml; charset=utf-8\"\n : \"text/plain; charset=utf-8\";\n}\n\nfunction list<T>(value: T | T[] | undefined): T[] {\n return value === undefined ? [] : Array.isArray(value) ? value : [value];\n}\n\n/**\n * A url made absolute. A relative one needs the root layout's metadataBase -\n * a crawler is handed these with no page to resolve them against.\n */\nexport function absoluteUrl(\n url: string,\n base: string | URL | null | undefined,\n file: string,\n): string {\n if (/^[a-z][a-z0-9+.-]*:/i.test(url)) return url;\n\n if (!base) {\n throw new Error(\n `[rsc-kit] ${file} names a relative url, ${JSON.stringify(url)}, and the root layout has no metadataBase to make it absolute. ` +\n \"Add metadataBase: new URL('https://example.com') to the root layout's metadata, or write the url in full.\",\n );\n }\n\n return new URL(url, base).href;\n}\n\nexport function robotsText(\n robots: MetadataRoute.Robots,\n base: string | URL | null | undefined,\n): string {\n const blocks = list(robots.rules).map((rule: RobotsRule) => {\n const lines: string[] = [];\n\n for (const agent of list(rule.userAgent).length\n ? list(rule.userAgent)\n : [\"*\"])\n lines.push(`User-Agent: ${agent}`);\n for (const path of list(rule.allow)) lines.push(`Allow: ${path}`);\n for (const path of list(rule.disallow)) lines.push(`Disallow: ${path}`);\n if (rule.crawlDelay !== undefined)\n lines.push(`Crawl-delay: ${rule.crawlDelay}`);\n\n return lines.join(\"\\n\");\n });\n\n const tail: string[] = [];\n\n for (const sitemap of list(robots.sitemap))\n tail.push(`Sitemap: ${absoluteUrl(sitemap, base, \"robots.ts\")}`);\n if (robots.host) tail.push(`Host: ${robots.host}`);\n\n return (\n [...blocks, ...(tail.length ? [tail.join(\"\\n\")] : [])].join(\"\\n\\n\") + \"\\n\"\n );\n}\n\nfunction escapeXml(text: string): string {\n return text.replace(\n /[&<>\"']/g,\n (c) =>\n ({\n \"&\": \"&amp;\",\n \"<\": \"&lt;\",\n \">\": \"&gt;\",\n '\"': \"&quot;\",\n \"'\": \"&apos;\",\n })[c]!,\n );\n}\n\nexport function sitemapXml(\n entries: MetadataRoute.Sitemap,\n base: string | URL | null | undefined,\n): string {\n const hasAlternates = entries.some(\n (e) =>\n e.alternates?.languages && Object.keys(e.alternates.languages).length > 0,\n );\n const hasImages = entries.some((e) => e.images && e.images.length > 0);\n\n const urls = entries.map((entry: SitemapEntry) => {\n const parts = [\n `<loc>${escapeXml(absoluteUrl(entry.url, base, \"sitemap.ts\"))}</loc>`,\n ];\n\n if (entry.lastModified !== undefined) {\n const when =\n entry.lastModified instanceof Date\n ? entry.lastModified.toISOString()\n : entry.lastModified;\n\n parts.push(`<lastmod>${escapeXml(when)}</lastmod>`);\n }\n if (entry.changeFrequency)\n parts.push(`<changefreq>${entry.changeFrequency}</changefreq>`);\n if (entry.priority !== undefined)\n parts.push(`<priority>${entry.priority}</priority>`);\n for (const [lang, href] of Object.entries(\n entry.alternates?.languages ?? {},\n )) {\n parts.push(\n `<xhtml:link rel=\"alternate\" hreflang=\"${escapeXml(lang)}\" href=\"${escapeXml(absoluteUrl(href, base, \"sitemap.ts\"))}\"/>`,\n );\n }\n for (const image of entry.images ?? []) {\n parts.push(\n `<image:image><image:loc>${escapeXml(absoluteUrl(image, base, \"sitemap.ts\"))}</image:loc></image:image>`,\n );\n }\n\n return `<url>${parts.join(\"\")}</url>`;\n });\n\n const namespaces = [\n 'xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"',\n ...(hasAlternates ? ['xmlns:xhtml=\"http://www.w3.org/1999/xhtml\"'] : []),\n ...(hasImages\n ? ['xmlns:image=\"http://www.google.com/schemas/sitemap-image/1.1\"']\n : []),\n ];\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<urlset ${namespaces.join(\" \")}>\\n${urls.join(\"\\n\")}\\n</urlset>\\n`;\n}\n\nexport function llmsText(\n llms: MetadataRoute.Llms,\n base: string | URL | null | undefined,\n): string {\n const out: string[] = [`# ${llms.title}`];\n\n if (llms.summary) out.push(\"\", `> ${llms.summary}`);\n for (const paragraph of list(llms.details)) out.push(\"\", paragraph);\n\n for (const section of llms.sections ?? []) {\n out.push(\"\", `## ${section.title}`, \"\");\n for (const link of section.links) {\n out.push(\n `- [${link.title}](${absoluteUrl(link.url, base, \"llms.ts\")})${link.description ? `: ${link.description}` : \"\"}`,\n );\n }\n }\n\n return out.join(\"\\n\") + \"\\n\";\n}\n\n/**\n * The response for one of these routes: what the app's function returned,\n * formatted, unless it returned the text itself. Called by the route the\n * build synthesised, never by an app directly.\n */\nexport async function metadataResponse(\n kind: MetadataRouteKind,\n produce: () => unknown,\n base: string | URL | null | undefined,\n): Promise<Response> {\n const value = await produce();\n const body =\n typeof value === \"string\"\n ? value\n : kind === \"robots\"\n ? robotsText(value as MetadataRoute.Robots, base)\n : kind === \"sitemap\"\n ? sitemapXml(value as MetadataRoute.Sitemap, base)\n : llmsText(value as MetadataRoute.Llms, base);\n\n return new Response(body, {\n headers: { \"Content-Type\": METADATA_ROUTES[kind].type },\n });\n}\n"]}
1
+ {"version":3,"file":"metadataRoutes.js","sourceRoot":"","sources":["../src/metadataRoutes.ts"],"names":[],"mappings":"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","sourcesContent":["// robots.txt, sitemap.xml and llms.txt, from a file beside the root layout.\n//\n// Each convention file becomes an api route the build synthesises - so a\n// sitemap that reads nothing per request is stored at build like any frozen\n// route, one that reads the request stays dynamic, and the build's table says\n// which. What lives here is the formatting: the value the app's function\n// returns, written the way the crawler expects it.\n\nimport type { MetadataRoute, RobotsRule, SitemapEntry } from \"./metadata.js\";\n\nexport const METADATA_ROUTES = {\n robots: { file: \"robots.txt\", type: \"text/plain; charset=utf-8\" },\n sitemap: { file: \"sitemap.xml\", type: \"application/xml; charset=utf-8\" },\n llms: { file: \"llms.txt\", type: \"text/plain; charset=utf-8\" },\n \"llms-full\": { file: \"llms-full.txt\", type: \"text/plain; charset=utf-8\" },\n} as const;\n\nexport type MetadataRouteKind = keyof typeof METADATA_ROUTES;\n\n/**\n * Files an app may drop beside the root layout to be served at the root as\n * they are: the same three, hand-written, and the handful of other files a\n * site is asked for at its root.\n */\nexport const ROOT_FILES =\n /^(?:robots\\.txt|sitemap(?:-[\\w.-]+)?\\.xml|llms(?:-full)?\\.txt|humans\\.txt|security\\.txt|ads\\.txt|app-ads\\.txt)$/;\n\nexport function rootFileType(name: string): string {\n return name.endsWith(\".xml\")\n ? \"application/xml; charset=utf-8\"\n : \"text/plain; charset=utf-8\";\n}\n\nfunction list<T>(value: T | T[] | undefined): T[] {\n return value === undefined ? [] : Array.isArray(value) ? value : [value];\n}\n\n/**\n * A url made absolute. A relative one needs the root layout's metadataBase -\n * a crawler is handed these with no page to resolve them against.\n */\nexport function absoluteUrl(\n url: string,\n base: string | URL | null | undefined,\n file: string,\n): string {\n if (/^[a-z][a-z0-9+.-]*:/i.test(url)) return url;\n\n if (!base) {\n throw new Error(\n `[rsc-kit] ${file} names a relative url, ${JSON.stringify(url)}, and the root layout has no metadataBase to make it absolute. ` +\n \"Add metadataBase: new URL('https://example.com') to the root layout's metadata, or write the url in full.\",\n );\n }\n\n return new URL(url, base).href;\n}\n\nexport function robotsText(\n robots: MetadataRoute.Robots,\n base: string | URL | null | undefined,\n): string {\n const blocks = list(robots.rules).map((rule: RobotsRule) => {\n const lines: string[] = [];\n\n for (const agent of list(rule.userAgent).length\n ? list(rule.userAgent)\n : [\"*\"])\n lines.push(`User-Agent: ${agent}`);\n for (const path of list(rule.allow)) lines.push(`Allow: ${path}`);\n for (const path of list(rule.disallow)) lines.push(`Disallow: ${path}`);\n if (rule.crawlDelay !== undefined)\n lines.push(`Crawl-delay: ${rule.crawlDelay}`);\n\n return lines.join(\"\\n\");\n });\n\n const tail: string[] = [];\n\n for (const sitemap of list(robots.sitemap))\n tail.push(`Sitemap: ${absoluteUrl(sitemap, base, \"robots.ts\")}`);\n if (robots.host) tail.push(`Host: ${robots.host}`);\n\n return (\n [...blocks, ...(tail.length ? [tail.join(\"\\n\")] : [])].join(\"\\n\\n\") + \"\\n\"\n );\n}\n\nfunction escapeXml(text: string): string {\n return text.replace(\n /[&<>\"']/g,\n (c) =>\n ({\n \"&\": \"&amp;\",\n \"<\": \"&lt;\",\n \">\": \"&gt;\",\n '\"': \"&quot;\",\n \"'\": \"&apos;\",\n })[c]!,\n );\n}\n\nexport function sitemapXml(\n entries: MetadataRoute.Sitemap,\n base: string | URL | null | undefined,\n): string {\n const hasAlternates = entries.some(\n (e) =>\n e.alternates?.languages && Object.keys(e.alternates.languages).length > 0,\n );\n const hasImages = entries.some((e) => e.images && e.images.length > 0);\n\n const urls = entries.map((entry: SitemapEntry) => {\n const parts = [\n `<loc>${escapeXml(absoluteUrl(entry.url, base, \"sitemap.ts\"))}</loc>`,\n ];\n\n if (entry.lastModified !== undefined) {\n const when =\n entry.lastModified instanceof Date\n ? entry.lastModified.toISOString()\n : entry.lastModified;\n\n parts.push(`<lastmod>${escapeXml(when)}</lastmod>`);\n }\n if (entry.changeFrequency)\n parts.push(`<changefreq>${entry.changeFrequency}</changefreq>`);\n if (entry.priority !== undefined)\n parts.push(`<priority>${entry.priority}</priority>`);\n for (const [lang, href] of Object.entries(\n entry.alternates?.languages ?? {},\n )) {\n parts.push(\n `<xhtml:link rel=\"alternate\" hreflang=\"${escapeXml(lang)}\" href=\"${escapeXml(absoluteUrl(href, base, \"sitemap.ts\"))}\"/>`,\n );\n }\n for (const image of entry.images ?? []) {\n parts.push(\n `<image:image><image:loc>${escapeXml(absoluteUrl(image, base, \"sitemap.ts\"))}</image:loc></image:image>`,\n );\n }\n\n return `<url>${parts.join(\"\")}</url>`;\n });\n\n const namespaces = [\n 'xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"',\n ...(hasAlternates ? ['xmlns:xhtml=\"http://www.w3.org/1999/xhtml\"'] : []),\n ...(hasImages\n ? ['xmlns:image=\"http://www.google.com/schemas/sitemap-image/1.1\"']\n : []),\n ];\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<urlset ${namespaces.join(\" \")}>\\n${urls.join(\"\\n\")}\\n</urlset>\\n`;\n}\n\nexport function llmsText(\n llms: MetadataRoute.Llms,\n base: string | URL | null | undefined,\n): string {\n const out: string[] = [`# ${llms.title}`];\n\n if (llms.summary) out.push(\"\", `> ${llms.summary}`);\n for (const paragraph of list(llms.details)) out.push(\"\", paragraph);\n\n for (const section of llms.sections ?? []) {\n out.push(\"\", `## ${section.title}`, \"\");\n for (const link of section.links) {\n out.push(\n `- [${link.title}](${absoluteUrl(link.url, base, \"llms.ts\")})${link.description ? `: ${link.description}` : \"\"}`,\n );\n }\n }\n\n return out.join(\"\\n\") + \"\\n\";\n}\n\n/**\n * The response for one of these routes: what the app's function returned,\n * formatted, unless it returned the text itself. Called by the route the\n * build synthesised, never by an app directly.\n */\nexport async function metadataResponse(\n kind: MetadataRouteKind,\n produce: () => unknown,\n base: string | URL | null | undefined,\n): Promise<Response> {\n const value = await produce();\n const body =\n typeof value === \"string\"\n ? value\n : kind === \"robots\"\n ? robotsText(value as MetadataRoute.Robots, base)\n : kind === \"sitemap\"\n ? sitemapXml(value as MetadataRoute.Sitemap, base)\n : llmsText(value as MetadataRoute.Llms, base);\n\n return new Response(body, {\n headers: { \"Content-Type\": METADATA_ROUTES[kind].type },\n });\n}\n\n/**\n * The sitemap the build writes when the app has no sitemap.ts.\n *\n * The build already knows what belongs in one: every page it stored, and\n * every url generateStaticParams listed, which is the set a crawler should\n * be told about. Left out: a route with middleware above it (a guard means\n * \"not for everyone\"), a page the build could not store (it varies per\n * visitor, so it has no one url worth listing... it does, but no freshness\n * to claim - listed without lastModified), the not-found page, and the\n * metadata files themselves. lastModified is the build, which is when the\n * stored copy changed. A sitemap.ts beside the root layout replaces this.\n */\nexport function automaticSitemap(\n results: readonly { url: string; type: string; component: string }[],\n routes: readonly { component: string; middleware: readonly string[] }[],\n base: string | URL,\n builtAt: Date = new Date(),\n): string {\n const guarded = new Set(\n routes.filter((r) => r.middleware.length > 0).map((r) => r.component),\n );\n const seen = new Set<string>();\n const entries: SitemapEntry[] = [];\n\n for (const result of results) {\n if (guarded.has(result.component)) continue;\n if (result.type === \"error\" || result.type === \"blocked\") continue;\n if (/(^|\\/)not-found$|\\/_/.test(result.url)) continue;\n if (/\\[.*\\]/.test(result.url)) continue; // a pattern, not a url\n if (seen.has(result.url)) continue;\n\n seen.add(result.url);\n entries.push(\n result.type === \"frozen\" || result.type === \"shell\"\n ? { url: result.url, lastModified: builtAt }\n : { url: result.url },\n );\n }\n\n entries.sort((a, b) => a.url.localeCompare(b.url));\n\n return sitemapXml(entries, base);\n}\n"]}
package/dist/prerender.js CHANGED
@@ -49,7 +49,9 @@ const DEFAULT_PRERENDER_CONCURRENCY = 4;
49
49
  * else in the list is the app's, and needs the runtime.
50
50
  */
51
51
  const RUNTIME_OWN = new Set([
52
+ "DefaultRouteError",
52
53
  "DocumentTitle",
54
+ "LoadingBoundary",
53
55
  "PathnameProvider",
54
56
  "RouteErrorBoundary",
55
57
  "SegmentBoundary",
@@ -1 +1 @@
1
- {"version":3,"file":"prerender.js","sourceRoot":"","sources":["../src/prerender.ts"],"names":[],"mappings":"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","sourcesContent":["// Rendering pages at build time, for a JavaScript host.\n//\n// The engine does the rendering; this decides what to render and what to do\n// with the result. Two decisions, and both are easy to get subtly wrong:\n//\n// Which urls exist — a route with no params is one url, a route with params is\n// however many `generateStaticParams` returns, and a route with params that\n// declares none cannot be prerendered at all.\n//\n// Whether a page can be frozen — asked by rendering it, never declared. The\n// shell probe replaces the host global with a promise that never resolves, so\n// a page that reaches for request data suspends and says so by doing it. A\n// page that simply takes too long says so by not finishing.\n//\n// The file layout matches the one Laravel writes, so both hosts serve the same\n// shapes and anything that reads them works for either.\n\nimport type { ManifestRoute, RouteManifest } from \"./manifest.js\";\nimport { withRedirect } from \"./redirect.js\";\nimport { withCache } from \"./cache.js\";\nimport {\n requestFallbacks,\n requestReadBy,\n requestReadWhere,\n requestWasRead,\n withRequest,\n} from \"./request.js\";\nimport { watchNondeterminism, whileRendering } from \"./nondeterminism.js\";\n\n/** What a prerenderer needs from the built bundle, beyond serving a request. */\n/**\n * How long the root-fallback diagnostic waits before answering.\n *\n * Short on purpose: the question is whether anything painted, not what. See\n * the call site.\n */\nconst ROOT_FALLBACK_BUDGET_MS = 200;\n\n/**\n * How many routes render at once.\n *\n * Each is a full React render, so this trades memory and CPU for wall time.\n * The gain flattens almost immediately — measured on a twelve-route example:\n * 10.2 s sequential, 4.1 s at four, 4.0 s at six, 4.0 s at twelve, beyond\n * which one route's own serial chain is the floor.\n *\n * Four rather than six because the difference between them is inside the\n * noise, and the smaller number leaves room for whatever else is running.\n * A build is rarely the only thing on a machine — it shares CI with other\n * jobs, and it shares a laptop with the test suite that renders its own\n * fixtures, where six was enough to turn a two-second budget into a timeout.\n */\nconst DEFAULT_PRERENDER_CONCURRENCY = 4;\n\n/**\n * The client components the engine itself puts around every page when the\n * bootstrap is on - the segment and slot boundaries, the title, the pathname\n * provider, the error boundary. They are in every payload, they are not the\n * app's, and a render without the bootstrap does not insert them. Anything\n * else in the list is the app's, and needs the runtime.\n */\nconst RUNTIME_OWN = new Set([\n \"DocumentTitle\",\n \"PathnameProvider\",\n \"RouteErrorBoundary\",\n \"SegmentBoundary\",\n \"SlotBoundary\",\n]);\n\n/**\n * The one line the bootstrap would have run for the worker, for a document\n * stored without a bootstrap. Same timing as the runtime's: after load, so\n * it competes with nothing the first visit needs. A page whose document has\n * no closing body tag is left alone.\n */\nconst WORKER_REGISTRATION =\n \"<script>'serviceWorker'in navigator&&addEventListener('load',function(){navigator.serviceWorker.register('/sw.js').catch(function(){})})</script>\";\n\n/**\n * Every `<link rel=\"stylesheet\">` whose source the reader answers for,\n * replaced by a `<style>` holding it. A link the reader declines - too big,\n * or not the build's - is left as it was.\n */\nexport function withInlineStylesheets(\n html: string,\n read: (href: string) => string | null,\n): string {\n return html.replace(/<link\\b[^>]*\\brel=\"stylesheet\"[^>]*>/g, (tag) => {\n const href = /\\bhref=\"([^\"]+)\"/.exec(tag)?.[1];\n const css = href ? read(href) : null;\n\n return css === null ? tag : `<style>${css}</style>`;\n });\n}\n\nexport function withWorkerRegistration(html: string): string {\n const at = html.lastIndexOf(\"</body>\");\n\n return at === -1\n ? html\n : html.slice(0, at) + WORKER_REGISTRATION + html.slice(at);\n}\n\nexport interface PrerenderEngine {\n manifest?(): RouteManifest;\n /**\n * A route.ts, answered. Optional: a bundle built before api routes existed\n * has none, and the build then simply stores no route.\n */\n handleApiRoute?(\n name: string,\n request: Request,\n params: Record<string, string>,\n allow: string,\n ): Promise<Response>;\n getStaticParams?(component: string): Promise<Record<string, string>[] | null>;\n handleRscPprShell(\n component: string,\n props?: Record<string, unknown>,\n layouts?: { component: string; props: Record<string, unknown> }[],\n loadings?: string[],\n parallelSlots?: Record<string, string>,\n pageKey?: string,\n /** How long to render before taking what has flushed. Defaults to the full budget. */\n budgetMs?: number,\n ): Promise<{\n shellHtml: string;\n timedOut: boolean;\n usedDynamicApis: boolean;\n /**\n * The host calls this render made, by name.\n *\n * So the build can say which one kept the page from being frozen rather\n * than only that something did. Optional: an engine built before this\n * existed reports nothing, and the line is printed without a reason.\n */\n dynamicBecause?: string[];\n error?: string;\n /**\n * Where the render stopped, when it stopped — React's own resumable state.\n *\n * Null when the page finished, which is the same thing as `timedOut` being\n * false. An engine built before this existed returns undefined, and the\n * shell is then served the way it always was: holes filled by the client\n * after hydration rather than resumed at the origin.\n */\n postponed?: unknown;\n /**\n * Anything that failed while producing the shell, including a rejection a\n * Suspense boundary caught.\n *\n * Such a rejection never reaches the caller: React keeps the fallback and\n * the render finishes, so without this a page whose data source was\n * unreachable looked complete and its loading state was frozen as a\n * finished page.\n */\n renderFailure?: string;\n }>;\n handleRsc(\n component: string,\n props?: Record<string, unknown>,\n callbackSocket?: string | null,\n layouts?: { component: string; props: Record<string, unknown> }[],\n loadings?: string[],\n parallelSlots?: Record<string, string>,\n from?: number,\n pageKey?: string,\n bootstrap?: boolean,\n /**\n * Whether a host is installed to answer rpc().\n *\n * False during a build, where there is none: every host call then suspends\n * and the page reports that it reached for one, instead of resolving to\n * undefined and being frozen holding it.\n */\n canReachHost?: boolean,\n ): Promise<{\n body: string;\n rscPayload: string;\n clientComponents: string[];\n /** A server action is in the tree - a form or a client prop - so a runtime is needed to submit it. */\n serverReferences?: boolean;\n usedDynamicApis?: boolean;\n }>;\n handleRscPayload(\n component: string,\n props?: Record<string, unknown>,\n layouts?: { component: string; props: Record<string, unknown> }[],\n loadings?: string[],\n parallelSlots?: Record<string, string>,\n from?: number,\n pageKey?: string,\n ): Promise<{ rscPayload: string }>;\n}\n\nexport interface PrerenderOptions {\n engine: PrerenderEngine;\n /**\n * The app has a service worker. A page stored without the bootstrap has\n * nothing to register it, so one line is put in its place - the worker is\n * for the second visit, and a visitor who lands on such a page first should\n * still get one.\n */\n serviceWorker?: boolean;\n /**\n * A stylesheet's source, by the href the document links it with, or null\n * to leave the link alone. A page stored without the runtime has nothing\n * to hydrate, so its stylesheet can be inlined into the document rather\n * than fetched before the first paint - one request and a round trip off\n * the critical path. The build passes a reader that answers only for small\n * files; a page with the runtime keeps its link, because React expects to\n * find it in the DOM.\n */\n stylesheet?: (href: string) => string | null;\n /**\n * Where the output goes, as a sink rather than a directory.\n *\n * `writeTo` in `@rsc-kit/core/files` is the one for a disk, which is what a\n * build normally wants. A function because the read side is one — a host\n * that supplies a reader should be able to supply the matching writer —\n * and because a test can hand it a Map instead of a temp directory.\n */\n write: (name: string, contents: string) => Promise<void> | void;\n /** The route table. Defaults to the one the bundle carries. */\n manifest?: RouteManifest;\n /**\n * Props for a page at build time.\n *\n * There is no request here, which is the point: anything a page needs that\n * only a request can supply is exactly what makes it un-freezable. Defaults\n * to the url params alone.\n */\n props?: (\n route: ManifestRoute,\n params: Record<string, string>,\n ) => Record<string, unknown>;\n /**\n * How many routes to render at once. Defaults to 6; 1 renders sequentially.\n *\n * Worth lowering when the pages talk to something that will not enjoy six\n * concurrent callers — a local database, a rate-limited API.\n */\n concurrency?: number;\n /** Identifies the build in what gets written, so a stale page can be spotted. */\n version?: string;\n /** Called as each url is decided, for build output. */\n onResult?: (result: PrerenderResult) => void;\n}\n\n/**\n * The build's refusal to store a route it cannot answer ahead of time.\n *\n * Thrown rather than reported, because the alternative is a category: a bucket\n * of routes that quietly render per request, which is where the slow ones go\n * to be forgotten. Every route is either stored or has said it will not be.\n */\nexport class NotPrerenderable extends Error {\n public readonly routes: PrerenderResult[];\n\n constructor(routes: PrerenderResult[]) {\n // Two different problems arrive here, and the advice for one is useless for\n // the other. A page that reads the request above every boundary needs a\n // boundary; a page whose render threw needs whatever it was reaching for.\n const threw = routes.filter((r) =>\n r.reason?.startsWith(\"could not be rendered\"),\n );\n const unpaintable = routes.filter(\n (r) => !r.reason?.startsWith(\"could not be rendered\"),\n );\n\n const advice: string[] = [];\n\n if (unpaintable.length > 0) {\n advice.push(\n \"These read request data — params, headers, cookies, or the host — above\\n\" +\n \"every Suspense boundary, so nothing can paint without it:\\n\\n\" +\n unpaintable\n .map((r) => ` ${r.url} — ${r.reason ?? \"nothing to paint\"}`)\n .join(\"\\n\") +\n \"\\n\\nPut the part that waits inside <Suspense>, or add a loading.tsx beside\\n\" +\n \"the page, so there is something to store while the rest arrives.\",\n );\n }\n\n if (threw.length > 0) {\n advice.push(\n \"These failed while rendering:\\n\\n\" +\n threw.map((r) => ` ${r.url} — ${r.reason}`).join(\"\\n\") +\n \"\\n\\nPrerendering runs your application code, so it needs whatever that code\\n\" +\n \"needs. If the page is fine and this machine simply cannot reach a\\n\" +\n \"database or an API, either give the build access or put `await connection()`\\n\" +\n \"before the read: the page then renders per request and the rest is still stored.\\n\\n\" +\n \"Reaching for data through the host — `await rpc(...)` — avoids this\\n\" +\n \"entirely: the build stubs that call, so the page freezes a shell\\n\" +\n \"without the data being available.\",\n );\n }\n\n super(\n \"Some routes could not be prerendered.\\n\\n\" + advice.join(\"\\n\\n\") + \"\\n\",\n );\n this.name = \"NotPrerenderable\";\n this.routes = routes;\n\n // Not enumerable: Vite prints an error's own properties under its stack,\n // and this list is the message again, as an object dump.\n Object.defineProperty(this, \"routes\", { value: routes, enumerable: false });\n }\n}\n\nexport interface PrerenderResult {\n url: string;\n component: string;\n /**\n * frozen — the whole page is on disk.\n * shell — the chrome is on disk and the rest is rendered per request.\n * blocked — nothing could be stored. Fails the build.\n * error — the render itself failed, or the build refused what it produced.\n *\n * dynamic — answered per request, and correctly so. Api routes only.\n *\n * There is no such outcome for a PAGE. A page that cannot be stored has its\n * boundary in the wrong place, and the fix is to move it — not to declare\n * the problem away, which is how the slow ones get forgotten. An api route\n * has no boundary to move: it either depends on the request or it does not,\n * and depending on it is the ordinary case rather than a mistake.\n */\n type: \"frozen\" | \"shell\" | \"blocked\" | \"error\" | \"dynamic\";\n reason: string | null;\n /**\n * Something worth knowing that is not a failure.\n *\n * The one that matters: a page whose only boundary is the root loading.tsx.\n * It is stored, so the build has nothing to refuse — but the fallback that\n * caught it belongs to the whole app rather than to this page, and every\n * page in the app shows the same thing while this one's data arrives.\n */\n warning?: string;\n /** A fact about how it was stored that is neither a reason nor a warning. */\n note?: string;\n}\n\n/**\n * The file name a route's shell is stored under, with params standing in for\n * themselves: /posts/[slug] → posts/_slug_.\n *\n * A shell contains nothing that varies by param — everything that does is\n * behind a boundary the client fills — so one shell serves every url the\n * route matches, including the ones the app never listed.\n */\nexport function patternKey(route: ManifestRoute): string {\n const parts = route.segments.map((s) =>\n s.type === \"static\" ? s.value : `_${s.value}_`,\n );\n\n return parts.join(\"/\") || \"index\";\n}\n\n/** Close a document the render was aborted in the middle of. */\nexport function closeDocument(html: string): string {\n let out = html;\n\n if (!/<\\/body>/i.test(out) && /<body/i.test(out)) out += \"</body>\";\n if (!/<\\/html>/i.test(out) && /<html/i.test(out)) out += \"</html>\";\n\n return out;\n}\n\n/**\n * The file name a url is stored under: / → index, /a/b → a/b.\n *\n * Refuses a key that could leave the directory it is written into. The input is\n * whatever generateStaticParams() returned — typically slugs from a database or\n * a CMS — so a record named `../../../../etc/cron.d/x` is an arbitrary file\n * write on the build machine with content the same record influences.\n *\n * Checked here rather than in the writer, because the writer is supplied by the\n * host: `writeTo` on disk does the obvious thing, but a KV or edge binding has\n * no notion of a parent directory and no reason to look for one.\n */\n/**\n * The key, showing only the marks that actually appear above it.\n *\n * Wording follows Next's build output deliberately. Most people arriving here\n * have read that legend already, and inventing a second vocabulary for the same\n * three states costs them a translation for nothing.\n */\nexport function legend(results: { type: string }[]): string {\n const has = (type: string) => results.some((r) => r.type === type);\n const lines: string[] = [];\n\n if (has(\"frozen\")) {\n lines.push(\" \\u25CB (Static) prerendered as static content\");\n }\n\n if (has(\"shell\")) {\n lines.push(\n \" \\u25D0 (Partial Prerender) prerendered as static HTML with dynamic server-streamed content\",\n );\n }\n\n if (has(\"dynamic\")) {\n lines.push(\" \\u0192 (Dynamic) server-rendered on demand\");\n }\n\n if (has(\"error\") || has(\"blocked\")) {\n lines.push(\n \" \\u2717 (Failed) did not render, or painted nothing — the build stops here\",\n );\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * How much JavaScript a route makes the browser download.\n *\n * Gzipped, because that is what crosses the wire — uncompressed bytes are a\n * number nobody is served.\n *\n * A real per-route figure only because client components are chunked per\n * module. Grouped the way plugin-rsc groups them by default, every route in an\n * app loads every client component and this column is one number repeated down\n * the page.\n */\nexport function clientJsSize(bytes: number): string {\n if (bytes === 0) return \"no js\";\n\n const kb = bytes / 1000;\n\n return `${kb < 10 ? kb.toFixed(1) : Math.round(kb)} kB`;\n}\n\n/**\n * The paragraph a mark cannot hold.\n *\n * \"dynamic — called rpc(\\\"getUser\\\")\" says what happened and not why the build\n * could not simply make the call, which is the first thing someone asks when a\n * page they expected to be static is not. The backend is running; the build is\n * not talking to it.\n *\n * Printed once under the summary rather than beside each route: an app where\n * every page reads from the backend would otherwise repeat the same paragraph\n * forty times.\n */\nexport function notes(\n results: { type?: string; reason?: string | null }[],\n): string {\n const said = (text: string) => results.some((r) => r.reason?.includes(text));\n const parts: string[] = [];\n\n // Every route not frozen, all for one reason, is the shape a read in the\n // root layout leaves: one cookies() in a header component and nothing on\n // the site can be stored. The build cannot see which component read it -\n // only that every page did - so it says what that usually means.\n const pages = results.filter(\n (r) => r.type && r.type !== \"error\" && r.type !== \"blocked\",\n );\n const reasons = new Set(pages.map((r) => r.reason ?? \"\"));\n\n if (\n pages.length > 1 &&\n !pages.some((r) => r.type === \"frozen\") &&\n reasons.size === 1\n ) {\n const [reason] = reasons;\n\n parts.push(\n ` Every route: ${reason}. When one read reaches every page it is usually\\n` +\n \" in the root layout - a header reading the session, a locale from a cookie.\\n\" +\n \" Move that read into the component that needs it, under a <Suspense>, and\\n\" +\n \" the rest of the site can freeze around it.\",\n );\n }\n\n if (said(\"rpc(\")) parts.push(rpcNote());\n\n return parts.join(\"\\n\\n\");\n}\n\nfunction rpcNote(): string {\n return (\n \" A build has no backend to call. rpc() suspends instead of answering, so a page\\n\" +\n \" that reads through one ships a shell and finishes for whoever asks — which is\\n\" +\n \" almost always what you want, since that data is rarely the same for everyone.\\n\" +\n \"\\n\" +\n \" If a page really should be frozen, move the read out of rpc(). If it really\\n\" +\n \" should be per visitor, say so with await connection() and the intent is on the\\n\" +\n \" page rather than inferred from a call that happened to suspend.\"\n );\n}\n\n/**\n * The one-line tally under the legend, in the legend's own words.\n */\nexport function summary(results: { type: string }[]): string {\n const count = (type: string) => results.filter((r) => r.type === type).length;\n const parts: string[] = [];\n\n if (count(\"frozen\")) parts.push(`${count(\"frozen\")} static`);\n if (count(\"shell\")) parts.push(`${count(\"shell\")} partial prerender`);\n if (count(\"dynamic\")) parts.push(`${count(\"dynamic\")} dynamic`);\n if (count(\"error\") + count(\"blocked\"))\n parts.push(`${count(\"error\") + count(\"blocked\")} failed`);\n\n return parts.join(\", \") || \"nothing to store\";\n}\n\nexport function pathKey(url: string): string {\n const key = url.replace(/^\\/+|\\/+$/g, \"\") || \"index\";\n\n if (key.split(\"/\").some((segment) => segment === \"..\" || segment === \".\")) {\n throw new Error(\n \"Refusing to store \" +\n JSON.stringify(url) +\n \": the path leaves the output directory. \" +\n 'A url segment came from generateStaticParams() or a route param and contains \"..\".',\n );\n }\n\n return key;\n}\n\n/**\n * Substitute params into a route's segments to get a concrete url.\n *\n * A param is one segment, so a value carrying a slash is not a deeper url — it\n * is a value that was never a single segment. A catch-all is the exception and\n * is spelled as one in the route.\n */\nexport function urlFor(\n route: ManifestRoute,\n params: Record<string, string>,\n): string {\n const parts = route.segments.map((segment) => {\n if (segment.type === \"static\") return segment.value;\n\n const value = params[segment.value] ?? \"\";\n\n if (segment.type !== \"catchAll\" && /[/\\\\]/.test(value)) {\n throw new Error(\n \"The \" +\n segment.value +\n \" param is \" +\n JSON.stringify(value) +\n \", which is not one url \" +\n \"segment. A value with a slash in it has to be a catch-all route, or be encoded.\",\n );\n }\n\n return value;\n });\n\n return \"/\" + parts.filter((p) => p !== \"\").join(\"/\");\n}\n\n/**\n * Every url this build should attempt, and the params each was built from.\n *\n * A parameterised route that declares no `generateStaticParams` yields\n * nothing — not an error: rendering on demand is a legitimate answer, and the\n * alternative is guessing at slugs the app never listed.\n */\n/** Stand-in values for a route whose real urls were never listed. */\nfunction placeholders(route: ManifestRoute): Record<string, string> {\n const params: Record<string, string> = {};\n\n for (const segment of route.segments) {\n if (segment.type !== \"static\") params[segment.value] = \"_\";\n }\n\n return params;\n}\n\nexport async function urlsToBuild(\n manifest: RouteManifest,\n engine: PrerenderEngine,\n): Promise<\n { route: ManifestRoute; params: Record<string, string>; url: string }[]\n> {\n const entries: {\n route: ManifestRoute;\n params: Record<string, string>;\n url: string;\n }[] = [];\n\n for (const route of manifest.routes) {\n const parameterised = route.segments.some((s) => s.type !== \"static\");\n\n if (!parameterised) {\n entries.push({ route, params: {}, url: urlFor(route, {}) });\n continue;\n }\n\n // A route that lists no urls still gets one attempt, with placeholder\n // params, so it can ship a shell. Nothing in a shell varies by param.\n if (!route.staticParams) {\n entries.push({\n route,\n params: placeholders(route),\n url: urlFor(route, placeholders(route)),\n });\n continue;\n }\n\n const sets = (await engine.getStaticParams?.(route.component)) ?? null;\n\n // Null means the route declares none, so it is rendered on demand. An\n // empty array means the app looked and there is nothing to build — both\n // produce no files, and only one of them is a mistake to warn about.\n if (!sets) continue;\n\n for (const params of sets) {\n entries.push({ route, params, url: urlFor(route, params) });\n }\n }\n\n return entries;\n}\n\nexport async function prerender(\n options: PrerenderOptions,\n): Promise<PrerenderResult[]> {\n const { engine, write, version } = options;\n const manifest = options.manifest ?? engine.manifest?.();\n\n if (!manifest) {\n throw new Error(\n \"No route table. Pass `manifest`, or build with a plugin version that embeds one.\",\n );\n }\n\n const entries = await urlsToBuild(manifest, engine);\n const results: PrerenderResult[] = new Array(entries.length);\n\n // Rendered a few at a time rather than one after another.\n //\n // Most of a build is this loop, and most of this loop is waiting: a page\n // whose shell is decided by a two-second budget spends two seconds doing\n // nothing while the next page waits its turn. Nothing here is shared between\n // routes — the probe's stand-in host is held in async context, so concurrent\n // renders cannot see each other's — which is what makes overlapping them\n // safe, and was not true until it was scoped.\n //\n // Bounded, because each one is a full React render: unbounded would turn a\n // large site into as many concurrent renders as it has pages.\n //\n // Results are placed by index, so what a build reports does not depend on\n // which page happened to finish first.\n const concurrency = Math.max(\n 1,\n options.concurrency ?? DEFAULT_PRERENDER_CONCURRENCY,\n );\n let next = 0;\n\n const worker = async () => {\n while (true) {\n const index = next++;\n\n if (index >= entries.length) return;\n\n const { route, params, url } = entries[index];\n\n results[index] = await prerenderOne(route, params, url);\n options.onResult?.(results[index]);\n }\n };\n\n const unwatch = watchNondeterminism();\n\n try {\n await Promise.all(\n Array.from({ length: Math.min(concurrency, entries.length) }, worker),\n );\n } finally {\n unwatch();\n }\n\n const refused = results.filter((r) => r.type === \"blocked\");\n\n if (refused.length > 0) {\n throw new NotPrerenderable(refused);\n }\n\n return results;\n\n async function prerenderOne(\n route: ManifestRoute,\n params: Record<string, string>,\n url: string,\n ): Promise<PrerenderResult> {\n const props = options.props ? options.props(route, params) : params;\n const layouts = route.layouts.map((component) => ({\n component,\n props: {},\n }));\n const unlistedNow =\n route.segments.some((seg) => seg.type !== \"static\") &&\n !route.staticParams;\n /**\n * Why this route ships a shell rather than a whole page.\n *\n * In the order that answers the question soonest. A named call is the most\n * actionable — you can go and look at it — so it wins over the two\n * structural reasons, either of which may also be true.\n */\n const shellReason = (calls: string[]): string | null => {\n // The shell is stored; what streams is named. \"dynamic\" would say the\n // page is, and the mark beside the line says it is not.\n if (calls.length)\n return (\n calls.join(\", \") +\n (calls.length > 1 ? \" stream\" : \" streams\") +\n \" per request; the rest is stored\"\n );\n\n // One shell serving every url the route matches. generateStaticParams is\n // what turns it into a page per url.\n if (unlistedNow)\n return \"one shell for every url — add generateStaticParams to store each\";\n\n // Nothing reached for the request; the data simply took too long. The\n // page is fine, it just finishes per visitor.\n if (shell?.timedOut) return \"data took longer than the build budget\";\n\n return null;\n };\n\n const said = (\n type: PrerenderResult[\"type\"],\n reason: string | null,\n ): PrerenderResult => ({\n // A route standing in for many urls reports the pattern. Reporting the\n // placeholder url instead prints `/posts/_`, which looks like a page.\n url: unlistedNow ? \"/\" + patternKey(route) : url,\n component: route.component,\n type,\n reason,\n });\n\n const unlisted =\n route.segments.some((seg) => seg.type !== \"static\") &&\n !route.staticParams;\n\n // Classify by rendering, never by asking. The probe is cheap and cannot\n // hang: anything still suspended when its budget expires is the answer.\n //\n // Wrapped so a redirect has somewhere to be recorded. Reading the scope\n // rather than inspecting the thrown error is the only thing that works\n // from out here: React catches what a component throws and re-raises its\n // own, whose message is stripped in production — so a redirect above the\n // boundaries arrives as a generic render failure, and one from inside a\n // boundary never arrives at all.\n // A build renders each url once, and each gets its own table: two routes\n // must not share an answer just because they were built in the same run.\n // No request, deliberately: a page that reads one is caught below rather\n // than frozen holding whatever the build machine happened to send.\n const [\n { shell, redirected, readRequest, readBy, readWhere, fallbacks },\n nondeterministic,\n ] = await whileRendering(() =>\n withRequest(null, () =>\n withCache(() =>\n withRedirect(async (taken) => {\n try {\n return {\n shell: await engine.handleRscPprShell(\n route.component,\n props,\n layouts,\n route.loadings,\n route.slots,\n // Only when this shell serves one url. A parameterised route's\n // shell is shared, so baking a url into it would put the wrong one\n // on every page but the one that happened to be built.\n unlistedNow ? \"\" : url,\n ),\n redirected: taken(),\n readRequest: requestWasRead(),\n // What reached for it, so the build can name the call rather than\n // only report that the page is dynamic.\n readBy: requestReadBy(),\n // And from which component, so the message is a line to open\n // rather than a category to search for.\n readWhere: requestReadWhere(),\n fallbacks: requestFallbacks(),\n };\n } catch (error) {\n // A guard refusing throws out of the probe rather than being caught\n // inside it: middleware run before the render, so there is no render yet\n // to capture the failure. A refusal is a classification, not a build\n // error — the route is one that cannot be frozen.\n const refused = taken();\n\n if (!refused) throw error;\n\n return {\n shell: null,\n redirected: refused,\n readRequest: requestWasRead(),\n readBy: requestReadBy(),\n readWhere: requestReadWhere(),\n fallbacks: requestFallbacks(),\n };\n }\n }),\n ),\n ),\n );\n\n // A page that leaves rather than renders is not a build failure, and it is\n // not something to freeze either: what would be stored is the redirect's\n // own emptiness, served for ever to everyone. Rendered on demand instead,\n // where the redirect can actually happen.\n /**\n * Did this page's own boundary catch the wait, or the app's?\n *\n * A root loading.tsx wraps every page, so a page that blocks — or throws,\n * which is how a client hook says it has no server answer — is caught\n * whatever it does. The route is stored either way and the build has\n * nothing to refuse, which makes a page whose boundary is in the wrong\n * place look exactly like one whose boundary is right.\n *\n * Asked by rendering again without the root fallback, and only for a route\n * that has no closer one.\n *\n * Only for a route that came out as a shell. A frozen one rendered to\n * completion with the root boundary present, and removing a boundary\n * cannot stop a render that already finished — so the second probe\n * finishes too, its markup is the whole document, and the emptiness test\n * cannot fire. It was being paid for anyway: a second full render of every\n * frozen page, which on a site whose pages are mostly frozen is most of\n * the prerender.\n */\n async function withRootFallbackChecked(\n result: PrerenderResult,\n ): Promise<PrerenderResult> {\n // Also for a frozen page whose SSR threw and was caught at a boundary -\n // useSearchParams() with nothing closer than the root loading.tsx. That\n // render finished, with the root fallback standing in for the page;\n // without it the throw reaches the root and nothing paints, which is\n // the question this asks.\n if (\n result.type !== \"shell\" &&\n !(result.type === \"frozen\" && fallbacks.length)\n )\n return result;\n if (!engine.handleRscPprShell) return result;\n\n // Only when the one fallback in the chain is the root layout's. A page\n // with its own loading.tsx beside it has put the boundary exactly where\n // the waiting is, and this used to tell it otherwise - \"exactly one\n // loading\" is not the same as \"only the root one\".\n const [only] = route.loadings;\n const root = route.layouts[0];\n const dirOf = (name: string) => name.slice(0, name.lastIndexOf(\"/\"));\n\n if (\n route.loadings.length !== 1 ||\n !only ||\n !root ||\n dirOf(only) !== dirOf(root)\n ) {\n // A boundary of its own caught it: the fallback there is stored and\n // the value is read in the browser. Said, because the page is not\n // quite what the source shows at first paint.\n if (fallbacks.length && !result.note) {\n result.note =\n fallbacks.join(\", \") +\n \" — its fallback is stored; the value is read in the browser\";\n }\n\n return result;\n }\n\n // A tenth of the shell budget, because this is a different question.\n //\n // Deciding what a page's shell IS means waiting out everything that can\n // resolve. Asking whether anything paints at all without the root\n // fallback is a boolean about the first flush — and a page that paints,\n // paints immediately. Given the full budget it cost two seconds a route\n // to learn what the first millisecond already said, which on this\n // example was 40% of the entire prerender.\n const withoutRoot = await withRequest(\n null,\n () =>\n withCache(() =>\n withRedirect(async () =>\n engine.handleRscPprShell(\n route.component,\n props,\n layouts,\n [],\n route.slots,\n url,\n ROOT_FALLBACK_BUDGET_MS,\n ),\n ),\n ),\n // A caught read with no boundary of its own: without the root's the\n // throw reaches the root, and the render fails rather than paints.\n ).catch(() => (fallbacks.length ? { shellHtml: \"\" } : null));\n\n if (withoutRoot && closeDocument(withoutRoot.shellHtml.trim()) === \"\") {\n result.warning = fallbacks.length\n ? fallbacks.join(\", \") +\n \" has no boundary closer than the root loading.tsx, so that is the whole page at first paint. \" +\n \"Put a <Suspense> around the component that reads, and the rest of the page is stored.\"\n : \"nothing painted without the root loading.tsx — the fallback the whole app shares \" +\n \"is standing in for this page. Put a boundary where the waiting is.\";\n } else if (fallbacks.length && !result.note) {\n result.note =\n fallbacks.join(\", \") +\n \" — its fallback is stored; the value is read in the browser\";\n }\n\n return result;\n }\n\n // A route that only redirects still has an answer to freeze — the answer\n // is the redirect, not a page. Rendering it per request re-derives a\n // constant, and on a static host there would be nothing to derive it with.\n if (redirected) {\n await write(\n `${pathKey(url)}.redirect.json`,\n JSON.stringify({\n status: redirected.status,\n location: redirected.location,\n }),\n );\n\n return said(\"frozen\", `redirects to ${redirected.location}`);\n }\n\n if (!shell) return said(\"error\", \"refused before it rendered\");\n\n if (shell.error) return said(\"error\", shell.error);\n\n // Something failed while rendering. Not necessarily the page's fault — a\n // build machine that cannot reach the database produces this, and so does a\n // genuinely broken component — so it is not fatal. It is simply not\n // something to freeze: whatever this render produced is a failure state,\n // and freezing it serves that state to everyone until the next build.\n //\n // Rendering per request is the honest answer. It works as soon as whatever\n // was missing is reachable, which at runtime it usually is.\n if (shell.renderFailure) {\n return said(\n \"blocked\",\n `could not be rendered at build time: ${shell.renderFailure}`,\n );\n }\n\n // A timeout is the ordinary path for a page that streams, not a failure:\n // the probe hands the page a host global that never resolves, React\n // flushes everything that does not depend on it, and the abort happens\n // once there is nothing left to flush. So the captured markup IS the\n // shell — layouts, static content, and the fallbacks standing in for what\n // has not arrived.\n if (shell.timedOut) {\n const body = closeDocument(shell.shellHtml.trim());\n\n // Nothing was flushed before the page blocked, so there is no shell to\n // ship — a page that blocks above every boundary can only be rendered on\n // demand. `reaches for the host` is the specific reason when both are\n // true; a page that merely ran long says the other thing.\n if (body === \"\") {\n return said(\n \"blocked\",\n (readRequest\n ? \"reads \" +\n (readWhere.length\n ? readWhere\n : readBy.length\n ? readBy\n : [\"the request\"]\n ).join(\", \")\n : shell.usedDynamicApis\n ? \"reaches for the host\"\n : \"blocks\") +\n \" before anything can paint.\" +\n (readWhere.some((w) => w.includes(\" awaited by \"))\n ? \" One of those has no boundary above it.\"\n : \"\") +\n \" Add a loading.tsx beside it, or put a \" +\n \"<Suspense> above the waiting, and it has a skeleton to store.\",\n );\n }\n\n await writeShell(route, url, body, shell.postponed);\n\n // Why it is a shell rather than a whole page. \"◐ /orders\" on its own\n // leaves someone reading the build output to guess what did it, which is\n // the question this line exists to answer.\n const calls = [\n ...(shell.dynamicBecause ?? []),\n ...(readWhere.length ? readWhere : readBy),\n ];\n\n return await withRootFallbackChecked(said(\"shell\", shellReason(calls)));\n }\n\n // Warned, not refused.\n //\n // A frozen `new Date()` may be exactly what the author meant — a build\n // stamp, a copyright year — and the build cannot tell that from a\n // \"3 minutes ago\" that will still say three minutes next month. Refusing\n // would make the honest case unbuildable in order to protect the careless\n // one, and there is no flag to add here without inventing the declaration\n // this design exists to avoid.\n //\n // So it says what happened, names what was called, and gives the repair.\n // The escape hatch is that a warning does not stop the build — which is the\n // right weight for something that is occasionally correct.\n //\n // Only for a page frozen WHOLE. On a shell the call may sit inside a hole,\n // which renders per request, where it is correct.\n const noteNondeterminism = (result: PrerenderResult): PrerenderResult => {\n if (nondeterministic.length === 0) return result;\n\n result.warning =\n `froze ${nondeterministic.join(\" and \")} — a stored page keeps whatever that ` +\n \"returned at build time. If it should differ per visitor, await connection() so \" +\n \"the page renders per request; if only the browser needs it, use(browser()) keeps \" +\n \"it out of the build entirely.\";\n\n return result;\n };\n\n // Rendered whole, with params that were invented because the route listed\n // none. Freezing that stores a page whose id is literally `_`, and a shell\n // is no better: the value is in the markup rather than behind a boundary\n // the client fills. A route reaches this only by rendering its params\n // before it can paint, which is exactly the shape that cannot be shared\n // across urls.\n if (unlisted) {\n return said(\n \"blocked\",\n \"renders its params before it can paint, and lists no urls to build\",\n );\n }\n\n const rendered = await engine.handleRsc(\n route.component,\n props,\n null,\n layouts,\n // Not empty: a page whose layout declares a parallel slot renders without\n // it otherwise, and nothing says so — the page comes out whole apart from\n // the missing region.\n route.loadings,\n route.slots,\n 0,\n url,\n true,\n // A build has no host to answer rpc(), so every host call must suspend\n // rather than resolve. Without this they found no host at all and the\n // page was frozen holding whatever undefined rendered to — a document\n // that looks right, hydrates against an undefined prop, and blanks.\n false,\n );\n\n // The render reached for the host, so its data is not the same for\n // everyone and there is no build-time answer for it. Not frozen: a shell\n // is shipped instead and the page finishes for whoever asks.\n if (rendered.usedDynamicApis) {\n return said(\"shell\", \"reaches the host for data\");\n }\n\n // Nothing for a runtime to do. No client component means nothing to\n // hydrate, and no server reference means no form that would post through\n // React - so the bootstrap is 70 kB of javascript that runs and changes\n // nothing. Rendered once more without it and stored that way.\n //\n // No declaration in either direction, on purpose. A page cannot need the\n // runtime without a client component or an action in its tree - \"use\n // client\" IS the opt-in - and a page that must stay this way is an\n // assertion for the build report, not a switch.\n let note: string | undefined;\n let body = rendered.body;\n\n if (\n rendered.clientComponents.every((name) => RUNTIME_OWN.has(name)) &&\n !rendered.serverReferences\n ) {\n // Only the document. The flight payload stays the bootstrap render's:\n // a Link elsewhere navigating here fetches it and expects the segment\n // and title wrappers that render puts in, which this one leaves out.\n const bare = await engine.handleRsc(\n route.component,\n props,\n null,\n layouts,\n route.loadings,\n route.slots,\n 0,\n url,\n false,\n false,\n );\n\n body = options.serviceWorker\n ? withWorkerRegistration(bare.body)\n : bare.body;\n\n let inlined = false;\n\n if (options.stylesheet) {\n const before = body;\n body = withInlineStylesheets(body, options.stylesheet);\n inlined = body !== before;\n }\n\n note =\n \"no client components, so ships no javascript\" +\n (inlined ? \"; stylesheet inlined\" : \"\");\n }\n\n const key = pathKey(url);\n\n await write(`${key}.html`, body);\n await write(`${key}.flight`, rendered.rscPayload);\n\n // One variant per depth the client might already hold. Without them every\n // navigation to a prerendered route is a whole document, which replaces the\n // root and unmounts the pages retained behind it — so going back does not\n // restore the form you were filling in. Most routes in a real app are\n // prerendered, which makes this the common path rather than an edge case.\n for (let depth = 1; depth <= route.layouts.length; depth++) {\n const { rscPayload } = await engine.handleRscPayload(\n route.component,\n props,\n layouts,\n route.loadings,\n route.slots,\n depth,\n url,\n );\n\n await write(`${key}.seg${depth}.flight`, rscPayload);\n }\n\n await write(\n `${key}.meta.json`,\n JSON.stringify(\n {\n layouts: route.layouts,\n component: route.component,\n version: version ?? null,\n },\n null,\n 2,\n ),\n );\n\n const frozen = noteNondeterminism(\n await withRootFallbackChecked(said(\"frozen\", null)),\n );\n\n return note ? { ...frozen, note } : frozen;\n }\n\n /**\n * Freeze a shell, under the url when it is one and under the route's pattern\n * when it stands for many.\n *\n * A route whose urls were never listed still gets a shell: nothing in it\n * varies by param, so the same markup is correct for every url the route\n * matches. That is most of the value — the routes you can enumerate are the\n * ones you could already freeze whole.\n */\n async function writeShell(\n route: ManifestRoute,\n url: string,\n body: string,\n postponed?: unknown,\n ): Promise<void> {\n const parameterised = route.segments.some((s) => s.type !== \"static\");\n const key =\n parameterised && !route.staticParams ? patternKey(route) : pathKey(url);\n\n await write(`${key}.ppr.html`, body);\n\n // Written only when there is something to resume from. Its absence is\n // meaningful rather than incidental: a host that finds no postponed state\n // serves the shell and lets the client fill it, which is what every build\n // before this one did.\n if (postponed != null) {\n await write(`${key}.postponed.json`, JSON.stringify(postponed));\n }\n await write(\n `${key}.ppr-meta.json`,\n JSON.stringify(\n {\n layouts: route.layouts,\n component: route.component,\n parameterised,\n version: version ?? null,\n },\n null,\n 2,\n ),\n );\n }\n}\n"]}
1
+ {"version":3,"file":"prerender.js","sourceRoot":"","sources":["../src/prerender.ts"],"names":[],"mappings":"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","sourcesContent":["// Rendering pages at build time, for a JavaScript host.\n//\n// The engine does the rendering; this decides what to render and what to do\n// with the result. Two decisions, and both are easy to get subtly wrong:\n//\n// Which urls exist — a route with no params is one url, a route with params is\n// however many `generateStaticParams` returns, and a route with params that\n// declares none cannot be prerendered at all.\n//\n// Whether a page can be frozen — asked by rendering it, never declared. The\n// shell probe replaces the host global with a promise that never resolves, so\n// a page that reaches for request data suspends and says so by doing it. A\n// page that simply takes too long says so by not finishing.\n//\n// The file layout matches the one Laravel writes, so both hosts serve the same\n// shapes and anything that reads them works for either.\n\nimport type { ManifestRoute, RouteManifest } from \"./manifest.js\";\nimport { withRedirect } from \"./redirect.js\";\nimport { withCache } from \"./cache.js\";\nimport {\n requestFallbacks,\n requestReadBy,\n requestReadWhere,\n requestWasRead,\n withRequest,\n} from \"./request.js\";\nimport { watchNondeterminism, whileRendering } from \"./nondeterminism.js\";\n\n/** What a prerenderer needs from the built bundle, beyond serving a request. */\n/**\n * How long the root-fallback diagnostic waits before answering.\n *\n * Short on purpose: the question is whether anything painted, not what. See\n * the call site.\n */\nconst ROOT_FALLBACK_BUDGET_MS = 200;\n\n/**\n * How many routes render at once.\n *\n * Each is a full React render, so this trades memory and CPU for wall time.\n * The gain flattens almost immediately — measured on a twelve-route example:\n * 10.2 s sequential, 4.1 s at four, 4.0 s at six, 4.0 s at twelve, beyond\n * which one route's own serial chain is the floor.\n *\n * Four rather than six because the difference between them is inside the\n * noise, and the smaller number leaves room for whatever else is running.\n * A build is rarely the only thing on a machine — it shares CI with other\n * jobs, and it shares a laptop with the test suite that renders its own\n * fixtures, where six was enough to turn a two-second budget into a timeout.\n */\nconst DEFAULT_PRERENDER_CONCURRENCY = 4;\n\n/**\n * The client components the engine itself puts around every page when the\n * bootstrap is on - the segment and slot boundaries, the title, the pathname\n * provider, the error boundary. They are in every payload, they are not the\n * app's, and a render without the bootstrap does not insert them. Anything\n * else in the list is the app's, and needs the runtime.\n */\nconst RUNTIME_OWN = new Set([\n \"DefaultRouteError\",\n \"DocumentTitle\",\n \"LoadingBoundary\",\n \"PathnameProvider\",\n \"RouteErrorBoundary\",\n \"SegmentBoundary\",\n \"SlotBoundary\",\n]);\n\n/**\n * The one line the bootstrap would have run for the worker, for a document\n * stored without a bootstrap. Same timing as the runtime's: after load, so\n * it competes with nothing the first visit needs. A page whose document has\n * no closing body tag is left alone.\n */\nconst WORKER_REGISTRATION =\n \"<script>'serviceWorker'in navigator&&addEventListener('load',function(){navigator.serviceWorker.register('/sw.js').catch(function(){})})</script>\";\n\n/**\n * Every `<link rel=\"stylesheet\">` whose source the reader answers for,\n * replaced by a `<style>` holding it. A link the reader declines - too big,\n * or not the build's - is left as it was.\n */\nexport function withInlineStylesheets(\n html: string,\n read: (href: string) => string | null,\n): string {\n return html.replace(/<link\\b[^>]*\\brel=\"stylesheet\"[^>]*>/g, (tag) => {\n const href = /\\bhref=\"([^\"]+)\"/.exec(tag)?.[1];\n const css = href ? read(href) : null;\n\n return css === null ? tag : `<style>${css}</style>`;\n });\n}\n\nexport function withWorkerRegistration(html: string): string {\n const at = html.lastIndexOf(\"</body>\");\n\n return at === -1\n ? html\n : html.slice(0, at) + WORKER_REGISTRATION + html.slice(at);\n}\n\nexport interface PrerenderEngine {\n manifest?(): RouteManifest;\n /**\n * A route.ts, answered. Optional: a bundle built before api routes existed\n * has none, and the build then simply stores no route.\n */\n handleApiRoute?(\n name: string,\n request: Request,\n params: Record<string, string>,\n allow: string,\n ): Promise<Response>;\n getStaticParams?(component: string): Promise<Record<string, string>[] | null>;\n handleRscPprShell(\n component: string,\n props?: Record<string, unknown>,\n layouts?: { component: string; props: Record<string, unknown> }[],\n loadings?: string[],\n parallelSlots?: Record<string, string>,\n pageKey?: string,\n /** How long to render before taking what has flushed. Defaults to the full budget. */\n budgetMs?: number,\n ): Promise<{\n shellHtml: string;\n timedOut: boolean;\n usedDynamicApis: boolean;\n /**\n * The host calls this render made, by name.\n *\n * So the build can say which one kept the page from being frozen rather\n * than only that something did. Optional: an engine built before this\n * existed reports nothing, and the line is printed without a reason.\n */\n dynamicBecause?: string[];\n error?: string;\n /**\n * Where the render stopped, when it stopped — React's own resumable state.\n *\n * Null when the page finished, which is the same thing as `timedOut` being\n * false. An engine built before this existed returns undefined, and the\n * shell is then served the way it always was: holes filled by the client\n * after hydration rather than resumed at the origin.\n */\n postponed?: unknown;\n /**\n * Anything that failed while producing the shell, including a rejection a\n * Suspense boundary caught.\n *\n * Such a rejection never reaches the caller: React keeps the fallback and\n * the render finishes, so without this a page whose data source was\n * unreachable looked complete and its loading state was frozen as a\n * finished page.\n */\n renderFailure?: string;\n }>;\n handleRsc(\n component: string,\n props?: Record<string, unknown>,\n callbackSocket?: string | null,\n layouts?: { component: string; props: Record<string, unknown> }[],\n loadings?: string[],\n parallelSlots?: Record<string, string>,\n from?: number,\n pageKey?: string,\n bootstrap?: boolean,\n /**\n * Whether a host is installed to answer rpc().\n *\n * False during a build, where there is none: every host call then suspends\n * and the page reports that it reached for one, instead of resolving to\n * undefined and being frozen holding it.\n */\n canReachHost?: boolean,\n ): Promise<{\n body: string;\n rscPayload: string;\n clientComponents: string[];\n /** A server action is in the tree - a form or a client prop - so a runtime is needed to submit it. */\n serverReferences?: boolean;\n usedDynamicApis?: boolean;\n }>;\n handleRscPayload(\n component: string,\n props?: Record<string, unknown>,\n layouts?: { component: string; props: Record<string, unknown> }[],\n loadings?: string[],\n parallelSlots?: Record<string, string>,\n from?: number,\n pageKey?: string,\n ): Promise<{ rscPayload: string }>;\n}\n\nexport interface PrerenderOptions {\n engine: PrerenderEngine;\n /**\n * The app has a service worker. A page stored without the bootstrap has\n * nothing to register it, so one line is put in its place - the worker is\n * for the second visit, and a visitor who lands on such a page first should\n * still get one.\n */\n serviceWorker?: boolean;\n /**\n * A stylesheet's source, by the href the document links it with, or null\n * to leave the link alone. A page stored without the runtime has nothing\n * to hydrate, so its stylesheet can be inlined into the document rather\n * than fetched before the first paint - one request and a round trip off\n * the critical path. The build passes a reader that answers only for small\n * files; a page with the runtime keeps its link, because React expects to\n * find it in the DOM.\n */\n stylesheet?: (href: string) => string | null;\n /**\n * Where the output goes, as a sink rather than a directory.\n *\n * `writeTo` in `@rsc-kit/core/files` is the one for a disk, which is what a\n * build normally wants. A function because the read side is one — a host\n * that supplies a reader should be able to supply the matching writer —\n * and because a test can hand it a Map instead of a temp directory.\n */\n write: (name: string, contents: string) => Promise<void> | void;\n /** The route table. Defaults to the one the bundle carries. */\n manifest?: RouteManifest;\n /**\n * Props for a page at build time.\n *\n * There is no request here, which is the point: anything a page needs that\n * only a request can supply is exactly what makes it un-freezable. Defaults\n * to the url params alone.\n */\n props?: (\n route: ManifestRoute,\n params: Record<string, string>,\n ) => Record<string, unknown>;\n /**\n * How many routes to render at once. Defaults to 6; 1 renders sequentially.\n *\n * Worth lowering when the pages talk to something that will not enjoy six\n * concurrent callers — a local database, a rate-limited API.\n */\n concurrency?: number;\n /** Identifies the build in what gets written, so a stale page can be spotted. */\n version?: string;\n /** Called as each url is decided, for build output. */\n onResult?: (result: PrerenderResult) => void;\n}\n\n/**\n * The build's refusal to store a route it cannot answer ahead of time.\n *\n * Thrown rather than reported, because the alternative is a category: a bucket\n * of routes that quietly render per request, which is where the slow ones go\n * to be forgotten. Every route is either stored or has said it will not be.\n */\nexport class NotPrerenderable extends Error {\n public readonly routes: PrerenderResult[];\n\n constructor(routes: PrerenderResult[]) {\n // Two different problems arrive here, and the advice for one is useless for\n // the other. A page that reads the request above every boundary needs a\n // boundary; a page whose render threw needs whatever it was reaching for.\n const threw = routes.filter((r) =>\n r.reason?.startsWith(\"could not be rendered\"),\n );\n const unpaintable = routes.filter(\n (r) => !r.reason?.startsWith(\"could not be rendered\"),\n );\n\n const advice: string[] = [];\n\n if (unpaintable.length > 0) {\n advice.push(\n \"These read request data — params, headers, cookies, or the host — above\\n\" +\n \"every Suspense boundary, so nothing can paint without it:\\n\\n\" +\n unpaintable\n .map((r) => ` ${r.url} — ${r.reason ?? \"nothing to paint\"}`)\n .join(\"\\n\") +\n \"\\n\\nPut the part that waits inside <Suspense>, or add a loading.tsx beside\\n\" +\n \"the page, so there is something to store while the rest arrives.\",\n );\n }\n\n if (threw.length > 0) {\n advice.push(\n \"These failed while rendering:\\n\\n\" +\n threw.map((r) => ` ${r.url} — ${r.reason}`).join(\"\\n\") +\n \"\\n\\nPrerendering runs your application code, so it needs whatever that code\\n\" +\n \"needs. If the page is fine and this machine simply cannot reach a\\n\" +\n \"database or an API, either give the build access or put `await connection()`\\n\" +\n \"before the read: the page then renders per request and the rest is still stored.\\n\\n\" +\n \"Reaching for data through the host — `await rpc(...)` — avoids this\\n\" +\n \"entirely: the build stubs that call, so the page freezes a shell\\n\" +\n \"without the data being available.\",\n );\n }\n\n super(\n \"Some routes could not be prerendered.\\n\\n\" + advice.join(\"\\n\\n\") + \"\\n\",\n );\n this.name = \"NotPrerenderable\";\n this.routes = routes;\n\n // Not enumerable: Vite prints an error's own properties under its stack,\n // and this list is the message again, as an object dump.\n Object.defineProperty(this, \"routes\", { value: routes, enumerable: false });\n }\n}\n\nexport interface PrerenderResult {\n url: string;\n component: string;\n /**\n * frozen — the whole page is on disk.\n * shell — the chrome is on disk and the rest is rendered per request.\n * blocked — nothing could be stored. Fails the build.\n * error — the render itself failed, or the build refused what it produced.\n *\n * dynamic — answered per request, and correctly so. Api routes only.\n *\n * There is no such outcome for a PAGE. A page that cannot be stored has its\n * boundary in the wrong place, and the fix is to move it — not to declare\n * the problem away, which is how the slow ones get forgotten. An api route\n * has no boundary to move: it either depends on the request or it does not,\n * and depending on it is the ordinary case rather than a mistake.\n */\n type: \"frozen\" | \"shell\" | \"blocked\" | \"error\" | \"dynamic\";\n reason: string | null;\n /**\n * Something worth knowing that is not a failure.\n *\n * The one that matters: a page whose only boundary is the root loading.tsx.\n * It is stored, so the build has nothing to refuse — but the fallback that\n * caught it belongs to the whole app rather than to this page, and every\n * page in the app shows the same thing while this one's data arrives.\n */\n warning?: string;\n /** A fact about how it was stored that is neither a reason nor a warning. */\n note?: string;\n}\n\n/**\n * The file name a route's shell is stored under, with params standing in for\n * themselves: /posts/[slug] → posts/_slug_.\n *\n * A shell contains nothing that varies by param — everything that does is\n * behind a boundary the client fills — so one shell serves every url the\n * route matches, including the ones the app never listed.\n */\nexport function patternKey(route: ManifestRoute): string {\n const parts = route.segments.map((s) =>\n s.type === \"static\" ? s.value : `_${s.value}_`,\n );\n\n return parts.join(\"/\") || \"index\";\n}\n\n/** Close a document the render was aborted in the middle of. */\nexport function closeDocument(html: string): string {\n let out = html;\n\n if (!/<\\/body>/i.test(out) && /<body/i.test(out)) out += \"</body>\";\n if (!/<\\/html>/i.test(out) && /<html/i.test(out)) out += \"</html>\";\n\n return out;\n}\n\n/**\n * The file name a url is stored under: / → index, /a/b → a/b.\n *\n * Refuses a key that could leave the directory it is written into. The input is\n * whatever generateStaticParams() returned — typically slugs from a database or\n * a CMS — so a record named `../../../../etc/cron.d/x` is an arbitrary file\n * write on the build machine with content the same record influences.\n *\n * Checked here rather than in the writer, because the writer is supplied by the\n * host: `writeTo` on disk does the obvious thing, but a KV or edge binding has\n * no notion of a parent directory and no reason to look for one.\n */\n/**\n * The key, showing only the marks that actually appear above it.\n *\n * Wording follows Next's build output deliberately. Most people arriving here\n * have read that legend already, and inventing a second vocabulary for the same\n * three states costs them a translation for nothing.\n */\nexport function legend(results: { type: string }[]): string {\n const has = (type: string) => results.some((r) => r.type === type);\n const lines: string[] = [];\n\n if (has(\"frozen\")) {\n lines.push(\" \\u25CB (Static) prerendered as static content\");\n }\n\n if (has(\"shell\")) {\n lines.push(\n \" \\u25D0 (Partial Prerender) prerendered as static HTML with dynamic server-streamed content\",\n );\n }\n\n if (has(\"dynamic\")) {\n lines.push(\" \\u0192 (Dynamic) server-rendered on demand\");\n }\n\n if (has(\"error\") || has(\"blocked\")) {\n lines.push(\n \" \\u2717 (Failed) did not render, or painted nothing — the build stops here\",\n );\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * How much JavaScript a route makes the browser download.\n *\n * Gzipped, because that is what crosses the wire — uncompressed bytes are a\n * number nobody is served.\n *\n * A real per-route figure only because client components are chunked per\n * module. Grouped the way plugin-rsc groups them by default, every route in an\n * app loads every client component and this column is one number repeated down\n * the page.\n */\nexport function clientJsSize(bytes: number): string {\n if (bytes === 0) return \"no js\";\n\n const kb = bytes / 1000;\n\n return `${kb < 10 ? kb.toFixed(1) : Math.round(kb)} kB`;\n}\n\n/**\n * The paragraph a mark cannot hold.\n *\n * \"dynamic — called rpc(\\\"getUser\\\")\" says what happened and not why the build\n * could not simply make the call, which is the first thing someone asks when a\n * page they expected to be static is not. The backend is running; the build is\n * not talking to it.\n *\n * Printed once under the summary rather than beside each route: an app where\n * every page reads from the backend would otherwise repeat the same paragraph\n * forty times.\n */\nexport function notes(\n results: { type?: string; reason?: string | null }[],\n): string {\n const said = (text: string) => results.some((r) => r.reason?.includes(text));\n const parts: string[] = [];\n\n // Every route not frozen, all for one reason, is the shape a read in the\n // root layout leaves: one cookies() in a header component and nothing on\n // the site can be stored. The build cannot see which component read it -\n // only that every page did - so it says what that usually means.\n const pages = results.filter(\n (r) => r.type && r.type !== \"error\" && r.type !== \"blocked\",\n );\n const reasons = new Set(pages.map((r) => r.reason ?? \"\"));\n\n if (\n pages.length > 1 &&\n !pages.some((r) => r.type === \"frozen\") &&\n reasons.size === 1\n ) {\n const [reason] = reasons;\n\n parts.push(\n ` Every route: ${reason}. When one read reaches every page it is usually\\n` +\n \" in the root layout - a header reading the session, a locale from a cookie.\\n\" +\n \" Move that read into the component that needs it, under a <Suspense>, and\\n\" +\n \" the rest of the site can freeze around it.\",\n );\n }\n\n if (said(\"rpc(\")) parts.push(rpcNote());\n\n return parts.join(\"\\n\\n\");\n}\n\nfunction rpcNote(): string {\n return (\n \" A build has no backend to call. rpc() suspends instead of answering, so a page\\n\" +\n \" that reads through one ships a shell and finishes for whoever asks — which is\\n\" +\n \" almost always what you want, since that data is rarely the same for everyone.\\n\" +\n \"\\n\" +\n \" If a page really should be frozen, move the read out of rpc(). If it really\\n\" +\n \" should be per visitor, say so with await connection() and the intent is on the\\n\" +\n \" page rather than inferred from a call that happened to suspend.\"\n );\n}\n\n/**\n * The one-line tally under the legend, in the legend's own words.\n */\nexport function summary(results: { type: string }[]): string {\n const count = (type: string) => results.filter((r) => r.type === type).length;\n const parts: string[] = [];\n\n if (count(\"frozen\")) parts.push(`${count(\"frozen\")} static`);\n if (count(\"shell\")) parts.push(`${count(\"shell\")} partial prerender`);\n if (count(\"dynamic\")) parts.push(`${count(\"dynamic\")} dynamic`);\n if (count(\"error\") + count(\"blocked\"))\n parts.push(`${count(\"error\") + count(\"blocked\")} failed`);\n\n return parts.join(\", \") || \"nothing to store\";\n}\n\nexport function pathKey(url: string): string {\n const key = url.replace(/^\\/+|\\/+$/g, \"\") || \"index\";\n\n if (key.split(\"/\").some((segment) => segment === \"..\" || segment === \".\")) {\n throw new Error(\n \"Refusing to store \" +\n JSON.stringify(url) +\n \": the path leaves the output directory. \" +\n 'A url segment came from generateStaticParams() or a route param and contains \"..\".',\n );\n }\n\n return key;\n}\n\n/**\n * Substitute params into a route's segments to get a concrete url.\n *\n * A param is one segment, so a value carrying a slash is not a deeper url — it\n * is a value that was never a single segment. A catch-all is the exception and\n * is spelled as one in the route.\n */\nexport function urlFor(\n route: ManifestRoute,\n params: Record<string, string>,\n): string {\n const parts = route.segments.map((segment) => {\n if (segment.type === \"static\") return segment.value;\n\n const value = params[segment.value] ?? \"\";\n\n if (segment.type !== \"catchAll\" && /[/\\\\]/.test(value)) {\n throw new Error(\n \"The \" +\n segment.value +\n \" param is \" +\n JSON.stringify(value) +\n \", which is not one url \" +\n \"segment. A value with a slash in it has to be a catch-all route, or be encoded.\",\n );\n }\n\n return value;\n });\n\n return \"/\" + parts.filter((p) => p !== \"\").join(\"/\");\n}\n\n/**\n * Every url this build should attempt, and the params each was built from.\n *\n * A parameterised route that declares no `generateStaticParams` yields\n * nothing — not an error: rendering on demand is a legitimate answer, and the\n * alternative is guessing at slugs the app never listed.\n */\n/** Stand-in values for a route whose real urls were never listed. */\nfunction placeholders(route: ManifestRoute): Record<string, string> {\n const params: Record<string, string> = {};\n\n for (const segment of route.segments) {\n if (segment.type !== \"static\") params[segment.value] = \"_\";\n }\n\n return params;\n}\n\nexport async function urlsToBuild(\n manifest: RouteManifest,\n engine: PrerenderEngine,\n): Promise<\n { route: ManifestRoute; params: Record<string, string>; url: string }[]\n> {\n const entries: {\n route: ManifestRoute;\n params: Record<string, string>;\n url: string;\n }[] = [];\n\n for (const route of manifest.routes) {\n const parameterised = route.segments.some((s) => s.type !== \"static\");\n\n if (!parameterised) {\n entries.push({ route, params: {}, url: urlFor(route, {}) });\n continue;\n }\n\n // A route that lists no urls still gets one attempt, with placeholder\n // params, so it can ship a shell. Nothing in a shell varies by param.\n if (!route.staticParams) {\n entries.push({\n route,\n params: placeholders(route),\n url: urlFor(route, placeholders(route)),\n });\n continue;\n }\n\n const sets = (await engine.getStaticParams?.(route.component)) ?? null;\n\n // Null means the route declares none, so it is rendered on demand. An\n // empty array means the app looked and there is nothing to build — both\n // produce no files, and only one of them is a mistake to warn about.\n if (!sets) continue;\n\n for (const params of sets) {\n entries.push({ route, params, url: urlFor(route, params) });\n }\n }\n\n return entries;\n}\n\nexport async function prerender(\n options: PrerenderOptions,\n): Promise<PrerenderResult[]> {\n const { engine, write, version } = options;\n const manifest = options.manifest ?? engine.manifest?.();\n\n if (!manifest) {\n throw new Error(\n \"No route table. Pass `manifest`, or build with a plugin version that embeds one.\",\n );\n }\n\n const entries = await urlsToBuild(manifest, engine);\n const results: PrerenderResult[] = new Array(entries.length);\n\n // Rendered a few at a time rather than one after another.\n //\n // Most of a build is this loop, and most of this loop is waiting: a page\n // whose shell is decided by a two-second budget spends two seconds doing\n // nothing while the next page waits its turn. Nothing here is shared between\n // routes — the probe's stand-in host is held in async context, so concurrent\n // renders cannot see each other's — which is what makes overlapping them\n // safe, and was not true until it was scoped.\n //\n // Bounded, because each one is a full React render: unbounded would turn a\n // large site into as many concurrent renders as it has pages.\n //\n // Results are placed by index, so what a build reports does not depend on\n // which page happened to finish first.\n const concurrency = Math.max(\n 1,\n options.concurrency ?? DEFAULT_PRERENDER_CONCURRENCY,\n );\n let next = 0;\n\n const worker = async () => {\n while (true) {\n const index = next++;\n\n if (index >= entries.length) return;\n\n const { route, params, url } = entries[index];\n\n results[index] = await prerenderOne(route, params, url);\n options.onResult?.(results[index]);\n }\n };\n\n const unwatch = watchNondeterminism();\n\n try {\n await Promise.all(\n Array.from({ length: Math.min(concurrency, entries.length) }, worker),\n );\n } finally {\n unwatch();\n }\n\n const refused = results.filter((r) => r.type === \"blocked\");\n\n if (refused.length > 0) {\n throw new NotPrerenderable(refused);\n }\n\n return results;\n\n async function prerenderOne(\n route: ManifestRoute,\n params: Record<string, string>,\n url: string,\n ): Promise<PrerenderResult> {\n const props = options.props ? options.props(route, params) : params;\n const layouts = route.layouts.map((component) => ({\n component,\n props: {},\n }));\n const unlistedNow =\n route.segments.some((seg) => seg.type !== \"static\") &&\n !route.staticParams;\n /**\n * Why this route ships a shell rather than a whole page.\n *\n * In the order that answers the question soonest. A named call is the most\n * actionable — you can go and look at it — so it wins over the two\n * structural reasons, either of which may also be true.\n */\n const shellReason = (calls: string[]): string | null => {\n // The shell is stored; what streams is named. \"dynamic\" would say the\n // page is, and the mark beside the line says it is not.\n if (calls.length)\n return (\n calls.join(\", \") +\n (calls.length > 1 ? \" stream\" : \" streams\") +\n \" per request; the rest is stored\"\n );\n\n // One shell serving every url the route matches. generateStaticParams is\n // what turns it into a page per url.\n if (unlistedNow)\n return \"one shell for every url — add generateStaticParams to store each\";\n\n // Nothing reached for the request; the data simply took too long. The\n // page is fine, it just finishes per visitor.\n if (shell?.timedOut) return \"data took longer than the build budget\";\n\n return null;\n };\n\n const said = (\n type: PrerenderResult[\"type\"],\n reason: string | null,\n ): PrerenderResult => ({\n // A route standing in for many urls reports the pattern. Reporting the\n // placeholder url instead prints `/posts/_`, which looks like a page.\n url: unlistedNow ? \"/\" + patternKey(route) : url,\n component: route.component,\n type,\n reason,\n });\n\n const unlisted =\n route.segments.some((seg) => seg.type !== \"static\") &&\n !route.staticParams;\n\n // Classify by rendering, never by asking. The probe is cheap and cannot\n // hang: anything still suspended when its budget expires is the answer.\n //\n // Wrapped so a redirect has somewhere to be recorded. Reading the scope\n // rather than inspecting the thrown error is the only thing that works\n // from out here: React catches what a component throws and re-raises its\n // own, whose message is stripped in production — so a redirect above the\n // boundaries arrives as a generic render failure, and one from inside a\n // boundary never arrives at all.\n // A build renders each url once, and each gets its own table: two routes\n // must not share an answer just because they were built in the same run.\n // No request, deliberately: a page that reads one is caught below rather\n // than frozen holding whatever the build machine happened to send.\n const [\n { shell, redirected, readRequest, readBy, readWhere, fallbacks },\n nondeterministic,\n ] = await whileRendering(() =>\n withRequest(null, () =>\n withCache(() =>\n withRedirect(async (taken) => {\n try {\n return {\n shell: await engine.handleRscPprShell(\n route.component,\n props,\n layouts,\n route.loadings,\n route.slots,\n // Only when this shell serves one url. A parameterised route's\n // shell is shared, so baking a url into it would put the wrong one\n // on every page but the one that happened to be built.\n unlistedNow ? \"\" : url,\n ),\n redirected: taken(),\n readRequest: requestWasRead(),\n // What reached for it, so the build can name the call rather than\n // only report that the page is dynamic.\n readBy: requestReadBy(),\n // And from which component, so the message is a line to open\n // rather than a category to search for.\n readWhere: requestReadWhere(),\n fallbacks: requestFallbacks(),\n };\n } catch (error) {\n // A guard refusing throws out of the probe rather than being caught\n // inside it: middleware run before the render, so there is no render yet\n // to capture the failure. A refusal is a classification, not a build\n // error — the route is one that cannot be frozen.\n const refused = taken();\n\n if (!refused) throw error;\n\n return {\n shell: null,\n redirected: refused,\n readRequest: requestWasRead(),\n readBy: requestReadBy(),\n readWhere: requestReadWhere(),\n fallbacks: requestFallbacks(),\n };\n }\n }),\n ),\n ),\n );\n\n // A page that leaves rather than renders is not a build failure, and it is\n // not something to freeze either: what would be stored is the redirect's\n // own emptiness, served for ever to everyone. Rendered on demand instead,\n // where the redirect can actually happen.\n /**\n * Did this page's own boundary catch the wait, or the app's?\n *\n * A root loading.tsx wraps every page, so a page that blocks — or throws,\n * which is how a client hook says it has no server answer — is caught\n * whatever it does. The route is stored either way and the build has\n * nothing to refuse, which makes a page whose boundary is in the wrong\n * place look exactly like one whose boundary is right.\n *\n * Asked by rendering again without the root fallback, and only for a route\n * that has no closer one.\n *\n * Only for a route that came out as a shell. A frozen one rendered to\n * completion with the root boundary present, and removing a boundary\n * cannot stop a render that already finished — so the second probe\n * finishes too, its markup is the whole document, and the emptiness test\n * cannot fire. It was being paid for anyway: a second full render of every\n * frozen page, which on a site whose pages are mostly frozen is most of\n * the prerender.\n */\n async function withRootFallbackChecked(\n result: PrerenderResult,\n ): Promise<PrerenderResult> {\n // Also for a frozen page whose SSR threw and was caught at a boundary -\n // useSearchParams() with nothing closer than the root loading.tsx. That\n // render finished, with the root fallback standing in for the page;\n // without it the throw reaches the root and nothing paints, which is\n // the question this asks.\n if (\n result.type !== \"shell\" &&\n !(result.type === \"frozen\" && fallbacks.length)\n )\n return result;\n if (!engine.handleRscPprShell) return result;\n\n // Only when the one fallback in the chain is the root layout's. A page\n // with its own loading.tsx beside it has put the boundary exactly where\n // the waiting is, and this used to tell it otherwise - \"exactly one\n // loading\" is not the same as \"only the root one\".\n const [only] = route.loadings;\n const root = route.layouts[0];\n const dirOf = (name: string) => name.slice(0, name.lastIndexOf(\"/\"));\n\n if (\n route.loadings.length !== 1 ||\n !only ||\n !root ||\n dirOf(only) !== dirOf(root)\n ) {\n // A boundary of its own caught it: the fallback there is stored and\n // the value is read in the browser. Said, because the page is not\n // quite what the source shows at first paint.\n if (fallbacks.length && !result.note) {\n result.note =\n fallbacks.join(\", \") +\n \" — its fallback is stored; the value is read in the browser\";\n }\n\n return result;\n }\n\n // A tenth of the shell budget, because this is a different question.\n //\n // Deciding what a page's shell IS means waiting out everything that can\n // resolve. Asking whether anything paints at all without the root\n // fallback is a boolean about the first flush — and a page that paints,\n // paints immediately. Given the full budget it cost two seconds a route\n // to learn what the first millisecond already said, which on this\n // example was 40% of the entire prerender.\n const withoutRoot = await withRequest(\n null,\n () =>\n withCache(() =>\n withRedirect(async () =>\n engine.handleRscPprShell(\n route.component,\n props,\n layouts,\n [],\n route.slots,\n url,\n ROOT_FALLBACK_BUDGET_MS,\n ),\n ),\n ),\n // A caught read with no boundary of its own: without the root's the\n // throw reaches the root, and the render fails rather than paints.\n ).catch(() => (fallbacks.length ? { shellHtml: \"\" } : null));\n\n if (withoutRoot && closeDocument(withoutRoot.shellHtml.trim()) === \"\") {\n result.warning = fallbacks.length\n ? fallbacks.join(\", \") +\n \" has no boundary closer than the root loading.tsx, so that is the whole page at first paint. \" +\n \"Put a <Suspense> around the component that reads, and the rest of the page is stored.\"\n : \"nothing painted without the root loading.tsx — the fallback the whole app shares \" +\n \"is standing in for this page. Put a boundary where the waiting is.\";\n } else if (fallbacks.length && !result.note) {\n result.note =\n fallbacks.join(\", \") +\n \" — its fallback is stored; the value is read in the browser\";\n }\n\n return result;\n }\n\n // A route that only redirects still has an answer to freeze — the answer\n // is the redirect, not a page. Rendering it per request re-derives a\n // constant, and on a static host there would be nothing to derive it with.\n if (redirected) {\n await write(\n `${pathKey(url)}.redirect.json`,\n JSON.stringify({\n status: redirected.status,\n location: redirected.location,\n }),\n );\n\n return said(\"frozen\", `redirects to ${redirected.location}`);\n }\n\n if (!shell) return said(\"error\", \"refused before it rendered\");\n\n if (shell.error) return said(\"error\", shell.error);\n\n // Something failed while rendering. Not necessarily the page's fault — a\n // build machine that cannot reach the database produces this, and so does a\n // genuinely broken component — so it is not fatal. It is simply not\n // something to freeze: whatever this render produced is a failure state,\n // and freezing it serves that state to everyone until the next build.\n //\n // Rendering per request is the honest answer. It works as soon as whatever\n // was missing is reachable, which at runtime it usually is.\n if (shell.renderFailure) {\n return said(\n \"blocked\",\n `could not be rendered at build time: ${shell.renderFailure}`,\n );\n }\n\n // A timeout is the ordinary path for a page that streams, not a failure:\n // the probe hands the page a host global that never resolves, React\n // flushes everything that does not depend on it, and the abort happens\n // once there is nothing left to flush. So the captured markup IS the\n // shell — layouts, static content, and the fallbacks standing in for what\n // has not arrived.\n if (shell.timedOut) {\n const body = closeDocument(shell.shellHtml.trim());\n\n // Nothing was flushed before the page blocked, so there is no shell to\n // ship — a page that blocks above every boundary can only be rendered on\n // demand. `reaches for the host` is the specific reason when both are\n // true; a page that merely ran long says the other thing.\n if (body === \"\") {\n return said(\n \"blocked\",\n (readRequest\n ? \"reads \" +\n (readWhere.length\n ? readWhere\n : readBy.length\n ? readBy\n : [\"the request\"]\n ).join(\", \")\n : shell.usedDynamicApis\n ? \"reaches for the host\"\n : \"blocks\") +\n \" before anything can paint.\" +\n (readWhere.some((w) => w.includes(\" awaited by \"))\n ? \" One of those has no boundary above it.\"\n : \"\") +\n \" Add a loading.tsx beside it, or put a \" +\n \"<Suspense> above the waiting, and it has a skeleton to store.\",\n );\n }\n\n await writeShell(route, url, body, shell.postponed);\n\n // Why it is a shell rather than a whole page. \"◐ /orders\" on its own\n // leaves someone reading the build output to guess what did it, which is\n // the question this line exists to answer.\n const calls = [\n ...(shell.dynamicBecause ?? []),\n ...(readWhere.length ? readWhere : readBy),\n ];\n\n return await withRootFallbackChecked(said(\"shell\", shellReason(calls)));\n }\n\n // Warned, not refused.\n //\n // A frozen `new Date()` may be exactly what the author meant — a build\n // stamp, a copyright year — and the build cannot tell that from a\n // \"3 minutes ago\" that will still say three minutes next month. Refusing\n // would make the honest case unbuildable in order to protect the careless\n // one, and there is no flag to add here without inventing the declaration\n // this design exists to avoid.\n //\n // So it says what happened, names what was called, and gives the repair.\n // The escape hatch is that a warning does not stop the build — which is the\n // right weight for something that is occasionally correct.\n //\n // Only for a page frozen WHOLE. On a shell the call may sit inside a hole,\n // which renders per request, where it is correct.\n const noteNondeterminism = (result: PrerenderResult): PrerenderResult => {\n if (nondeterministic.length === 0) return result;\n\n result.warning =\n `froze ${nondeterministic.join(\" and \")} — a stored page keeps whatever that ` +\n \"returned at build time. If it should differ per visitor, await connection() so \" +\n \"the page renders per request; if only the browser needs it, use(browser()) keeps \" +\n \"it out of the build entirely.\";\n\n return result;\n };\n\n // Rendered whole, with params that were invented because the route listed\n // none. Freezing that stores a page whose id is literally `_`, and a shell\n // is no better: the value is in the markup rather than behind a boundary\n // the client fills. A route reaches this only by rendering its params\n // before it can paint, which is exactly the shape that cannot be shared\n // across urls.\n if (unlisted) {\n return said(\n \"blocked\",\n \"renders its params before it can paint, and lists no urls to build\",\n );\n }\n\n const rendered = await engine.handleRsc(\n route.component,\n props,\n null,\n layouts,\n // Not empty: a page whose layout declares a parallel slot renders without\n // it otherwise, and nothing says so — the page comes out whole apart from\n // the missing region.\n route.loadings,\n route.slots,\n 0,\n url,\n true,\n // A build has no host to answer rpc(), so every host call must suspend\n // rather than resolve. Without this they found no host at all and the\n // page was frozen holding whatever undefined rendered to — a document\n // that looks right, hydrates against an undefined prop, and blanks.\n false,\n );\n\n // The render reached for the host, so its data is not the same for\n // everyone and there is no build-time answer for it. Not frozen: a shell\n // is shipped instead and the page finishes for whoever asks.\n if (rendered.usedDynamicApis) {\n return said(\"shell\", \"reaches the host for data\");\n }\n\n // Nothing for a runtime to do. No client component means nothing to\n // hydrate, and no server reference means no form that would post through\n // React - so the bootstrap is 70 kB of javascript that runs and changes\n // nothing. Rendered once more without it and stored that way.\n //\n // No declaration in either direction, on purpose. A page cannot need the\n // runtime without a client component or an action in its tree - \"use\n // client\" IS the opt-in - and a page that must stay this way is an\n // assertion for the build report, not a switch.\n let note: string | undefined;\n let body = rendered.body;\n\n if (\n rendered.clientComponents.every((name) => RUNTIME_OWN.has(name)) &&\n !rendered.serverReferences\n ) {\n // Only the document. The flight payload stays the bootstrap render's:\n // a Link elsewhere navigating here fetches it and expects the segment\n // and title wrappers that render puts in, which this one leaves out.\n const bare = await engine.handleRsc(\n route.component,\n props,\n null,\n layouts,\n route.loadings,\n route.slots,\n 0,\n url,\n false,\n false,\n );\n\n body = options.serviceWorker\n ? withWorkerRegistration(bare.body)\n : bare.body;\n\n let inlined = false;\n\n if (options.stylesheet) {\n const before = body;\n body = withInlineStylesheets(body, options.stylesheet);\n inlined = body !== before;\n }\n\n note =\n \"no client components, so ships no javascript\" +\n (inlined ? \"; stylesheet inlined\" : \"\");\n }\n\n const key = pathKey(url);\n\n await write(`${key}.html`, body);\n await write(`${key}.flight`, rendered.rscPayload);\n\n // One variant per depth the client might already hold. Without them every\n // navigation to a prerendered route is a whole document, which replaces the\n // root and unmounts the pages retained behind it — so going back does not\n // restore the form you were filling in. Most routes in a real app are\n // prerendered, which makes this the common path rather than an edge case.\n for (let depth = 1; depth <= route.layouts.length; depth++) {\n const { rscPayload } = await engine.handleRscPayload(\n route.component,\n props,\n layouts,\n route.loadings,\n route.slots,\n depth,\n url,\n );\n\n await write(`${key}.seg${depth}.flight`, rscPayload);\n }\n\n await write(\n `${key}.meta.json`,\n JSON.stringify(\n {\n layouts: route.layouts,\n component: route.component,\n version: version ?? null,\n },\n null,\n 2,\n ),\n );\n\n const frozen = noteNondeterminism(\n await withRootFallbackChecked(said(\"frozen\", null)),\n );\n\n return note ? { ...frozen, note } : frozen;\n }\n\n /**\n * Freeze a shell, under the url when it is one and under the route's pattern\n * when it stands for many.\n *\n * A route whose urls were never listed still gets a shell: nothing in it\n * varies by param, so the same markup is correct for every url the route\n * matches. That is most of the value — the routes you can enumerate are the\n * ones you could already freeze whole.\n */\n async function writeShell(\n route: ManifestRoute,\n url: string,\n body: string,\n postponed?: unknown,\n ): Promise<void> {\n const parameterised = route.segments.some((s) => s.type !== \"static\");\n const key =\n parameterised && !route.staticParams ? patternKey(route) : pathKey(url);\n\n await write(`${key}.ppr.html`, body);\n\n // Written only when there is something to resume from. Its absence is\n // meaningful rather than incidental: a host that finds no postponed state\n // serves the shell and lets the client fill it, which is what every build\n // before this one did.\n if (postponed != null) {\n await write(`${key}.postponed.json`, JSON.stringify(postponed));\n }\n await write(\n `${key}.ppr-meta.json`,\n JSON.stringify(\n {\n layouts: route.layouts,\n component: route.component,\n parameterised,\n version: version ?? null,\n },\n null,\n 2,\n ),\n );\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import type { Href } from './routes.js';
1
+ import type { Href, SearchFor } from './routes.js';
2
2
  import type { Redirection } from './redirectDigest.js';
3
3
  export { RedirectSignal, isRedirectSignal, redirectDigest, parseRedirectDigest } from './redirectDigest.js';
4
4
  export type { Redirection } from './redirectDigest.js';
@@ -20,7 +20,21 @@ export type { Redirection } from './redirectDigest.js';
20
20
  * answered after the shell — which holds no data from inside the boundary,
21
21
  * but does hold whatever the layouts above it rendered.
22
22
  */
23
- export declare function redirect(location: Href, status?: number): never;
23
+ /**
24
+ * What a redirect may carry beside its destination. `search` is typed to the
25
+ * destination page's own `searchParams` schema when it exports one - the
26
+ * same check `Link` puts on its `search` prop - so a key the page never
27
+ * reads, or a number written as text, does not compile.
28
+ */
29
+ export type RedirectOptions<H extends Href> = ({} extends SearchFor<H> ? {
30
+ search?: SearchFor<H>;
31
+ } : {
32
+ search: SearchFor<H>;
33
+ }) & {
34
+ /** 307 unless said otherwise; 308 for a permanent one. */
35
+ status?: number;
36
+ };
37
+ export declare function redirect<H extends Href>(location: H, ...rest: {} extends SearchFor<H> ? [options?: RedirectOptions<H> | number] : [options: RedirectOptions<H>]): never;
24
38
  /** The redirect asked for during the current render, if any. */
25
39
  export declare function currentRedirect(): Redirection | null;
26
40
  /**
package/dist/redirect.js CHANGED
@@ -30,6 +30,7 @@
30
30
  // already awaits the shell before writing anything; the second because React
31
31
  // already carries an error digest to the client.
32
32
  import { assertSafeRedirect } from './safeUrl.js';
33
+ import { withSearch } from './routes.js';
33
34
  import { resolveScope } from './revalidate.js';
34
35
  import { RedirectSignal } from './redirectDigest.js';
35
36
  export { RedirectSignal, isRedirectSignal, redirectDigest, parseRedirectDigest } from './redirectDigest.js';
@@ -47,25 +48,15 @@ let ready = null;
47
48
  function scope() {
48
49
  return globals[SCOPE] ?? null;
49
50
  }
50
- /**
51
- * Leave this page for another one.
52
- *
53
- * Never returns: it throws, which stops the component that called it. Do not
54
- * wrap a call in `try`/`catch` without rethrowing what you do not recognise —
55
- * swallowing this turns a redirect into a blank region.
56
- *
57
- * `location` is typed to the routes the build found, so a redirect to a page
58
- * that no longer exists stops compiling. Cast with `as Href` when the
59
- * destination is computed — remembering where someone was going and sending
60
- * them back to it is the usual case.
61
- *
62
- * Where it is called decides how it is delivered, and the difference matters
63
- * for anything that must not be seen. A call above every Suspense boundary is
64
- * answered with a status code before a byte is written. A call inside one is
65
- * answered after the shell — which holds no data from inside the boundary,
66
- * but does hold whatever the layouts above it rendered.
67
- */
68
- export function redirect(location, status = 307) {
51
+ export function redirect(location, ...rest) {
52
+ // The second argument was a status alone once; it still is, and an object
53
+ // carries the query string beside it.
54
+ const options = typeof rest[0] === 'number' ? { status: rest[0] } : (rest[0] ?? {});
55
+ const status = options.status ?? 307;
56
+ const search = options.search;
57
+ return redirectTo(search ? withSearch(location, search) : location, status);
58
+ }
59
+ function redirectTo(location, status) {
69
60
  // Refused here, at the one place every delivery path leads back to. The
70
61
  // destination reaches location.href on the client and an inline script in a
71
62
  // document, and a javascript: url runs in all of them.
@@ -1 +1 @@
1
- {"version":3,"file":"redirect.js","sourceRoot":"","sources":["../src/redirect.ts"],"names":[],"mappings":"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","sourcesContent":["// Redirecting from inside a render.\n//\n// import { redirect } from '@rsc-kit/core/redirect'\n//\n// export default async function ProductPage({ slug }) {\n// const product = await findProduct(slug)\n// if (!product) redirect('/products')\n// ...\n// }\n//\n// The hard part is not throwing — it is that a redirect decided during a\n// render may be decided after the response has already begun. Headers flush\n// early on purpose (see the stream-start invariant), so by the time a\n// component deep in a Suspense boundary changes its mind, the 200 is gone.\n//\n// So there are two windows, and which one a redirect lands in is decided by\n// where it was thrown rather than by anything the caller does:\n//\n// Before the shell resolves — nothing has been written. The host answers\n// with a real 3xx, or for a navigation with X-RSC-Redirect, and the browser\n// never sees the page. This is the window every guard lands in, because a\n// guard runs above the boundaries.\n//\n// After the shell resolves — the shell is already on the wire. It holds\n// layouts and Suspense fallbacks, so no data from the redirecting subtree\n// has been shown. The location travels to the client instead, which\n// performs it as an ordinary SPA navigation.\n//\n// Neither window costs a buffered byte. The first exists because the host\n// already awaits the shell before writing anything; the second because React\n// already carries an error digest to the client.\n\nimport { assertSafeRedirect } from './safeUrl.js'\nimport type { Href } from './routes.js'\nimport { resolveScope } from './revalidate.js'\nimport { RedirectSignal } from './redirectDigest.js'\nimport type { Redirection } from './redirectDigest.js'\n\nexport { RedirectSignal, isRedirectSignal, redirectDigest, parseRedirectDigest } from './redirectDigest.js'\nexport type { Redirection } from './redirectDigest.js'\n\n/** Per-render state, for the same reason revalidation has it: two can be in flight. */\ninterface Slot {\n redirect: Redirection | null\n /**\n * Whether the render asked for the not-found page.\n *\n * Shares this scope rather than opening a second one, because it is the same\n * question asked once per render — \"did this page decide to answer as\n * something other than itself\" — and every render path is already wrapped in\n * this one. notFound.ts sets it through the scope symbol without importing\n * this module; see the note there.\n */\n notFound?: boolean\n}\n\ninterface Scope {\n getStore(): Slot | undefined\n run<T>(store: Slot, fn: () => T): T\n}\n\n/**\n * One scope, however many copies of this module exist.\n *\n * The app's components are bundled into the server bundle and the host is\n * not, so this module is loaded twice. Two scopes would mean the component\n * records in one and the host reads the other: the redirect is simply never\n * honoured, and nothing on either side reports a problem.\n */\nconst SCOPE = Symbol.for('@rsc-kit/core.redirect-scope')\n\nconst globals = globalThis as Record<symbol | string, unknown>\n\nlet ready: Promise<void> | null = null\n\nfunction scope(): Scope | null {\n return (globals[SCOPE] as Scope | undefined) ?? null\n}\n\n/**\n * Leave this page for another one.\n *\n * Never returns: it throws, which stops the component that called it. Do not\n * wrap a call in `try`/`catch` without rethrowing what you do not recognise —\n * swallowing this turns a redirect into a blank region.\n *\n * `location` is typed to the routes the build found, so a redirect to a page\n * that no longer exists stops compiling. Cast with `as Href` when the\n * destination is computed — remembering where someone was going and sending\n * them back to it is the usual case.\n *\n * Where it is called decides how it is delivered, and the difference matters\n * for anything that must not be seen. A call above every Suspense boundary is\n * answered with a status code before a byte is written. A call inside one is\n * answered after the shell — which holds no data from inside the boundary,\n * but does hold whatever the layouts above it rendered.\n */\nexport function redirect(location: Href, status = 307): never {\n // Refused here, at the one place every delivery path leads back to. The\n // destination reaches location.href on the client and an inline script in a\n // document, and a javascript: url runs in all of them.\n assertSafeRedirect(location)\n\n // A redirect is a 3xx. Anything else produces a response carrying Location\n // that no browser acts on — the page renders, the redirect silently does not\n // happen, and nothing says why.\n if (status < 300 || status > 399) {\n throw new Error(\n 'Not a redirect status: ' + status + '. A redirect is 3xx; 307 preserves the method.',\n )\n }\n\n const store = scope()?.getStore()\n\n // First wins. A layout that redirects and a page that also redirects should\n // land where the outer one said, not wherever finished last.\n if (store && !store.redirect) {\n store.redirect = { location, status }\n }\n\n throw new RedirectSignal(location, status)\n}\n\n/** The redirect asked for during the current render, if any. */\nexport function currentRedirect(): Redirection | null {\n return scope()?.getStore()?.redirect ?? null\n}\n\n/**\n * Whether the current render called notFound().\n *\n * Read rather than caught, for the reason the redirect above is: React\n * re-raises a component's error as its own, so the thrown signal does not\n * arrive intact at the host in production.\n */\nexport function currentNotFound(): boolean {\n return scope()?.getStore()?.notFound === true\n}\n\n/**\n * Run a render with somewhere for a redirect to be recorded, and report one.\n *\n * `taken()` is read twice by a streaming host: once when the shell resolves,\n * to answer with a status code, and again when the stream ends, for a\n * redirect that arrived too late for one.\n */\nexport async function withRedirect<T>(\n run: (taken: () => Redirection | null) => Promise<T>,\n): Promise<T> {\n if (!globals[SCOPE]) {\n ready ??= resolveScope().then((resolved) => {\n globals[SCOPE] ??= resolved as unknown as Scope\n })\n\n await ready\n }\n\n const slot: Slot = { redirect: null, notFound: false }\n\n return await scope()!.run(slot, () => run(() => slot.redirect))\n}\n"]}
1
+ {"version":3,"file":"redirect.js","sourceRoot":"","sources":["../src/redirect.ts"],"names":[],"mappings":"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","sourcesContent":["// Redirecting from inside a render.\n//\n// import { redirect } from '@rsc-kit/core/redirect'\n//\n// export default async function ProductPage({ slug }) {\n// const product = await findProduct(slug)\n// if (!product) redirect('/products')\n// ...\n// }\n//\n// The hard part is not throwing — it is that a redirect decided during a\n// render may be decided after the response has already begun. Headers flush\n// early on purpose (see the stream-start invariant), so by the time a\n// component deep in a Suspense boundary changes its mind, the 200 is gone.\n//\n// So there are two windows, and which one a redirect lands in is decided by\n// where it was thrown rather than by anything the caller does:\n//\n// Before the shell resolves — nothing has been written. The host answers\n// with a real 3xx, or for a navigation with X-RSC-Redirect, and the browser\n// never sees the page. This is the window every guard lands in, because a\n// guard runs above the boundaries.\n//\n// After the shell resolves — the shell is already on the wire. It holds\n// layouts and Suspense fallbacks, so no data from the redirecting subtree\n// has been shown. The location travels to the client instead, which\n// performs it as an ordinary SPA navigation.\n//\n// Neither window costs a buffered byte. The first exists because the host\n// already awaits the shell before writing anything; the second because React\n// already carries an error digest to the client.\n\nimport { assertSafeRedirect } from './safeUrl.js'\nimport { withSearch } from './routes.js'\nimport type { Href, SearchFor } from './routes.js'\nimport { resolveScope } from './revalidate.js'\nimport { RedirectSignal } from './redirectDigest.js'\nimport type { Redirection } from './redirectDigest.js'\n\nexport { RedirectSignal, isRedirectSignal, redirectDigest, parseRedirectDigest } from './redirectDigest.js'\nexport type { Redirection } from './redirectDigest.js'\n\n/** Per-render state, for the same reason revalidation has it: two can be in flight. */\ninterface Slot {\n redirect: Redirection | null\n /**\n * Whether the render asked for the not-found page.\n *\n * Shares this scope rather than opening a second one, because it is the same\n * question asked once per render — \"did this page decide to answer as\n * something other than itself\" — and every render path is already wrapped in\n * this one. notFound.ts sets it through the scope symbol without importing\n * this module; see the note there.\n */\n notFound?: boolean\n}\n\ninterface Scope {\n getStore(): Slot | undefined\n run<T>(store: Slot, fn: () => T): T\n}\n\n/**\n * One scope, however many copies of this module exist.\n *\n * The app's components are bundled into the server bundle and the host is\n * not, so this module is loaded twice. Two scopes would mean the component\n * records in one and the host reads the other: the redirect is simply never\n * honoured, and nothing on either side reports a problem.\n */\nconst SCOPE = Symbol.for('@rsc-kit/core.redirect-scope')\n\nconst globals = globalThis as Record<symbol | string, unknown>\n\nlet ready: Promise<void> | null = null\n\nfunction scope(): Scope | null {\n return (globals[SCOPE] as Scope | undefined) ?? null\n}\n\n/**\n * Leave this page for another one.\n *\n * Never returns: it throws, which stops the component that called it. Do not\n * wrap a call in `try`/`catch` without rethrowing what you do not recognise —\n * swallowing this turns a redirect into a blank region.\n *\n * `location` is typed to the routes the build found, so a redirect to a page\n * that no longer exists stops compiling. Cast with `as Href` when the\n * destination is computed — remembering where someone was going and sending\n * them back to it is the usual case.\n *\n * Where it is called decides how it is delivered, and the difference matters\n * for anything that must not be seen. A call above every Suspense boundary is\n * answered with a status code before a byte is written. A call inside one is\n * answered after the shell — which holds no data from inside the boundary,\n * but does hold whatever the layouts above it rendered.\n */\n/**\n * What a redirect may carry beside its destination. `search` is typed to the\n * destination page's own `searchParams` schema when it exports one - the\n * same check `Link` puts on its `search` prop - so a key the page never\n * reads, or a number written as text, does not compile.\n */\nexport type RedirectOptions<H extends Href> = ({} extends SearchFor<H>\n ? { search?: SearchFor<H> }\n : { search: SearchFor<H> }) & {\n /** 307 unless said otherwise; 308 for a permanent one. */\n status?: number\n}\n\nexport function redirect<H extends Href>(\n location: H,\n ...rest: {} extends SearchFor<H> ? [options?: RedirectOptions<H> | number] : [options: RedirectOptions<H>]\n): never {\n // The second argument was a status alone once; it still is, and an object\n // carries the query string beside it.\n const options = typeof rest[0] === 'number' ? { status: rest[0] } : (rest[0] ?? {})\n const status = options.status ?? 307\n const search = (options as { search?: object }).search\n\n return redirectTo(search ? (withSearch(location, search) as Href) : location, status)\n}\n\nfunction redirectTo(location: Href, status: number): never {\n // Refused here, at the one place every delivery path leads back to. The\n // destination reaches location.href on the client and an inline script in a\n // document, and a javascript: url runs in all of them.\n assertSafeRedirect(location)\n\n // A redirect is a 3xx. Anything else produces a response carrying Location\n // that no browser acts on — the page renders, the redirect silently does not\n // happen, and nothing says why.\n if (status < 300 || status > 399) {\n throw new Error(\n 'Not a redirect status: ' + status + '. A redirect is 3xx; 307 preserves the method.',\n )\n }\n\n const store = scope()?.getStore()\n\n // First wins. A layout that redirects and a page that also redirects should\n // land where the outer one said, not wherever finished last.\n if (store && !store.redirect) {\n store.redirect = { location, status }\n }\n\n throw new RedirectSignal(location, status)\n}\n\n/** The redirect asked for during the current render, if any. */\nexport function currentRedirect(): Redirection | null {\n return scope()?.getStore()?.redirect ?? null\n}\n\n/**\n * Whether the current render called notFound().\n *\n * Read rather than caught, for the reason the redirect above is: React\n * re-raises a component's error as its own, so the thrown signal does not\n * arrive intact at the host in production.\n */\nexport function currentNotFound(): boolean {\n return scope()?.getStore()?.notFound === true\n}\n\n/**\n * Run a render with somewhere for a redirect to be recorded, and report one.\n *\n * `taken()` is read twice by a streaming host: once when the shell resolves,\n * to answer with a status code, and again when the stream ends, for a\n * redirect that arrived too late for one.\n */\nexport async function withRedirect<T>(\n run: (taken: () => Redirection | null) => Promise<T>,\n): Promise<T> {\n if (!globals[SCOPE]) {\n ready ??= resolveScope().then((resolved) => {\n globals[SCOPE] ??= resolved as unknown as Scope\n })\n\n await ready\n }\n\n const slot: Slot = { redirect: null, notFound: false }\n\n return await scope()!.run(slot, () => run(() => slot.redirect))\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import type { RevalidateTarget } from "./routes.js";
1
2
  /** What this needs from a runtime: somewhere to keep per-action state. */
2
3
  interface Scope {
3
4
  getStore(): Set<string> | undefined;
@@ -21,15 +22,16 @@ export declare function resolveScope(from?: Record<string, unknown>): Promise<Sc
21
22
  * Mark a region of the current page for re-rendering.
22
23
  *
23
24
  * `'page'` and `'all'` re-render the page or the whole document; any other
24
- * name is a section or a parallel slot. Unknown names are refused by the
25
- * renderer with the names it does know, rather than quietly refreshing
26
- * nothing.
25
+ * name is a section or a parallel slot. The names are typed to the ones the
26
+ * build found, so a typo stops compiling; a name that reaches the renderer
27
+ * unknown anyway is refused with the names it does know, rather than quietly
28
+ * refreshing nothing.
27
29
  *
28
30
  * Outside an action this does nothing rather than throwing: it is reasonable
29
31
  * for shared code to mark, and unreasonable for that to fail when the same
30
32
  * function is called during an ordinary render.
31
33
  */
32
- export declare function revalidate(target: string): void;
34
+ export declare function revalidate(target: RevalidateTarget): void;
33
35
  /** Whether anything is listening, for a host that wants to warn about the rest. */
34
36
  export declare function isRevalidating(): boolean;
35
37
  /**
@@ -28,7 +28,7 @@
28
28
  * The engine installs its host callable on globalThis for exactly this
29
29
  * reason. This is the same crossing.
30
30
  */
31
- const SCOPE = Symbol.for('@rsc-kit/core.revalidation-scope');
31
+ const SCOPE = Symbol.for("@rsc-kit/core.revalidation-scope");
32
32
  const globals = globalThis;
33
33
  let ready = null;
34
34
  let warned = false;
@@ -52,7 +52,7 @@ from = globals) {
52
52
  const Ambient = from.AsyncLocalStorage;
53
53
  if (Ambient)
54
54
  return new Ambient();
55
- const { AsyncLocalStorage } = await import('node:async_hooks');
55
+ const { AsyncLocalStorage } = await import("node:async_hooks");
56
56
  return new AsyncLocalStorage();
57
57
  }
58
58
  /** The scope, once resolved. Null before the first action runs. */
@@ -63,9 +63,10 @@ function scope() {
63
63
  * Mark a region of the current page for re-rendering.
64
64
  *
65
65
  * `'page'` and `'all'` re-render the page or the whole document; any other
66
- * name is a section or a parallel slot. Unknown names are refused by the
67
- * renderer with the names it does know, rather than quietly refreshing
68
- * nothing.
66
+ * name is a section or a parallel slot. The names are typed to the ones the
67
+ * build found, so a typo stops compiling; a name that reaches the renderer
68
+ * unknown anyway is refused with the names it does know, rather than quietly
69
+ * refreshing nothing.
69
70
  *
70
71
  * Outside an action this does nothing rather than throwing: it is reasonable
71
72
  * for shared code to mark, and unreasonable for that to fail when the same