@rsc-kit/core 0.20.8 → 0.20.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/earlyHints.d.ts +14 -2
- package/dist/earlyHints.js +15 -8
- package/dist/earlyHints.js.map +1 -1
- package/dist/host.js +1 -2
- package/dist/host.js.map +1 -1
- package/dist/js/segmentStore.d.ts +6 -0
- package/dist/js/segmentStore.js +17 -8
- package/dist/js/segmentStore.js.map +1 -1
- package/package.json +1 -1
package/dist/earlyHints.d.ts
CHANGED
|
@@ -13,5 +13,17 @@ export declare function linkHeader(assets: CriticalAssets): string;
|
|
|
13
13
|
* The first 16 KB, which is the head of any document this build writes.
|
|
14
14
|
*/
|
|
15
15
|
export declare function criticalAssetsOf(html: string): CriticalAssets;
|
|
16
|
-
/**
|
|
17
|
-
|
|
16
|
+
/**
|
|
17
|
+
* One set over another: the build's names, for a document whose own are not
|
|
18
|
+
* known.
|
|
19
|
+
*
|
|
20
|
+
* `primary` is null when nothing was read - a document rendered per request,
|
|
21
|
+
* whose head does not exist until after its headers have gone. A document
|
|
22
|
+
* that WAS read is the authority on itself, including when the answer is
|
|
23
|
+
* "nothing": a stored page with no client component names no module, and
|
|
24
|
+
* hinting the build's entry made the browser fetch 82 KB of runtime that
|
|
25
|
+
* the page never runs - the whole claim of a route that ships no
|
|
26
|
+
* JavaScript, undone by its own headers. Per field it was worse still: a
|
|
27
|
+
* page with its stylesheet inlined was hinted the build's stylesheet too.
|
|
28
|
+
*/
|
|
29
|
+
export declare function mergeAssets(primary: CriticalAssets | null, fallback: CriticalAssets | null): CriticalAssets;
|
package/dist/earlyHints.js
CHANGED
|
@@ -52,14 +52,21 @@ export function criticalAssetsOf(html) {
|
|
|
52
52
|
found.modules.push(entry[1]);
|
|
53
53
|
return found;
|
|
54
54
|
}
|
|
55
|
-
/**
|
|
55
|
+
/**
|
|
56
|
+
* One set over another: the build's names, for a document whose own are not
|
|
57
|
+
* known.
|
|
58
|
+
*
|
|
59
|
+
* `primary` is null when nothing was read - a document rendered per request,
|
|
60
|
+
* whose head does not exist until after its headers have gone. A document
|
|
61
|
+
* that WAS read is the authority on itself, including when the answer is
|
|
62
|
+
* "nothing": a stored page with no client component names no module, and
|
|
63
|
+
* hinting the build's entry made the browser fetch 82 KB of runtime that
|
|
64
|
+
* the page never runs - the whole claim of a route that ships no
|
|
65
|
+
* JavaScript, undone by its own headers. Per field it was worse still: a
|
|
66
|
+
* page with its stylesheet inlined was hinted the build's stylesheet too.
|
|
67
|
+
*/
|
|
56
68
|
export function mergeAssets(primary, fallback) {
|
|
57
|
-
|
|
58
|
-
return primary;
|
|
59
|
-
return {
|
|
60
|
-
styles: primary.styles.length ? primary.styles : fallback.styles,
|
|
61
|
-
modules: primary.modules.length ? primary.modules : fallback.modules,
|
|
62
|
-
fonts: primary.fonts.length ? primary.fonts : fallback.fonts,
|
|
63
|
-
};
|
|
69
|
+
return primary ?? fallback ?? EMPTY;
|
|
64
70
|
}
|
|
71
|
+
const EMPTY = { styles: [], modules: [], fonts: [] };
|
|
65
72
|
//# sourceMappingURL=earlyHints.js.map
|
package/dist/earlyHints.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"earlyHints.js","sourceRoot":"","sources":["../src/earlyHints.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,yEAAyE;AACzE,wEAAwE;AACxE,sEAAsE;AACtE,yEAAyE;AACzE,oBAAoB;AACpB,EAAE;AACF,4EAA4E;AAC5E,0EAA0E;AAC1E,0EAA0E;AAC1E,4EAA4E;AAC5E,4EAA4E;AAC5E,+DAA+D;AAW/D,0EAA0E;AAC1E,MAAM,UAAU,UAAU,CAAC,MAAsB;IAC/C,MAAM,KAAK,GAAa,EAAE,CAAA;IAE1B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,0BAA0B,CAAC,CAAA;IAChF,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,sBAAsB,CAAC,CAAA;IAC7E,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,sCAAsC,CAAC,CAAA;IAE3F,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC;AAED,MAAM,UAAU,GAAG,MAAM,CAAA;AACzB,MAAM,IAAI,GAAG,gBAAgB,CAAA;AAC7B,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,GAAW,EAAiB,EAAE;IACxD,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,MAAM,IAAI,mBAAmB,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAEtE,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AAChC,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAA;IACtC,MAAM,KAAK,GAAmB,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAA;IAEpE,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QACzC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,WAAW,EAAE,CAAA;QAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;QAE9B,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAQ;QAE5C,IAAI,GAAG,KAAK,YAAY;YAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;aAC5C,IAAI,GAAG,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,WAAW,EAAE,KAAK,MAAM;YAAE,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACjG,CAAC;IAED,2EAA2E;IAC3E,yEAAyE;IACzE,MAAM,KAAK,GAAG,kCAAkC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,kCAAkC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAEzH,IAAI,KAAK;QAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;IAEvC,OAAO,KAAK,CAAA;AACd,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"earlyHints.js","sourceRoot":"","sources":["../src/earlyHints.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,yEAAyE;AACzE,wEAAwE;AACxE,sEAAsE;AACtE,yEAAyE;AACzE,oBAAoB;AACpB,EAAE;AACF,4EAA4E;AAC5E,0EAA0E;AAC1E,0EAA0E;AAC1E,4EAA4E;AAC5E,4EAA4E;AAC5E,+DAA+D;AAW/D,0EAA0E;AAC1E,MAAM,UAAU,UAAU,CAAC,MAAsB;IAC/C,MAAM,KAAK,GAAa,EAAE,CAAA;IAE1B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,0BAA0B,CAAC,CAAA;IAChF,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,sBAAsB,CAAC,CAAA;IAC7E,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,sCAAsC,CAAC,CAAA;IAE3F,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC;AAED,MAAM,UAAU,GAAG,MAAM,CAAA;AACzB,MAAM,IAAI,GAAG,gBAAgB,CAAA;AAC7B,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,GAAW,EAAiB,EAAE;IACxD,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,MAAM,IAAI,mBAAmB,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAEtE,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AAChC,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAA;IACtC,MAAM,KAAK,GAAmB,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAA;IAEpE,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QACzC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,WAAW,EAAE,CAAA;QAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;QAE9B,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAQ;QAE5C,IAAI,GAAG,KAAK,YAAY;YAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;aAC5C,IAAI,GAAG,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,WAAW,EAAE,KAAK,MAAM;YAAE,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACjG,CAAC;IAED,2EAA2E;IAC3E,yEAAyE;IACzE,MAAM,KAAK,GAAG,kCAAkC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,kCAAkC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAEzH,IAAI,KAAK;QAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;IAEvC,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,WAAW,CAAC,OAA8B,EAAE,QAA+B;IACzF,OAAO,OAAO,IAAI,QAAQ,IAAI,KAAK,CAAA;AACrC,CAAC;AAED,MAAM,KAAK,GAAmB,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAA","sourcesContent":["// The Link header a document answers with, for a CDN to send ahead as 103\n// Early Hints - so the stylesheet, the client entry and the fonts are on\n// their way while the HTML is still being written. Cloudflare turns the\n// header into hints and caches them at the edge for the next visitor;\n// anything else passes it through, where a browser still reads it as the\n// document arrives.\n//\n// The critical set and nothing more: a hint promotes whatever it names, and\n// naming every chunk demotes the document behind them. The stylesheet and\n// the client entry come from the build's own manifest, the same names the\n// document carries. The fonts are the app's - preloaded in its layout - and\n// are read from a stored document's own head; a rendered document's head is\n// not known until it is rendered, after its headers have gone.\n\nexport interface CriticalAssets {\n /** Stylesheets the document links: `<link rel=\"stylesheet\">`. */\n styles: string[];\n /** The client entry: `<script type=\"module\">`'s import. */\n modules: string[];\n /** Fonts the document preloads: `<link rel=\"preload\" as=\"font\">`. */\n fonts: string[];\n}\n\n/** One `Link` header value for the set. Empty string for an empty set. */\nexport function linkHeader(assets: CriticalAssets): string {\n const parts: string[] = []\n\n for (const href of assets.styles) parts.push(`<${href}>; rel=preload; as=style`)\n for (const href of assets.modules) parts.push(`<${href}>; rel=modulepreload`)\n for (const href of assets.fonts) parts.push(`<${href}>; rel=preload; as=font; crossorigin`)\n\n return parts.join(', ')\n}\n\nconst HEAD_LIMIT = 16_384\nconst LINK = /<link\\s[^>]*>/g\nconst ATTR = (name: string, tag: string): string | null => {\n const match = new RegExp(`\\\\b${name}=[\"']([^\"']*)[\"']`, 'i').exec(tag)\n\n return match ? match[1] : null\n}\n\n/**\n * What a stored document's head names: its stylesheets and preloaded fonts.\n * The first 16 KB, which is the head of any document this build writes.\n */\nexport function criticalAssetsOf(html: string): CriticalAssets {\n const head = html.slice(0, HEAD_LIMIT)\n const found: CriticalAssets = { styles: [], modules: [], fonts: [] }\n\n for (const tag of head.match(LINK) ?? []) {\n const rel = ATTR('rel', tag)?.toLowerCase()\n const href = ATTR('href', tag)\n\n if (!href || !href.startsWith('/')) continue\n\n if (rel === 'stylesheet') found.styles.push(href)\n else if (rel === 'preload' && ATTR('as', tag)?.toLowerCase() === 'font') found.fonts.push(href)\n }\n\n // The bootstrap script is the last thing in the body, after the shell; its\n // import names the entry. The tail, then, and the head for a short page.\n const entry = /import\\([\"'](\\/[^\"']+\\.js)[\"']\\)/.exec(html.slice(-4096)) ?? /import\\([\"'](\\/[^\"']+\\.js)[\"']\\)/.exec(head)\n\n if (entry) found.modules.push(entry[1])\n\n return found\n}\n\n/**\n * One set over another: the build's names, for a document whose own are not\n * known.\n *\n * `primary` is null when nothing was read - a document rendered per request,\n * whose head does not exist until after its headers have gone. A document\n * that WAS read is the authority on itself, including when the answer is\n * \"nothing\": a stored page with no client component names no module, and\n * hinting the build's entry made the browser fetch 82 KB of runtime that\n * the page never runs - the whole claim of a route that ships no\n * JavaScript, undone by its own headers. Per field it was worse still: a\n * page with its stylesheet inlined was hinted the build's stylesheet too.\n */\nexport function mergeAssets(primary: CriticalAssets | null, fallback: CriticalAssets | null): CriticalAssets {\n return primary ?? fallback ?? EMPTY\n}\n\nconst EMPTY: CriticalAssets = { styles: [], modules: [], fonts: [] }\n"]}
|
package/dist/host.js
CHANGED
|
@@ -374,7 +374,6 @@ export function createRscHandler(options) {
|
|
|
374
374
|
/** What a stored document's head names, read once per file, for the Link header. */
|
|
375
375
|
const hinted = new WeakMap();
|
|
376
376
|
const hintsByKey = new Map();
|
|
377
|
-
const EMPTY_ASSETS = { styles: [], modules: [], fonts: [] };
|
|
378
377
|
/**
|
|
379
378
|
* The page a payload url belongs to, if this is one.
|
|
380
379
|
*
|
|
@@ -482,7 +481,7 @@ export function createRscHandler(options) {
|
|
|
482
481
|
// document, stored ones included - a stored document's own head
|
|
483
482
|
// names its fonts; a rendered one's is not known until too late.
|
|
484
483
|
if (response.status === 200 && (response.headers.get("Content-Type") ?? "").startsWith("text/html")) {
|
|
485
|
-
const link = linkHeader(mergeAssets(hinted.get(response) ??
|
|
484
|
+
const link = linkHeader(mergeAssets(hinted.get(response) ?? null, engine.criticalAssets?.() ?? null));
|
|
486
485
|
if (link)
|
|
487
486
|
response.headers.set("Link", link);
|
|
488
487
|
}
|
package/dist/host.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.js","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"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","sourcesContent":["// Everything a JavaScript host has to do to serve the RSC engine.\n//\n// PHP needs ~2,400 lines for this because it cannot run JavaScript: a socket\n// bridge, a worker pool, a frame protocol. A JS host imports the engine and\n// calls it, and what remains is the part every host would otherwise rewrite —\n// matching a url to a route, negotiating how much of the page to send, and\n// speaking the header protocol the client expects.\n//\n// Deliberately not Hono, or Express, or anything: this takes a Request and\n// returns a Response, so it runs under Bun.serve, Deno, Workers, Node's\n// fetch adapters and any framework built on them. `./hono` is the three-line\n// binding for one of them.\n//\n// const rsc = createRscHandler({ engine, manifest, assets })\n// Bun.serve({ fetch: (req) => rsc(req).then((r) => r ?? new Response('', { status: 404 })) })\n\nimport {\n allowFor,\n matchApiRoute,\n matchIntercept,\n matchRoute,\n retentionKey,\n sharedDepth,\n} from \"./routing.js\";\nimport { pathKey, patternKey } from \"./prerender.js\";\nimport { apiKey } from \"./apiPrerender.js\";\nimport { hostPath, hostSegment, routableHost } from \"./hostRouting.js\";\nimport type { FrozenApiResponse } from \"./apiPrerender.js\";\nimport { withRevalidation } from \"./revalidate.js\";\n/**\n * @internal For a host adapter that embeds the engine. An app imports this\n * from `@rsc-kit/core/revalidate`.\n */\nexport { revalidate } from \"./revalidate.js\";\nimport { currentNotFound, withRedirect } from \"./redirect.js\";\nimport { compressed } from \"./compress.js\";\nimport { withCache } from \"./cache.js\";\nimport { takeAfterWork, withRequest, withResponseDraft } from \"./request.js\";\nimport { criticalAssetsOf, linkHeader, mergeAssets, type CriticalAssets } from \"./earlyHints.js\";\nimport { withHead } from \"./shellHead.js\";\nimport type { Redirection } from \"./redirect.js\";\n/**\n * @internal For a host adapter that embeds the engine. An app imports this\n * from `@rsc-kit/core/redirect` - the one the guides teach, and the one an\n * editor should offer first.\n */\nexport { redirect } from \"./redirect.js\";\n// Re-exported, not redefined: routing.ts is the one implementation, shared with\n// the prerenderer and the generated bundle, and this stays the adapter's\n// public surface so a host imports from one place.\n/** @internal For a host adapter. An app never matches its own routes. */\nexport { matchIntercept, matchRoute, sharedDepth } from \"./routing.js\";\nexport type { MatchedRoute } from \"./routing.js\";\nimport {\n FLIGHT_TYPE,\n HEADER,\n HTML_TYPE,\n PER_CLIENT,\n REVALIDATE,\n VARY_ON_RSC,\n} from \"./headers.js\";\nimport type { MatchedApiRoute, MatchedRoute } from \"./routing.js\";\nimport {\n ServerAuthenticationError,\n ServerAuthorizationError,\n} from \"./js/errors.js\";\nimport type { RouteManifest } from \"./manifest.js\";\n\n/** The built server bundle. Only the parts a host calls. */\nexport interface RscEngine {\n /** The route table this bundle was built from. */\n manifest?(): RouteManifest;\n /** A short id of this build's client, for the version the host answers with when given none. */\n buildId?(): Promise<string>;\n /** The stylesheet and client entry every document links, for the Link header a CDN sends ahead. */\n criticalAssets?(): CriticalAssets;\n installHostFn(fn: (name: string, ...args: unknown[]) => unknown): void;\n handleRscStream(\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 slotOverrides?: Record<string, unknown>,\n from?: number,\n pageKey?: string,\n pathname?: string | null,\n ): Promise<{ stream: ReadableStream; segmentDepth: number }>;\n handleRscHtmlStream(\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 slotOverrides?: Record<string, unknown>,\n nonce?: string,\n pageKey?: string,\n bootstrap?: boolean,\n ): Promise<{ htmlStream: ReadableStream }>;\n /**\n * A form posted to the page's own url before the page had a runtime to\n * catch it: React wrote the action's id into the form, and this runs that\n * action from the posted fields, then renders the page with the result.\n * Optional: an engine built by an older plugin answers such a post 404.\n */\n handleRscFormPost?(\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 slotOverrides: Record<string, unknown>,\n nonce: string | undefined,\n pageKey: string,\n bootstrap: boolean,\n formData: FormData,\n ): Promise<{ htmlStream: ReadableStream }>;\n /**\n * Finish a shell frozen at build time, against data that exists now.\n *\n * Emits only the boundaries the shell left unfinished, meant to be written\n * straight after it. Optional so a host can be pointed at an engine built\n * before resuming existed; without it a shell has no way to be completed and\n * the page is rendered whole instead.\n */\n handleRscResume?(\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 slotOverrides?: Record<string, unknown>,\n postponed?: unknown,\n nonce?: string,\n pageKey?: string,\n pathname?: string | null,\n ): Promise<{ htmlStream: ReadableStream }>;\n handleRscRevalidate?(\n target: string,\n page: unknown,\n ): Promise<{ rscPayload: string }>;\n /**\n * The page's metadata for these params, merged with its layouts'. Used to\n * put the real title into a shell stored for a whole pattern, whose build\n * could not know the url.\n */\n resolveMetadata?(\n component: string,\n props?: Record<string, unknown>,\n layouts?: { component: string; props: Record<string, unknown> }[],\n ): Promise<Record<string, unknown> | null>;\n /**\n * Run a route's middleware without rendering anything.\n *\n * For a frozen page: the host reads it from disk and the engine never sees\n * the request, so the check has to be asked for separately.\n */\n runRouteMiddleware?(\n component: string,\n props: Record<string, unknown>,\n ): Promise<void>;\n handleAction(\n actionId: string,\n body: Uint8Array | string | FormData,\n contentType?: string,\n page?: unknown,\n takeRevalidated?: () => string[],\n ): Promise<{ stream: ReadableStream }>;\n /**\n * Answer one read declared with `query()`, or null if that id is not one.\n *\n * Optional so a host can be pointed at a bundle built before queries existed;\n * without it the endpoint 404s rather than throwing, which is what a client\n * built against the same old bundle expects anyway.\n */\n handleQuery?(\n id: string,\n args: string,\n report?: (error: unknown) => string,\n ): Promise<\n | { stream: ReadableStream; cacheControl: string }\n | { status: number; message: string; errors?: Record<string, string[]> }\n | null\n >;\n /**\n * Answer a `route.ts` — an api endpoint rather than a page.\n *\n * Optional so a host can be pointed at a bundle built before these existed;\n * without it the url falls through to page routing, which is what that\n * bundle would have done anyway.\n */\n handleApiRoute?(\n name: string,\n request: Request,\n params: Record<string, string>,\n allow: string,\n ): Promise<Response>;\n}\n\nexport interface RscHostOptions {\n /** The built server bundle — `import * as engine from './build/rsc/index.js'`. */\n engine: RscEngine;\n /**\n * The route table. Defaults to the one the bundle was built with, which is\n * almost always what you want — a manifest passed separately can go stale\n * against the bundle it is describing.\n */\n manifest?: RouteManifest;\n /**\n * Functions the app's server components call as `await rpc('name', ...args)`.\n *\n * In the Laravel host this crosses a socket into PHP. Here they are just\n * functions, which is the whole reason a JS host is smaller.\n */\n rpc?: Record<string, (...args: unknown[]) => unknown>;\n /**\n * Where a host call goes when this process cannot answer it.\n *\n * `rpc` is checked first, so a host can answer some calls in JS and leave\n * the rest to a backend. `httpHostCalls` in `@rsc-kit/core/host-calls`\n * builds one of these over an ordinary POST, which is how a host written in\n * another language answers without implementing the socket framing.\n */\n hostCalls?: (name: string, ...args: unknown[]) => Promise<unknown>;\n /**\n * Props for a page, given whatever its url bound.\n *\n * Defaults to the url params alone. A host that loads a user, reads a\n * session or resolves a tenant does it here — this is the one place the\n * engine cannot supply anything for.\n */\n props?: (\n match: MatchedRoute,\n request: Request,\n ) => Record<string, unknown> | Promise<Record<string, unknown>>;\n /**\n * Reads what the prerenderer wrote, if this build has any.\n *\n * A function rather than a directory, because not every host has a\n * filesystem: on an edge runtime these live in a KV store or a static-asset\n * binding. `prerenderedFrom` in `@rsc-kit/core/files` is the one for a disk.\n *\n * Checked before rendering, and anything it cannot find falls through to\n * being rendered now — so a partial prerender is a valid state, not a\n * broken one.\n */\n prerendered?: (name: string) => Promise<string | null> | string | null;\n /** Serve a built browser asset. Return null for anything not found. */\n assets?: (\n pathname: string,\n request: Request,\n ) => Promise<Response | null> | Response | null;\n /**\n * Identifies this build to the client, which says it back on every\n * navigation and is sent to load the document when it differs. For an\n * engine with no `buildId` of its own; the generated one has, and every\n * document it renders says that id, so a version named here would\n * disagree with what the client was told and refuse every navigation.\n */\n version?: string;\n /**\n * The most an action body may be, in bytes. 8 MB unless said otherwise.\n *\n * Everything an action receives arrives in one body - arguments, and the\n * files a form uploads - and it is read whole before the action runs. With\n * no ceiling a single request could ask this process to hold as much as a\n * caller cares to send. Above the ceiling the answer is 413, before a byte\n * of the body is kept. Raise it for an app that uploads larger files\n * through actions; a proxy in front usually has its own limit too.\n */\n maxActionBody?: number;\n /**\n * gzip what this host answers, for a request that accepts it.\n *\n * On by default where the runtime has a compressor - Node and Bun - and\n * never on a Worker, where the platform compresses. Behind a CDN or a\n * proxy that compresses, the proxy sees an already-encoded answer and\n * leaves it; a bun or node server answering the internet by itself sent\n * every byte raw, which was a port's whole mobile performance story. Off\n * for a deployment that would rather its proxy did it.\n */\n compress?: boolean;\n}\n\n/**\n * The answer to a redirect that was decided before anything was written.\n *\n * A document gets a real status code. A payload request must NOT: `fetch`\n * follows a 3xx transparently, so the client would receive the destination's\n * HTML and hand it to the Flight decoder, which reports its own confusion\n * rather than the redirect. It gets 204 and a header instead, and navigates\n * itself — which is also what makes the redirect an SPA one.\n */\n/**\n * A string safe to write inside a <script> element.\n *\n * `JSON.stringify` escapes for JavaScript, and this is not a JavaScript\n * context — it is HTML that happens to contain JavaScript. The parser ends the\n * element at the first `</script`, wherever it appears, so a destination\n * carrying one closes the tag and whatever follows is markup the browser runs.\n *\n * That destination is routinely computed rather than written — redirect()\n * documents \"remembering where someone was going and sending them back to it\"\n * as the usual case, which is a query string or a cookie arriving verbatim\n * here. U+2028 and U+2029 are escaped too: legal in JSON, line terminators in\n * JavaScript.\n */\nfunction inScript(value: string): string {\n return JSON.stringify(value)\n .replace(/</g, \"\\\\u003c\")\n .replace(/\\u2028/g, \"\\\\u2028\")\n .replace(/\\u2029/g, \"\\\\u2029\");\n}\n\n/**\n * Whether the browser itself asked, for a document.\n *\n * Sec-Fetch-Mode is what every current browser sends and nothing else does;\n * the Accept fallback is for the ones that do not, and for a test's Request.\n * A payload request never counts, whatever it accepts.\n */\nfunction isNavigation(request: Request): boolean {\n if (request.headers.has(HEADER.rsc)) return false;\n\n const mode = request.headers.get(\"sec-fetch-mode\");\n\n if (mode) return mode === \"navigate\";\n\n return (request.headers.get(\"accept\") ?? \"\").includes(\"text/html\");\n}\n\nfunction redirectResponse(\n to: Redirection,\n isPayloadRequest: boolean,\n): Response {\n if (isPayloadRequest) {\n return new Response(null, {\n status: 204,\n headers: { [HEADER.redirect]: to.location, Vary: VARY_ON_RSC },\n });\n }\n\n return new Response(null, {\n status: to.status,\n headers: { Location: to.location, Vary: VARY_ON_RSC },\n });\n}\n\n/**\n * Append the redirect a render asked for after its shell had already gone out.\n *\n * The status line is spent by then, so the instruction travels in the body. A\n * script rather than waiting for hydration to notice the error digest: it runs\n * as the browser parses it, which is sooner, and it is the only path that\n * works at all for a route shipping no client runtime.\n *\n * Read on flush, because that is when the render has finished and a redirect\n * from inside a Suspense boundary is finally known.\n */\nfunction appendLateRedirect(\n stream: ReadableStream,\n taken: () => Redirection | null,\n): ReadableStream {\n // An engine that answered with a finished body rather than a stream has no\n // late window at all: the render was over before this was called, so the\n // caller's own check already saw everything there was to see.\n if (typeof stream?.getReader !== \"function\") return stream;\n\n const encoder = new TextEncoder();\n const reader = stream.getReader();\n\n // Read-and-re-emit rather than pipeThrough(new TransformStream(...)): a\n // TransformStream from a different realm than the stream it is piped into\n // is rejected outright, and a host embedded in a runtime that supplies its\n // own web streams is exactly that case.\n return new ReadableStream({\n async pull(controller) {\n const { done, value } = await reader.read();\n\n if (!done) {\n controller.enqueue(value);\n\n return;\n }\n\n const to = taken();\n\n // replace, so Back does not return to a url that redirected.\n if (to) {\n controller.enqueue(\n encoder.encode(\n `<script>location.replace(${inScript(to.location)})</script>`,\n ),\n );\n }\n\n controller.close();\n },\n cancel(reason) {\n return reader.cancel(reason);\n },\n });\n}\n\n/**\n * The status a refusal deserves, or null when this was not one.\n *\n * A host answers an unauthenticated call 401 and an unauthorized one 403, and\n * the transport raises each as its own error. Without this they arrive at the\n * render as ordinary failures and leave as 500s — which reads, to anyone\n * looking at a log or a browser, as the application being broken rather than\n * the visitor being turned away.\n */\nfunction refusalStatus(error: unknown): number | null {\n if (error instanceof ServerAuthenticationError) return 401;\n if (error instanceof ServerAuthorizationError) return 403;\n\n // Named rather than matched by identity, because the error may have been\n // raised by another copy of the module: an app's actions are bundled apart\n // from the engine, and instanceof is false across that seam.\n const name = (error as { name?: string } | null)?.name;\n\n if (name === \"ServerAuthenticationError\") return 401;\n if (name === \"ServerAuthorizationError\") return 403;\n\n // A status the host chose — a throttle's 429, a policy's 403 — carried on\n // the error by the transport. Bounded to refusals: a host answering 500\n // should not be able to make this look like a client's fault, and one\n // answering 200 should not turn a failed render into a success.\n const carried = (error as { refusalStatus?: unknown } | null)?.refusalStatus;\n\n if (typeof carried === \"number\" && carried >= 400 && carried <= 499)\n return carried;\n\n return null;\n}\n\nfunction refusalMessage(error: unknown): string {\n const message = (error as { message?: string } | null)?.message;\n\n return typeof message === \"string\" && message !== \"\" ? message : \"Refused.\";\n}\n\n/**\n * Whether a browser was told it could post this action.\n *\n * Defence in depth, not the only defence. An action already requires the\n * X-RSC-Action header, which makes a cross-origin post a non-simple request —\n * so the browser must preflight it, and nothing here answers a preflight. A\n * browser can be tricked into sending cookies; it cannot be tricked into\n * sending a header it does not know. This is the belt to that pair of braces,\n * and it is what Next does for server actions.\n *\n * Compared against X-Forwarded-Host first, because a proxied deployment is the\n * normal one: the backend forwards the name the visitor typed, while Host is\n * this process on loopback. Comparing against Host alone would reject every\n * legitimate action that arrived through a proxy — a check that only fires on\n * correct requests is worse than none.\n *\n * No Origin at all is allowed through. It is absent on same-origin requests in\n * some browsers and on anything that is not a browser, and refusing those would\n * break server-to-server callers to catch an attacker who is already blocked by\n * the preflight.\n */\nexport function actionOriginAllowed(request: Request, url: URL): boolean {\n const origin = request.headers.get(\"origin\");\n\n if (!origin) return true;\n\n const expected =\n request.headers.get(\"x-forwarded-host\") ??\n request.headers.get(\"host\") ??\n url.host;\n\n try {\n return new URL(origin).host === expected;\n } catch {\n // An Origin that is not a url is not one this can vouch for.\n return false;\n }\n}\n\nconst DEFAULT_MAX_ACTION_BODY = 8 * 1024 * 1024;\n\n/**\n * The body, read whole, or null once it has passed the ceiling.\n *\n * Content-Length is checked first because it is free, and the stream is\n * counted anyway because a body need not announce its size and a stated size\n * need not be true. Reading stops at the first byte over: what was held is\n * dropped, and the caller answers 413 rather than holding the rest.\n */\nasync function readBodyUpTo(\n request: Request,\n limit: number,\n): Promise<Uint8Array | null> {\n const declared = Number(request.headers.get(\"content-length\"));\n\n if (Number.isFinite(declared) && declared > limit) return null;\n if (!request.body) return new Uint8Array(0);\n\n const reader = request.body.getReader();\n const chunks: Uint8Array[] = [];\n let held = 0;\n\n for (;;) {\n const { done, value } = await reader.read();\n\n if (done) break;\n\n held += value.byteLength;\n\n if (held > limit) {\n await reader.cancel().catch(() => {});\n return null;\n }\n\n chunks.push(value);\n }\n\n const body = new Uint8Array(held);\n let at = 0;\n\n for (const chunk of chunks) {\n body.set(chunk, at);\n at += chunk.byteLength;\n }\n\n return body;\n}\n\n/**\n * The page a client says it was on, as a path this router can match - or\n * null. A header is a string anyone can send, and `new URL` throws on one\n * that is not a url; that must not become a 500 on the action endpoint.\n */\nfunction refererPath(\n referer: string | null,\n origin: string,\n hosts: readonly string[] = [],\n): string | null {\n if (!referer) return null;\n\n try {\n const parsed = new URL(referer, origin);\n\n // The page the action was invoked from is routed the way a request for\n // it would be: on a tenant host, the referer's host names the segment.\n return hostPath(parsed.host, parsed.pathname, hosts);\n } catch {\n return null;\n }\n}\n\n/**\n * How large a query url may be before it is refused.\n *\n * Matched to the client's own limit, and enforced here too because the limit is\n * what keeps an attacker from making this endpoint decode megabytes of\n * attacker-chosen payload per request.\n *\n * Module scope, not inside the handler: everything declared after the handler\n * is returned never initialises, and a `const` read from the closure then\n * throws on every request instead of being undefined.\n */\nconst MAX_QUERY = 8_000;\n\n/**\n * The host segment a routed url begins with, by url. Kept beside the url\n * rather than in it, so the pathname stays what a page and a stored file\n * are keyed by, and the matcher alone is told the leading part is the host's.\n */\nconst hostOf = new WeakMap<URL, string>();\n\nfunction matchPage(routes: RouteManifest, url: URL): MatchedRoute | null {\n return matchRoute(routes, url.pathname, hostOf.get(url) ?? null);\n}\n\nexport function createRscHandler(\n options: RscHostOptions,\n): (request: Request) => Promise<Response | null> {\n const { engine, assets } = options;\n // The build's own id, which is also what every document says it is - the\n // two must agree, or a client's honest claim is a 409 on every request.\n // A version named by the app applies only to an engine with no id of its\n // own. Resolved on the first request: the engine reads it from a build\n // product it only has at runtime.\n let version = engine.buildId ? undefined : options.version;\n const maxActionBody = options.maxActionBody ?? DEFAULT_MAX_ACTION_BODY;\n const compress = options.compress ?? true;\n // Annotated rather than inferred: the narrowing below is lost inside the\n // closures that use it, and every one of them runs after the throw.\n const manifest: RouteManifest | undefined =\n 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 in the bundle.\",\n );\n }\n\n const routes: RouteManifest = manifest;\n\n // Only when this host has functions of its own. Installing unconditionally\n // overwrites whatever was already registered — a prerenderer sharing the\n // same engine instance, or a host that set its own up first — and the\n // symptom is every call failing as unregistered.\n if (options.rpc || options.hostCalls)\n installHostFunctions(options.rpc ?? {}, options.hostCalls);\n\n function installHostFunctions(\n fns: NonNullable<RscHostOptions[\"rpc\"]>,\n remote: RscHostOptions[\"hostCalls\"],\n ): void {\n engine.installHostFn(async (name: string, ...args: unknown[]) => {\n const fn = fns[name];\n\n if (fn) return await fn(...args);\n\n // A remote transport cannot enumerate what the backend registered, so\n // an unknown name is the backend's to reject — with a message naming the\n // function, which is more than this side could say.\n if (remote) return await remote(name, ...args);\n\n // Louder than returning null: a typo in a server component otherwise\n // renders as missing data with nothing anywhere saying why.\n throw new Error(\n `No host function named ${JSON.stringify(name)}. Registered: ${Object.keys(fns).join(\", \") || \"(none)\"}`,\n );\n });\n }\n\n async function propsFor(\n match: MatchedRoute,\n request: Request,\n ): Promise<Record<string, unknown>> {\n return options.props ? await options.props(match, request) : match.params;\n }\n\n /** The page a server action was invoked from, so it can re-render regions of it. */\n /** Whether a document at this url is served from the route's pattern shell: no page or shell of its own, and one for the pattern. */\n async function servedFromPatternShell(url: URL, match: MatchedRoute): Promise<boolean> {\n const source = options.prerendered;\n\n if (!source) return false;\n\n const key = pathKey(url.pathname);\n\n if ((await source(`${key}.html`)) !== null) return false;\n if ((await source(`${key}.ppr.html`)) !== null) return false;\n\n return (await source(`${patternKey(match.route)}.ppr.html`)) !== null;\n }\n\n function pageContext(match: MatchedRoute, props: Record<string, unknown>, url?: string) {\n return {\n component: match.route.component,\n props,\n url,\n layouts: match.route.layouts.map((component) => ({\n component,\n props: {},\n })),\n loadings: match.route.loadings,\n parallelSlots: match.route.slots,\n // What may be named in X-RSC-Revalidate — see renderRevalidated.\n sections: match.route.sections,\n };\n }\n\n function withVersion(\n headers: Record<string, string>,\n ): Record<string, string> {\n return version ? { ...headers, [HEADER.version]: version } : headers;\n }\n\n // A build made for export ships a client that asks for payloads by url,\n // because a static host cannot read a header. Serving that build from a\n // server is a reasonable thing to do — previewing an export, or one build\n // used both ways — and without this every navigation 404s in the console\n // while the page itself looks fine.\n const payloadName = manifest.build?.payloadName || \"\";\n /** The site's own hosts; any other host is routed with its segment in front of the path. */\n const siteHosts = manifest.build?.hosts ?? [];\n /** Whether responses say what built them. How they were served is always said. */\n const identify = Boolean(manifest.build?.identify);\n /** How a response was answered, for X-RSC-Kit: a file the build wrote, or a shell of one. */\n const servedFrom = new WeakMap<Response, \"stored\" | \"shell\">();\n /** What a stored document's head names, read once per file, for the Link header. */\n const hinted = new WeakMap<Response, CriticalAssets>();\n const hintsByKey = new Map<string, CriticalAssets>();\n const EMPTY_ASSETS: CriticalAssets = { styles: [], modules: [], fonts: [] };\n\n /**\n * The page a payload url belongs to, if this is one.\n *\n * Both the whole-document name and the depth variants beside it: a client\n * built for export asks for index.seg1.rsc when it already holds a layout,\n * and matching only the plain name leaves that as a 404 no page reports.\n */\n const payloadNames = new RegExp(\n \"/\" +\n payloadName\n .replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")\n .replace(/^index\\\\\\./, \"index(\\\\.seg\\\\d+)?\\\\.\") +\n \"$\",\n );\n\n function pageForPayload(pathname: string): string | null {\n if (payloadName === \"\") return null;\n\n const match = payloadNames.exec(pathname);\n\n if (!match) return null;\n\n return pathname.slice(0, match.index) || \"/\";\n }\n\n // One memo table per request, opened at the outermost point so that\n // everything below shares it: middleware, layouts, the page, and an action. A\n // guard that reads the session and a layout that reads it again are one\n // query, not two.\n /**\n * The fields of a form posted to a page, or null for anything else.\n *\n * A POST with a form body, from this origin, to a url that is a page and\n * not the action endpoint, with an engine that can run what the form\n * names. Read here so the decision is made once; the action reads the\n * same fields from what is returned.\n */\n async function formPostOf(request: Request, url: URL): Promise<FormData | null> {\n if (request.method !== \"POST\" || !engine.handleRscFormPost) return null;\n if (request.headers.has(HEADER.rsc)) return null;\n\n const type = request.headers.get(\"content-type\") ?? \"\";\n\n if (!/^(?:application\\/x-www-form-urlencoded|multipart\\/form-data)/i.test(type)) return null;\n if (!matchPage(routes, url)) return null;\n if (!actionOriginAllowed(request, url)) return null;\n\n try {\n return await request.formData();\n } catch {\n return null;\n }\n }\n\n /**\n * What a stored answer's compressed bytes are kept under.\n *\n * The build, the url, and the value of every request header the answer\n * says it varies on - which is what tells the document for /login apart\n * from the payload for /login. Keyed by the path alone, the payload\n * request found the document's bytes waiting and hydration decoded HTML\n * as Flight, silently, on every stored page in production.\n */\n function storedKey(request: Request, response: Response): string {\n const url = new URL(request.url);\n const varies = (response.headers.get(\"Vary\") ?? \"\")\n .split(\",\")\n .map((name) => name.trim().toLowerCase())\n .filter((name) => name && name !== \"*\" && name !== \"accept-encoding\")\n .sort()\n .map((name) => `${name}=${request.headers.get(name) ?? \"\"}`);\n\n return [version ?? \"\", url.pathname + url.search, ...varies].join(\"\\n\");\n }\n\n return async function handle(request: Request): Promise<Response | null> {\n if (version === undefined && engine.buildId) version = await engine.buildId();\n\n return await withRequest(request, () =>\n withCache(() =>\n // Open for the whole request and sealed the moment an answer exists,\n // so middleware — which runs before any rendering — can put headers on\n // it, and a component, which runs after, is told why it cannot.\n withResponseDraft(async ({ taken, seal }) => {\n const response = await route(request);\n\n seal();\n\n if (!response) return null;\n\n const collected = taken();\n\n collected.forEach((value, name) => {\n // Set-Cookie is applied below, once per cookie: iterating a Headers\n // gives it joined in some runtimes and per-cookie in others, and a\n // joined one is a single malformed cookie the browser discards.\n if (name.toLowerCase() === \"set-cookie\") return;\n\n // set, not append: a middleware asking for a header means that\n // value, not that value added to whatever the host already chose.\n response.headers.set(name, value);\n });\n\n // Appended, because several cookies are several headers.\n for (const cookie of collected.getSetCookie()) {\n response.headers.append(\"Set-Cookie\", cookie);\n }\n\n // How this answer was served - the header a developer reads in the\n // Network tab, the way X-Nextjs-Cache is. Always: it names no\n // product, and a CDN rule or a check can key on it.\n response.headers.set(\"X-RSC-Kit\", servedFrom.get(response) ?? \"rendered\");\n\n // What the document needs first, as a Link header: a CDN sends it\n // ahead as 103 Early Hints, and the stylesheet, the entry and the\n // fonts download while the HTML is still being written. Every\n // document, stored ones included - a stored document's own head\n // names its fonts; a rendered one's is not known until too late.\n if (response.status === 200 && (response.headers.get(\"Content-Type\") ?? \"\").startsWith(\"text/html\")) {\n const link = linkHeader(mergeAssets(hinted.get(response) ?? EMPTY_ASSETS, engine.criticalAssets?.() ?? null));\n\n if (link) response.headers.set(\"Link\", link);\n }\n\n // What built it. The name only, never the version - a version in\n // every response is what a vulnerability scanner filters on - and\n // off for a team whose policy strips every framework identifier.\n if (identify) response.headers.set(\"X-Powered-By\", \"rsc-kit\");\n\n // Work after() queued, now that the answer exists. A Worker keeps\n // the isolate alive only for what is handed to waitUntil - Nitro's\n // Cloudflare preset puts the execution context on the request - so\n // it goes there where it can; a process keeps a detached promise.\n const pending = takeAfterWork();\n\n if (pending) {\n const context = (request as Request & { context?: { waitUntil?: (p: Promise<unknown>) => void } }).context;\n\n if (typeof context?.waitUntil === \"function\") context.waitUntil(pending);\n }\n\n // Last, over the finished answer, headers and all. A stored answer\n // is the same bytes for everyone and is compressed once, keyed by\n // the build and the url it was stored for.\n if (compress) {\n const answer = await compressed(\n request,\n response,\n servedFrom.get(response) === \"stored\" ? storedKey(request, response) : undefined,\n );\n\n const from = servedFrom.get(response);\n\n if (answer !== response && from) servedFrom.set(answer, from);\n\n return answer;\n }\n\n return response;\n }),\n ),\n );\n };\n\n async function route(request: Request): Promise<Response | null> {\n let url = new URL(request.url);\n\n // A host other than the site's own is matched with its segment in front\n // of the path, once, here: everything below - the api match, the page\n // match, the stored answer, the payload - sees that path and nothing\n // else knows a host was involved. The visitor's url is untouched.\n // Compared against X-Forwarded-Host first, for the same reason the\n // action's origin check is: a proxied deployment is the common one.\n // Only when a route can begin with that segment - a [domain] directory or\n // one named for the host - so an app with a metadataBase and no tenant\n // tree routes every host by path, and a proxy forwarding by an internal\n // name is not read as a tenant.\n if (siteHosts.length > 0) {\n const host =\n request.headers.get(\"x-forwarded-host\") ??\n request.headers.get(\"host\") ??\n url.host;\n const segment = hostSegment(host, siteHosts);\n\n if (segment !== null && routableHost(segment, routes.routes)) {\n url = new URL(\n hostPath(host, url.pathname, siteHosts) + url.search,\n url.origin,\n );\n hostOf.set(url, segment);\n }\n }\n\n const asPayload = pageForPayload(url.pathname);\n\n if (asPayload !== null) {\n // Rewritten to the page it is asking about, with the header the rest of\n // this handler reads — one path through, however the client asked.\n const host = hostOf.get(url);\n\n url = new URL(asPayload + url.search, url.origin);\n if (host !== undefined) hostOf.set(url, host);\n const headers = new Headers(request.headers);\n\n headers.set(HEADER.rsc, \"1\");\n request = new Request(url, { method: request.method, headers });\n }\n\n if (assets) {\n const asset = await assets(url.pathname, request);\n\n if (asset) return asset;\n }\n\n if (request.method === \"POST\" && url.pathname === HEADER.actionPath) {\n if (!actionOriginAllowed(request, url)) {\n return new Response(\"Cross-origin action\", { status: 403 });\n }\n\n return await handleAction(request, url);\n }\n\n // Api routes first. A url is one or the other, and a page that shares a\n // path with a route.ts would otherwise win by accident of ordering.\n const api = matchApiRoute(routes, url.pathname);\n\n if (api && engine.handleApiRoute) {\n // The guards above it run first, exactly as they would for a page in the\n // same directory. A route.ts is colocated with the pages it belongs\n // with, so adding one under a guarded path must not open a way around\n // the guard.\n const refused = await refuseApiUnlessAllowed(request, api);\n\n if (refused) return refused;\n\n const stored = await frozenApi(request, url, api);\n\n if (stored) return stored;\n\n // A redirect() thrown from the handler is the route's answer, not a\n // fault: a real Location, because whoever asked is meant to go there\n // - a browser that followed a link to this route, or a fetch of an\n // export that lives on a signed url. notFound() is its 404.\n return await withRedirect(async (taken) => {\n try {\n return await engine.handleApiRoute!(\n api.route.name,\n request,\n api.params,\n allowFor(api.route),\n );\n } catch (error) {\n const redirected = taken();\n\n if (redirected) return redirectResponse(redirected, false);\n if (currentNotFound()) return new Response(\"Not found\", { status: 404 });\n\n throw error;\n }\n });\n }\n\n if (request.method === \"GET\" && url.pathname === HEADER.queryPath) {\n // Same check as an action, for a smaller reason: a cross-origin page\n // cannot read this answer — CORS sees to that — but it can still cause\n // the read to run with the visitor's cookies. A query is side-effect\n // free by contract, so this is depth rather than the only defence.\n if (!actionOriginAllowed(request, url)) {\n return new Response(\"Cross-origin query\", { status: 403 });\n }\n\n return await handleQuery(request, url);\n }\n\n // The two halves an edge cache needs: hand it a shell it may keep, and\n // finish that shell for a visitor it cannot answer for itself.\n if (options.prerendered && url.pathname === HEADER.pprShellPath) {\n return await servePprShell(request, url, options.prerendered);\n }\n\n if (\n request.method === \"POST\" &&\n options.prerendered &&\n url.pathname === HEADER.pprResumePath\n ) {\n return await servePprResume(request, url, options.prerendered);\n }\n\n // A form submitted before the page had a runtime: the browser posts it\n // to the page's own url, as React wrote it, with the action's id among\n // the fields. The action runs and the page renders with the result -\n // what the guide promises for a form that had to work without\n // javascript. Same-origin, as an action is; anything else that is not\n // a read is not this host's.\n const formPost = await formPostOf(request, url);\n\n if (!formPost && request.method !== \"GET\" && request.method !== \"HEAD\") return null;\n\n // A client saying which build it runs, and it is not this one: its\n // manifest cannot load what this build's payload names - a client\n // component added since is \"client reference not found\" and the route's\n // error boundary, on a page that worked a click ago. Under a service\n // worker that serves the last build's document first, that is every\n // returning visitor's first navigation after a deploy, not an open tab.\n // A 409 sends the client to load the document instead, from this build.\n const claimed = request.headers.get(HEADER.version);\n\n if (claimed !== null && claimed !== \"\" && version && claimed !== version && request.headers.get(HEADER.rsc) !== null) {\n return new Response(null, {\n status: 409,\n headers: withVersion({ \"X-RSC-Location\": url.pathname + url.search, \"Cache-Control\": \"no-store\" }),\n });\n }\n\n // One named region of this page, asked for without mutating anything to\n // earn it. What an action invalidated does not come through here — that\n // travels back inside the action's own answer, which is the whole point of\n // marking rather than telling the client to go and ask.\n const revalidating = request.headers.get(HEADER.revalidate);\n\n if (revalidating !== null && request.headers.get(HEADER.rsc) !== null) {\n return await handleRevalidate(request, url, revalidating);\n }\n\n // An intercepted navigation renders the page you are already on, with the\n // interceptor dropped into one of its slots — so the modal opens over it\n // and the url changes. Only ever on a client navigation: a hard load has\n // no referer to open over and gets the real page.\n const interceptSlot = request.headers.get(HEADER.intercept);\n\n if (interceptSlot !== null && request.headers.get(HEADER.rsc) !== null) {\n return await handleIntercept(request, url, interceptSlot);\n }\n\n // Only now. A frozen page is a whole page, and both requests above ask for\n // something smaller than one: answering a named region with the whole\n // document puts the entire page inside that region, and answering an\n // interception with it replaces the page the modal was opening over.\n const match = matchPage(routes, url);\n\n if (options.prerendered && !formPost) {\n // A guarded route can still be frozen: whether the content is the same\n // for everyone, and whether this caller may see it, are different\n // questions. The build answers the first; this answers the second, and\n // only then is the frozen page handed over.\n const refusal = await refuseUnlessAllowed(request, match);\n\n if (refusal) return refusal;\n\n const frozen = await servePrerendered(request, url, options.prerendered);\n\n // A whole page from a file, or a shell of one with the holes rendered\n // now: the header says which. servePrerendered marks the shell.\n if (frozen && !servedFrom.has(frozen)) servedFrom.set(frozen, \"stored\");\n\n if (frozen) return frozen;\n }\n\n if (!match) return null;\n\n const props = await propsFor(match, request);\n const layouts = match.route.layouts.map((component) => ({\n component,\n props: {},\n }));\n const chain = match.route.layouts;\n\n // A payload request says so with a header on the page's own url, so one\n // route serves both the document and the navigation that follows it.\n if (request.headers.get(HEADER.rsc) === null) {\n // Scoped to this render, so two requests redirecting at once cannot read\n // each other's destination.\n return await withRedirect(async (taken) => {\n // Awaited, and that await is the whole design: React resolves this\n // when the SHELL is ready, so a redirect thrown above every Suspense\n // boundary rejects here — before a byte is written, with a status line\n // still available. Nothing is buffered to make that true.\n let htmlStream: ReadableStream;\n\n try {\n ({ htmlStream } = formPost\n ? await engine.handleRscFormPost!(\n match.route.component,\n props,\n layouts,\n match.route.loadings,\n match.route.slots,\n {},\n undefined,\n url.pathname,\n true,\n formPost,\n )\n : await engine.handleRscHtmlStream(\n match.route.component,\n props,\n layouts,\n match.route.loadings,\n match.route.slots,\n {},\n undefined,\n url.pathname,\n // A route that ships no runtime gets no bootstrap and no segment\n // boundary — the boundary is itself a client component, so leaving\n // it in means no page could ever be JS-free.\n true,\n ));\n } catch (error) {\n // A rejected shell is how a redirect above every boundary arrives:\n // React could not finish the shell, because the component that would\n // have produced it left instead.\n //\n // The scope decides, not the error. React catches what a component\n // threw and re-raises its own — whose message is stripped in\n // production — so testing the caught value for a redirect signal\n // fails exactly where it matters, and the answer is a 500 with the\n // destination sitting in a scope nobody read.\n const refused = taken();\n\n if (refused) return redirectResponse(refused, false);\n\n // The page said this url names nothing. Null rather than a rendered\n // 404: null is already how this host says \"not mine\", and the caller\n // in front answers it with not-found.tsx and the right status. One\n // path, so a page that calls notFound() and a url that matched no\n // route are indistinguishable to whoever is asking — which is the\n // point of a 404.\n if (currentNotFound()) return null;\n\n // A guard refusing is not a failed render. Without this a visitor\n // who may not see the page gets a 500, which reads as the\n // application being broken rather than them being turned away —\n // and a host middleware refusal arrives exactly here, because the\n // engine asks before it renders anything.\n const status = refusalStatus(error);\n\n if (status) return new Response(refusalMessage(error), { status });\n throw error;\n }\n\n const early = taken();\n\n if (early) return redirectResponse(early, false);\n\n // Above every boundary, so the shell resolving means the page did not\n // refuse itself. Deeper than that and the shell is already on the wire\n // — the digest carries it to the boundary instead, and the status\n // stays 200 because the status line has gone.\n if (currentNotFound()) return null;\n\n return new Response(appendLateRedirect(htmlStream, taken), {\n headers: withVersion({\n \"Content-Type\": HTML_TYPE,\n [HEADER.layouts]: chain.join(\",\"),\n Vary: VARY_ON_RSC,\n // The answer to a post is the result of something that happened\n // once; nothing may keep it.\n \"Cache-Control\": formPost\n ? \"no-store\"\n : match.route.middleware?.length\n ? PER_CLIENT\n : REVALIDATE,\n }),\n });\n });\n }\n\n const from = sharedDepth(request.headers.get(HEADER.segments), chain);\n\n // A boot - X-RSC and no segments - of a document served from a pattern\n // shell: the shell was rendered for no url, and the client hydrates\n // this payload against it, so the hooks are told nothing here either\n // and read the browser's url once hydration is done. A navigation to\n // the same url renders for it, as it is client-rendered, not hydrated.\n const boot = request.headers.get(HEADER.segments) === null;\n const pathname =\n boot && (await servedFromPatternShell(url, match)) ? null : url.pathname;\n\n // Proposed by the host, decided by the engine: an interceptor can force a\n // wider render than the client asked for, so what goes back is the depth\n // that came out, never the one that went in.\n return await withRedirect(async (taken) => {\n let stream: ReadableStream;\n let segmentDepth: number;\n\n try {\n ({ stream, segmentDepth } = await engine.handleRscStream(\n match.route.component,\n props,\n layouts,\n match.route.loadings,\n match.route.slots,\n {},\n from,\n url.pathname,\n pathname,\n ));\n } catch (error) {\n // Same reasoning as the document path: what the render recorded is\n // reliable, what React re-raised is not.\n const refused = taken();\n\n if (refused) return redirectResponse(refused, true);\n\n // Same answer the document path gives, so a client navigating to a\n // url and a browser loading it fresh agree about whether it exists.\n if (currentNotFound()) return null;\n\n // A payload request is guarded exactly as the document is. Narrowing\n // a request must never narrow what is checked.\n const status = refusalStatus(error);\n\n if (status) return new Response(refusalMessage(error), { status });\n throw error;\n }\n\n const early = taken();\n\n // 204 and a header. A payload request that redirected later than this\n // carries the destination in the error digest instead, and the client's\n // RedirectBoundary performs it.\n if (early) return redirectResponse(early, true);\n\n return new Response(stream, {\n headers: withVersion({\n \"Content-Type\": FLIGHT_TYPE,\n [HEADER.segmentDepth]: String(segmentDepth),\n [HEADER.layouts]: chain.join(\",\"),\n Vary: VARY_ON_RSC,\n \"Cache-Control\": PER_CLIENT,\n }),\n });\n });\n }\n\n /**\n * A page rendered at build time, if there is one for this url.\n *\n * The payload has to match the depth the client shares, not simply exist.\n * Serving the whole document to a client that already holds the layouts\n * replaces the root — and replacing the root unmounts everything retained\n * behind it, so going back stops restoring what you had.\n */\n /**\n * The shell an edge cache may hold, for a route named by `?url=`.\n *\n * Only ever a build artifact, so there is nothing here that belongs to\n * whoever asked. What it deliberately does NOT return is the postponed\n * state. Next's protocol hands that to the CDN and takes it back on the\n * resume, which makes the resume endpoint parse a blob an attacker can write\n * — the shape of a known denial-of-service against it. Our origin has the\n * file already, so the state never needs to leave.\n *\n * A guarded route is refused outright rather than guarded here. Its shell is\n * not cacheable by a shared cache at all, so handing one to an edge that\n * exists to cache things is an invitation to a mistake nobody would see.\n */\n /**\n * The answer the build stored for this route, if it stored one.\n *\n * Three conditions, each closing a way the stored answer could be wrong:\n *\n * GET or HEAD, because a stored answer to a POST is a stored answer to\n * something that was meant to happen once.\n *\n * No query string. The build answered the bare url, and a route that reads\n * the query would answer differently for every one — so rather than trying\n * to detect that during the probe, anything carrying a query goes to the\n * route itself. A stored answer is for the url it was stored for.\n *\n * No middleware. A guarded route answers differently depending on who is\n * asking, which is the point of the guard; one stored answer served to\n * everyone is how a guard is quietly removed. The build refuses to store one\n * for the same reason, so this is the second of two locks on the same door.\n */\n async function frozenApi(\n request: Request,\n url: URL,\n api: MatchedApiRoute,\n ): Promise<Response | null> {\n if (!options.prerendered) return null;\n if (request.method !== \"GET\" && request.method !== \"HEAD\") return null;\n if (api.route.middleware.length > 0) return null;\n\n const stored = await options.prerendered(apiKey(url.pathname));\n\n if (stored === null) return null;\n\n let frozen: FrozenApiResponse;\n\n try {\n frozen = JSON.parse(stored) as FrozenApiResponse;\n } catch {\n // A file this host wrote and cannot read back is a bug, not a request\n // to answer badly. Falling through runs the route, which is correct.\n return null;\n }\n\n // The build said whether this route's answer depends on the query. A route\n // that never awaited searchParams gives the same answer whatever is on the\n // end of the url — which matters more than it sounds, because every\n // ?utm_source= and ?fbclid= would otherwise miss the stored answer.\n //\n // Defaulting to varying when the field is absent: a file written by an\n // older build did not record this, and serving it for every query would be\n // guessing on the unsafe side.\n if (url.search && frozen.varies !== false) return null;\n\n const answer = new Response(request.method === \"HEAD\" ? null : frozen.body, {\n status: frozen.status,\n headers: withVersion(Object.fromEntries(frozen.headers)),\n });\n\n servedFrom.set(answer, \"stored\");\n\n return answer;\n }\n\n async function servePprShell(\n request: Request,\n url: URL,\n read: NonNullable<RscHostOptions[\"prerendered\"]>,\n ): Promise<Response | null> {\n if (request.method !== \"GET\" && request.method !== \"HEAD\") return null;\n\n const target = url.searchParams.get(\"url\");\n\n if (!target || !target.startsWith(\"/\")) {\n return new Response(\"A url is required\", { status: 400 });\n }\n\n // Matched from the url asked for, never from anything else the caller sent.\n const route = matchRoute(routes, new URL(target, url.origin).pathname);\n\n if (!route) return new Response(\"No such page\", { status: 404 });\n\n if (route.route.middleware?.length) {\n return new Response(\"This route is not edge-cacheable\", { status: 404 });\n }\n\n const key = pathKey(new URL(target, url.origin).pathname);\n const shell =\n (await read(`${key}.ppr.html`)) ??\n (await read(`${patternKey(route.route)}.ppr.html`));\n\n if (shell === null)\n return new Response(\"No shell for this page\", { status: 404 });\n\n return new Response(JSON.stringify({ shell, version: version ?? null }), {\n headers: withVersion({\n \"Content-Type\": \"application/json\",\n // Deliberately NOT the REVALIDATE the rest of the host sends. That is\n // `max-age=0, must-revalidate`, which a cache honours by treating the\n // entry as stale the moment it arrives — an edge would store this and\n // never once serve it, so the whole thing would quietly do nothing\n // while looking like it worked, because the miss path serves correct\n // pages.\n //\n // This is build output with nothing of the caller in it, and a guarded\n // route never reaches here at all, so it is genuinely cacheable. An\n // hour bounds how long a deploy can be served against a stale shell;\n // the version below catches it sooner than that.\n \"Cache-Control\": \"public, max-age=3600\",\n }),\n });\n }\n\n /**\n * Finish a shell for the visitor this request belongs to.\n *\n * The whole security question lives here, because the holes are the part a\n * guard exists to protect — the shell is chrome, and everything private is\n * behind the boundaries this fills in. So it runs exactly the guard chain the\n * page itself would, derived from the url and nothing else, against the\n * cookies and headers the caller actually sent.\n *\n * Which means an edge worker must forward the visitor's request, not make one\n * of its own. A resume asked for with no cookies is an anonymous visitor and\n * gets an anonymous answer.\n */\n async function servePprResume(\n request: Request,\n url: URL,\n read: NonNullable<RscHostOptions[\"prerendered\"]>,\n ): Promise<Response | null> {\n const target = url.searchParams.get(\"url\");\n\n if (!target || !target.startsWith(\"/\")) {\n return new Response(\"A url is required\", { status: 400 });\n }\n\n const pathname = new URL(target, url.origin).pathname;\n const route = matchRoute(routes, pathname);\n\n if (!route) return new Response(\"No such page\", { status: 404 });\n\n // The same refusal the document would get, before a byte of the holes is\n // rendered. Nothing below runs for a caller this turns away.\n const refusal = await refuseUnlessAllowed(request, route);\n\n if (refusal) return refusal;\n\n if (!engine.handleRscResume) {\n return new Response(\"This engine cannot resume\", { status: 500 });\n }\n\n const key = pathKey(pathname);\n const pattern = patternKey(route.route);\n\n let shellKey: string | null = null;\n\n if ((await read(`${key}.ppr.html`)) !== null) shellKey = key;\n else if ((await read(`${pattern}.ppr.html`)) !== null) shellKey = pattern;\n\n // Read from our own artifacts. Never from the request body — that is the\n // difference between this and the protocol it is modelled on.\n const state =\n shellKey === null ? null : await read(`${shellKey}.postponed.json`);\n\n if (state === null)\n return new Response(\"Nothing to resume\", { status: 404 });\n\n const { htmlStream } = await engine.handleRscResume(\n route.route.component,\n route.params,\n route.route.layouts.map((component) => ({ component, props: {} })),\n route.route.loadings,\n route.route.slots,\n {},\n JSON.parse(state),\n undefined,\n shellKey === key ? pathname : \"\",\n pathname,\n );\n\n // Carries the build version so a caller holding a cached shell can tell\n // that it no longer belongs to this origin. A shell from an older build\n // does not make the resume fail — it replays against slots that have moved\n // and React falls back to client rendering, silently and for good. Nothing\n // else would ever report it.\n return new Response(htmlStream, {\n headers: withVersion({\n \"Content-Type\": HTML_TYPE,\n // Rendered for whoever asked. Never cacheable.\n \"Cache-Control\": PER_CLIENT,\n }),\n });\n }\n\n async function servePrerendered(\n request: Request,\n url: URL,\n source: NonNullable<RscHostOptions[\"prerendered\"]>,\n ): Promise<Response | null> {\n const key = pathKey(url.pathname);\n const read = async (name: string) => await source(name);\n\n // Before anything else: a route that only redirects was frozen as the\n // redirect itself, so there is no page under this url and never will be.\n const frozenRedirect = await read(`${key}.redirect.json`);\n\n if (frozenRedirect !== null) {\n const to = JSON.parse(frozenRedirect) as {\n status: number;\n location: string;\n };\n\n return redirectResponse(to, request.headers.get(HEADER.rsc) !== null);\n }\n\n if (request.headers.get(HEADER.rsc) === null) {\n // A frozen page first; then a shell, under this url or under the route's\n // pattern. Nothing in a shell varies by param, so one shell serves every\n // url its route matches — which is the only way a route whose urls were\n // never listed gets anything frozen at all.\n const route = matchPage(routes, url);\n const whole = await read(`${key}.html`);\n\n // A whole page is finished. Nothing to resume, nothing to render.\n if (whole !== null) {\n const response = new Response(whole, {\n headers: withVersion({\n \"Content-Type\": HTML_TYPE,\n Vary: VARY_ON_RSC,\n \"Cache-Control\": route?.route.middleware?.length\n ? PER_CLIENT\n : REVALIDATE,\n }),\n });\n\n // Its head is in hand, so its fonts are too. Read once per file.\n let found = hintsByKey.get(key);\n\n if (!found) {\n found = criticalAssetsOf(whole);\n hintsByKey.set(key, found);\n }\n\n hinted.set(response, found);\n\n return response;\n }\n\n // Then a shell, under this url or under the route's pattern. Which of the\n // two answered is tracked, because the state that resumes it sits beside\n // the file that was found rather than beside the url that was asked for.\n let shellKey: string | null = null;\n let shell = await read(`${key}.ppr.html`);\n\n if (shell !== null) {\n shellKey = key;\n } else if (route) {\n const pattern = patternKey(route.route);\n\n shell = await read(`${pattern}.ppr.html`);\n\n if (shell !== null) shellKey = pattern;\n }\n\n if (shell === null || shellKey === null) return null;\n\n const state = await read(`${shellKey}.postponed.json`);\n\n // A shell with no state cannot be finished by anyone. It was frozen with\n // its fallbacks showing and there is no record of what came next, so\n // serving it would be serving a page that stays on its loading state for\n // good. Fall through and render the page now instead.\n if (state === null || !engine.handleRscResume || !route) return null;\n\n const { htmlStream } = await engine.handleRscResume(\n route.route.component,\n route.params,\n // Empty props, because that is what the build passed. Resuming replays\n // the tree against the slots the shell left, and React matches those by\n // key — so an argument that differs from the frozen render at all is a\n // tree that \"doesn't match\", and every boundary falls back to the\n // client instead of being filled here.\n route.route.layouts.map((component) => ({ component, props: {} })),\n route.route.loadings,\n route.route.slots,\n {},\n JSON.parse(state),\n undefined,\n // A shell found under the route's pattern was frozen for no particular\n // url, so it was rendered with no page key. Handing one over now would\n // key the tree differently from the one being resumed.\n shellKey === key ? url.pathname : \"\",\n // But the url itself, for the hooks: the holes are rendered for it.\n url.pathname,\n );\n\n // A shell stored for the pattern was built without a url, so its title\n // is the layouts' - the page's generateMetadata reads the params and\n // was left out. This request has the params.\n const served =\n shellKey === key || !engine.resolveMetadata\n ? shell\n : withHead(\n shell,\n await engine\n .resolveMetadata(\n route.route.component,\n route.params,\n route.route.layouts.map((component) => ({ component, props: {} })),\n )\n .catch(() => null),\n );\n\n // The shell first, then whatever the resume writes. React's own script\n // travels with the resumed segments and moves them into place, so this is\n // a plain concatenation and the holes land without hydration.\n const body = new ReadableStream({\n async start(controller) {\n controller.enqueue(new TextEncoder().encode(served));\n\n const reader = htmlStream.getReader();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) break;\n\n controller.enqueue(value);\n }\n } finally {\n controller.close();\n }\n },\n });\n\n const withHoles = new Response(body, {\n headers: withVersion({\n \"Content-Type\": HTML_TYPE,\n Vary: VARY_ON_RSC,\n // The shell is cacheable; this response is not. It carries the holes,\n // which were rendered for whoever asked.\n \"Cache-Control\": PER_CLIENT,\n }),\n });\n\n servedFrom.set(withHoles, \"shell\");\n\n // The shell's head is the document's head; its fonts are known too.\n let found = hintsByKey.get(shellKey);\n\n if (!found) {\n found = criticalAssetsOf(shell);\n hintsByKey.set(shellKey, found);\n }\n\n hinted.set(withHoles, found);\n\n return withHoles;\n }\n\n // Only the document is ever served frozen for a shell. The payload is what\n // fills it in, and it has to be rendered now — answering with a frozen one\n // would hand back the same fallbacks the shell already shows, and the page\n // would never finish loading.\n\n const meta = await read(`${key}.meta.json`);\n\n // Both or neither: without the chain there is no way to know which depth a\n // payload is for, and guessing means handing the client a segment for a\n // boundary it does not have.\n if (meta === null) return null;\n\n const chain = (JSON.parse(meta).layouts ?? []) as string[];\n const shared = sharedDepth(request.headers.get(HEADER.segments), chain);\n\n // The variant for exactly this depth, or the whole document. Anything else\n // would be a payload for a boundary the client is not holding.\n const variant =\n shared > 0 ? await read(`${key}.seg${shared}.flight`) : null;\n const payload = variant ?? (await read(`${key}.flight`));\n\n if (payload === null) return null;\n\n // As cacheable as the document it boots: the same build-time bytes for\n // everyone, unless a guard above the route decides who may have them.\n // Marked no-store, the service worker refused to keep it, and a\n // precached page rendered offline and never hydrated - the markup was\n // there and the payload it boots from was not.\n const guarded = matchPage(routes, url)?.route.middleware?.length ?? 0;\n\n return new Response(payload, {\n headers: withVersion({\n \"Content-Type\": FLIGHT_TYPE,\n [HEADER.segmentDepth]: String(variant ? shared : 0),\n [HEADER.layouts]: chain.join(\",\"),\n Vary: VARY_ON_RSC,\n \"Cache-Control\": guarded ? PER_CLIENT : REVALIDATE,\n }),\n });\n }\n\n /**\n * The middleware of a route, or null to go ahead.\n *\n * Used wherever a render can be reached without the engine running the chain\n * itself: a page served from disk, and an interception, which renders a\n * component the route table did not choose.\n *\n * Asked before anything is read or rendered — the answer to a refusal must\n * not be a page that has already been fetched.\n */\n async function refuseUnlessAllowed(\n request: Request,\n match: MatchedRoute | null,\n ): Promise<Response | null> {\n // hostMiddleware as well as the engine's own. A page served from disk\n // never touches the engine, so a route guarded only by the host would be\n // handed over without anyone being asked — the guard would hold right up\n // until the build froze the page, then silently stop.\n if (!match) return null;\n\n const guarded =\n (match.route.middleware?.length ?? 0) > 0 ||\n (match.route.hostMiddleware?.length ?? 0) > 0;\n\n if (!guarded) return null;\n\n // A route that declares middleware and an engine that cannot run it is not\n // \"no middleware\" — it is a check that silently does not happen. Refusing\n // is the only safe reading, and it names the cause rather than serving the\n // guarded page. Reachable when a host runs a bundle built by an older\n // plugin, where the export did not exist.\n if (!engine.runRouteMiddleware) {\n return new Response(\n \"This route declares middleware, and the engine cannot run it. \" +\n \"Rebuild the app against the current @rsc-kit/core.\",\n { status: 500 },\n );\n }\n\n const asPayload = request.headers.get(HEADER.rsc) !== null;\n\n return await withRedirect(async (taken) => {\n try {\n await engine.runRouteMiddleware!(\n match.route.component,\n await propsFor(match, request),\n );\n } catch (error) {\n const refused = taken();\n\n if (refused) return redirectResponse(refused, asPayload);\n\n // A visitor who may not see this page has not caused a server\n // error. Answering 500 makes a guarded route indistinguishable from\n // a broken one, in the logs and to the person looking at it.\n const status = refusalStatus(error);\n\n if (status) return new Response(refusalMessage(error), { status });\n\n throw error;\n }\n\n const refused = taken();\n\n return refused ? redirectResponse(refused, asPayload) : null;\n });\n }\n\n async function handleRevalidate(\n request: Request,\n url: URL,\n target: string,\n ): Promise<Response> {\n if (!engine.handleRscRevalidate) {\n return new Response(\"This build cannot revalidate\", { status: 501 });\n }\n\n const match = matchPage(routes, url);\n\n if (!match) return new Response(\"No such page\", { status: 404 });\n\n // Scoped like the render paths: a guard above the target may refuse, and\n // that refusal is an answer rather than a failure.\n return await withRedirect(async (taken) => {\n let rscPayload: string;\n\n try {\n ({ rscPayload } = await engine.handleRscRevalidate!(\n target,\n pageContext(match, await propsFor(match, request)),\n ));\n } catch (error) {\n const refused = taken();\n\n if (refused) return redirectResponse(refused, true);\n\n throw error;\n }\n\n const refused = taken();\n\n if (refused) return redirectResponse(refused, true);\n\n return new Response(rscPayload, {\n headers: withVersion({\n \"Content-Type\": FLIGHT_TYPE,\n // Echoed so the client can tell which region it is holding.\n [HEADER.revalidate]: target,\n Vary: VARY_ON_RSC,\n \"Cache-Control\": \"private, no-store\",\n }),\n });\n });\n }\n\n async function handleIntercept(\n request: Request,\n url: URL,\n slot: string,\n ): Promise<Response> {\n const intercept = matchIntercept(routes, url.pathname, slot);\n\n if (!intercept)\n return new Response(\"No interceptor for this url\", { status: 404 });\n\n // The guards of the route being intercepted, before anything is rendered.\n //\n // An interceptor exists to show the same resource as the route it stands in\n // for — a modal over /orders/[id] shows that order. So it has to be behind\n // the same checks, and nothing else in this path runs them: the engine is\n // handed the interceptor component, which the route table did not choose\n // and whose middleware chain is keyed off manifest().routes, where an\n // interceptor does not appear.\n //\n // Derived from the url, never from X-RSC-Referer. The referer is a header\n // the caller writes, and guarding by it means the caller picks the guard.\n const intercepted = matchPage(routes, url);\n\n // Nothing to guard means nothing to serve. A url that matches an\n // interceptor but no route has no middleware chain to consult, so there is\n // no way to know whether this caller may see it — and an interceptor\n // stands in for a route, so a url with no route behind it is not a page\n // anyone was entitled to open a modal over.\n if (!intercepted) return new Response(\"No such page\", { status: 404 });\n\n const refusal = await refuseUnlessAllowed(request, intercepted);\n\n if (refusal) return refusal;\n\n const from = refererPath(\n request.headers.get(HEADER.referer),\n url.origin,\n siteHosts,\n );\n const under = from ? matchRoute(routes, from) : null;\n\n // Without a page to open over there is nothing to intercept: render the\n // interceptor on its own rather than answering with the wrong page.\n const component = under ? under.route.component : intercept.component;\n const props = under ? await propsFor(under, request) : intercept.params;\n const chain = under ? under.route.layouts : [];\n const slots = under ? under.route.slots : {};\n const loadings = under ? under.route.loadings : [];\n\n // The interceptor alone, when there is a page to open it over and this\n // build can render a region on its own.\n //\n // Re-rendering the page underneath would put the modal on screen at the\n // cost of rebuilding everything below the layout that declares the slot —\n // so opening a modal from a half-filled form throws the form away. The\n // page beneath is already mounted and correct; only the slot is new.\n if (under && engine.handleRscRevalidate) {\n const { rscPayload } = await engine.handleRscRevalidate(slot, {\n component: under.route.component,\n // The target's params, not the page's: a modal for /posts/hello opened\n // from /feed is about hello.\n props: intercept.params,\n layouts: [],\n loadings: [],\n // Named as the slot so the renderer finds it there, but pointing at\n // the interceptor rather than the default this route would otherwise\n // fill it with.\n parallelSlots: { [slot]: intercept.component },\n });\n\n return new Response(rscPayload, {\n headers: withVersion({\n \"Content-Type\": FLIGHT_TYPE,\n // Says what this payload is, so the client puts it in the slot\n // instead of treating it as a segment of the page.\n [HEADER.revalidate]: slot,\n Vary: VARY_ON_RSC,\n // Per-client by construction: which region this is was chosen by a\n // request header, so a shared cache has nothing useful to key on.\n \"Cache-Control\": \"private, no-store\",\n }),\n });\n }\n\n const { stream, segmentDepth } = await engine.handleRscStream(\n component,\n props,\n chain.map((layout) => ({ component: layout, props: {} })),\n loadings,\n slots,\n {},\n sharedDepth(request.headers.get(HEADER.segments), chain),\n retentionKey(url.pathname, slot),\n );\n\n return new Response(stream, {\n headers: withVersion({\n \"Content-Type\": FLIGHT_TYPE,\n [HEADER.segmentDepth]: String(segmentDepth),\n [HEADER.layouts]: chain.join(\",\"),\n Vary: VARY_ON_RSC,\n \"Cache-Control\": PER_CLIENT,\n }),\n });\n }\n\n /**\n * Run an api route's middleware, and answer instead of it if one refuses.\n *\n * Separate from the page version because the answer is different. A caller\n * that is not a browser gets a status rather than a redirect to a login page\n * it cannot render — a fetch would follow the 302 and hand back the login\n * HTML as though it were the api's answer.\n */\n async function refuseApiUnlessAllowed(\n request: Request,\n api: {\n route: { name: string; middleware?: string[] };\n params: Record<string, string>;\n },\n ): Promise<Response | null> {\n if (!(api.route.middleware?.length ?? 0)) return null;\n\n // A route that declares middleware and an engine that cannot run it is not\n // \"no middleware\" — it is a check that silently does not happen.\n if (!engine.runRouteMiddleware) {\n return new Response(\n \"This route declares middleware, and the engine cannot run it. \" +\n \"Rebuild the app against the current @rsc-kit/core.\",\n { status: 500 },\n );\n }\n\n return await withRedirect(async (taken) => {\n try {\n await engine.runRouteMiddleware!(api.route.name, api.params);\n } catch (error) {\n // A redirect is a refusal here. Where it was going is told rather than\n // followed, so a client can decide for itself.\n const redirected = taken();\n\n if (redirected) return apiRedirect(request, redirected);\n\n // A visitor who may not use this endpoint has not caused a server\n // error, and answering 500 makes a guarded route indistinguishable\n // from a broken one. Null means the middleware threw something that is\n // not a refusal, which is a real fault and says so.\n const status = refusalStatus(error);\n\n if (status === null) throw error;\n\n return new Response(status === 401 ? \"Unauthorized\" : \"Forbidden\", {\n status,\n });\n }\n\n const redirected = taken();\n\n if (redirected) return apiRedirect(request, redirected);\n\n return null;\n });\n }\n\n /**\n * A guard's redirect on a route.ts, answered for whoever asked.\n *\n * A browser that navigated here - followed a link to the route, typed the\n * url - is sent on with a real Location; a 401 would show it \"Unauthorized\"\n * over a page it cannot see. Code that fetched the route is told instead:\n * fetch follows a Location on its own and would hand back the login page's\n * html as the endpoint's answer, so it gets the 401 with the destination in\n * a header, and decides for itself.\n */\n function apiRedirect(request: Request, to: Redirection): Response {\n if (isNavigation(request)) return redirectResponse(to, false);\n\n return new Response(\"Unauthorized\", {\n status: 401,\n headers: { \"X-RSC-Redirect\": to.location },\n });\n }\n\n async function handleQuery(\n request: Request,\n url: URL,\n ): Promise<Response | null> {\n if (!engine.handleQuery) return null;\n\n // Required, and the reason is CSRF rather than routing. A GET carrying no\n // unusual header is a SIMPLE request: any page anywhere can trigger one\n // with <img src=\"…/_rsc/query?…\"> and it goes out with the visitor's\n // cookies. CORS stops them reading the answer; it does not stop the read\n // running. This header is not CORS-safelisted, so a browser preflights it\n // and nothing here answers a preflight — the same protection a POST\n // carrying X-RSC-Action already had.\n if (!request.headers.get(HEADER.query)) {\n return new Response(\"Missing \" + HEADER.query, { status: 400 });\n }\n\n const id = url.searchParams.get(\"id\");\n const args = url.searchParams.get(\"args\");\n\n if (!id || args === null)\n return new Response(\"Missing id or args\", { status: 400 });\n\n // Enforced here as well as in the client, because the limit is what keeps\n // an attacker from making this endpoint decode megabytes of their payload\n // per request.\n if (url.search.length > MAX_QUERY)\n return new Response(\"Query too large\", { status: 414 });\n\n const answered = await engine.handleQuery(id, args);\n\n // Unknown id and registered-but-not-a-query are the same answer on purpose.\n if (!answered) return new Response(\"No such query\", { status: 404 });\n\n // The read refused. Answered as a status with the message in the body, so\n // the fetcher rejects with something a person can read — a failure rendered\n // into a 200 would reach the browser as React's opaque error instead.\n if (!(\"stream\" in answered)) {\n return new Response(\n JSON.stringify({ message: answered.message, errors: answered.errors }),\n {\n status: answered.status,\n headers: withVersion({\n \"Content-Type\": \"application/json\",\n \"Cache-Control\": PER_CLIENT,\n }),\n },\n );\n }\n\n return new Response(answered.stream, {\n headers: withVersion({\n \"Content-Type\": FLIGHT_TYPE,\n \"Cache-Control\": answered.cacheControl,\n // The answer is narrowed by who is asking whenever a read touches the\n // session, and the request that carries that is the cookie. Without\n // this a shared cache keyed on the url alone hands one visitor\n // another's answer — for any query that opted out of no-store.\n Vary: \"Cookie, \" + HEADER.referer,\n }),\n });\n }\n\n async function handleAction(request: Request, url: URL): Promise<Response> {\n const actionId = request.headers.get(HEADER.action);\n\n if (!actionId) return new Response(\"Missing X-RSC-Action\", { status: 400 });\n\n // The body travels as application/octet-stream so a host that parses\n // multipart cannot consume it first; its real type rides in a header.\n const body = await readBodyUpTo(request, maxActionBody);\n\n if (body === null) {\n return new Response(`Action body over ${maxActionBody} bytes`, {\n status: 413,\n });\n }\n\n const contentType =\n request.headers.get(HEADER.contentType) ?? \"text/plain;charset=UTF-8\";\n\n // Where it was invoked from, so anything the action invalidates can be\n // re-rendered against the page that is actually on screen.\n const from = refererPath(\n request.headers.get(HEADER.referer),\n url.origin,\n siteHosts,\n );\n const match = from ? matchRoute(routes, from) : null;\n const page = match\n ? pageContext(match, await propsFor(match, request), from ?? undefined)\n : undefined;\n\n // Scoped to this action: revalidate() called anywhere inside it, at any\n // depth, marks here and nowhere else — two requests can be in flight and\n // marking is per-request state. And redirect(): the guide says \"throw\n // from the action and the client follows it\", and the client does\n // follow an X-RSC-Redirect on an action's response — but the signal the\n // throw raises was never caught here, so every login that redirected\n // after signing in was a 500. Caught, it is the instruction the client\n // already knows how to read.\n return await withRedirect(async (redirected) => {\n let stream: ReadableStream;\n\n try {\n ({ stream } = await withRevalidation((taken) =>\n engine.handleAction(actionId, body, contentType, page, taken),\n ));\n } catch (error) {\n const to = redirected();\n\n if (to) return redirectResponse(to, true);\n\n throw error;\n }\n\n return new Response(stream, {\n headers: withVersion({\n \"Content-Type\": \"text/x-component; charset=utf-8\",\n }),\n });\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"host.js","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"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","sourcesContent":["// Everything a JavaScript host has to do to serve the RSC engine.\n//\n// PHP needs ~2,400 lines for this because it cannot run JavaScript: a socket\n// bridge, a worker pool, a frame protocol. A JS host imports the engine and\n// calls it, and what remains is the part every host would otherwise rewrite —\n// matching a url to a route, negotiating how much of the page to send, and\n// speaking the header protocol the client expects.\n//\n// Deliberately not Hono, or Express, or anything: this takes a Request and\n// returns a Response, so it runs under Bun.serve, Deno, Workers, Node's\n// fetch adapters and any framework built on them. `./hono` is the three-line\n// binding for one of them.\n//\n// const rsc = createRscHandler({ engine, manifest, assets })\n// Bun.serve({ fetch: (req) => rsc(req).then((r) => r ?? new Response('', { status: 404 })) })\n\nimport {\n allowFor,\n matchApiRoute,\n matchIntercept,\n matchRoute,\n retentionKey,\n sharedDepth,\n} from \"./routing.js\";\nimport { pathKey, patternKey } from \"./prerender.js\";\nimport { apiKey } from \"./apiPrerender.js\";\nimport { hostPath, hostSegment, routableHost } from \"./hostRouting.js\";\nimport type { FrozenApiResponse } from \"./apiPrerender.js\";\nimport { withRevalidation } from \"./revalidate.js\";\n/**\n * @internal For a host adapter that embeds the engine. An app imports this\n * from `@rsc-kit/core/revalidate`.\n */\nexport { revalidate } from \"./revalidate.js\";\nimport { currentNotFound, withRedirect } from \"./redirect.js\";\nimport { compressed } from \"./compress.js\";\nimport { withCache } from \"./cache.js\";\nimport { takeAfterWork, withRequest, withResponseDraft } from \"./request.js\";\nimport { criticalAssetsOf, linkHeader, mergeAssets, type CriticalAssets } from \"./earlyHints.js\";\nimport { withHead } from \"./shellHead.js\";\nimport type { Redirection } from \"./redirect.js\";\n/**\n * @internal For a host adapter that embeds the engine. An app imports this\n * from `@rsc-kit/core/redirect` - the one the guides teach, and the one an\n * editor should offer first.\n */\nexport { redirect } from \"./redirect.js\";\n// Re-exported, not redefined: routing.ts is the one implementation, shared with\n// the prerenderer and the generated bundle, and this stays the adapter's\n// public surface so a host imports from one place.\n/** @internal For a host adapter. An app never matches its own routes. */\nexport { matchIntercept, matchRoute, sharedDepth } from \"./routing.js\";\nexport type { MatchedRoute } from \"./routing.js\";\nimport {\n FLIGHT_TYPE,\n HEADER,\n HTML_TYPE,\n PER_CLIENT,\n REVALIDATE,\n VARY_ON_RSC,\n} from \"./headers.js\";\nimport type { MatchedApiRoute, MatchedRoute } from \"./routing.js\";\nimport {\n ServerAuthenticationError,\n ServerAuthorizationError,\n} from \"./js/errors.js\";\nimport type { RouteManifest } from \"./manifest.js\";\n\n/** The built server bundle. Only the parts a host calls. */\nexport interface RscEngine {\n /** The route table this bundle was built from. */\n manifest?(): RouteManifest;\n /** A short id of this build's client, for the version the host answers with when given none. */\n buildId?(): Promise<string>;\n /** The stylesheet and client entry every document links, for the Link header a CDN sends ahead. */\n criticalAssets?(): CriticalAssets;\n installHostFn(fn: (name: string, ...args: unknown[]) => unknown): void;\n handleRscStream(\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 slotOverrides?: Record<string, unknown>,\n from?: number,\n pageKey?: string,\n pathname?: string | null,\n ): Promise<{ stream: ReadableStream; segmentDepth: number }>;\n handleRscHtmlStream(\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 slotOverrides?: Record<string, unknown>,\n nonce?: string,\n pageKey?: string,\n bootstrap?: boolean,\n ): Promise<{ htmlStream: ReadableStream }>;\n /**\n * A form posted to the page's own url before the page had a runtime to\n * catch it: React wrote the action's id into the form, and this runs that\n * action from the posted fields, then renders the page with the result.\n * Optional: an engine built by an older plugin answers such a post 404.\n */\n handleRscFormPost?(\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 slotOverrides: Record<string, unknown>,\n nonce: string | undefined,\n pageKey: string,\n bootstrap: boolean,\n formData: FormData,\n ): Promise<{ htmlStream: ReadableStream }>;\n /**\n * Finish a shell frozen at build time, against data that exists now.\n *\n * Emits only the boundaries the shell left unfinished, meant to be written\n * straight after it. Optional so a host can be pointed at an engine built\n * before resuming existed; without it a shell has no way to be completed and\n * the page is rendered whole instead.\n */\n handleRscResume?(\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 slotOverrides?: Record<string, unknown>,\n postponed?: unknown,\n nonce?: string,\n pageKey?: string,\n pathname?: string | null,\n ): Promise<{ htmlStream: ReadableStream }>;\n handleRscRevalidate?(\n target: string,\n page: unknown,\n ): Promise<{ rscPayload: string }>;\n /**\n * The page's metadata for these params, merged with its layouts'. Used to\n * put the real title into a shell stored for a whole pattern, whose build\n * could not know the url.\n */\n resolveMetadata?(\n component: string,\n props?: Record<string, unknown>,\n layouts?: { component: string; props: Record<string, unknown> }[],\n ): Promise<Record<string, unknown> | null>;\n /**\n * Run a route's middleware without rendering anything.\n *\n * For a frozen page: the host reads it from disk and the engine never sees\n * the request, so the check has to be asked for separately.\n */\n runRouteMiddleware?(\n component: string,\n props: Record<string, unknown>,\n ): Promise<void>;\n handleAction(\n actionId: string,\n body: Uint8Array | string | FormData,\n contentType?: string,\n page?: unknown,\n takeRevalidated?: () => string[],\n ): Promise<{ stream: ReadableStream }>;\n /**\n * Answer one read declared with `query()`, or null if that id is not one.\n *\n * Optional so a host can be pointed at a bundle built before queries existed;\n * without it the endpoint 404s rather than throwing, which is what a client\n * built against the same old bundle expects anyway.\n */\n handleQuery?(\n id: string,\n args: string,\n report?: (error: unknown) => string,\n ): Promise<\n | { stream: ReadableStream; cacheControl: string }\n | { status: number; message: string; errors?: Record<string, string[]> }\n | null\n >;\n /**\n * Answer a `route.ts` — an api endpoint rather than a page.\n *\n * Optional so a host can be pointed at a bundle built before these existed;\n * without it the url falls through to page routing, which is what that\n * bundle would have done anyway.\n */\n handleApiRoute?(\n name: string,\n request: Request,\n params: Record<string, string>,\n allow: string,\n ): Promise<Response>;\n}\n\nexport interface RscHostOptions {\n /** The built server bundle — `import * as engine from './build/rsc/index.js'`. */\n engine: RscEngine;\n /**\n * The route table. Defaults to the one the bundle was built with, which is\n * almost always what you want — a manifest passed separately can go stale\n * against the bundle it is describing.\n */\n manifest?: RouteManifest;\n /**\n * Functions the app's server components call as `await rpc('name', ...args)`.\n *\n * In the Laravel host this crosses a socket into PHP. Here they are just\n * functions, which is the whole reason a JS host is smaller.\n */\n rpc?: Record<string, (...args: unknown[]) => unknown>;\n /**\n * Where a host call goes when this process cannot answer it.\n *\n * `rpc` is checked first, so a host can answer some calls in JS and leave\n * the rest to a backend. `httpHostCalls` in `@rsc-kit/core/host-calls`\n * builds one of these over an ordinary POST, which is how a host written in\n * another language answers without implementing the socket framing.\n */\n hostCalls?: (name: string, ...args: unknown[]) => Promise<unknown>;\n /**\n * Props for a page, given whatever its url bound.\n *\n * Defaults to the url params alone. A host that loads a user, reads a\n * session or resolves a tenant does it here — this is the one place the\n * engine cannot supply anything for.\n */\n props?: (\n match: MatchedRoute,\n request: Request,\n ) => Record<string, unknown> | Promise<Record<string, unknown>>;\n /**\n * Reads what the prerenderer wrote, if this build has any.\n *\n * A function rather than a directory, because not every host has a\n * filesystem: on an edge runtime these live in a KV store or a static-asset\n * binding. `prerenderedFrom` in `@rsc-kit/core/files` is the one for a disk.\n *\n * Checked before rendering, and anything it cannot find falls through to\n * being rendered now — so a partial prerender is a valid state, not a\n * broken one.\n */\n prerendered?: (name: string) => Promise<string | null> | string | null;\n /** Serve a built browser asset. Return null for anything not found. */\n assets?: (\n pathname: string,\n request: Request,\n ) => Promise<Response | null> | Response | null;\n /**\n * Identifies this build to the client, which says it back on every\n * navigation and is sent to load the document when it differs. For an\n * engine with no `buildId` of its own; the generated one has, and every\n * document it renders says that id, so a version named here would\n * disagree with what the client was told and refuse every navigation.\n */\n version?: string;\n /**\n * The most an action body may be, in bytes. 8 MB unless said otherwise.\n *\n * Everything an action receives arrives in one body - arguments, and the\n * files a form uploads - and it is read whole before the action runs. With\n * no ceiling a single request could ask this process to hold as much as a\n * caller cares to send. Above the ceiling the answer is 413, before a byte\n * of the body is kept. Raise it for an app that uploads larger files\n * through actions; a proxy in front usually has its own limit too.\n */\n maxActionBody?: number;\n /**\n * gzip what this host answers, for a request that accepts it.\n *\n * On by default where the runtime has a compressor - Node and Bun - and\n * never on a Worker, where the platform compresses. Behind a CDN or a\n * proxy that compresses, the proxy sees an already-encoded answer and\n * leaves it; a bun or node server answering the internet by itself sent\n * every byte raw, which was a port's whole mobile performance story. Off\n * for a deployment that would rather its proxy did it.\n */\n compress?: boolean;\n}\n\n/**\n * The answer to a redirect that was decided before anything was written.\n *\n * A document gets a real status code. A payload request must NOT: `fetch`\n * follows a 3xx transparently, so the client would receive the destination's\n * HTML and hand it to the Flight decoder, which reports its own confusion\n * rather than the redirect. It gets 204 and a header instead, and navigates\n * itself — which is also what makes the redirect an SPA one.\n */\n/**\n * A string safe to write inside a <script> element.\n *\n * `JSON.stringify` escapes for JavaScript, and this is not a JavaScript\n * context — it is HTML that happens to contain JavaScript. The parser ends the\n * element at the first `</script`, wherever it appears, so a destination\n * carrying one closes the tag and whatever follows is markup the browser runs.\n *\n * That destination is routinely computed rather than written — redirect()\n * documents \"remembering where someone was going and sending them back to it\"\n * as the usual case, which is a query string or a cookie arriving verbatim\n * here. U+2028 and U+2029 are escaped too: legal in JSON, line terminators in\n * JavaScript.\n */\nfunction inScript(value: string): string {\n return JSON.stringify(value)\n .replace(/</g, \"\\\\u003c\")\n .replace(/\\u2028/g, \"\\\\u2028\")\n .replace(/\\u2029/g, \"\\\\u2029\");\n}\n\n/**\n * Whether the browser itself asked, for a document.\n *\n * Sec-Fetch-Mode is what every current browser sends and nothing else does;\n * the Accept fallback is for the ones that do not, and for a test's Request.\n * A payload request never counts, whatever it accepts.\n */\nfunction isNavigation(request: Request): boolean {\n if (request.headers.has(HEADER.rsc)) return false;\n\n const mode = request.headers.get(\"sec-fetch-mode\");\n\n if (mode) return mode === \"navigate\";\n\n return (request.headers.get(\"accept\") ?? \"\").includes(\"text/html\");\n}\n\nfunction redirectResponse(\n to: Redirection,\n isPayloadRequest: boolean,\n): Response {\n if (isPayloadRequest) {\n return new Response(null, {\n status: 204,\n headers: { [HEADER.redirect]: to.location, Vary: VARY_ON_RSC },\n });\n }\n\n return new Response(null, {\n status: to.status,\n headers: { Location: to.location, Vary: VARY_ON_RSC },\n });\n}\n\n/**\n * Append the redirect a render asked for after its shell had already gone out.\n *\n * The status line is spent by then, so the instruction travels in the body. A\n * script rather than waiting for hydration to notice the error digest: it runs\n * as the browser parses it, which is sooner, and it is the only path that\n * works at all for a route shipping no client runtime.\n *\n * Read on flush, because that is when the render has finished and a redirect\n * from inside a Suspense boundary is finally known.\n */\nfunction appendLateRedirect(\n stream: ReadableStream,\n taken: () => Redirection | null,\n): ReadableStream {\n // An engine that answered with a finished body rather than a stream has no\n // late window at all: the render was over before this was called, so the\n // caller's own check already saw everything there was to see.\n if (typeof stream?.getReader !== \"function\") return stream;\n\n const encoder = new TextEncoder();\n const reader = stream.getReader();\n\n // Read-and-re-emit rather than pipeThrough(new TransformStream(...)): a\n // TransformStream from a different realm than the stream it is piped into\n // is rejected outright, and a host embedded in a runtime that supplies its\n // own web streams is exactly that case.\n return new ReadableStream({\n async pull(controller) {\n const { done, value } = await reader.read();\n\n if (!done) {\n controller.enqueue(value);\n\n return;\n }\n\n const to = taken();\n\n // replace, so Back does not return to a url that redirected.\n if (to) {\n controller.enqueue(\n encoder.encode(\n `<script>location.replace(${inScript(to.location)})</script>`,\n ),\n );\n }\n\n controller.close();\n },\n cancel(reason) {\n return reader.cancel(reason);\n },\n });\n}\n\n/**\n * The status a refusal deserves, or null when this was not one.\n *\n * A host answers an unauthenticated call 401 and an unauthorized one 403, and\n * the transport raises each as its own error. Without this they arrive at the\n * render as ordinary failures and leave as 500s — which reads, to anyone\n * looking at a log or a browser, as the application being broken rather than\n * the visitor being turned away.\n */\nfunction refusalStatus(error: unknown): number | null {\n if (error instanceof ServerAuthenticationError) return 401;\n if (error instanceof ServerAuthorizationError) return 403;\n\n // Named rather than matched by identity, because the error may have been\n // raised by another copy of the module: an app's actions are bundled apart\n // from the engine, and instanceof is false across that seam.\n const name = (error as { name?: string } | null)?.name;\n\n if (name === \"ServerAuthenticationError\") return 401;\n if (name === \"ServerAuthorizationError\") return 403;\n\n // A status the host chose — a throttle's 429, a policy's 403 — carried on\n // the error by the transport. Bounded to refusals: a host answering 500\n // should not be able to make this look like a client's fault, and one\n // answering 200 should not turn a failed render into a success.\n const carried = (error as { refusalStatus?: unknown } | null)?.refusalStatus;\n\n if (typeof carried === \"number\" && carried >= 400 && carried <= 499)\n return carried;\n\n return null;\n}\n\nfunction refusalMessage(error: unknown): string {\n const message = (error as { message?: string } | null)?.message;\n\n return typeof message === \"string\" && message !== \"\" ? message : \"Refused.\";\n}\n\n/**\n * Whether a browser was told it could post this action.\n *\n * Defence in depth, not the only defence. An action already requires the\n * X-RSC-Action header, which makes a cross-origin post a non-simple request —\n * so the browser must preflight it, and nothing here answers a preflight. A\n * browser can be tricked into sending cookies; it cannot be tricked into\n * sending a header it does not know. This is the belt to that pair of braces,\n * and it is what Next does for server actions.\n *\n * Compared against X-Forwarded-Host first, because a proxied deployment is the\n * normal one: the backend forwards the name the visitor typed, while Host is\n * this process on loopback. Comparing against Host alone would reject every\n * legitimate action that arrived through a proxy — a check that only fires on\n * correct requests is worse than none.\n *\n * No Origin at all is allowed through. It is absent on same-origin requests in\n * some browsers and on anything that is not a browser, and refusing those would\n * break server-to-server callers to catch an attacker who is already blocked by\n * the preflight.\n */\nexport function actionOriginAllowed(request: Request, url: URL): boolean {\n const origin = request.headers.get(\"origin\");\n\n if (!origin) return true;\n\n const expected =\n request.headers.get(\"x-forwarded-host\") ??\n request.headers.get(\"host\") ??\n url.host;\n\n try {\n return new URL(origin).host === expected;\n } catch {\n // An Origin that is not a url is not one this can vouch for.\n return false;\n }\n}\n\nconst DEFAULT_MAX_ACTION_BODY = 8 * 1024 * 1024;\n\n/**\n * The body, read whole, or null once it has passed the ceiling.\n *\n * Content-Length is checked first because it is free, and the stream is\n * counted anyway because a body need not announce its size and a stated size\n * need not be true. Reading stops at the first byte over: what was held is\n * dropped, and the caller answers 413 rather than holding the rest.\n */\nasync function readBodyUpTo(\n request: Request,\n limit: number,\n): Promise<Uint8Array | null> {\n const declared = Number(request.headers.get(\"content-length\"));\n\n if (Number.isFinite(declared) && declared > limit) return null;\n if (!request.body) return new Uint8Array(0);\n\n const reader = request.body.getReader();\n const chunks: Uint8Array[] = [];\n let held = 0;\n\n for (;;) {\n const { done, value } = await reader.read();\n\n if (done) break;\n\n held += value.byteLength;\n\n if (held > limit) {\n await reader.cancel().catch(() => {});\n return null;\n }\n\n chunks.push(value);\n }\n\n const body = new Uint8Array(held);\n let at = 0;\n\n for (const chunk of chunks) {\n body.set(chunk, at);\n at += chunk.byteLength;\n }\n\n return body;\n}\n\n/**\n * The page a client says it was on, as a path this router can match - or\n * null. A header is a string anyone can send, and `new URL` throws on one\n * that is not a url; that must not become a 500 on the action endpoint.\n */\nfunction refererPath(\n referer: string | null,\n origin: string,\n hosts: readonly string[] = [],\n): string | null {\n if (!referer) return null;\n\n try {\n const parsed = new URL(referer, origin);\n\n // The page the action was invoked from is routed the way a request for\n // it would be: on a tenant host, the referer's host names the segment.\n return hostPath(parsed.host, parsed.pathname, hosts);\n } catch {\n return null;\n }\n}\n\n/**\n * How large a query url may be before it is refused.\n *\n * Matched to the client's own limit, and enforced here too because the limit is\n * what keeps an attacker from making this endpoint decode megabytes of\n * attacker-chosen payload per request.\n *\n * Module scope, not inside the handler: everything declared after the handler\n * is returned never initialises, and a `const` read from the closure then\n * throws on every request instead of being undefined.\n */\nconst MAX_QUERY = 8_000;\n\n/**\n * The host segment a routed url begins with, by url. Kept beside the url\n * rather than in it, so the pathname stays what a page and a stored file\n * are keyed by, and the matcher alone is told the leading part is the host's.\n */\nconst hostOf = new WeakMap<URL, string>();\n\nfunction matchPage(routes: RouteManifest, url: URL): MatchedRoute | null {\n return matchRoute(routes, url.pathname, hostOf.get(url) ?? null);\n}\n\nexport function createRscHandler(\n options: RscHostOptions,\n): (request: Request) => Promise<Response | null> {\n const { engine, assets } = options;\n // The build's own id, which is also what every document says it is - the\n // two must agree, or a client's honest claim is a 409 on every request.\n // A version named by the app applies only to an engine with no id of its\n // own. Resolved on the first request: the engine reads it from a build\n // product it only has at runtime.\n let version = engine.buildId ? undefined : options.version;\n const maxActionBody = options.maxActionBody ?? DEFAULT_MAX_ACTION_BODY;\n const compress = options.compress ?? true;\n // Annotated rather than inferred: the narrowing below is lost inside the\n // closures that use it, and every one of them runs after the throw.\n const manifest: RouteManifest | undefined =\n 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 in the bundle.\",\n );\n }\n\n const routes: RouteManifest = manifest;\n\n // Only when this host has functions of its own. Installing unconditionally\n // overwrites whatever was already registered — a prerenderer sharing the\n // same engine instance, or a host that set its own up first — and the\n // symptom is every call failing as unregistered.\n if (options.rpc || options.hostCalls)\n installHostFunctions(options.rpc ?? {}, options.hostCalls);\n\n function installHostFunctions(\n fns: NonNullable<RscHostOptions[\"rpc\"]>,\n remote: RscHostOptions[\"hostCalls\"],\n ): void {\n engine.installHostFn(async (name: string, ...args: unknown[]) => {\n const fn = fns[name];\n\n if (fn) return await fn(...args);\n\n // A remote transport cannot enumerate what the backend registered, so\n // an unknown name is the backend's to reject — with a message naming the\n // function, which is more than this side could say.\n if (remote) return await remote(name, ...args);\n\n // Louder than returning null: a typo in a server component otherwise\n // renders as missing data with nothing anywhere saying why.\n throw new Error(\n `No host function named ${JSON.stringify(name)}. Registered: ${Object.keys(fns).join(\", \") || \"(none)\"}`,\n );\n });\n }\n\n async function propsFor(\n match: MatchedRoute,\n request: Request,\n ): Promise<Record<string, unknown>> {\n return options.props ? await options.props(match, request) : match.params;\n }\n\n /** The page a server action was invoked from, so it can re-render regions of it. */\n /** Whether a document at this url is served from the route's pattern shell: no page or shell of its own, and one for the pattern. */\n async function servedFromPatternShell(url: URL, match: MatchedRoute): Promise<boolean> {\n const source = options.prerendered;\n\n if (!source) return false;\n\n const key = pathKey(url.pathname);\n\n if ((await source(`${key}.html`)) !== null) return false;\n if ((await source(`${key}.ppr.html`)) !== null) return false;\n\n return (await source(`${patternKey(match.route)}.ppr.html`)) !== null;\n }\n\n function pageContext(match: MatchedRoute, props: Record<string, unknown>, url?: string) {\n return {\n component: match.route.component,\n props,\n url,\n layouts: match.route.layouts.map((component) => ({\n component,\n props: {},\n })),\n loadings: match.route.loadings,\n parallelSlots: match.route.slots,\n // What may be named in X-RSC-Revalidate — see renderRevalidated.\n sections: match.route.sections,\n };\n }\n\n function withVersion(\n headers: Record<string, string>,\n ): Record<string, string> {\n return version ? { ...headers, [HEADER.version]: version } : headers;\n }\n\n // A build made for export ships a client that asks for payloads by url,\n // because a static host cannot read a header. Serving that build from a\n // server is a reasonable thing to do — previewing an export, or one build\n // used both ways — and without this every navigation 404s in the console\n // while the page itself looks fine.\n const payloadName = manifest.build?.payloadName || \"\";\n /** The site's own hosts; any other host is routed with its segment in front of the path. */\n const siteHosts = manifest.build?.hosts ?? [];\n /** Whether responses say what built them. How they were served is always said. */\n const identify = Boolean(manifest.build?.identify);\n /** How a response was answered, for X-RSC-Kit: a file the build wrote, or a shell of one. */\n const servedFrom = new WeakMap<Response, \"stored\" | \"shell\">();\n /** What a stored document's head names, read once per file, for the Link header. */\n const hinted = new WeakMap<Response, CriticalAssets>();\n const hintsByKey = new Map<string, CriticalAssets>();\n\n /**\n * The page a payload url belongs to, if this is one.\n *\n * Both the whole-document name and the depth variants beside it: a client\n * built for export asks for index.seg1.rsc when it already holds a layout,\n * and matching only the plain name leaves that as a 404 no page reports.\n */\n const payloadNames = new RegExp(\n \"/\" +\n payloadName\n .replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")\n .replace(/^index\\\\\\./, \"index(\\\\.seg\\\\d+)?\\\\.\") +\n \"$\",\n );\n\n function pageForPayload(pathname: string): string | null {\n if (payloadName === \"\") return null;\n\n const match = payloadNames.exec(pathname);\n\n if (!match) return null;\n\n return pathname.slice(0, match.index) || \"/\";\n }\n\n // One memo table per request, opened at the outermost point so that\n // everything below shares it: middleware, layouts, the page, and an action. A\n // guard that reads the session and a layout that reads it again are one\n // query, not two.\n /**\n * The fields of a form posted to a page, or null for anything else.\n *\n * A POST with a form body, from this origin, to a url that is a page and\n * not the action endpoint, with an engine that can run what the form\n * names. Read here so the decision is made once; the action reads the\n * same fields from what is returned.\n */\n async function formPostOf(request: Request, url: URL): Promise<FormData | null> {\n if (request.method !== \"POST\" || !engine.handleRscFormPost) return null;\n if (request.headers.has(HEADER.rsc)) return null;\n\n const type = request.headers.get(\"content-type\") ?? \"\";\n\n if (!/^(?:application\\/x-www-form-urlencoded|multipart\\/form-data)/i.test(type)) return null;\n if (!matchPage(routes, url)) return null;\n if (!actionOriginAllowed(request, url)) return null;\n\n try {\n return await request.formData();\n } catch {\n return null;\n }\n }\n\n /**\n * What a stored answer's compressed bytes are kept under.\n *\n * The build, the url, and the value of every request header the answer\n * says it varies on - which is what tells the document for /login apart\n * from the payload for /login. Keyed by the path alone, the payload\n * request found the document's bytes waiting and hydration decoded HTML\n * as Flight, silently, on every stored page in production.\n */\n function storedKey(request: Request, response: Response): string {\n const url = new URL(request.url);\n const varies = (response.headers.get(\"Vary\") ?? \"\")\n .split(\",\")\n .map((name) => name.trim().toLowerCase())\n .filter((name) => name && name !== \"*\" && name !== \"accept-encoding\")\n .sort()\n .map((name) => `${name}=${request.headers.get(name) ?? \"\"}`);\n\n return [version ?? \"\", url.pathname + url.search, ...varies].join(\"\\n\");\n }\n\n return async function handle(request: Request): Promise<Response | null> {\n if (version === undefined && engine.buildId) version = await engine.buildId();\n\n return await withRequest(request, () =>\n withCache(() =>\n // Open for the whole request and sealed the moment an answer exists,\n // so middleware — which runs before any rendering — can put headers on\n // it, and a component, which runs after, is told why it cannot.\n withResponseDraft(async ({ taken, seal }) => {\n const response = await route(request);\n\n seal();\n\n if (!response) return null;\n\n const collected = taken();\n\n collected.forEach((value, name) => {\n // Set-Cookie is applied below, once per cookie: iterating a Headers\n // gives it joined in some runtimes and per-cookie in others, and a\n // joined one is a single malformed cookie the browser discards.\n if (name.toLowerCase() === \"set-cookie\") return;\n\n // set, not append: a middleware asking for a header means that\n // value, not that value added to whatever the host already chose.\n response.headers.set(name, value);\n });\n\n // Appended, because several cookies are several headers.\n for (const cookie of collected.getSetCookie()) {\n response.headers.append(\"Set-Cookie\", cookie);\n }\n\n // How this answer was served - the header a developer reads in the\n // Network tab, the way X-Nextjs-Cache is. Always: it names no\n // product, and a CDN rule or a check can key on it.\n response.headers.set(\"X-RSC-Kit\", servedFrom.get(response) ?? \"rendered\");\n\n // What the document needs first, as a Link header: a CDN sends it\n // ahead as 103 Early Hints, and the stylesheet, the entry and the\n // fonts download while the HTML is still being written. Every\n // document, stored ones included - a stored document's own head\n // names its fonts; a rendered one's is not known until too late.\n if (response.status === 200 && (response.headers.get(\"Content-Type\") ?? \"\").startsWith(\"text/html\")) {\n const link = linkHeader(mergeAssets(hinted.get(response) ?? null, engine.criticalAssets?.() ?? null));\n\n if (link) response.headers.set(\"Link\", link);\n }\n\n // What built it. The name only, never the version - a version in\n // every response is what a vulnerability scanner filters on - and\n // off for a team whose policy strips every framework identifier.\n if (identify) response.headers.set(\"X-Powered-By\", \"rsc-kit\");\n\n // Work after() queued, now that the answer exists. A Worker keeps\n // the isolate alive only for what is handed to waitUntil - Nitro's\n // Cloudflare preset puts the execution context on the request - so\n // it goes there where it can; a process keeps a detached promise.\n const pending = takeAfterWork();\n\n if (pending) {\n const context = (request as Request & { context?: { waitUntil?: (p: Promise<unknown>) => void } }).context;\n\n if (typeof context?.waitUntil === \"function\") context.waitUntil(pending);\n }\n\n // Last, over the finished answer, headers and all. A stored answer\n // is the same bytes for everyone and is compressed once, keyed by\n // the build and the url it was stored for.\n if (compress) {\n const answer = await compressed(\n request,\n response,\n servedFrom.get(response) === \"stored\" ? storedKey(request, response) : undefined,\n );\n\n const from = servedFrom.get(response);\n\n if (answer !== response && from) servedFrom.set(answer, from);\n\n return answer;\n }\n\n return response;\n }),\n ),\n );\n };\n\n async function route(request: Request): Promise<Response | null> {\n let url = new URL(request.url);\n\n // A host other than the site's own is matched with its segment in front\n // of the path, once, here: everything below - the api match, the page\n // match, the stored answer, the payload - sees that path and nothing\n // else knows a host was involved. The visitor's url is untouched.\n // Compared against X-Forwarded-Host first, for the same reason the\n // action's origin check is: a proxied deployment is the common one.\n // Only when a route can begin with that segment - a [domain] directory or\n // one named for the host - so an app with a metadataBase and no tenant\n // tree routes every host by path, and a proxy forwarding by an internal\n // name is not read as a tenant.\n if (siteHosts.length > 0) {\n const host =\n request.headers.get(\"x-forwarded-host\") ??\n request.headers.get(\"host\") ??\n url.host;\n const segment = hostSegment(host, siteHosts);\n\n if (segment !== null && routableHost(segment, routes.routes)) {\n url = new URL(\n hostPath(host, url.pathname, siteHosts) + url.search,\n url.origin,\n );\n hostOf.set(url, segment);\n }\n }\n\n const asPayload = pageForPayload(url.pathname);\n\n if (asPayload !== null) {\n // Rewritten to the page it is asking about, with the header the rest of\n // this handler reads — one path through, however the client asked.\n const host = hostOf.get(url);\n\n url = new URL(asPayload + url.search, url.origin);\n if (host !== undefined) hostOf.set(url, host);\n const headers = new Headers(request.headers);\n\n headers.set(HEADER.rsc, \"1\");\n request = new Request(url, { method: request.method, headers });\n }\n\n if (assets) {\n const asset = await assets(url.pathname, request);\n\n if (asset) return asset;\n }\n\n if (request.method === \"POST\" && url.pathname === HEADER.actionPath) {\n if (!actionOriginAllowed(request, url)) {\n return new Response(\"Cross-origin action\", { status: 403 });\n }\n\n return await handleAction(request, url);\n }\n\n // Api routes first. A url is one or the other, and a page that shares a\n // path with a route.ts would otherwise win by accident of ordering.\n const api = matchApiRoute(routes, url.pathname);\n\n if (api && engine.handleApiRoute) {\n // The guards above it run first, exactly as they would for a page in the\n // same directory. A route.ts is colocated with the pages it belongs\n // with, so adding one under a guarded path must not open a way around\n // the guard.\n const refused = await refuseApiUnlessAllowed(request, api);\n\n if (refused) return refused;\n\n const stored = await frozenApi(request, url, api);\n\n if (stored) return stored;\n\n // A redirect() thrown from the handler is the route's answer, not a\n // fault: a real Location, because whoever asked is meant to go there\n // - a browser that followed a link to this route, or a fetch of an\n // export that lives on a signed url. notFound() is its 404.\n return await withRedirect(async (taken) => {\n try {\n return await engine.handleApiRoute!(\n api.route.name,\n request,\n api.params,\n allowFor(api.route),\n );\n } catch (error) {\n const redirected = taken();\n\n if (redirected) return redirectResponse(redirected, false);\n if (currentNotFound()) return new Response(\"Not found\", { status: 404 });\n\n throw error;\n }\n });\n }\n\n if (request.method === \"GET\" && url.pathname === HEADER.queryPath) {\n // Same check as an action, for a smaller reason: a cross-origin page\n // cannot read this answer — CORS sees to that — but it can still cause\n // the read to run with the visitor's cookies. A query is side-effect\n // free by contract, so this is depth rather than the only defence.\n if (!actionOriginAllowed(request, url)) {\n return new Response(\"Cross-origin query\", { status: 403 });\n }\n\n return await handleQuery(request, url);\n }\n\n // The two halves an edge cache needs: hand it a shell it may keep, and\n // finish that shell for a visitor it cannot answer for itself.\n if (options.prerendered && url.pathname === HEADER.pprShellPath) {\n return await servePprShell(request, url, options.prerendered);\n }\n\n if (\n request.method === \"POST\" &&\n options.prerendered &&\n url.pathname === HEADER.pprResumePath\n ) {\n return await servePprResume(request, url, options.prerendered);\n }\n\n // A form submitted before the page had a runtime: the browser posts it\n // to the page's own url, as React wrote it, with the action's id among\n // the fields. The action runs and the page renders with the result -\n // what the guide promises for a form that had to work without\n // javascript. Same-origin, as an action is; anything else that is not\n // a read is not this host's.\n const formPost = await formPostOf(request, url);\n\n if (!formPost && request.method !== \"GET\" && request.method !== \"HEAD\") return null;\n\n // A client saying which build it runs, and it is not this one: its\n // manifest cannot load what this build's payload names - a client\n // component added since is \"client reference not found\" and the route's\n // error boundary, on a page that worked a click ago. Under a service\n // worker that serves the last build's document first, that is every\n // returning visitor's first navigation after a deploy, not an open tab.\n // A 409 sends the client to load the document instead, from this build.\n const claimed = request.headers.get(HEADER.version);\n\n if (claimed !== null && claimed !== \"\" && version && claimed !== version && request.headers.get(HEADER.rsc) !== null) {\n return new Response(null, {\n status: 409,\n headers: withVersion({ \"X-RSC-Location\": url.pathname + url.search, \"Cache-Control\": \"no-store\" }),\n });\n }\n\n // One named region of this page, asked for without mutating anything to\n // earn it. What an action invalidated does not come through here — that\n // travels back inside the action's own answer, which is the whole point of\n // marking rather than telling the client to go and ask.\n const revalidating = request.headers.get(HEADER.revalidate);\n\n if (revalidating !== null && request.headers.get(HEADER.rsc) !== null) {\n return await handleRevalidate(request, url, revalidating);\n }\n\n // An intercepted navigation renders the page you are already on, with the\n // interceptor dropped into one of its slots — so the modal opens over it\n // and the url changes. Only ever on a client navigation: a hard load has\n // no referer to open over and gets the real page.\n const interceptSlot = request.headers.get(HEADER.intercept);\n\n if (interceptSlot !== null && request.headers.get(HEADER.rsc) !== null) {\n return await handleIntercept(request, url, interceptSlot);\n }\n\n // Only now. A frozen page is a whole page, and both requests above ask for\n // something smaller than one: answering a named region with the whole\n // document puts the entire page inside that region, and answering an\n // interception with it replaces the page the modal was opening over.\n const match = matchPage(routes, url);\n\n if (options.prerendered && !formPost) {\n // A guarded route can still be frozen: whether the content is the same\n // for everyone, and whether this caller may see it, are different\n // questions. The build answers the first; this answers the second, and\n // only then is the frozen page handed over.\n const refusal = await refuseUnlessAllowed(request, match);\n\n if (refusal) return refusal;\n\n const frozen = await servePrerendered(request, url, options.prerendered);\n\n // A whole page from a file, or a shell of one with the holes rendered\n // now: the header says which. servePrerendered marks the shell.\n if (frozen && !servedFrom.has(frozen)) servedFrom.set(frozen, \"stored\");\n\n if (frozen) return frozen;\n }\n\n if (!match) return null;\n\n const props = await propsFor(match, request);\n const layouts = match.route.layouts.map((component) => ({\n component,\n props: {},\n }));\n const chain = match.route.layouts;\n\n // A payload request says so with a header on the page's own url, so one\n // route serves both the document and the navigation that follows it.\n if (request.headers.get(HEADER.rsc) === null) {\n // Scoped to this render, so two requests redirecting at once cannot read\n // each other's destination.\n return await withRedirect(async (taken) => {\n // Awaited, and that await is the whole design: React resolves this\n // when the SHELL is ready, so a redirect thrown above every Suspense\n // boundary rejects here — before a byte is written, with a status line\n // still available. Nothing is buffered to make that true.\n let htmlStream: ReadableStream;\n\n try {\n ({ htmlStream } = formPost\n ? await engine.handleRscFormPost!(\n match.route.component,\n props,\n layouts,\n match.route.loadings,\n match.route.slots,\n {},\n undefined,\n url.pathname,\n true,\n formPost,\n )\n : await engine.handleRscHtmlStream(\n match.route.component,\n props,\n layouts,\n match.route.loadings,\n match.route.slots,\n {},\n undefined,\n url.pathname,\n // A route that ships no runtime gets no bootstrap and no segment\n // boundary — the boundary is itself a client component, so leaving\n // it in means no page could ever be JS-free.\n true,\n ));\n } catch (error) {\n // A rejected shell is how a redirect above every boundary arrives:\n // React could not finish the shell, because the component that would\n // have produced it left instead.\n //\n // The scope decides, not the error. React catches what a component\n // threw and re-raises its own — whose message is stripped in\n // production — so testing the caught value for a redirect signal\n // fails exactly where it matters, and the answer is a 500 with the\n // destination sitting in a scope nobody read.\n const refused = taken();\n\n if (refused) return redirectResponse(refused, false);\n\n // The page said this url names nothing. Null rather than a rendered\n // 404: null is already how this host says \"not mine\", and the caller\n // in front answers it with not-found.tsx and the right status. One\n // path, so a page that calls notFound() and a url that matched no\n // route are indistinguishable to whoever is asking — which is the\n // point of a 404.\n if (currentNotFound()) return null;\n\n // A guard refusing is not a failed render. Without this a visitor\n // who may not see the page gets a 500, which reads as the\n // application being broken rather than them being turned away —\n // and a host middleware refusal arrives exactly here, because the\n // engine asks before it renders anything.\n const status = refusalStatus(error);\n\n if (status) return new Response(refusalMessage(error), { status });\n throw error;\n }\n\n const early = taken();\n\n if (early) return redirectResponse(early, false);\n\n // Above every boundary, so the shell resolving means the page did not\n // refuse itself. Deeper than that and the shell is already on the wire\n // — the digest carries it to the boundary instead, and the status\n // stays 200 because the status line has gone.\n if (currentNotFound()) return null;\n\n return new Response(appendLateRedirect(htmlStream, taken), {\n headers: withVersion({\n \"Content-Type\": HTML_TYPE,\n [HEADER.layouts]: chain.join(\",\"),\n Vary: VARY_ON_RSC,\n // The answer to a post is the result of something that happened\n // once; nothing may keep it.\n \"Cache-Control\": formPost\n ? \"no-store\"\n : match.route.middleware?.length\n ? PER_CLIENT\n : REVALIDATE,\n }),\n });\n });\n }\n\n const from = sharedDepth(request.headers.get(HEADER.segments), chain);\n\n // A boot - X-RSC and no segments - of a document served from a pattern\n // shell: the shell was rendered for no url, and the client hydrates\n // this payload against it, so the hooks are told nothing here either\n // and read the browser's url once hydration is done. A navigation to\n // the same url renders for it, as it is client-rendered, not hydrated.\n const boot = request.headers.get(HEADER.segments) === null;\n const pathname =\n boot && (await servedFromPatternShell(url, match)) ? null : url.pathname;\n\n // Proposed by the host, decided by the engine: an interceptor can force a\n // wider render than the client asked for, so what goes back is the depth\n // that came out, never the one that went in.\n return await withRedirect(async (taken) => {\n let stream: ReadableStream;\n let segmentDepth: number;\n\n try {\n ({ stream, segmentDepth } = await engine.handleRscStream(\n match.route.component,\n props,\n layouts,\n match.route.loadings,\n match.route.slots,\n {},\n from,\n url.pathname,\n pathname,\n ));\n } catch (error) {\n // Same reasoning as the document path: what the render recorded is\n // reliable, what React re-raised is not.\n const refused = taken();\n\n if (refused) return redirectResponse(refused, true);\n\n // Same answer the document path gives, so a client navigating to a\n // url and a browser loading it fresh agree about whether it exists.\n if (currentNotFound()) return null;\n\n // A payload request is guarded exactly as the document is. Narrowing\n // a request must never narrow what is checked.\n const status = refusalStatus(error);\n\n if (status) return new Response(refusalMessage(error), { status });\n throw error;\n }\n\n const early = taken();\n\n // 204 and a header. A payload request that redirected later than this\n // carries the destination in the error digest instead, and the client's\n // RedirectBoundary performs it.\n if (early) return redirectResponse(early, true);\n\n return new Response(stream, {\n headers: withVersion({\n \"Content-Type\": FLIGHT_TYPE,\n [HEADER.segmentDepth]: String(segmentDepth),\n [HEADER.layouts]: chain.join(\",\"),\n Vary: VARY_ON_RSC,\n \"Cache-Control\": PER_CLIENT,\n }),\n });\n });\n }\n\n /**\n * A page rendered at build time, if there is one for this url.\n *\n * The payload has to match the depth the client shares, not simply exist.\n * Serving the whole document to a client that already holds the layouts\n * replaces the root — and replacing the root unmounts everything retained\n * behind it, so going back stops restoring what you had.\n */\n /**\n * The shell an edge cache may hold, for a route named by `?url=`.\n *\n * Only ever a build artifact, so there is nothing here that belongs to\n * whoever asked. What it deliberately does NOT return is the postponed\n * state. Next's protocol hands that to the CDN and takes it back on the\n * resume, which makes the resume endpoint parse a blob an attacker can write\n * — the shape of a known denial-of-service against it. Our origin has the\n * file already, so the state never needs to leave.\n *\n * A guarded route is refused outright rather than guarded here. Its shell is\n * not cacheable by a shared cache at all, so handing one to an edge that\n * exists to cache things is an invitation to a mistake nobody would see.\n */\n /**\n * The answer the build stored for this route, if it stored one.\n *\n * Three conditions, each closing a way the stored answer could be wrong:\n *\n * GET or HEAD, because a stored answer to a POST is a stored answer to\n * something that was meant to happen once.\n *\n * No query string. The build answered the bare url, and a route that reads\n * the query would answer differently for every one — so rather than trying\n * to detect that during the probe, anything carrying a query goes to the\n * route itself. A stored answer is for the url it was stored for.\n *\n * No middleware. A guarded route answers differently depending on who is\n * asking, which is the point of the guard; one stored answer served to\n * everyone is how a guard is quietly removed. The build refuses to store one\n * for the same reason, so this is the second of two locks on the same door.\n */\n async function frozenApi(\n request: Request,\n url: URL,\n api: MatchedApiRoute,\n ): Promise<Response | null> {\n if (!options.prerendered) return null;\n if (request.method !== \"GET\" && request.method !== \"HEAD\") return null;\n if (api.route.middleware.length > 0) return null;\n\n const stored = await options.prerendered(apiKey(url.pathname));\n\n if (stored === null) return null;\n\n let frozen: FrozenApiResponse;\n\n try {\n frozen = JSON.parse(stored) as FrozenApiResponse;\n } catch {\n // A file this host wrote and cannot read back is a bug, not a request\n // to answer badly. Falling through runs the route, which is correct.\n return null;\n }\n\n // The build said whether this route's answer depends on the query. A route\n // that never awaited searchParams gives the same answer whatever is on the\n // end of the url — which matters more than it sounds, because every\n // ?utm_source= and ?fbclid= would otherwise miss the stored answer.\n //\n // Defaulting to varying when the field is absent: a file written by an\n // older build did not record this, and serving it for every query would be\n // guessing on the unsafe side.\n if (url.search && frozen.varies !== false) return null;\n\n const answer = new Response(request.method === \"HEAD\" ? null : frozen.body, {\n status: frozen.status,\n headers: withVersion(Object.fromEntries(frozen.headers)),\n });\n\n servedFrom.set(answer, \"stored\");\n\n return answer;\n }\n\n async function servePprShell(\n request: Request,\n url: URL,\n read: NonNullable<RscHostOptions[\"prerendered\"]>,\n ): Promise<Response | null> {\n if (request.method !== \"GET\" && request.method !== \"HEAD\") return null;\n\n const target = url.searchParams.get(\"url\");\n\n if (!target || !target.startsWith(\"/\")) {\n return new Response(\"A url is required\", { status: 400 });\n }\n\n // Matched from the url asked for, never from anything else the caller sent.\n const route = matchRoute(routes, new URL(target, url.origin).pathname);\n\n if (!route) return new Response(\"No such page\", { status: 404 });\n\n if (route.route.middleware?.length) {\n return new Response(\"This route is not edge-cacheable\", { status: 404 });\n }\n\n const key = pathKey(new URL(target, url.origin).pathname);\n const shell =\n (await read(`${key}.ppr.html`)) ??\n (await read(`${patternKey(route.route)}.ppr.html`));\n\n if (shell === null)\n return new Response(\"No shell for this page\", { status: 404 });\n\n return new Response(JSON.stringify({ shell, version: version ?? null }), {\n headers: withVersion({\n \"Content-Type\": \"application/json\",\n // Deliberately NOT the REVALIDATE the rest of the host sends. That is\n // `max-age=0, must-revalidate`, which a cache honours by treating the\n // entry as stale the moment it arrives — an edge would store this and\n // never once serve it, so the whole thing would quietly do nothing\n // while looking like it worked, because the miss path serves correct\n // pages.\n //\n // This is build output with nothing of the caller in it, and a guarded\n // route never reaches here at all, so it is genuinely cacheable. An\n // hour bounds how long a deploy can be served against a stale shell;\n // the version below catches it sooner than that.\n \"Cache-Control\": \"public, max-age=3600\",\n }),\n });\n }\n\n /**\n * Finish a shell for the visitor this request belongs to.\n *\n * The whole security question lives here, because the holes are the part a\n * guard exists to protect — the shell is chrome, and everything private is\n * behind the boundaries this fills in. So it runs exactly the guard chain the\n * page itself would, derived from the url and nothing else, against the\n * cookies and headers the caller actually sent.\n *\n * Which means an edge worker must forward the visitor's request, not make one\n * of its own. A resume asked for with no cookies is an anonymous visitor and\n * gets an anonymous answer.\n */\n async function servePprResume(\n request: Request,\n url: URL,\n read: NonNullable<RscHostOptions[\"prerendered\"]>,\n ): Promise<Response | null> {\n const target = url.searchParams.get(\"url\");\n\n if (!target || !target.startsWith(\"/\")) {\n return new Response(\"A url is required\", { status: 400 });\n }\n\n const pathname = new URL(target, url.origin).pathname;\n const route = matchRoute(routes, pathname);\n\n if (!route) return new Response(\"No such page\", { status: 404 });\n\n // The same refusal the document would get, before a byte of the holes is\n // rendered. Nothing below runs for a caller this turns away.\n const refusal = await refuseUnlessAllowed(request, route);\n\n if (refusal) return refusal;\n\n if (!engine.handleRscResume) {\n return new Response(\"This engine cannot resume\", { status: 500 });\n }\n\n const key = pathKey(pathname);\n const pattern = patternKey(route.route);\n\n let shellKey: string | null = null;\n\n if ((await read(`${key}.ppr.html`)) !== null) shellKey = key;\n else if ((await read(`${pattern}.ppr.html`)) !== null) shellKey = pattern;\n\n // Read from our own artifacts. Never from the request body — that is the\n // difference between this and the protocol it is modelled on.\n const state =\n shellKey === null ? null : await read(`${shellKey}.postponed.json`);\n\n if (state === null)\n return new Response(\"Nothing to resume\", { status: 404 });\n\n const { htmlStream } = await engine.handleRscResume(\n route.route.component,\n route.params,\n route.route.layouts.map((component) => ({ component, props: {} })),\n route.route.loadings,\n route.route.slots,\n {},\n JSON.parse(state),\n undefined,\n shellKey === key ? pathname : \"\",\n pathname,\n );\n\n // Carries the build version so a caller holding a cached shell can tell\n // that it no longer belongs to this origin. A shell from an older build\n // does not make the resume fail — it replays against slots that have moved\n // and React falls back to client rendering, silently and for good. Nothing\n // else would ever report it.\n return new Response(htmlStream, {\n headers: withVersion({\n \"Content-Type\": HTML_TYPE,\n // Rendered for whoever asked. Never cacheable.\n \"Cache-Control\": PER_CLIENT,\n }),\n });\n }\n\n async function servePrerendered(\n request: Request,\n url: URL,\n source: NonNullable<RscHostOptions[\"prerendered\"]>,\n ): Promise<Response | null> {\n const key = pathKey(url.pathname);\n const read = async (name: string) => await source(name);\n\n // Before anything else: a route that only redirects was frozen as the\n // redirect itself, so there is no page under this url and never will be.\n const frozenRedirect = await read(`${key}.redirect.json`);\n\n if (frozenRedirect !== null) {\n const to = JSON.parse(frozenRedirect) as {\n status: number;\n location: string;\n };\n\n return redirectResponse(to, request.headers.get(HEADER.rsc) !== null);\n }\n\n if (request.headers.get(HEADER.rsc) === null) {\n // A frozen page first; then a shell, under this url or under the route's\n // pattern. Nothing in a shell varies by param, so one shell serves every\n // url its route matches — which is the only way a route whose urls were\n // never listed gets anything frozen at all.\n const route = matchPage(routes, url);\n const whole = await read(`${key}.html`);\n\n // A whole page is finished. Nothing to resume, nothing to render.\n if (whole !== null) {\n const response = new Response(whole, {\n headers: withVersion({\n \"Content-Type\": HTML_TYPE,\n Vary: VARY_ON_RSC,\n \"Cache-Control\": route?.route.middleware?.length\n ? PER_CLIENT\n : REVALIDATE,\n }),\n });\n\n // Its head is in hand, so its fonts are too. Read once per file.\n let found = hintsByKey.get(key);\n\n if (!found) {\n found = criticalAssetsOf(whole);\n hintsByKey.set(key, found);\n }\n\n hinted.set(response, found);\n\n return response;\n }\n\n // Then a shell, under this url or under the route's pattern. Which of the\n // two answered is tracked, because the state that resumes it sits beside\n // the file that was found rather than beside the url that was asked for.\n let shellKey: string | null = null;\n let shell = await read(`${key}.ppr.html`);\n\n if (shell !== null) {\n shellKey = key;\n } else if (route) {\n const pattern = patternKey(route.route);\n\n shell = await read(`${pattern}.ppr.html`);\n\n if (shell !== null) shellKey = pattern;\n }\n\n if (shell === null || shellKey === null) return null;\n\n const state = await read(`${shellKey}.postponed.json`);\n\n // A shell with no state cannot be finished by anyone. It was frozen with\n // its fallbacks showing and there is no record of what came next, so\n // serving it would be serving a page that stays on its loading state for\n // good. Fall through and render the page now instead.\n if (state === null || !engine.handleRscResume || !route) return null;\n\n const { htmlStream } = await engine.handleRscResume(\n route.route.component,\n route.params,\n // Empty props, because that is what the build passed. Resuming replays\n // the tree against the slots the shell left, and React matches those by\n // key — so an argument that differs from the frozen render at all is a\n // tree that \"doesn't match\", and every boundary falls back to the\n // client instead of being filled here.\n route.route.layouts.map((component) => ({ component, props: {} })),\n route.route.loadings,\n route.route.slots,\n {},\n JSON.parse(state),\n undefined,\n // A shell found under the route's pattern was frozen for no particular\n // url, so it was rendered with no page key. Handing one over now would\n // key the tree differently from the one being resumed.\n shellKey === key ? url.pathname : \"\",\n // But the url itself, for the hooks: the holes are rendered for it.\n url.pathname,\n );\n\n // A shell stored for the pattern was built without a url, so its title\n // is the layouts' - the page's generateMetadata reads the params and\n // was left out. This request has the params.\n const served =\n shellKey === key || !engine.resolveMetadata\n ? shell\n : withHead(\n shell,\n await engine\n .resolveMetadata(\n route.route.component,\n route.params,\n route.route.layouts.map((component) => ({ component, props: {} })),\n )\n .catch(() => null),\n );\n\n // The shell first, then whatever the resume writes. React's own script\n // travels with the resumed segments and moves them into place, so this is\n // a plain concatenation and the holes land without hydration.\n const body = new ReadableStream({\n async start(controller) {\n controller.enqueue(new TextEncoder().encode(served));\n\n const reader = htmlStream.getReader();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) break;\n\n controller.enqueue(value);\n }\n } finally {\n controller.close();\n }\n },\n });\n\n const withHoles = new Response(body, {\n headers: withVersion({\n \"Content-Type\": HTML_TYPE,\n Vary: VARY_ON_RSC,\n // The shell is cacheable; this response is not. It carries the holes,\n // which were rendered for whoever asked.\n \"Cache-Control\": PER_CLIENT,\n }),\n });\n\n servedFrom.set(withHoles, \"shell\");\n\n // The shell's head is the document's head; its fonts are known too.\n let found = hintsByKey.get(shellKey);\n\n if (!found) {\n found = criticalAssetsOf(shell);\n hintsByKey.set(shellKey, found);\n }\n\n hinted.set(withHoles, found);\n\n return withHoles;\n }\n\n // Only the document is ever served frozen for a shell. The payload is what\n // fills it in, and it has to be rendered now — answering with a frozen one\n // would hand back the same fallbacks the shell already shows, and the page\n // would never finish loading.\n\n const meta = await read(`${key}.meta.json`);\n\n // Both or neither: without the chain there is no way to know which depth a\n // payload is for, and guessing means handing the client a segment for a\n // boundary it does not have.\n if (meta === null) return null;\n\n const chain = (JSON.parse(meta).layouts ?? []) as string[];\n const shared = sharedDepth(request.headers.get(HEADER.segments), chain);\n\n // The variant for exactly this depth, or the whole document. Anything else\n // would be a payload for a boundary the client is not holding.\n const variant =\n shared > 0 ? await read(`${key}.seg${shared}.flight`) : null;\n const payload = variant ?? (await read(`${key}.flight`));\n\n if (payload === null) return null;\n\n // As cacheable as the document it boots: the same build-time bytes for\n // everyone, unless a guard above the route decides who may have them.\n // Marked no-store, the service worker refused to keep it, and a\n // precached page rendered offline and never hydrated - the markup was\n // there and the payload it boots from was not.\n const guarded = matchPage(routes, url)?.route.middleware?.length ?? 0;\n\n return new Response(payload, {\n headers: withVersion({\n \"Content-Type\": FLIGHT_TYPE,\n [HEADER.segmentDepth]: String(variant ? shared : 0),\n [HEADER.layouts]: chain.join(\",\"),\n Vary: VARY_ON_RSC,\n \"Cache-Control\": guarded ? PER_CLIENT : REVALIDATE,\n }),\n });\n }\n\n /**\n * The middleware of a route, or null to go ahead.\n *\n * Used wherever a render can be reached without the engine running the chain\n * itself: a page served from disk, and an interception, which renders a\n * component the route table did not choose.\n *\n * Asked before anything is read or rendered — the answer to a refusal must\n * not be a page that has already been fetched.\n */\n async function refuseUnlessAllowed(\n request: Request,\n match: MatchedRoute | null,\n ): Promise<Response | null> {\n // hostMiddleware as well as the engine's own. A page served from disk\n // never touches the engine, so a route guarded only by the host would be\n // handed over without anyone being asked — the guard would hold right up\n // until the build froze the page, then silently stop.\n if (!match) return null;\n\n const guarded =\n (match.route.middleware?.length ?? 0) > 0 ||\n (match.route.hostMiddleware?.length ?? 0) > 0;\n\n if (!guarded) return null;\n\n // A route that declares middleware and an engine that cannot run it is not\n // \"no middleware\" — it is a check that silently does not happen. Refusing\n // is the only safe reading, and it names the cause rather than serving the\n // guarded page. Reachable when a host runs a bundle built by an older\n // plugin, where the export did not exist.\n if (!engine.runRouteMiddleware) {\n return new Response(\n \"This route declares middleware, and the engine cannot run it. \" +\n \"Rebuild the app against the current @rsc-kit/core.\",\n { status: 500 },\n );\n }\n\n const asPayload = request.headers.get(HEADER.rsc) !== null;\n\n return await withRedirect(async (taken) => {\n try {\n await engine.runRouteMiddleware!(\n match.route.component,\n await propsFor(match, request),\n );\n } catch (error) {\n const refused = taken();\n\n if (refused) return redirectResponse(refused, asPayload);\n\n // A visitor who may not see this page has not caused a server\n // error. Answering 500 makes a guarded route indistinguishable from\n // a broken one, in the logs and to the person looking at it.\n const status = refusalStatus(error);\n\n if (status) return new Response(refusalMessage(error), { status });\n\n throw error;\n }\n\n const refused = taken();\n\n return refused ? redirectResponse(refused, asPayload) : null;\n });\n }\n\n async function handleRevalidate(\n request: Request,\n url: URL,\n target: string,\n ): Promise<Response> {\n if (!engine.handleRscRevalidate) {\n return new Response(\"This build cannot revalidate\", { status: 501 });\n }\n\n const match = matchPage(routes, url);\n\n if (!match) return new Response(\"No such page\", { status: 404 });\n\n // Scoped like the render paths: a guard above the target may refuse, and\n // that refusal is an answer rather than a failure.\n return await withRedirect(async (taken) => {\n let rscPayload: string;\n\n try {\n ({ rscPayload } = await engine.handleRscRevalidate!(\n target,\n pageContext(match, await propsFor(match, request)),\n ));\n } catch (error) {\n const refused = taken();\n\n if (refused) return redirectResponse(refused, true);\n\n throw error;\n }\n\n const refused = taken();\n\n if (refused) return redirectResponse(refused, true);\n\n return new Response(rscPayload, {\n headers: withVersion({\n \"Content-Type\": FLIGHT_TYPE,\n // Echoed so the client can tell which region it is holding.\n [HEADER.revalidate]: target,\n Vary: VARY_ON_RSC,\n \"Cache-Control\": \"private, no-store\",\n }),\n });\n });\n }\n\n async function handleIntercept(\n request: Request,\n url: URL,\n slot: string,\n ): Promise<Response> {\n const intercept = matchIntercept(routes, url.pathname, slot);\n\n if (!intercept)\n return new Response(\"No interceptor for this url\", { status: 404 });\n\n // The guards of the route being intercepted, before anything is rendered.\n //\n // An interceptor exists to show the same resource as the route it stands in\n // for — a modal over /orders/[id] shows that order. So it has to be behind\n // the same checks, and nothing else in this path runs them: the engine is\n // handed the interceptor component, which the route table did not choose\n // and whose middleware chain is keyed off manifest().routes, where an\n // interceptor does not appear.\n //\n // Derived from the url, never from X-RSC-Referer. The referer is a header\n // the caller writes, and guarding by it means the caller picks the guard.\n const intercepted = matchPage(routes, url);\n\n // Nothing to guard means nothing to serve. A url that matches an\n // interceptor but no route has no middleware chain to consult, so there is\n // no way to know whether this caller may see it — and an interceptor\n // stands in for a route, so a url with no route behind it is not a page\n // anyone was entitled to open a modal over.\n if (!intercepted) return new Response(\"No such page\", { status: 404 });\n\n const refusal = await refuseUnlessAllowed(request, intercepted);\n\n if (refusal) return refusal;\n\n const from = refererPath(\n request.headers.get(HEADER.referer),\n url.origin,\n siteHosts,\n );\n const under = from ? matchRoute(routes, from) : null;\n\n // Without a page to open over there is nothing to intercept: render the\n // interceptor on its own rather than answering with the wrong page.\n const component = under ? under.route.component : intercept.component;\n const props = under ? await propsFor(under, request) : intercept.params;\n const chain = under ? under.route.layouts : [];\n const slots = under ? under.route.slots : {};\n const loadings = under ? under.route.loadings : [];\n\n // The interceptor alone, when there is a page to open it over and this\n // build can render a region on its own.\n //\n // Re-rendering the page underneath would put the modal on screen at the\n // cost of rebuilding everything below the layout that declares the slot —\n // so opening a modal from a half-filled form throws the form away. The\n // page beneath is already mounted and correct; only the slot is new.\n if (under && engine.handleRscRevalidate) {\n const { rscPayload } = await engine.handleRscRevalidate(slot, {\n component: under.route.component,\n // The target's params, not the page's: a modal for /posts/hello opened\n // from /feed is about hello.\n props: intercept.params,\n layouts: [],\n loadings: [],\n // Named as the slot so the renderer finds it there, but pointing at\n // the interceptor rather than the default this route would otherwise\n // fill it with.\n parallelSlots: { [slot]: intercept.component },\n });\n\n return new Response(rscPayload, {\n headers: withVersion({\n \"Content-Type\": FLIGHT_TYPE,\n // Says what this payload is, so the client puts it in the slot\n // instead of treating it as a segment of the page.\n [HEADER.revalidate]: slot,\n Vary: VARY_ON_RSC,\n // Per-client by construction: which region this is was chosen by a\n // request header, so a shared cache has nothing useful to key on.\n \"Cache-Control\": \"private, no-store\",\n }),\n });\n }\n\n const { stream, segmentDepth } = await engine.handleRscStream(\n component,\n props,\n chain.map((layout) => ({ component: layout, props: {} })),\n loadings,\n slots,\n {},\n sharedDepth(request.headers.get(HEADER.segments), chain),\n retentionKey(url.pathname, slot),\n );\n\n return new Response(stream, {\n headers: withVersion({\n \"Content-Type\": FLIGHT_TYPE,\n [HEADER.segmentDepth]: String(segmentDepth),\n [HEADER.layouts]: chain.join(\",\"),\n Vary: VARY_ON_RSC,\n \"Cache-Control\": PER_CLIENT,\n }),\n });\n }\n\n /**\n * Run an api route's middleware, and answer instead of it if one refuses.\n *\n * Separate from the page version because the answer is different. A caller\n * that is not a browser gets a status rather than a redirect to a login page\n * it cannot render — a fetch would follow the 302 and hand back the login\n * HTML as though it were the api's answer.\n */\n async function refuseApiUnlessAllowed(\n request: Request,\n api: {\n route: { name: string; middleware?: string[] };\n params: Record<string, string>;\n },\n ): Promise<Response | null> {\n if (!(api.route.middleware?.length ?? 0)) return null;\n\n // A route that declares middleware and an engine that cannot run it is not\n // \"no middleware\" — it is a check that silently does not happen.\n if (!engine.runRouteMiddleware) {\n return new Response(\n \"This route declares middleware, and the engine cannot run it. \" +\n \"Rebuild the app against the current @rsc-kit/core.\",\n { status: 500 },\n );\n }\n\n return await withRedirect(async (taken) => {\n try {\n await engine.runRouteMiddleware!(api.route.name, api.params);\n } catch (error) {\n // A redirect is a refusal here. Where it was going is told rather than\n // followed, so a client can decide for itself.\n const redirected = taken();\n\n if (redirected) return apiRedirect(request, redirected);\n\n // A visitor who may not use this endpoint has not caused a server\n // error, and answering 500 makes a guarded route indistinguishable\n // from a broken one. Null means the middleware threw something that is\n // not a refusal, which is a real fault and says so.\n const status = refusalStatus(error);\n\n if (status === null) throw error;\n\n return new Response(status === 401 ? \"Unauthorized\" : \"Forbidden\", {\n status,\n });\n }\n\n const redirected = taken();\n\n if (redirected) return apiRedirect(request, redirected);\n\n return null;\n });\n }\n\n /**\n * A guard's redirect on a route.ts, answered for whoever asked.\n *\n * A browser that navigated here - followed a link to the route, typed the\n * url - is sent on with a real Location; a 401 would show it \"Unauthorized\"\n * over a page it cannot see. Code that fetched the route is told instead:\n * fetch follows a Location on its own and would hand back the login page's\n * html as the endpoint's answer, so it gets the 401 with the destination in\n * a header, and decides for itself.\n */\n function apiRedirect(request: Request, to: Redirection): Response {\n if (isNavigation(request)) return redirectResponse(to, false);\n\n return new Response(\"Unauthorized\", {\n status: 401,\n headers: { \"X-RSC-Redirect\": to.location },\n });\n }\n\n async function handleQuery(\n request: Request,\n url: URL,\n ): Promise<Response | null> {\n if (!engine.handleQuery) return null;\n\n // Required, and the reason is CSRF rather than routing. A GET carrying no\n // unusual header is a SIMPLE request: any page anywhere can trigger one\n // with <img src=\"…/_rsc/query?…\"> and it goes out with the visitor's\n // cookies. CORS stops them reading the answer; it does not stop the read\n // running. This header is not CORS-safelisted, so a browser preflights it\n // and nothing here answers a preflight — the same protection a POST\n // carrying X-RSC-Action already had.\n if (!request.headers.get(HEADER.query)) {\n return new Response(\"Missing \" + HEADER.query, { status: 400 });\n }\n\n const id = url.searchParams.get(\"id\");\n const args = url.searchParams.get(\"args\");\n\n if (!id || args === null)\n return new Response(\"Missing id or args\", { status: 400 });\n\n // Enforced here as well as in the client, because the limit is what keeps\n // an attacker from making this endpoint decode megabytes of their payload\n // per request.\n if (url.search.length > MAX_QUERY)\n return new Response(\"Query too large\", { status: 414 });\n\n const answered = await engine.handleQuery(id, args);\n\n // Unknown id and registered-but-not-a-query are the same answer on purpose.\n if (!answered) return new Response(\"No such query\", { status: 404 });\n\n // The read refused. Answered as a status with the message in the body, so\n // the fetcher rejects with something a person can read — a failure rendered\n // into a 200 would reach the browser as React's opaque error instead.\n if (!(\"stream\" in answered)) {\n return new Response(\n JSON.stringify({ message: answered.message, errors: answered.errors }),\n {\n status: answered.status,\n headers: withVersion({\n \"Content-Type\": \"application/json\",\n \"Cache-Control\": PER_CLIENT,\n }),\n },\n );\n }\n\n return new Response(answered.stream, {\n headers: withVersion({\n \"Content-Type\": FLIGHT_TYPE,\n \"Cache-Control\": answered.cacheControl,\n // The answer is narrowed by who is asking whenever a read touches the\n // session, and the request that carries that is the cookie. Without\n // this a shared cache keyed on the url alone hands one visitor\n // another's answer — for any query that opted out of no-store.\n Vary: \"Cookie, \" + HEADER.referer,\n }),\n });\n }\n\n async function handleAction(request: Request, url: URL): Promise<Response> {\n const actionId = request.headers.get(HEADER.action);\n\n if (!actionId) return new Response(\"Missing X-RSC-Action\", { status: 400 });\n\n // The body travels as application/octet-stream so a host that parses\n // multipart cannot consume it first; its real type rides in a header.\n const body = await readBodyUpTo(request, maxActionBody);\n\n if (body === null) {\n return new Response(`Action body over ${maxActionBody} bytes`, {\n status: 413,\n });\n }\n\n const contentType =\n request.headers.get(HEADER.contentType) ?? \"text/plain;charset=UTF-8\";\n\n // Where it was invoked from, so anything the action invalidates can be\n // re-rendered against the page that is actually on screen.\n const from = refererPath(\n request.headers.get(HEADER.referer),\n url.origin,\n siteHosts,\n );\n const match = from ? matchRoute(routes, from) : null;\n const page = match\n ? pageContext(match, await propsFor(match, request), from ?? undefined)\n : undefined;\n\n // Scoped to this action: revalidate() called anywhere inside it, at any\n // depth, marks here and nowhere else — two requests can be in flight and\n // marking is per-request state. And redirect(): the guide says \"throw\n // from the action and the client follows it\", and the client does\n // follow an X-RSC-Redirect on an action's response — but the signal the\n // throw raises was never caught here, so every login that redirected\n // after signing in was a 500. Caught, it is the instruction the client\n // already knows how to read.\n return await withRedirect(async (redirected) => {\n let stream: ReadableStream;\n\n try {\n ({ stream } = await withRevalidation((taken) =>\n engine.handleAction(actionId, body, contentType, page, taken),\n ));\n } catch (error) {\n const to = redirected();\n\n if (to) return redirectResponse(to, true);\n\n throw error;\n }\n\n return new Response(stream, {\n headers: withVersion({\n \"Content-Type\": \"text/x-component; charset=utf-8\",\n }),\n });\n });\n }\n}\n"]}
|
|
@@ -45,6 +45,12 @@ interface Entry {
|
|
|
45
45
|
* however long ago that was.
|
|
46
46
|
*/
|
|
47
47
|
at: number;
|
|
48
|
+
/**
|
|
49
|
+
* Its place in the order things happened, for the question "was this
|
|
50
|
+
* here before the mutation?" - which a clock answers wrongly for a seed
|
|
51
|
+
* and a write in the same millisecond, and a test hit exactly that.
|
|
52
|
+
*/
|
|
53
|
+
seq: number;
|
|
48
54
|
/**
|
|
49
55
|
* Rendered before the click, hidden, on the strength of a touch or a
|
|
50
56
|
* settled hover - see prerenderSegment. Outside the retention window: it
|
package/dist/js/segmentStore.js
CHANGED
|
@@ -37,7 +37,9 @@
|
|
|
37
37
|
/** Pages kept alive per boundary. Four covers ordinary back-and-forth. */
|
|
38
38
|
export const RETENTION = 4;
|
|
39
39
|
const depths = new Map();
|
|
40
|
-
/**
|
|
40
|
+
/** A counter every entry takes a number from, in order. */
|
|
41
|
+
let tick = 0;
|
|
42
|
+
/** The number the last mutation took: everything held before it is wrong. */
|
|
41
43
|
let invalidatedAt = 0;
|
|
42
44
|
const listeners = new Map();
|
|
43
45
|
function notify(depth) {
|
|
@@ -74,7 +76,7 @@ function put(depth, key, tree) {
|
|
|
74
76
|
const state = depths.get(depth);
|
|
75
77
|
const entries = [
|
|
76
78
|
...(state?.entries ?? []).filter((entry) => entry.key !== key),
|
|
77
|
-
{ key, tree, at: Date.now() },
|
|
79
|
+
{ key, tree, at: Date.now(), seq: ++tick },
|
|
78
80
|
];
|
|
79
81
|
const order = [...(state?.order ?? []).filter((k) => k !== key), key];
|
|
80
82
|
depths.set(depth, retain(entries, order, key));
|
|
@@ -133,7 +135,7 @@ export function prerenderSegment(depth, key, tree) {
|
|
|
133
135
|
...state,
|
|
134
136
|
entries: [
|
|
135
137
|
...state.entries.filter((entry) => !entry.speculative),
|
|
136
|
-
{ key, tree, at: Date.now(), speculative: true },
|
|
138
|
+
{ key, tree, at: Date.now(), seq: ++tick, speculative: true },
|
|
137
139
|
],
|
|
138
140
|
});
|
|
139
141
|
notify(depth);
|
|
@@ -161,9 +163,16 @@ export function replaceActive(depth, tree) {
|
|
|
161
163
|
const active = state.entries.find((entry) => entry.key === state.activeKey);
|
|
162
164
|
if (!active || active.tree === tree)
|
|
163
165
|
return;
|
|
166
|
+
// The tree changes; when the entry arrived does not. A layout's entry is
|
|
167
|
+
// keyed by the page it was seeded with - "/" for a document loaded at
|
|
168
|
+
// home - and stays active through every navigation below it. Stamped
|
|
169
|
+
// with the re-render's time it read as held since the mutation, and a
|
|
170
|
+
// tap on the brand link after "Add to cart" revealed it: the url went
|
|
171
|
+
// to "/" and the product stayed, because the tree under that key was
|
|
172
|
+
// now the product's document. See dropHidden and isHeld.
|
|
164
173
|
depths.set(depth, {
|
|
165
174
|
...state,
|
|
166
|
-
entries: state.entries.map((entry) => (entry === active ? { ...entry, tree
|
|
175
|
+
entries: state.entries.map((entry) => (entry === active ? { ...entry, tree } : entry)),
|
|
167
176
|
});
|
|
168
177
|
notify(depth);
|
|
169
178
|
}
|
|
@@ -182,7 +191,7 @@ export function seedSegment(depth, key, tree) {
|
|
|
182
191
|
}
|
|
183
192
|
// Older than whatever is showing, so it goes to the front of the eviction
|
|
184
193
|
// order — and crucially does not become the active page.
|
|
185
|
-
depths.set(depth, retain([...state.entries, { key, tree, at: Date.now() }], [key, ...state.order.filter((k) => k !== key)], state.activeKey));
|
|
194
|
+
depths.set(depth, retain([...state.entries, { key, tree, at: Date.now(), seq: ++tick }], [key, ...state.order.filter((k) => k !== key)], state.activeKey));
|
|
186
195
|
notify(depth);
|
|
187
196
|
}
|
|
188
197
|
/**
|
|
@@ -207,7 +216,7 @@ export function seedSegment(depth, key, tree) {
|
|
|
207
216
|
* wasted payload per navigation.
|
|
208
217
|
*/
|
|
209
218
|
export function isHeld(key, maxAge) {
|
|
210
|
-
const ages = [...depths.values()].flatMap((state) => state.entries.filter((entry) => entry.key === key && !entry.speculative && entry.
|
|
219
|
+
const ages = [...depths.values()].flatMap((state) => state.entries.filter((entry) => entry.key === key && !entry.speculative && entry.seq > invalidatedAt).map((entry) => entry.at));
|
|
211
220
|
if (ages.length === 0)
|
|
212
221
|
return false;
|
|
213
222
|
if (maxAge === undefined)
|
|
@@ -227,7 +236,7 @@ export function dropHidden() {
|
|
|
227
236
|
// before it too. A layout's entry is keyed by the page it was seeded
|
|
228
237
|
// with, and revealing that key later shows the page inside it as it was
|
|
229
238
|
// then. Nothing seeded before this moment is revealed again.
|
|
230
|
-
invalidatedAt =
|
|
239
|
+
invalidatedAt = ++tick;
|
|
231
240
|
for (const [depth, state] of depths) {
|
|
232
241
|
if (state.entries.length <= 1 && !state.entries.some((entry) => entry.speculative))
|
|
233
242
|
continue;
|
|
@@ -254,7 +263,7 @@ export function restoreSegments(key, maxAge) {
|
|
|
254
263
|
// data as the page the visitor was on. The navigation takes the
|
|
255
264
|
// prerendered tree through setSegment instead, where it is a reveal too.
|
|
256
265
|
// Nor is a page from before a mutation - see dropHidden.
|
|
257
|
-
const holding = [...depths.keys()].filter((d) => depths.get(d).entries.some((entry) => entry.key === key && !entry.speculative && entry.
|
|
266
|
+
const holding = [...depths.keys()].filter((d) => depths.get(d).entries.some((entry) => entry.key === key && !entry.speculative && entry.seq > invalidatedAt));
|
|
258
267
|
if (holding.length === 0)
|
|
259
268
|
return false;
|
|
260
269
|
if (maxAge !== undefined) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"segmentStore.js","sourceRoot":"","sources":["../../src/js/segmentStore.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * What each segment boundary is showing, and what it is keeping alive behind it.\n *\n * A navigation replaces one segment. Keeping the previous one mounted — hidden,\n * not unmounted — is what lets going back restore it with its client state:\n * the half-typed form, the open disclosure, the scrolled list. Unmounting\n * throws all of that away, which is what replacing the root used to do.\n *\n * Entries are keyed by page (the URL, or its intercept variant), so a boundary\n * can hold several and reveal one. Empty is meaningful: a boundary with nothing\n * stored renders the children the server gave it.\n *\n * A store rather than state, and not a preference — three things rule state out.\n * A boundary is inserted between every layout level, so there are several and a\n * navigation targets one by depth; they are separated by server components, so\n * no setter can be threaded down to them, because a function does not cross\n * that boundary; and navigate.ts is a plain module with no component instance\n * to call one on. Addressing a component you hold no reference to is what an\n * external store is for.\n *\n * Underneath it is the wire protocol. A partial navigation sends only the\n * segment that changed — see the X-RSC-Segments headers — so there is nothing\n * for a root to re-render with even if it held the state. Next.js keeps its\n * router in useState and derives every segment from it; that is the same trade\n * in the other direction.\n *\n * What it costs: React pins an external store's updates to synchronous\n * priority, because a store cannot be safely time-sliced. Synchronous is never\n * a transition, and anything that only runs for one — React's <ViewTransition>\n * among them — never ran for a navigation.\n *\n * Which is why SegmentBoundary does not read this with useSyncExternalStore\n * any more. The store still does the addressing, which is the part only it can\n * do; the boundary copies into state, so the render is a transition. See the\n * view transitions guide.\n */\n\ntype Tree = unknown;\ntype Listener = () => void;\n\ninterface Entry {\n key: string;\n tree: Tree;\n /**\n * When this tree arrived, so a link can decide whether it is still worth\n * revealing. The back button never asks — it means \"the page I was on\",\n * however long ago that was.\n */\n at: number;\n /**\n * Rendered before the click, hidden, on the strength of a touch or a\n * settled hover - see prerenderSegment. Outside the retention window: it\n * is a guess, and a guess must not evict a page the visitor was on. One\n * per depth; the next guess replaces it, and a navigation to anything\n * else drops it.\n */\n speculative?: boolean;\n}\n\n/**\n * Immutable: useSyncExternalStore compares snapshots by identity, so a new\n * object per read reads as \"changed every render\" and loops forever. Every\n * mutation replaces this wholesale; nothing edits one in place.\n */\ninterface DepthState {\n readonly entries: readonly Entry[];\n readonly activeKey: string;\n /** Most recently shown last; eviction takes from the front. */\n readonly order: readonly string[];\n}\n\n/** Pages kept alive per boundary. Four covers ordinary back-and-forth. */\nexport const RETENTION = 4;\n\nconst depths = new Map<number, DepthState>();\n/** When a mutation last made everything held before it wrong. */\nlet invalidatedAt = 0;\nconst listeners = new Map<number, Set<Listener>>();\n\nfunction notify(depth: number): void {\n for (const listener of listeners.get(depth) ?? []) listener();\n}\n\nexport function subscribeToSegment(\n depth: number,\n listener: Listener,\n): () => void {\n let set = listeners.get(depth);\n\n if (!set) {\n set = new Set();\n listeners.set(depth, set);\n }\n\n set.add(listener);\n\n return () => {\n set!.delete(listener);\n if (set!.size === 0) listeners.delete(depth);\n };\n}\n\n/** Everything a boundary at this depth needs to render, or null for \"use children\". */\nexport function getSegmentState(depth: number): DepthState | null {\n return depths.get(depth) ?? null;\n}\n\n/** Apply the retention window to a candidate state. */\nfunction retain(\n entries: readonly Entry[],\n order: readonly string[],\n activeKey: string,\n): DepthState {\n const kept = order.slice(-RETENTION);\n\n return {\n entries: entries.filter((entry) => kept.includes(entry.key) || entry.speculative),\n order: kept,\n activeKey,\n };\n}\n\nfunction put(depth: number, key: string, tree: Tree): void {\n const state = depths.get(depth);\n const entries = [\n ...(state?.entries ?? []).filter((entry) => entry.key !== key),\n { key, tree, at: Date.now() },\n ];\n const order = [...(state?.order ?? []).filter((k) => k !== key), key];\n\n depths.set(depth, retain(entries, order, key));\n}\n\n/**\n * Show `tree` at `depth` for `key`, retaining what was there.\n *\n * Deeper segments belonged to the page being replaced; leaving them would\n * render the previous page inside the new one.\n */\nexport function setSegment(depth: number, key: string, tree: Tree): void {\n // A guess about another page was wrong; the one about this page, if there\n // was one, is replaced by put() below - with the same tree, when the\n // prerender and the navigation read the same decoded payload, which is\n // what makes the update a reveal rather than a render.\n dropSpeculative(depth, key);\n put(depth, key, tree);\n\n const stale = [...depths.keys()].filter((d) => d > depth);\n for (const d of stale) depths.delete(d);\n\n notify(depth);\n for (const d of stale) notify(d);\n}\n\nfunction dropSpeculative(depth: number, except?: string): void {\n const state = depths.get(depth);\n\n if (!state?.entries.some((entry) => entry.speculative && entry.key !== except)) return;\n\n depths.set(depth, {\n ...state,\n entries: state.entries.filter((entry) => !entry.speculative || entry.key === except),\n });\n}\n\n/**\n * Render a page hidden at `depth`, before any navigation to it.\n *\n * The click then finds the work done: setSegment with the same tree is a\n * bail-out for React - same element, same props - and the Activity flips\n * from hidden to visible. What was 87 ms of rendering on a phone, after\n * the tap, is paid before the finger lifts, at idle priority, yielding to\n * the scroll. Never changes what is showing, never counts against\n * retention, and a page already held needs nothing.\n */\nexport function prerenderSegment(depth: number, key: string, tree: Tree): void {\n const state = depths.get(depth);\n\n // Nothing at this depth yet: the boundary is still showing the server's\n // children, and it has no page key to keep them under. A guess would take\n // the store over with no active entry to show. seedSegment runs on mount,\n // so this is the gap between hydration and that effect; the click will\n // render.\n if (!state) return;\n\n if (state.entries.some((entry) => entry.key === key)) return;\n\n depths.set(depth, {\n ...state,\n entries: [\n ...state.entries.filter((entry) => !entry.speculative),\n { key, tree, at: Date.now(), speculative: true },\n ],\n });\n\n notify(depth);\n}\n\n/** Whether a page is rendered hidden at `depth`, ahead of a navigation to it. */\nexport function isPrerendered(depth: number, key: string): boolean {\n return depths.get(depth)?.entries.some((entry) => entry.key === key && entry.speculative) ?? false;\n}\n\n/**\n * Give the page on screen at `depth` a new tree, under the key it has.\n *\n * For revalidate(\"all\"): the whole document rendered again, in place. The\n * root hands its layout the new tree, the layout hands its boundary new\n * children, and a boundary that holds state would otherwise keep showing\n * the store's tree and drop the new one on the floor - or, cleared first,\n * re-key its Activity to the current url and remount everything under it.\n * Neither. The entry that is showing takes the new tree and keeps its key,\n * so React reconciles the page in place, and the boundary below gets its\n * new children the same way.\n */\nexport function replaceActive(depth: number, tree: Tree): void {\n const state = depths.get(depth);\n\n if (!state) return;\n\n const active = state.entries.find((entry) => entry.key === state.activeKey);\n\n if (!active || active.tree === tree) return;\n\n depths.set(depth, {\n ...state,\n entries: state.entries.map((entry) => (entry === active ? { ...entry, tree, at: Date.now() } : entry)),\n });\n notify(depth);\n}\n\n/**\n * Record the children the server rendered, so the page you arrived on can be\n * returned to later. Never changes what is showing.\n */\nexport function seedSegment(depth: number, key: string, tree: Tree): void {\n const state = depths.get(depth);\n\n if (state?.entries.some((entry) => entry.key === key)) return;\n\n if (!state) {\n put(depth, key, tree);\n notify(depth);\n\n return;\n }\n\n // Older than whatever is showing, so it goes to the front of the eviction\n // order — and crucially does not become the active page.\n depths.set(\n depth,\n retain(\n [...state.entries, { key, tree, at: Date.now() }],\n [key, ...state.order.filter((k) => k !== key)],\n state.activeKey,\n ),\n );\n\n notify(depth);\n}\n\n/**\n * Reveal a page the boundaries are still holding, without asking the server.\n *\n * Restoring is anchored on the deepest boundary that can show the page. Deeper\n * ones than that belonged to the page being left — a section with its own\n * layout adds a boundary the page you are going back to never had — so they\n * are dropped, exactly as setSegment drops them. Requiring every boundary to\n * hold the key instead made any such page refuse to restore.\n *\n * Shallower boundaries need no key of their own: their trees contain the\n * deeper boundary, so they delegate to whatever it is showing. One that does\n * hold the key is switched to it, since that is a real change at its level.\n */\n/**\n * Whether a link to `key` would be answered by revealing a held page.\n *\n * The question restoreSegments answers, asked without acting on it: a\n * prefetch of a page the boundaries still hold is a request for nothing -\n * a navigation would reveal it. The page just left is the usual case, one\n * wasted payload per navigation.\n */\nexport function isHeld(key: string, maxAge?: number): boolean {\n const ages = [...depths.values()].flatMap((state) =>\n state.entries.filter((entry) => entry.key === key && !entry.speculative && entry.at >= invalidatedAt).map((entry) => entry.at),\n );\n\n if (ages.length === 0) return false;\n if (maxAge === undefined) return true;\n\n return Date.now() - Math.min(...ages) < maxAge;\n}\n\n/**\n * Drop every page held behind the one on screen.\n *\n * After a mutation: a page kept for the back button holds the data from\n * before it, and revealing it would show a row that is gone, a name that\n * changed. The page on screen stays - it was re-rendered by the action, or\n * is about to be.\n */\nexport function dropHidden(): void {\n // And the ones that stay - the active entry at each depth - are from\n // before it too. A layout's entry is keyed by the page it was seeded\n // with, and revealing that key later shows the page inside it as it was\n // then. Nothing seeded before this moment is revealed again.\n invalidatedAt = Date.now();\n\n for (const [depth, state] of depths) {\n if (state.entries.length <= 1 && !state.entries.some((entry) => entry.speculative)) continue;\n\n depths.set(depth, {\n entries: state.entries.filter((entry) => entry.key === state.activeKey),\n order: state.order.filter((key) => key === state.activeKey),\n activeKey: state.activeKey,\n });\n notify(depth);\n }\n}\n\n/**\n * Reveal a page still being held, if it is worth revealing.\n *\n * `maxAge` is what a link passes and the back button does not. Going back is\n * unambiguous — it names a moment, and the page from that moment is the right\n * answer however old. A link says \"go here\", and answering it with a tree from\n * twenty minutes ago is stale data presented as fresh, which is the objection\n * this design started with. Recent enough, and it is the same page you were\n * just on, with the form you were filling in still filled in.\n */\nexport function restoreSegments(key: string, maxAge?: number): boolean {\n // A guess is not a held page: revealing it would be showing prefetched\n // data as the page the visitor was on. The navigation takes the\n // prerendered tree through setSegment instead, where it is a reveal too.\n // Nor is a page from before a mutation - see dropHidden.\n const holding = [...depths.keys()].filter((d) =>\n depths.get(d)!.entries.some((entry) => entry.key === key && !entry.speculative && entry.at >= invalidatedAt),\n );\n\n if (holding.length === 0) return false;\n\n if (maxAge !== undefined) {\n const ages = holding.flatMap((d) =>\n depths\n .get(d)!\n .entries.filter((entry) => entry.key === key)\n .map((entry) => entry.at),\n );\n\n // The oldest layer decides: revealing a fresh page under a stale layout\n // would be a chain nobody rendered together.\n // >= rather than >, so a window of 0 means never rather than \"only within\n // the same millisecond\".\n if (Date.now() - Math.min(...ages) >= maxAge) return false;\n }\n\n const anchor = Math.max(...holding);\n\n for (const d of [...depths.keys()].filter((d) => d > anchor)) {\n depths.delete(d);\n notify(d);\n }\n\n for (const d of holding) {\n dropSpeculative(d);\n\n const state = depths.get(d)!;\n\n depths.set(\n d,\n retain(\n state.entries,\n [...state.order.filter((k) => k !== key), key],\n key,\n ),\n );\n notify(d);\n }\n\n return true;\n}\n\n/**\n * Drop everything, so boundaries fall back to their server-given children.\n *\n * A deployment invalidates them all: a segment from the previous build has no\n * claim on being correct for this one.\n */\nexport function clearSegments(): void {\n const all = [...depths.keys()];\n depths.clear();\n for (const depth of all) notify(depth);\n}\n\n/**\n * Whether a navigation has happened in this document.\n *\n * The first commit after hydration is the boundary taking over its\n * server-rendered children - the same page, re-keyed for retention. A view\n * transition for that commit fades the page into itself: the blank-then-\n * content a first load or a reload showed. Inertia transitions on visits and\n * never on load; so does this. The router notes the first navigation before\n * it updates a segment, and the boundary animates from then on.\n */\nlet navigated = false;\n\nexport function noteNavigation(): void {\n navigated = true;\n}\n\nexport function navigatedOnce(): boolean {\n return navigated;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"segmentStore.js","sourceRoot":"","sources":["../../src/js/segmentStore.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * What each segment boundary is showing, and what it is keeping alive behind it.\n *\n * A navigation replaces one segment. Keeping the previous one mounted — hidden,\n * not unmounted — is what lets going back restore it with its client state:\n * the half-typed form, the open disclosure, the scrolled list. Unmounting\n * throws all of that away, which is what replacing the root used to do.\n *\n * Entries are keyed by page (the URL, or its intercept variant), so a boundary\n * can hold several and reveal one. Empty is meaningful: a boundary with nothing\n * stored renders the children the server gave it.\n *\n * A store rather than state, and not a preference — three things rule state out.\n * A boundary is inserted between every layout level, so there are several and a\n * navigation targets one by depth; they are separated by server components, so\n * no setter can be threaded down to them, because a function does not cross\n * that boundary; and navigate.ts is a plain module with no component instance\n * to call one on. Addressing a component you hold no reference to is what an\n * external store is for.\n *\n * Underneath it is the wire protocol. A partial navigation sends only the\n * segment that changed — see the X-RSC-Segments headers — so there is nothing\n * for a root to re-render with even if it held the state. Next.js keeps its\n * router in useState and derives every segment from it; that is the same trade\n * in the other direction.\n *\n * What it costs: React pins an external store's updates to synchronous\n * priority, because a store cannot be safely time-sliced. Synchronous is never\n * a transition, and anything that only runs for one — React's <ViewTransition>\n * among them — never ran for a navigation.\n *\n * Which is why SegmentBoundary does not read this with useSyncExternalStore\n * any more. The store still does the addressing, which is the part only it can\n * do; the boundary copies into state, so the render is a transition. See the\n * view transitions guide.\n */\n\ntype Tree = unknown;\ntype Listener = () => void;\n\ninterface Entry {\n key: string;\n tree: Tree;\n /**\n * When this tree arrived, so a link can decide whether it is still worth\n * revealing. The back button never asks — it means \"the page I was on\",\n * however long ago that was.\n */\n at: number;\n /**\n * Its place in the order things happened, for the question \"was this\n * here before the mutation?\" - which a clock answers wrongly for a seed\n * and a write in the same millisecond, and a test hit exactly that.\n */\n seq: number;\n /**\n * Rendered before the click, hidden, on the strength of a touch or a\n * settled hover - see prerenderSegment. Outside the retention window: it\n * is a guess, and a guess must not evict a page the visitor was on. One\n * per depth; the next guess replaces it, and a navigation to anything\n * else drops it.\n */\n speculative?: boolean;\n}\n\n/**\n * Immutable: useSyncExternalStore compares snapshots by identity, so a new\n * object per read reads as \"changed every render\" and loops forever. Every\n * mutation replaces this wholesale; nothing edits one in place.\n */\ninterface DepthState {\n readonly entries: readonly Entry[];\n readonly activeKey: string;\n /** Most recently shown last; eviction takes from the front. */\n readonly order: readonly string[];\n}\n\n/** Pages kept alive per boundary. Four covers ordinary back-and-forth. */\nexport const RETENTION = 4;\n\nconst depths = new Map<number, DepthState>();\n/** A counter every entry takes a number from, in order. */\nlet tick = 0;\n/** The number the last mutation took: everything held before it is wrong. */\nlet invalidatedAt = 0;\nconst listeners = new Map<number, Set<Listener>>();\n\nfunction notify(depth: number): void {\n for (const listener of listeners.get(depth) ?? []) listener();\n}\n\nexport function subscribeToSegment(\n depth: number,\n listener: Listener,\n): () => void {\n let set = listeners.get(depth);\n\n if (!set) {\n set = new Set();\n listeners.set(depth, set);\n }\n\n set.add(listener);\n\n return () => {\n set!.delete(listener);\n if (set!.size === 0) listeners.delete(depth);\n };\n}\n\n/** Everything a boundary at this depth needs to render, or null for \"use children\". */\nexport function getSegmentState(depth: number): DepthState | null {\n return depths.get(depth) ?? null;\n}\n\n/** Apply the retention window to a candidate state. */\nfunction retain(\n entries: readonly Entry[],\n order: readonly string[],\n activeKey: string,\n): DepthState {\n const kept = order.slice(-RETENTION);\n\n return {\n entries: entries.filter((entry) => kept.includes(entry.key) || entry.speculative),\n order: kept,\n activeKey,\n };\n}\n\nfunction put(depth: number, key: string, tree: Tree): void {\n const state = depths.get(depth);\n const entries = [\n ...(state?.entries ?? []).filter((entry) => entry.key !== key),\n { key, tree, at: Date.now(), seq: ++tick },\n ];\n const order = [...(state?.order ?? []).filter((k) => k !== key), key];\n\n depths.set(depth, retain(entries, order, key));\n}\n\n/**\n * Show `tree` at `depth` for `key`, retaining what was there.\n *\n * Deeper segments belonged to the page being replaced; leaving them would\n * render the previous page inside the new one.\n */\nexport function setSegment(depth: number, key: string, tree: Tree): void {\n // A guess about another page was wrong; the one about this page, if there\n // was one, is replaced by put() below - with the same tree, when the\n // prerender and the navigation read the same decoded payload, which is\n // what makes the update a reveal rather than a render.\n dropSpeculative(depth, key);\n put(depth, key, tree);\n\n const stale = [...depths.keys()].filter((d) => d > depth);\n for (const d of stale) depths.delete(d);\n\n notify(depth);\n for (const d of stale) notify(d);\n}\n\nfunction dropSpeculative(depth: number, except?: string): void {\n const state = depths.get(depth);\n\n if (!state?.entries.some((entry) => entry.speculative && entry.key !== except)) return;\n\n depths.set(depth, {\n ...state,\n entries: state.entries.filter((entry) => !entry.speculative || entry.key === except),\n });\n}\n\n/**\n * Render a page hidden at `depth`, before any navigation to it.\n *\n * The click then finds the work done: setSegment with the same tree is a\n * bail-out for React - same element, same props - and the Activity flips\n * from hidden to visible. What was 87 ms of rendering on a phone, after\n * the tap, is paid before the finger lifts, at idle priority, yielding to\n * the scroll. Never changes what is showing, never counts against\n * retention, and a page already held needs nothing.\n */\nexport function prerenderSegment(depth: number, key: string, tree: Tree): void {\n const state = depths.get(depth);\n\n // Nothing at this depth yet: the boundary is still showing the server's\n // children, and it has no page key to keep them under. A guess would take\n // the store over with no active entry to show. seedSegment runs on mount,\n // so this is the gap between hydration and that effect; the click will\n // render.\n if (!state) return;\n\n if (state.entries.some((entry) => entry.key === key)) return;\n\n depths.set(depth, {\n ...state,\n entries: [\n ...state.entries.filter((entry) => !entry.speculative),\n { key, tree, at: Date.now(), seq: ++tick, speculative: true },\n ],\n });\n\n notify(depth);\n}\n\n/** Whether a page is rendered hidden at `depth`, ahead of a navigation to it. */\nexport function isPrerendered(depth: number, key: string): boolean {\n return depths.get(depth)?.entries.some((entry) => entry.key === key && entry.speculative) ?? false;\n}\n\n/**\n * Give the page on screen at `depth` a new tree, under the key it has.\n *\n * For revalidate(\"all\"): the whole document rendered again, in place. The\n * root hands its layout the new tree, the layout hands its boundary new\n * children, and a boundary that holds state would otherwise keep showing\n * the store's tree and drop the new one on the floor - or, cleared first,\n * re-key its Activity to the current url and remount everything under it.\n * Neither. The entry that is showing takes the new tree and keeps its key,\n * so React reconciles the page in place, and the boundary below gets its\n * new children the same way.\n */\nexport function replaceActive(depth: number, tree: Tree): void {\n const state = depths.get(depth);\n\n if (!state) return;\n\n const active = state.entries.find((entry) => entry.key === state.activeKey);\n\n if (!active || active.tree === tree) return;\n\n // The tree changes; when the entry arrived does not. A layout's entry is\n // keyed by the page it was seeded with - \"/\" for a document loaded at\n // home - and stays active through every navigation below it. Stamped\n // with the re-render's time it read as held since the mutation, and a\n // tap on the brand link after \"Add to cart\" revealed it: the url went\n // to \"/\" and the product stayed, because the tree under that key was\n // now the product's document. See dropHidden and isHeld.\n depths.set(depth, {\n ...state,\n entries: state.entries.map((entry) => (entry === active ? { ...entry, tree } : entry)),\n });\n notify(depth);\n}\n\n/**\n * Record the children the server rendered, so the page you arrived on can be\n * returned to later. Never changes what is showing.\n */\nexport function seedSegment(depth: number, key: string, tree: Tree): void {\n const state = depths.get(depth);\n\n if (state?.entries.some((entry) => entry.key === key)) return;\n\n if (!state) {\n put(depth, key, tree);\n notify(depth);\n\n return;\n }\n\n // Older than whatever is showing, so it goes to the front of the eviction\n // order — and crucially does not become the active page.\n depths.set(\n depth,\n retain(\n [...state.entries, { key, tree, at: Date.now(), seq: ++tick }],\n [key, ...state.order.filter((k) => k !== key)],\n state.activeKey,\n ),\n );\n\n notify(depth);\n}\n\n/**\n * Reveal a page the boundaries are still holding, without asking the server.\n *\n * Restoring is anchored on the deepest boundary that can show the page. Deeper\n * ones than that belonged to the page being left — a section with its own\n * layout adds a boundary the page you are going back to never had — so they\n * are dropped, exactly as setSegment drops them. Requiring every boundary to\n * hold the key instead made any such page refuse to restore.\n *\n * Shallower boundaries need no key of their own: their trees contain the\n * deeper boundary, so they delegate to whatever it is showing. One that does\n * hold the key is switched to it, since that is a real change at its level.\n */\n/**\n * Whether a link to `key` would be answered by revealing a held page.\n *\n * The question restoreSegments answers, asked without acting on it: a\n * prefetch of a page the boundaries still hold is a request for nothing -\n * a navigation would reveal it. The page just left is the usual case, one\n * wasted payload per navigation.\n */\nexport function isHeld(key: string, maxAge?: number): boolean {\n const ages = [...depths.values()].flatMap((state) =>\n state.entries.filter((entry) => entry.key === key && !entry.speculative && entry.seq > invalidatedAt).map((entry) => entry.at),\n );\n\n if (ages.length === 0) return false;\n if (maxAge === undefined) return true;\n\n return Date.now() - Math.min(...ages) < maxAge;\n}\n\n/**\n * Drop every page held behind the one on screen.\n *\n * After a mutation: a page kept for the back button holds the data from\n * before it, and revealing it would show a row that is gone, a name that\n * changed. The page on screen stays - it was re-rendered by the action, or\n * is about to be.\n */\nexport function dropHidden(): void {\n // And the ones that stay - the active entry at each depth - are from\n // before it too. A layout's entry is keyed by the page it was seeded\n // with, and revealing that key later shows the page inside it as it was\n // then. Nothing seeded before this moment is revealed again.\n invalidatedAt = ++tick;\n\n for (const [depth, state] of depths) {\n if (state.entries.length <= 1 && !state.entries.some((entry) => entry.speculative)) continue;\n\n depths.set(depth, {\n entries: state.entries.filter((entry) => entry.key === state.activeKey),\n order: state.order.filter((key) => key === state.activeKey),\n activeKey: state.activeKey,\n });\n notify(depth);\n }\n}\n\n/**\n * Reveal a page still being held, if it is worth revealing.\n *\n * `maxAge` is what a link passes and the back button does not. Going back is\n * unambiguous — it names a moment, and the page from that moment is the right\n * answer however old. A link says \"go here\", and answering it with a tree from\n * twenty minutes ago is stale data presented as fresh, which is the objection\n * this design started with. Recent enough, and it is the same page you were\n * just on, with the form you were filling in still filled in.\n */\nexport function restoreSegments(key: string, maxAge?: number): boolean {\n // A guess is not a held page: revealing it would be showing prefetched\n // data as the page the visitor was on. The navigation takes the\n // prerendered tree through setSegment instead, where it is a reveal too.\n // Nor is a page from before a mutation - see dropHidden.\n const holding = [...depths.keys()].filter((d) =>\n depths.get(d)!.entries.some((entry) => entry.key === key && !entry.speculative && entry.seq > invalidatedAt),\n );\n\n if (holding.length === 0) return false;\n\n if (maxAge !== undefined) {\n const ages = holding.flatMap((d) =>\n depths\n .get(d)!\n .entries.filter((entry) => entry.key === key)\n .map((entry) => entry.at),\n );\n\n // The oldest layer decides: revealing a fresh page under a stale layout\n // would be a chain nobody rendered together.\n // >= rather than >, so a window of 0 means never rather than \"only within\n // the same millisecond\".\n if (Date.now() - Math.min(...ages) >= maxAge) return false;\n }\n\n const anchor = Math.max(...holding);\n\n for (const d of [...depths.keys()].filter((d) => d > anchor)) {\n depths.delete(d);\n notify(d);\n }\n\n for (const d of holding) {\n dropSpeculative(d);\n\n const state = depths.get(d)!;\n\n depths.set(\n d,\n retain(\n state.entries,\n [...state.order.filter((k) => k !== key), key],\n key,\n ),\n );\n notify(d);\n }\n\n return true;\n}\n\n/**\n * Drop everything, so boundaries fall back to their server-given children.\n *\n * A deployment invalidates them all: a segment from the previous build has no\n * claim on being correct for this one.\n */\nexport function clearSegments(): void {\n const all = [...depths.keys()];\n depths.clear();\n for (const depth of all) notify(depth);\n}\n\n/**\n * Whether a navigation has happened in this document.\n *\n * The first commit after hydration is the boundary taking over its\n * server-rendered children - the same page, re-keyed for retention. A view\n * transition for that commit fades the page into itself: the blank-then-\n * content a first load or a reload showed. Inertia transitions on visits and\n * never on load; so does this. The router notes the first navigation before\n * it updates a segment, and the boundary animates from then on.\n */\nlet navigated = false;\n\nexport function noteNavigation(): void {\n navigated = true;\n}\n\nexport function navigatedOnce(): boolean {\n return navigated;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rsc-kit/core",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.10",
|
|
4
4
|
"description": "React Server Components as a Vite plugin. Routing, streaming, server actions, typed urls and build-time prerendering — deploy to Bun, Node, Workers, Vercel or Deno.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|