@rshono/core 1.0.0-rc.13 → 1.0.0-rc.14
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/LICENSE +21 -0
- package/README.md +29 -8
- package/dist/builder/env-shadow-loader.cjs +20 -1
- package/dist/builder/react-versions.d.ts +13 -0
- package/dist/builder/react-versions.d.ts.map +1 -0
- package/dist/builder/react-versions.js +74 -0
- package/dist/builder/react-versions.js.map +1 -0
- package/dist/builder/rspack-config.d.ts.map +1 -1
- package/dist/builder/rspack-config.js +45 -5
- package/dist/builder/rspack-config.js.map +1 -1
- package/dist/cli/build.d.ts.map +1 -1
- package/dist/cli/build.js +4 -0
- package/dist/cli/build.js.map +1 -1
- package/dist/cli/index.js +2 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/start.d.ts.map +1 -1
- package/dist/cli/start.js +10 -13
- package/dist/cli/start.js.map +1 -1
- package/dist/deploy/cloudflare/runtime.js +1 -1
- package/dist/deploy/cloudflare/runtime.js.map +1 -1
- package/dist/deploy/filesystem.d.ts.map +1 -1
- package/dist/deploy/filesystem.js +8 -0
- package/dist/deploy/filesystem.js.map +1 -1
- package/dist/deploy/presets.d.ts.map +1 -1
- package/dist/deploy/presets.js +24 -0
- package/dist/deploy/presets.js.map +1 -1
- package/dist/deploy/vercel/build.d.ts.map +1 -1
- package/dist/deploy/vercel/build.js +10 -4
- package/dist/deploy/vercel/build.js.map +1 -1
- package/dist/deploy/vercel/runtime.d.ts +1 -1
- package/dist/deploy/vercel/runtime.d.ts.map +1 -1
- package/dist/deploy/vercel/runtime.js +10 -1
- package/dist/deploy/vercel/runtime.js.map +1 -1
- package/dist/runtime/context.d.ts.map +1 -1
- package/dist/runtime/context.js +15 -0
- package/dist/runtime/context.js.map +1 -1
- package/dist/runtime/entry.client.js +55 -11
- package/dist/runtime/entry.client.js.map +1 -1
- package/dist/runtime/entry.rsc.d.ts.map +1 -1
- package/dist/runtime/entry.rsc.js +74 -8
- package/dist/runtime/entry.rsc.js.map +1 -1
- package/dist/runtime/flight-inject.d.ts.map +1 -1
- package/dist/runtime/flight-inject.js +31 -4
- package/dist/runtime/flight-inject.js.map +1 -1
- package/dist/runtime/request.d.ts +12 -4
- package/dist/runtime/request.d.ts.map +1 -1
- package/dist/runtime/request.js +28 -7
- package/dist/runtime/request.js.map +1 -1
- package/dist/server/prerendered.d.ts +11 -3
- package/dist/server/prerendered.d.ts.map +1 -1
- package/dist/server/prerendered.js +31 -5
- package/dist/server/prerendered.js.map +1 -1
- package/dist/server/shutdown.d.ts +4 -1
- package/dist/server/shutdown.d.ts.map +1 -1
- package/dist/server/shutdown.js +4 -1
- package/dist/server/shutdown.js.map +1 -1
- package/dist/server/ssg.js +1 -1
- package/dist/server/ssg.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entry.rsc.js","sourceRoot":"","sources":["../../src/runtime/entry.rsc.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { Context, Handler } from 'hono';\nimport { Hono } from 'hono';\nimport { HTTPException } from 'hono/http-exception';\n// Type-only side effect: augments Hono's `ContextVariableMap` with `secureHeadersNonce`, read in `cspNonce`.\nimport type {} from 'hono/secure-headers';\nimport type { ContentfulStatusCode, RedirectStatusCode } from 'hono/utils/http-status';\nimport type React from 'react';\nimport type { ReactFormState } from 'react-dom/client';\n// Called directly rather than as `<Page {...props} />`: a spread would drop the non-enumerable `ctx`\n// prop. See `pageProps`.\nimport { jsx } from 'react/jsx-runtime';\n// The bare specifier, not `/server.node`: the RSC layer's `conditionNames` picks the build for the\n// deploy target being compiled for.\nimport {\n createTemporaryReferenceSet,\n decodeAction,\n decodeFormState,\n decodeReply,\n loadServerAction,\n renderToReadableStream,\n type ServerEntry,\n type TemporaryReferenceSet,\n} from 'react-server-dom-rspack/server';\n// Aliased at build time to the selected preset's runtime — the one place this file knows where it runs.\nimport { runtime } from '@rshono/deploy';\n// @ts-expect-error — resolved by the '@rshono/routes' alias to the app's routes.ts\nimport { routes as userRoutes } from '@rshono/routes';\n// @ts-expect-error — resolved by the '@rshono/server-app' alias (src/server.ts or the empty fallback)\nimport * as serverAppModule from '@rshono/server-app';\nimport { isPageRoute, type ErrorPageInfo, type FallbackPage, type PageComponent, type PageProps, type Route, type RouteConfig } from '../router.js';\nimport { appendVary, etagMatches } from '../server/headers.js';\nimport { beginPageRender, getRequestContext, publicUrl, readParams, reportServerError, runWithContext } from './context.js';\nimport { isControlSignal, RedirectSignal, type ControlSignal } from './control.js';\nimport { renderHTML } from './entry.ssr.js';\n// Type-only, so it is erased — the RSC layer does not take its own instance of the SSR layer's module.\nimport type { CancellableTransformer } from './flight-inject.js';\nimport { RouterProvider } from './navigation.js';\nimport { acceptsRsc, isActionRequest, parseRenderRequest, requestWantsRsc, wantsRsc } from './request.js';\n\nconst serverApp = ((serverAppModule as { default?: unknown }).default ?? null) as Hono | null;\n\n// Compiled into the bundle from rshono.config.ts by DefinePlugin; there is no runtime env-var interface.\nconst { isDev } = __RSHONO_CONFIG__;\n\n/** How long a prerendered page may be reused before revalidating. Also what `public/` files get. */\nconst SSG_CACHE_CONTROL = 'public, max-age=300';\n\n/** The two content types a page can be served as, from the same URL — which is what makes `Vary` non-optional. */\nconst PAGE_CONTENT_TYPE = /^(?:text\\/html|text\\/x-component)\\b/;\n\nruntime.loadEnv();\n\nconst routeConfig = userRoutes as RouteConfig;\nexport const routes: readonly Route[] = routeConfig.routes;\n\n/** The result of a server action, as a `Result<T, E>` rather than an `ok` flag over one field. */\nexport type ActionResult = { ok: true; value: unknown } | { ok: false; error: unknown };\n\nexport type RscPayload = {\n root: React.ReactNode;\n returnValue?: ActionResult;\n formState?: ReactFormState;\n redirect?: string;\n notFound?: boolean;\n};\n\n/**\n * The per-request CSP nonce, if the app asked for one.\n *\n * The framework never mints it: `secureHeaders()` does, when its policy contains the `NONCE`\n * placeholder, and stores it here — so all the framework does is stamp the value into the render. It is\n * readable from a route handler because `secureHeaders` resolves its directives before `next()`.\n */\nfunction cspNonce(c: Context): string | undefined {\n return c.get('secureHeadersNonce');\n}\n\nasync function loadPageModule(load: () => Promise<{ default: PageComponent }>, label: string): Promise<ServerEntry<PageComponent>> {\n const mod = await load();\n const Page = mod.default as ServerEntry<PageComponent> | undefined;\n if (typeof Page !== 'function') {\n throw new Error(`[rshono] The page module for ${label} must default-export a server component.`);\n }\n if (!Page.entryJsFiles) {\n throw new Error(\n `[rshono] The page component for ${label} is missing its client-asset info ('use server-entry'). ` +\n \"The directive is added automatically for inline `component: () => import('…')` thunks in routes.ts. \" +\n \"If this page is wired up another way, put 'use server-entry' on the first line of the page module yourself — \" +\n \"and make sure the page is a server component (a 'use client' page must be wrapped by a server component instead).\",\n );\n }\n return Page;\n}\n\n/** A browser navigation or a crawler, as opposed to a fetch that would rather have plain text. */\nfunction acceptsHtml(c: Context): boolean {\n return c.req.header('accept')?.includes('text/html') ?? false;\n}\n\n/**\n * The 404 for an app with no `notFound` page, and for a client that wanted neither HTML nor a flight\n * payload. It carries the `Vary` too: this is one of the answers a page URL gives depending on `Accept`.\n */\nfunction plainNotFound(c: Context): Response {\n return c.text('Not Found', 404, { vary: 'Accept' });\n}\n\n/** A lazy once-cell: runs `load` at most once, but clears a rejection so a later call can retry. */\nfunction once<T>(load: () => Promise<T>): () => Promise<T> {\n let promise: Promise<T> | undefined;\n return () => {\n if (!promise) {\n const pending = (promise = load());\n pending.catch(() => {\n if (promise === pending) promise = undefined;\n });\n }\n return promise;\n };\n}\n\n/**\n * Passes `stream` through untouched, calling `done` however it ends — for the flight-only response\n * path, which has no transform of its own to hang a completion hook off. `done` must be idempotent.\n */\nfunction releaseWhenDone(stream: ReadableStream<Uint8Array>, done: () => void): ReadableStream<Uint8Array> {\n return stream.pipeThrough(\n new TransformStream<Uint8Array, Uint8Array>({\n transform(chunk, controller) {\n controller.enqueue(chunk);\n },\n flush: done,\n cancel: done,\n } as CancellableTransformer<Uint8Array, Uint8Array>),\n );\n}\n\ninterface ComponentRenderOptions {\n status?: number;\n isRsc: boolean;\n formState?: ReactFormState;\n returnValue?: RscPayload['returnValue'];\n temporaryReferences?: TemporaryReferenceSet;\n /** Passed when the page being rendered is the `error` page, which takes it as an extra prop. */\n errorInfo?: ErrorPageInfo;\n /** Marks the payload as the not-found page, so a soft navigation can tell it apart from the page it asked for. */\n notFound?: boolean;\n}\n\n/**\n * Builds the props a page component is called with.\n *\n * `ctx` is *defined* rather than assigned, and both halves are load-bearing:\n *\n * - **A getter**, so nothing is built for the pages that never read it, and a `render: 'static'` page\n * that does gets {@link getRequestContext}'s prerendering error rather than a bare `undefined`.\n * - **Non-enumerable**, so React's dev-only serialization of a server component's props skips it. That\n * walks own enumerable properties, and `ctx.hono.env` holds the runtime's bindings — an enumerable\n * `ctx` would ship every secret to the browser in dev.\n *\n * The cost: the element is created by handing this object to `jsx()` by reference, since a\n * `<Page {...props} />` spread would silently drop `ctx`.\n */\nfunction pageProps(c: Context, errorInfo: ErrorPageInfo | undefined): PageProps & { error?: ErrorPageInfo } {\n const props = { url: publicUrl(c), params: readParams(c), ...(errorInfo ? { error: errorInfo } : null) };\n Object.defineProperty(props, 'ctx', { get: getRequestContext, enumerable: false, configurable: true });\n return props as PageProps & { error?: ErrorPageInfo };\n}\n\nasync function renderComponent(c: Context, Page: ServerEntry<PageComponent>, opts: ComponentRenderOptions): Promise<Response> {\n // React's renderers must never be handed `c.req.raw.signal`: they add an `abort` listener and only\n // remove it if the abort fires, so on the happy path it stays on a request-lifetime signal and pins the\n // whole rendered tree. The render gets its own controller and the request signal forwards into it —\n // `release` detaches on the normal path. Not `AbortSignal.any()`, whose composite signals Node holds in\n // a process-lifetime set until they abort.\n const requestSignal = c.req.raw.signal;\n const renderAbort = new AbortController();\n const signal = renderAbort.signal;\n const forwardAbort = () => renderAbort.abort(requestSignal.reason);\n if (requestSignal.aborted) renderAbort.abort(requestSignal.reason);\n else requestSignal.addEventListener('abort', forwardAbort, { once: true });\n const release = () => requestSignal.removeEventListener('abort', forwardAbort);\n\n // Documents only: the nonce goes on the bootstrap scripts and the `<meta>` React hydrates from, and a\n // flight payload has neither — which is what keeps a prerendered one servable under a nonce-based CSP.\n const nonce = opts.isRsc ? undefined : cspNonce(c);\n const props = pageProps(c, opts.errorInfo);\n const root = (\n <>\n {nonce && <meta property=\"csp-nonce\" nonce={nonce} />}\n {Page.entryCssFiles?.map((href) => (\n <link key={href} rel=\"stylesheet\" href={href} precedence=\"default\" />\n ))}\n {/* `href`, not the `URL`: these props cross into a client component, so they have to be serializable. */}\n <RouterProvider href={props.url.href} params={props.params}>\n {jsx(Page, props)}\n </RouterProvider>\n </>\n );\n\n // `notFound` only when true, so an ordinary page's payload doesn't carry the key.\n const rscPayload: RscPayload = { root, formState: opts.formState, returnValue: opts.returnValue, ...(opts.notFound ? { notFound: true } : null) };\n\n // The last thing before the render: past here the response head is the framework's, so `ctx.setHeader()`\n // starts throwing — while the action `renderPage` just ran, and the middleware around it, legitimately wrote.\n beginPageRender(c);\n\n let controlSignal: ControlSignal | undefined;\n const rscStream = renderToReadableStream(rscPayload, {\n temporaryReferences: opts.temporaryReferences,\n signal,\n onError(error) {\n if (isControlSignal(error)) {\n controlSignal = error;\n return error.digest;\n }\n if (!signal.aborted) reportServerError(error, { source: 'render', request: c.req.raw, message: '[rshono] render error:' });\n },\n });\n\n if (opts.isRsc) {\n return c.body(releaseWhenDone(rscStream, release), (opts.status ?? 200) as ContentfulStatusCode, {\n 'content-type': 'text/x-component;charset=utf-8',\n });\n }\n\n let ssrResult: Awaited<ReturnType<typeof renderHTML>>;\n try {\n ssrResult = await renderHTML(rscStream, {\n bootstrapScripts: Page.entryJsFiles,\n formState: opts.formState,\n signal,\n nonce,\n onDone: release,\n onShellError: (error) => reportServerError(error, { source: 'ssr', request: c.req.raw, message: '[rshono] SSR shell error:' }),\n onError: (error) => reportServerError(error, { source: 'ssr', request: c.req.raw, message: '[rshono] SSR error:' }),\n });\n } catch (error) {\n release();\n if (controlSignal) throw controlSignal;\n throw error;\n }\n if (controlSignal) {\n release();\n throw controlSignal;\n }\n return c.body(ssrResult.stream, (ssrResult.status ?? opts.status ?? 200) as ContentfulStatusCode, {\n 'content-type': 'text/html;charset=utf-8',\n });\n}\n\nasync function renderPage(c: Context, loadPage: () => Promise<ServerEntry<PageComponent>>): Promise<Response> {\n const request = c.req.raw;\n const renderRequest = parseRenderRequest(request);\n\n let returnValue: ActionResult | undefined;\n let formState: ReactFormState | undefined;\n let temporaryReferences: TemporaryReferenceSet | undefined;\n let actionStatus: number | undefined;\n if (isActionRequest(renderRequest)) {\n if (renderRequest.kind === 'rsc-action') {\n // Before the body is decoded, so an unknown id costs nothing to reject. `hasOwn` so `__proto__`\n // does not resolve to a manifest entry.\n if (!Object.hasOwn(__rspack_rsc_manifest__.serverManifest, renderRequest.actionId)) {\n return c.text('Bad Request: unknown server action', 400);\n }\n const contentType = request.headers.get('content-type');\n const body = contentType?.startsWith('multipart/form-data') ? await request.formData() : await request.text();\n temporaryReferences = createTemporaryReferenceSet();\n const args = await decodeReply<unknown[]>(body, { temporaryReferences });\n const action = loadServerAction(renderRequest.actionId);\n try {\n returnValue = { ok: true, value: await action(...args) };\n } catch (error) {\n if (isControlSignal(error)) throw error;\n // In production React sends a thrown action error to the client as an opaque marker, so this is\n // the only place the real one is visible.\n reportServerError(error, { source: 'action', request, message: '[rshono] server action error:' });\n returnValue = { ok: false, error };\n actionStatus = 500;\n }\n } else {\n const formData = await request.formData();\n const decodedAction = await decodeAction(formData, __rspack_rsc_manifest__.serverManifest);\n if (decodedAction) {\n const result = await decodedAction();\n formState = (await decodeFormState(result, formData, __rspack_rsc_manifest__.serverManifest)) ?? undefined;\n }\n }\n }\n\n const Page = await loadPage();\n return renderComponent(c, Page, {\n status: actionStatus,\n isRsc: wantsRsc(renderRequest),\n formState,\n returnValue,\n temporaryReferences,\n });\n}\n\nfunction buildApp(): Hono {\n const app = new Hono();\n\n // A floor, not a policy: an app wanting the full set registers `secureHeaders()` in src/server.ts, and\n // because this is registered first it unwinds last, so the \"only if unset\" checks stand aside for it.\n // Owned by the framework because it also has to cover `mountStaticAssets` — a terminal handler the\n // app's own middleware never sees.\n app.use(async (c, next) => {\n await next();\n const headers = c.res.headers;\n if (!headers.has('x-content-type-options')) headers.set('x-content-type-options', 'nosniff');\n if (!headers.has('referrer-policy')) headers.set('referrer-policy', 'strict-origin-when-cross-origin');\n if (!headers.has('x-frame-options')) headers.set('x-frame-options', 'SAMEORIGIN');\n\n // React Refresh compiles updates with `eval`, so a dev build cannot run under a production CSP.\n // Widened here so one policy in src/server.ts serves both.\n if (isDev) {\n const csp = headers.get('content-security-policy');\n if (csp?.includes('script-src ')) {\n headers.set('content-security-policy', csp.replace('script-src ', \"script-src 'unsafe-eval' \"));\n }\n }\n\n // Page responses only from here down.\n if (!PAGE_CONTENT_TYPE.test(headers.get('content-type') ?? '')) return;\n appendVary(headers, 'Accept');\n // Without a default a shared cache is free to store a logged-in user's page and hand it to someone\n // else. `private, no-cache` forbids that without blocking bfcache, which `no-store` would.\n if (!headers.has('cache-control')) headers.set('cache-control', 'private, no-cache');\n });\n\n runtime.mountStaticAssets(app);\n\n // Ahead of the page routes, so the app's own middleware (`csrf()`, `bodyLimit()`, auth, logging) wraps\n // page requests too. The flip side: a *terminal* handler in src/server.ts shadows a page at the same path.\n if (serverApp) {\n app.route('/', serverApp);\n }\n\n const memoizePage = (page: FallbackPage, label: string) => once(() => loadPageModule(page.component, label));\n const loadNotFoundPage = routeConfig.notFound ? memoizePage(routeConfig.notFound, 'the notFound page') : null;\n\n /** Turns a thrown `redirect()` / `notFound()` into the response it stands for. */\n const respondToControlSignal = async (c: Context, signal: ControlSignal): Promise<Response> => {\n const isRsc = requestWantsRsc(c.req.raw);\n if (signal instanceof RedirectSignal) {\n if (isRsc) {\n // No `signal`: two fields and no component tree, so there is nothing worth aborting.\n return c.body(renderToReadableStream({ root: null, redirect: signal.location } satisfies RscPayload), 200, {\n 'content-type': 'text/x-component;charset=utf-8',\n });\n }\n return c.redirect(signal.location, signal.status as RedirectStatusCode);\n }\n if (loadNotFoundPage) {\n return renderComponent(c, await loadNotFoundPage(), { status: 404, isRsc, notFound: true });\n }\n return plainNotFound(c);\n };\n\n for (const route of routes) {\n if (isPageRoute(route)) {\n // Both fixed for the life of the process, so resolved once rather than per request.\n const servesPrerendered = !isDev && route.render === 'static';\n const loadPage = once(() => loadPageModule(route.component, `\"${route.path}\"`));\n\n const handler: Handler = async (c) => {\n try {\n if (servesPrerendered && c.req.method === 'GET') {\n const isRsc = acceptsRsc(c.req.raw);\n // One fixed set of bytes cannot carry a per-request nonce, so a document has to be rendered\n // where the app's CSP has one. Decided per request, so an app whose policy carries no `NONCE`\n // keeps its prerendered documents. A flight payload never carries a nonce either way.\n const mustRenderForNonce = !isRsc && cspNonce(c) !== undefined;\n if (!mustRenderForNonce) {\n const page = await runtime.readPrerendered(c, isRsc ? 'flight' : 'html');\n // Request-independent by construction, so it is safe to cache publicly; the ETag turns the\n // revalidation that follows into a 304. Answered outside `runWithContext` — no app code runs\n // on this path, so there is no `getRequestContext()` to serve.\n if (page !== null) {\n const headers = {\n 'cache-control': SSG_CACHE_CONTROL,\n etag: page.etag,\n vary: 'Accept',\n 'content-type': isRsc ? 'text/x-component;charset=utf-8' : 'text/html;charset=utf-8',\n };\n if (etagMatches(c.req.header('if-none-match'), page.etag)) return c.body(null, 304, headers);\n return c.body(page.body, 200, { ...headers, 'content-length': page.contentLength });\n }\n }\n }\n return await runWithContext(c, () => renderPage(c, loadPage));\n } catch (error) {\n if (isControlSignal(error)) return runWithContext(c, () => respondToControlSignal(c, error));\n throw error;\n }\n };\n app.on(['GET', 'POST'], route.path, handler);\n } else {\n const loadEndpoint = once(() => route.server());\n const handler: Handler = async (c, next) => {\n const { handler: endpointHandler } = await loadEndpoint();\n // Hono's `Handler` leaves its return parameter defaulted to `any`, so this hands back exactly what\n // the app's own handler is declared to return — there is nothing narrower to assert here.\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return endpointHandler(c, next);\n };\n const method = route.method ?? 'all';\n if (method === 'all') app.all(route.path, handler);\n else app.on(method.toUpperCase(), route.path, handler);\n }\n }\n\n runtime.mountPublicFallback(app);\n\n app.notFound(async (c) => {\n const isRsc = requestWantsRsc(c.req.raw);\n if (loadNotFoundPage && (isRsc || acceptsHtml(c))) {\n return runWithContext(c, async () => renderComponent(c, await loadNotFoundPage(), { status: 404, isRsc }));\n }\n return plainNotFound(c);\n });\n\n const loadErrorPage = routeConfig.error ? memoizePage(routeConfig.error, 'the error page') : null;\n app.onError(async (error, c) => {\n if (isControlSignal(error)) return runWithContext(c, () => respondToControlSignal(c, error));\n // Registering an `onError` replaces Hono's default handler, which is what turns an `HTTPException`\n // into the response it carries — without this, `csrf()`'s 403 and `bodyLimit()`'s 413 would both\n // surface as a 500 error page. Rebuilt through `c`, as Hono's default does, so headers middleware\n // already prepared survive.\n if (error instanceof HTTPException) {\n const res = error.getResponse();\n return c.newResponse(res.body, res);\n }\n reportServerError(error, { source: 'request', request: c.req.raw, message: '[rshono] request error:' });\n const isRsc = requestWantsRsc(c.req.raw);\n if (loadErrorPage && (isRsc || acceptsHtml(c))) {\n const errorInfo: ErrorPageInfo = isDev\n ? {\n message: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n }\n : { message: 'Internal Server Error' };\n try {\n return await runWithContext(c, async () => renderComponent(c, await loadErrorPage(), { status: 500, isRsc, errorInfo }));\n } catch (renderError) {\n reportServerError(renderError, { source: 'request', request: c.req.raw, message: '[rshono] the error page failed to render:' });\n }\n }\n const detail = isDev ? `\\n\\n${error instanceof Error ? (error.stack ?? error.message) : String(error)}` : '';\n return c.text(`Internal Server Error${detail}`, 500, { vary: 'Accept' });\n });\n\n return app;\n}\n\nexport const app = buildApp();\n\n/**\n * The app, handed to whatever is hosting it: this binds a port and exports nothing where rshono owns the\n * process, and *is* the export the platform looks for where the host owns it — so one entry serves both.\n *\n * `app` and `routes` stay named exports either way, because `rshono build` imports them to prerender\n * `render: 'static'` routes.\n */\nexport default runtime.serveApp(app);\n"]}
|
|
1
|
+
{"version":3,"file":"entry.rsc.js","sourceRoot":"","sources":["../../src/runtime/entry.rsc.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { Context, Handler } from 'hono';\nimport { Hono } from 'hono';\nimport { HTTPException } from 'hono/http-exception';\n// Type-only side effect: augments Hono's `ContextVariableMap` with `secureHeadersNonce`, read in `cspNonce`.\nimport type {} from 'hono/secure-headers';\nimport type { ContentfulStatusCode, RedirectStatusCode } from 'hono/utils/http-status';\nimport type React from 'react';\nimport type { ReactFormState } from 'react-dom/client';\n// Called directly rather than as `<Page {...props} />`: a spread would drop the non-enumerable `ctx`\n// prop. See `pageProps`.\nimport { jsx } from 'react/jsx-runtime';\n// The bare specifier, not `/server.node`: the RSC layer's `conditionNames` picks the build for the\n// deploy target being compiled for.\nimport {\n createTemporaryReferenceSet,\n decodeAction,\n decodeFormState,\n decodeReply,\n loadServerAction,\n renderToReadableStream,\n type ServerEntry,\n type TemporaryReferenceSet,\n} from 'react-server-dom-rspack/server';\n// Aliased at build time to the selected preset's runtime — the one place this file knows where it runs.\nimport { runtime } from '@rshono/deploy';\n// @ts-expect-error — resolved by the '@rshono/routes' alias to the app's routes.ts\nimport { routes as userRoutes } from '@rshono/routes';\n// @ts-expect-error — resolved by the '@rshono/server-app' alias (src/server.ts or the empty fallback)\nimport * as serverAppModule from '@rshono/server-app';\nimport { isPageRoute, type ErrorPageInfo, type FallbackPage, type PageComponent, type PageProps, type Route, type RouteConfig } from '../router.js';\nimport { appendVary, etagMatches } from '../server/headers.js';\nimport { beginPageRender, getRequestContext, publicUrl, readParams, reportServerError, runWithContext } from './context.js';\nimport { isControlSignal, RedirectSignal, type ControlSignal } from './control.js';\nimport { renderHTML } from './entry.ssr.js';\n// Type-only, so it is erased — the RSC layer does not take its own instance of the SSR layer's module.\nimport type { CancellableTransformer } from './flight-inject.js';\nimport { RouterProvider } from './navigation.js';\nimport { asksForRsc, isActionRequest, parseRenderRequest, requestWantsRsc, RSC_VARY_HEADER, wantsRsc } from './request.js';\n\nconst serverApp = ((serverAppModule as { default?: unknown }).default ?? null) as Hono | null;\n\n// Compiled into the bundle from rshono.config.ts by DefinePlugin; there is no runtime env-var interface.\nconst { isDev } = __RSHONO_CONFIG__;\n\n/** How long a prerendered page may be reused before revalidating. Also what `public/` files get. */\nconst SSG_CACHE_CONTROL = 'public, max-age=300';\n\n/** The two content types a page can be served as, from the same URL — which is what makes `Vary` non-optional. */\nconst PAGE_CONTENT_TYPE = /^(?:text\\/html|text\\/x-component)\\b/;\n\nruntime.loadEnv();\n\nconst routeConfig = userRoutes as RouteConfig;\nexport const routes: readonly Route[] = routeConfig.routes;\n\n/** The result of a server action, as a `Result<T, E>` rather than an `ok` flag over one field. */\nexport type ActionResult = { ok: true; value: unknown } | { ok: false; error: unknown };\n\nexport type RscPayload = {\n root: React.ReactNode;\n returnValue?: ActionResult;\n formState?: ReactFormState;\n redirect?: string;\n notFound?: boolean;\n};\n\n/**\n * The per-request CSP nonce, if the app asked for one.\n *\n * The framework never mints it: `secureHeaders()` does, when its policy contains the `NONCE`\n * placeholder, and stores it here — so all the framework does is stamp the value into the render. It is\n * readable from a route handler because `secureHeaders` resolves its directives before `next()`.\n */\nfunction cspNonce(c: Context): string | undefined {\n return c.get('secureHeadersNonce');\n}\n\n/**\n * Whether a `<form action={serverAction}>` post came from another site, and so must not be allowed to run one.\n *\n * This is not CSRF policy — that is `csrf()` from Hono, registered in `src/server.ts`, which runs ahead of\n * every page route and covers far more than this. It is the framework declining to run *its own* action\n * mechanism for a request that mechanism cannot legitimately produce, in the one place the two action shapes\n * are not equally exposed:\n *\n * - A client-initiated action carries `x-rsc-action`, which is not a CORS-simple header. A cross-origin caller\n * needs a preflight it will not be given, so that shape cannot be forged from a browser at all.\n * - A form post is `multipart/form-data` or `application/x-www-form-urlencoded` with no header of its own —\n * the content types that need no preflight. It is forgeable, and an app with no `src/server.ts` has nothing\n * standing in front of it.\n *\n * Both halves are required, because either alone refuses something real:\n *\n * - `Sec-Fetch-Site: cross-site` is the browser's own statement of provenance, and every browser that can post\n * a form to a server action sends it. An absent header means a non-browser client, which cannot be a CSRF\n * victim; `same-site` is left alone too, since a subdomain policy is `csrf()`'s to express.\n * - An `Origin` that is the app's own contradicts that label — a browser calls a post from the app's own pages\n * `same-origin` — so the pair is a shape no browser produces, and refusing it would only catch a proxy or a\n * test client setting the label by hand while posting from the app itself.\n *\n * `publicUrl(c)` rather than `c.req.url`, so it honours `trustProxy` and compares against the origin the\n * browser actually used — which behind a proxy, `rshono dev`'s included, is not the one the server was reached\n * on. The cost is that an app deliberately accepting cross-site *form* posts to an action cannot; that is what\n * an `{ type: 'endpoint' }` route is for.\n */\nfunction refusesCrossSiteForm(c: Context): boolean {\n if (c.req.header('sec-fetch-site') !== 'cross-site') return false;\n const origin = c.req.header('origin');\n return origin !== undefined && origin !== publicUrl(c).origin;\n}\n\nasync function loadPageModule(load: () => Promise<{ default: PageComponent }>, label: string): Promise<ServerEntry<PageComponent>> {\n const mod = await load();\n const Page = mod.default as ServerEntry<PageComponent> | undefined;\n if (typeof Page !== 'function') {\n throw new Error(`[rshono] The page module for ${label} must default-export a server component.`);\n }\n if (!Page.entryJsFiles) {\n throw new Error(\n `[rshono] The page component for ${label} is missing its client-asset info ('use server-entry'). ` +\n \"The directive is added automatically for inline `component: () => import('…')` thunks in routes.ts. \" +\n \"If this page is wired up another way, put 'use server-entry' on the first line of the page module yourself — \" +\n \"and make sure the page is a server component (a 'use client' page must be wrapped by a server component instead).\",\n );\n }\n return Page;\n}\n\n/** A browser navigation or a crawler, as opposed to a fetch that would rather have plain text. */\nfunction acceptsHtml(c: Context): boolean {\n return c.req.header('accept')?.includes('text/html') ?? false;\n}\n\n/**\n * The 404 for an app with no `notFound` page, and for a client that wanted neither HTML nor a flight\n * payload. It carries the `Vary` too: this is one of the answers a page URL gives depending on the `RSC` request header.\n */\nfunction plainNotFound(c: Context): Response {\n return c.text('Not Found', 404, { vary: RSC_VARY_HEADER });\n}\n\n/** A lazy once-cell: runs `load` at most once, but clears a rejection so a later call can retry. */\nfunction once<T>(load: () => Promise<T>): () => Promise<T> {\n let promise: Promise<T> | undefined;\n return () => {\n if (!promise) {\n const pending = (promise = load());\n pending.catch(() => {\n if (promise === pending) promise = undefined;\n });\n }\n return promise;\n };\n}\n\n/**\n * Passes `stream` through untouched, calling `done` however it ends — for the flight-only response\n * path, which has no transform of its own to hang a completion hook off. `done` must be idempotent.\n */\nfunction releaseWhenDone(stream: ReadableStream<Uint8Array>, done: () => void): ReadableStream<Uint8Array> {\n return stream.pipeThrough(\n new TransformStream<Uint8Array, Uint8Array>({\n transform(chunk, controller) {\n controller.enqueue(chunk);\n },\n flush: done,\n cancel: done,\n } as CancellableTransformer<Uint8Array, Uint8Array>),\n );\n}\n\ninterface ComponentRenderOptions {\n status?: number;\n isRsc: boolean;\n formState?: ReactFormState;\n returnValue?: RscPayload['returnValue'];\n temporaryReferences?: TemporaryReferenceSet;\n /** Passed when the page being rendered is the `error` page, which takes it as an extra prop. */\n errorInfo?: ErrorPageInfo;\n /** Marks the payload as the not-found page, so a soft navigation can tell it apart from the page it asked for. */\n notFound?: boolean;\n}\n\n/**\n * Builds the props a page component is called with.\n *\n * `ctx` is *defined* rather than assigned, and both halves are load-bearing:\n *\n * - **A getter**, so nothing is built for the pages that never read it, and a `render: 'static'` page\n * that does gets {@link getRequestContext}'s prerendering error rather than a bare `undefined`.\n * - **Non-enumerable**, so React's dev-only serialization of a server component's props skips it. That\n * walks own enumerable properties, and `ctx.hono.env` holds the runtime's bindings — an enumerable\n * `ctx` would ship every secret to the browser in dev.\n *\n * The cost: the element is created by handing this object to `jsx()` by reference, since a\n * `<Page {...props} />` spread would silently drop `ctx`.\n */\nfunction pageProps(c: Context, errorInfo: ErrorPageInfo | undefined): PageProps & { error?: ErrorPageInfo } {\n const props = { url: publicUrl(c), params: readParams(c), ...(errorInfo ? { error: errorInfo } : null) };\n Object.defineProperty(props, 'ctx', { get: getRequestContext, enumerable: false, configurable: true });\n return props as PageProps & { error?: ErrorPageInfo };\n}\n\nasync function renderComponent(c: Context, Page: ServerEntry<PageComponent>, opts: ComponentRenderOptions): Promise<Response> {\n // React's renderers must never be handed `c.req.raw.signal`: they add an `abort` listener and only\n // remove it if the abort fires, so on the happy path it stays on a request-lifetime signal and pins the\n // whole rendered tree. The render gets its own controller and the request signal forwards into it —\n // `release` detaches on the normal path. Not `AbortSignal.any()`, whose composite signals Node holds in\n // a process-lifetime set until they abort.\n const requestSignal = c.req.raw.signal;\n const renderAbort = new AbortController();\n const signal = renderAbort.signal;\n const forwardAbort = () => renderAbort.abort(requestSignal.reason);\n if (requestSignal.aborted) renderAbort.abort(requestSignal.reason);\n else requestSignal.addEventListener('abort', forwardAbort, { once: true });\n const release = () => requestSignal.removeEventListener('abort', forwardAbort);\n\n // Documents only: the nonce goes on the bootstrap scripts and the `<meta>` React hydrates from, and a\n // flight payload has neither — which is what keeps a prerendered one servable under a nonce-based CSP.\n const nonce = opts.isRsc ? undefined : cspNonce(c);\n const props = pageProps(c, opts.errorInfo);\n const root = (\n <>\n {nonce && <meta property=\"csp-nonce\" nonce={nonce} />}\n {Page.entryCssFiles?.map((href) => (\n <link key={href} rel=\"stylesheet\" href={href} precedence=\"default\" />\n ))}\n {/* `href`, not the `URL`: these props cross into a client component, so they have to be serializable. */}\n <RouterProvider href={props.url.href} params={props.params}>\n {jsx(Page, props)}\n </RouterProvider>\n </>\n );\n\n // `notFound` only when true, so an ordinary page's payload doesn't carry the key.\n const rscPayload: RscPayload = { root, formState: opts.formState, returnValue: opts.returnValue, ...(opts.notFound ? { notFound: true } : null) };\n\n // The last thing before the render: past here the response head is the framework's, so `ctx.setHeader()`\n // starts throwing — while the action `renderPage` just ran, and the middleware around it, legitimately wrote.\n beginPageRender(c);\n\n let controlSignal: ControlSignal | undefined;\n const rscStream = renderToReadableStream(rscPayload, {\n temporaryReferences: opts.temporaryReferences,\n signal,\n onError(error) {\n if (isControlSignal(error)) {\n controlSignal = error;\n return error.digest;\n }\n if (!signal.aborted) reportServerError(error, { source: 'render', request: c.req.raw, message: '[rshono] render error:' });\n },\n });\n\n if (opts.isRsc) {\n return c.body(releaseWhenDone(rscStream, release), (opts.status ?? 200) as ContentfulStatusCode, {\n 'content-type': 'text/x-component;charset=utf-8',\n });\n }\n\n let ssrResult: Awaited<ReturnType<typeof renderHTML>>;\n try {\n ssrResult = await renderHTML(rscStream, {\n bootstrapScripts: Page.entryJsFiles,\n formState: opts.formState,\n signal,\n nonce,\n onDone: release,\n onShellError: (error) => reportServerError(error, { source: 'ssr', request: c.req.raw, message: '[rshono] SSR shell error:' }),\n onError: (error) => reportServerError(error, { source: 'ssr', request: c.req.raw, message: '[rshono] SSR error:' }),\n });\n } catch (error) {\n release();\n if (controlSignal) throw controlSignal;\n throw error;\n }\n if (controlSignal) {\n // The shell resolved, so this response is live: React is being pumped into the payload-injecting\n // transform, and a `redirect()` that surfaced from a boundary settling just before the shell was ready\n // lands here. Nothing will read that stream now — the signal becomes a redirect instead — so it is stopped\n // rather than left to render to completion for a response that was replaced.\n //\n // Both calls, because they stop different halves. `abort` reaches the two renders through the signal they\n // were handed; cancelling the response readable propagates back through the transform to release the teed\n // flight branch it holds a reader on, which `abort` alone does not.\n renderAbort.abort();\n void ssrResult.stream.cancel().catch(() => {\n // Already errored or locked — there is nothing left to release either way.\n });\n release();\n throw controlSignal;\n }\n return c.body(ssrResult.stream, (ssrResult.status ?? opts.status ?? 200) as ContentfulStatusCode, {\n 'content-type': 'text/html;charset=utf-8',\n });\n}\n\nasync function renderPage(c: Context, loadPage: () => Promise<ServerEntry<PageComponent>>): Promise<Response> {\n const request = c.req.raw;\n const renderRequest = parseRenderRequest(request);\n\n let returnValue: ActionResult | undefined;\n let formState: ReactFormState | undefined;\n let temporaryReferences: TemporaryReferenceSet | undefined;\n let actionStatus: number | undefined;\n if (isActionRequest(renderRequest)) {\n if (renderRequest.kind === 'rsc-action') {\n // Before the body is decoded, so an unknown id costs nothing to reject. `hasOwn` so `__proto__`\n // does not resolve to a manifest entry.\n if (!Object.hasOwn(__rspack_rsc_manifest__.serverManifest, renderRequest.actionId)) {\n return c.text('Bad Request: unknown server action', 400);\n }\n const contentType = request.headers.get('content-type');\n const body = contentType?.startsWith('multipart/form-data') ? await request.formData() : await request.text();\n temporaryReferences = createTemporaryReferenceSet();\n const args = await decodeReply<unknown[]>(body, { temporaryReferences });\n const action = loadServerAction(renderRequest.actionId);\n try {\n returnValue = { ok: true, value: await action(...args) };\n } catch (error) {\n if (isControlSignal(error)) throw error;\n // In production React sends a thrown action error to the client as an opaque marker, so this is\n // the only place the real one is visible.\n reportServerError(error, { source: 'action', request, message: '[rshono] server action error:' });\n returnValue = { ok: false, error };\n actionStatus = 500;\n }\n } else {\n // A `<form action={serverAction}>` post, which is the path that runs before hydration and with\n // JavaScript off. Unlike the client-initiated one it carries no custom header, so it is also the only\n // action shape a browser can be made to send from another site: see `refusesCrossSiteForm`.\n if (refusesCrossSiteForm(c)) {\n return c.text('Forbidden: cross-site form post to a server action', 403, { vary: RSC_VARY_HEADER });\n }\n const formData = await request.formData();\n const decodedAction = await decodeAction(formData, __rspack_rsc_manifest__.serverManifest);\n if (decodedAction) {\n let result: unknown;\n try {\n result = await decodedAction();\n } catch (error) {\n if (isControlSignal(error)) throw error;\n // Reported here so a no-JS form post is attributed to the action that threw, exactly as the\n // client-initiated path is — the top-level handler would call it a `request`. Then re-thrown,\n // because this path has no client boundary and no `useActionState` to hand the error to, so the\n // app's `error` page is the honest answer. `reportServerError` de-duplicates, so the re-throw\n // reaching `onError` does not report it a second time.\n reportServerError(error, { source: 'action', request, message: '[rshono] server action error:' });\n throw error;\n }\n formState = (await decodeFormState(result, formData, __rspack_rsc_manifest__.serverManifest)) ?? undefined;\n }\n }\n }\n\n const Page = await loadPage();\n return renderComponent(c, Page, {\n status: actionStatus,\n isRsc: wantsRsc(renderRequest),\n formState,\n returnValue,\n temporaryReferences,\n });\n}\n\nfunction buildApp(): Hono {\n const app = new Hono();\n\n // A floor, not a policy: an app wanting the full set registers `secureHeaders()` in src/server.ts, and\n // because this is registered first it unwinds last, so the \"only if unset\" checks stand aside for it.\n // Owned by the framework because it also has to cover `mountStaticAssets` — a terminal handler the\n // app's own middleware never sees.\n app.use(async (c, next) => {\n await next();\n const headers = c.res.headers;\n if (!headers.has('x-content-type-options')) headers.set('x-content-type-options', 'nosniff');\n if (!headers.has('referrer-policy')) headers.set('referrer-policy', 'strict-origin-when-cross-origin');\n if (!headers.has('x-frame-options')) headers.set('x-frame-options', 'SAMEORIGIN');\n\n // React Refresh compiles updates with `eval`, so a dev build cannot run under a production CSP.\n // Widened here so one policy in src/server.ts serves both.\n if (isDev) {\n const csp = headers.get('content-security-policy');\n if (csp?.includes('script-src ')) {\n headers.set('content-security-policy', csp.replace('script-src ', \"script-src 'unsafe-eval' \"));\n }\n }\n\n // Page responses only from here down.\n if (!PAGE_CONTENT_TYPE.test(headers.get('content-type') ?? '')) return;\n appendVary(headers, RSC_VARY_HEADER);\n // Without a default a shared cache is free to store a logged-in user's page and hand it to someone\n // else. `private, no-cache` forbids that without blocking bfcache, which `no-store` would.\n if (!headers.has('cache-control')) headers.set('cache-control', 'private, no-cache');\n });\n\n runtime.mountStaticAssets(app);\n\n // Ahead of the page routes, so the app's own middleware (`csrf()`, `bodyLimit()`, auth, logging) wraps\n // page requests too. The flip side: a *terminal* handler in src/server.ts shadows a page at the same path.\n if (serverApp) {\n app.route('/', serverApp);\n }\n\n const memoizePage = (page: FallbackPage, label: string) => once(() => loadPageModule(page.component, label));\n const loadNotFoundPage = routeConfig.notFound ? memoizePage(routeConfig.notFound, 'the notFound page') : null;\n\n /** Turns a thrown `redirect()` / `notFound()` into the response it stands for. */\n const respondToControlSignal = async (c: Context, signal: ControlSignal): Promise<Response> => {\n const isRsc = requestWantsRsc(c.req.raw);\n if (signal instanceof RedirectSignal) {\n if (isRsc) {\n // No `signal`: two fields and no component tree, so there is nothing worth aborting.\n return c.body(renderToReadableStream({ root: null, redirect: signal.location } satisfies RscPayload), 200, {\n 'content-type': 'text/x-component;charset=utf-8',\n });\n }\n return c.redirect(signal.location, signal.status as RedirectStatusCode);\n }\n if (loadNotFoundPage) {\n return renderComponent(c, await loadNotFoundPage(), { status: 404, isRsc, notFound: true });\n }\n return plainNotFound(c);\n };\n\n for (const route of routes) {\n if (isPageRoute(route)) {\n // Both fixed for the life of the process, so resolved once rather than per request.\n const servesPrerendered = !isDev && route.render === 'static';\n const loadPage = once(() => loadPageModule(route.component, `\"${route.path}\"`));\n\n const handler: Handler = async (c) => {\n try {\n if (servesPrerendered && c.req.method === 'GET') {\n const isRsc = asksForRsc(c.req.raw);\n // One fixed set of bytes cannot carry a per-request nonce, so a document has to be rendered\n // where the app's CSP has one. Decided per request, so an app whose policy carries no `NONCE`\n // keeps its prerendered documents. A flight payload never carries a nonce either way.\n const mustRenderForNonce = !isRsc && cspNonce(c) !== undefined;\n if (!mustRenderForNonce) {\n const page = await runtime.readPrerendered(c, isRsc ? 'flight' : 'html');\n // Request-independent by construction, so it is safe to cache publicly; the ETag turns the\n // revalidation that follows into a 304. Answered outside `runWithContext` — no app code runs\n // on this path, so there is no `getRequestContext()` to serve.\n if (page !== null) {\n const headers = {\n 'cache-control': SSG_CACHE_CONTROL,\n etag: page.etag,\n vary: RSC_VARY_HEADER,\n 'content-type': isRsc ? 'text/x-component;charset=utf-8' : 'text/html;charset=utf-8',\n };\n if (etagMatches(c.req.header('if-none-match'), page.etag)) return c.body(null, 304, headers);\n return c.body(page.body, 200, { ...headers, 'content-length': page.contentLength });\n }\n }\n }\n return await runWithContext(c, () => renderPage(c, loadPage));\n } catch (error) {\n if (isControlSignal(error)) return runWithContext(c, () => respondToControlSignal(c, error));\n throw error;\n }\n };\n app.on(['GET', 'POST'], route.path, handler);\n } else {\n const loadEndpoint = once(() => route.server());\n const handler: Handler = async (c, next) => {\n const { handler: endpointHandler } = await loadEndpoint();\n // Hono's `Handler` leaves its return parameter defaulted to `any`, so this hands back exactly what\n // the app's own handler is declared to return — there is nothing narrower to assert here.\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return endpointHandler(c, next);\n };\n const method = route.method ?? 'all';\n if (method === 'all') app.all(route.path, handler);\n else app.on(method.toUpperCase(), route.path, handler);\n }\n }\n\n runtime.mountPublicFallback(app);\n\n app.notFound(async (c) => {\n const isRsc = requestWantsRsc(c.req.raw);\n if (loadNotFoundPage && (isRsc || acceptsHtml(c))) {\n return runWithContext(c, async () => renderComponent(c, await loadNotFoundPage(), { status: 404, isRsc }));\n }\n return plainNotFound(c);\n });\n\n const loadErrorPage = routeConfig.error ? memoizePage(routeConfig.error, 'the error page') : null;\n app.onError(async (error, c) => {\n if (isControlSignal(error)) return runWithContext(c, () => respondToControlSignal(c, error));\n // Registering an `onError` replaces Hono's default handler, which is what turns an `HTTPException`\n // into the response it carries — without this, `csrf()`'s 403 and `bodyLimit()`'s 413 would both\n // surface as a 500 error page. Rebuilt through `c`, as Hono's default does, so headers middleware\n // already prepared survive.\n if (error instanceof HTTPException) {\n const res = error.getResponse();\n return c.newResponse(res.body, res);\n }\n reportServerError(error, { source: 'request', request: c.req.raw, message: '[rshono] request error:' });\n const isRsc = requestWantsRsc(c.req.raw);\n if (loadErrorPage && (isRsc || acceptsHtml(c))) {\n const errorInfo: ErrorPageInfo = isDev\n ? {\n message: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n }\n : { message: 'Internal Server Error' };\n try {\n return await runWithContext(c, async () => renderComponent(c, await loadErrorPage(), { status: 500, isRsc, errorInfo }));\n } catch (renderError) {\n reportServerError(renderError, { source: 'request', request: c.req.raw, message: '[rshono] the error page failed to render:' });\n }\n }\n const detail = isDev ? `\\n\\n${error instanceof Error ? (error.stack ?? error.message) : String(error)}` : '';\n return c.text(`Internal Server Error${detail}`, 500, { vary: RSC_VARY_HEADER });\n });\n\n return app;\n}\n\nexport const app = buildApp();\n\n/**\n * The app, handed to whatever is hosting it: this binds a port and exports nothing where rshono owns the\n * process, and *is* the export the platform looks for where the host owns it — so one entry serves both.\n *\n * `app` and `routes` stay named exports either way, because `rshono build` imports them to prerender\n * `render: 'static'` routes.\n */\nexport default runtime.serveApp(app);\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flight-inject.d.ts","sourceRoot":"","sources":["../../src/runtime/flight-inject.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,sBAAsB,CAAC,CAAC,EAAE,CAAC,IAAI,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;IAAE,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;CAAE,CAAC;AAkDvG,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,cAAc,CAAC,UAAU,CAAC,EACrC,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;CAAO,GACpD,eAAe,CAAC,UAAU,EAAE,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"flight-inject.d.ts","sourceRoot":"","sources":["../../src/runtime/flight-inject.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,sBAAsB,CAAC,CAAC,EAAE,CAAC,IAAI,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;IAAE,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;CAAE,CAAC;AAkDvG,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,cAAc,CAAC,UAAU,CAAC,EACrC,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;CAAO,GACpD,eAAe,CAAC,UAAU,EAAE,UAAU,CAAC,CA2KzC"}
|
|
@@ -161,15 +161,42 @@ export function injectFlightPayload(rscStream, options = {}) {
|
|
|
161
161
|
});
|
|
162
162
|
},
|
|
163
163
|
async flush(controller) {
|
|
164
|
-
await
|
|
165
|
-
// That await spans the whole payload, and the consumer can go away inside it — with `cancel` skipped
|
|
166
|
-
// (see `cancelled`), a throwing enqueue is the only signal. Unguarded it rejects `flush`, which
|
|
167
|
-
// nothing owns and which surfaces as an unhandled rejection.
|
|
164
|
+
// Both of these have to happen *before* the await, and in this order.
|
|
168
165
|
try {
|
|
166
|
+
// Anything still batched belongs ahead of the payload scripts, which sit at the end of `<body>`.
|
|
169
167
|
if (boundary) {
|
|
170
168
|
unschedule(boundary);
|
|
169
|
+
boundary = null;
|
|
171
170
|
emitBatch(controller);
|
|
172
171
|
}
|
|
172
|
+
// A writable side that closed without ever reaching `transform` — an HTML stream with no chunks at
|
|
173
|
+
// all — leaves nothing to have started the payload, and `flightDone` is only ever called from that
|
|
174
|
+
// chain or from `cancel`. Without this the await below parks on a promise nothing will settle and the
|
|
175
|
+
// response never ends. `cancelled` short-circuits it: there is nowhere to write the payload to.
|
|
176
|
+
if (!startedFlight) {
|
|
177
|
+
startedFlight = true;
|
|
178
|
+
if (cancelled)
|
|
179
|
+
flightDone();
|
|
180
|
+
else
|
|
181
|
+
void writeFlight(controller)
|
|
182
|
+
.catch((error) => controller.error(error))
|
|
183
|
+
.then(flightDone);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
// The consumer went away while the batch was being emitted, so there is nothing left to write to and
|
|
188
|
+
// nothing to wait for. Settled explicitly rather than left dangling, so the payload chain is released.
|
|
189
|
+
cancelled = true;
|
|
190
|
+
flightReader?.cancel().catch(() => { });
|
|
191
|
+
flightDone();
|
|
192
|
+
onDone?.();
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
await flightWritten;
|
|
196
|
+
// That await spans the whole payload, and the consumer can go away inside it — with `cancel` skipped
|
|
197
|
+
// (see `cancelled`), a throwing enqueue is the only signal. Unguarded it rejects `flush`, which
|
|
198
|
+
// nothing owns and which surfaces as an unhandled rejection.
|
|
199
|
+
try {
|
|
173
200
|
if (!cancelled)
|
|
174
201
|
controller.enqueue(encoder.encode(TRAILER));
|
|
175
202
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flight-inject.js","sourceRoot":"","sources":["../../src/runtime/flight-inject.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Carrying the flight payload inside the HTML document, so the browser hydrates from bytes it already has\n * rather than fetching the page twice. The reader is `readFlightPayload` in `entry.client.tsx`.\n *\n * The wire format is `rsc-html-stream`'s — a run of `<script>(self.__FLIGHT_DATA||=[]).push(\"…\")</script>`\n * tags — but the implementation is first-party, because that package tests each HTML chunk for the\n * document trailer with `endsWith`: React's byte writer splits any write straddling its 2 kB views, so\n * `</body></html>` can arrive as two chunks and the document ends up with two trailers.\n */\n\n/**\n * {@link Transformer} plus the `cancel` hook the Streams standard added for a cancelled readable side —\n * declared here because the bundled lib types have not caught up with what Node calls.\n *\n * It matters because `cancel` is the only notification that a response ended *without* finishing, and both\n * users of it release a listener that would otherwise outlive the request.\n */\nexport type CancellableTransformer<I, O> = Transformer<I, O> & { cancel?: (reason?: unknown) => void };\n\nconst encoder = new TextEncoder();\n\n/** What React closes an `<html>` document with, and what this module re-emits after the last payload script. */\nconst TRAILER = '</body></html>';\nconst TRAILER_BYTES = encoder.encode(TRAILER);\n\n/**\n * A macrotask boundary: `setImmediate` where there is one, which is the current turn's check phase rather\n * than a timer, and `setTimeout` as the portable fallback. A Node timer has a 1ms floor that every HTML\n * flush would pay — 4.7ms → 3.0ms time-to-last-byte on a 30 kB payload.\n */\ntype TaskHandle = ReturnType<typeof setTimeout> | ReturnType<typeof setImmediate>;\nconst hasSetImmediate = typeof setImmediate === 'function';\nconst schedule: (fn: () => void) => TaskHandle = hasSetImmediate ? setImmediate : (fn) => setTimeout(fn, 0);\nconst unschedule = (handle: TaskHandle): void => {\n if (hasSetImmediate) clearImmediate(handle as ReturnType<typeof setImmediate>);\n else clearTimeout(handle as ReturnType<typeof setTimeout>);\n};\n\n/**\n * Escapes the two sequences that would end a `<script>` element early. Guarded by `includes('<')`, which is\n * far cheaper than two regex passes over 30 kB of payload that usually has no `<` in it. `</script` becomes\n * `</\\script`, not `<\\/script`, which would break the valid JS `0</script/`.\n */\nfunction escapeScript(script: string): string {\n return script.includes('<') ? script.replace(/<!--/g, '<\\\\!--').replace(/<\\/(script)/gi, '</\\\\$1') : script;\n}\n\n/**\n * The bytes of `chunk` as a latin1 string, which is the form `btoa` takes. Sliced because\n * `String.fromCharCode(...chunk)` passes one argument per byte and overflows the stack.\n */\nfunction latin1(chunk: Uint8Array): string {\n let out = '';\n for (let at = 0; at < chunk.length; at += 8192) out += String.fromCharCode(...chunk.subarray(at, at + 8192));\n return out;\n}\n\n/** Whether `buffer`'s first `length` bytes end with the document trailer. */\nfunction endsWithTrailer(buffer: Uint8Array, length: number): boolean {\n if (length < TRAILER_BYTES.length) return false;\n const from = length - TRAILER_BYTES.length;\n for (let i = 0; i < TRAILER_BYTES.length; i++) {\n if (buffer[from + i] !== TRAILER_BYTES[i]) return false;\n }\n return true;\n}\n\nexport function injectFlightPayload(\n rscStream: ReadableStream<Uint8Array>,\n options: { nonce?: string; onDone?: () => void } = {},\n): TransformStream<Uint8Array, Uint8Array> {\n const { nonce, onDone } = options;\n const scriptOpen = `<script${nonce ? ` nonce=\"${nonce}\"` : ''}>(self.__FLIGHT_DATA||=[]).push(`;\n const scriptClose = ')</script>';\n\n const { promise: flightWritten, resolve: flightDone } = Promise.withResolvers<void>();\n let startedFlight = false;\n\n const batch: Uint8Array[] = [];\n let boundary: TaskHandle | null = null;\n\n /**\n * Set once the consumer has gone away, so nothing tries to enqueue into a readable that cannot take it.\n *\n * The `cancel` hook alone cannot set this: per the Streams standard, cancelling the readable after the\n * close algorithm has started skips the transformer's `cancel` entirely — and `flush` awaiting the whole\n * payload is precisely that window. So a failed enqueue counts as the signal too.\n */\n let cancelled = false;\n /** Held so {@link cancelled} can release the teed RSC branch rather than leaving it to be pumped. */\n let flightReader: ReadableStreamDefaultReader<Uint8Array> | null = null;\n\n /**\n * Emits the HTML buffered since the last boundary, holding back the document trailer for\n * {@link TransformStream.flush} to re-emit after the payload scripts.\n *\n * The batch is joined before the trailer is looked for, so one React split across two views is still\n * found. React writes its final flush in one synchronous run, so a trailer split across *batches* is not\n * a shape it produces.\n */\n function emitBatch(controller: TransformStreamDefaultController<Uint8Array>): void {\n boundary = null;\n let total = 0;\n for (const chunk of batch) total += chunk.byteLength;\n if (total === 0) {\n batch.length = 0;\n return;\n }\n\n const joined = new Uint8Array(total);\n let at = 0;\n for (const chunk of batch) {\n joined.set(chunk, at);\n at += chunk.byteLength;\n }\n batch.length = 0;\n\n const end = endsWithTrailer(joined, total) ? total - TRAILER_BYTES.length : total;\n if (end > 0) controller.enqueue(joined.subarray(0, end));\n }\n\n async function writeFlight(controller: TransformStreamDefaultController<Uint8Array>): Promise<void> {\n const reader = (flightReader = rscStream.getReader());\n // `fatal`, so a chunk that split a multi-byte character throws instead of emitting U+FFFD; the catch\n // below falls back to a byte-exact encoding for it.\n const decoder = new TextDecoder('utf-8', { fatal: true });\n const push = (literal: string) => controller.enqueue(encoder.encode(scriptOpen + literal + scriptClose));\n for (;;) {\n if (cancelled) return;\n const { done, value } = await reader.read();\n if (done) break;\n // Only the decode is guarded: a `push` inside the same `try` would answer a dead controller by\n // re-encoding the chunk and enqueueing it again.\n let literal: string;\n try {\n literal = escapeScript(JSON.stringify(decoder.decode(value, { stream: true })));\n } catch {\n literal = `Uint8Array.from(atob(${JSON.stringify(btoa(latin1(value)))}), m => m.codePointAt(0))`;\n }\n if (cancelled) return;\n // A failed enqueue means the consumer is gone: release the RSC branch so `flush` unparks now rather\n // than whenever the payload would have ended on its own.\n try {\n push(literal);\n } catch {\n cancelled = true;\n reader.cancel().catch(() => {});\n return;\n }\n }\n if (cancelled) return;\n const remaining = decoder.decode();\n if (remaining.length) push(escapeScript(JSON.stringify(remaining)));\n }\n\n const transformer: CancellableTransformer<Uint8Array, Uint8Array> = {\n transform(chunk, controller) {\n batch.push(chunk);\n if (boundary) return;\n // A macrotask, not a microtask: React writes a whole flush in one synchronous run but `pipeThrough`\n // delivers it one microtask at a time, and a script injected between two chunks lands inside a tag.\n boundary = schedule(() => {\n try {\n emitBatch(controller);\n } catch (error) {\n controller.error(error);\n flightDone();\n return;\n }\n if (!startedFlight) {\n startedFlight = true;\n // Deliberately not awaited: this runs inside a scheduled callback with nothing to return to, and\n // the chain already routes a write failure to `controller.error` before settling `flightDone`.\n void writeFlight(controller)\n .catch((error) => controller.error(error))\n .then(flightDone);\n }\n });\n },\n async flush(controller) {\n await flightWritten;\n // That await spans the whole payload, and the consumer can go away inside it — with `cancel` skipped\n // (see `cancelled`), a throwing enqueue is the only signal. Unguarded it rejects `flush`, which\n // nothing owns and which surfaces as an unhandled rejection.\n try {\n if (boundary) {\n unschedule(boundary);\n emitBatch(controller);\n }\n if (!cancelled) controller.enqueue(encoder.encode(TRAILER));\n } catch {\n // Nowhere left to put the trailer. A response the client abandoned is not a fault.\n cancelled = true;\n flightReader?.cancel().catch(() => {});\n } finally {\n // A `finally` because `onDone` releases the abort forwarder in `renderComponent`, however this ended.\n onDone?.();\n }\n },\n cancel(reason) {\n cancelled = true;\n if (boundary) {\n unschedule(boundary);\n boundary = null;\n }\n batch.length = 0;\n // Otherwise the teed RSC branch keeps being pumped for a response nobody will read, and the tee's\n // other half buffers every chunk waiting for this one to catch up.\n flightReader?.cancel(reason).catch(() => {});\n // Unparks `flush` if it is waiting on a payload that will now never arrive.\n flightDone();\n onDone?.();\n },\n };\n return new TransformStream<Uint8Array, Uint8Array>(transformer);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"flight-inject.js","sourceRoot":"","sources":["../../src/runtime/flight-inject.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAWH,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;AAElC,gHAAgH;AAChH,MAAM,OAAO,GAAG,gBAAgB,CAAC;AACjC,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAQ9C,MAAM,eAAe,GAAG,OAAO,YAAY,KAAK,UAAU,CAAC;AAC3D,MAAM,QAAQ,GAAmC,eAAe,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AAC5G,MAAM,UAAU,GAAG,CAAC,MAAkB,EAAQ,EAAE;IAC9C,IAAI,eAAe;QAAE,cAAc,CAAC,MAAyC,CAAC,CAAC;;QAC1E,YAAY,CAAC,MAAuC,CAAC,CAAC;AAC7D,CAAC,CAAC;AAEF;;;;GAIG;AACH,SAAS,YAAY,CAAC,MAAc;IAClC,OAAO,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AAC9G,CAAC;AAED;;;GAGG;AACH,SAAS,MAAM,CAAC,KAAiB;IAC/B,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,EAAE,IAAI,IAAI;QAAE,GAAG,IAAI,MAAM,CAAC,YAAY,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;IAC7G,OAAO,GAAG,CAAC;AACb,CAAC;AAED,6EAA6E;AAC7E,SAAS,eAAe,CAAC,MAAkB,EAAE,MAAc;IACzD,IAAI,MAAM,GAAG,aAAa,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAChD,MAAM,IAAI,GAAG,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC;IAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,IAAI,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,KAAK,aAAa,CAAC,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;IAC1D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,SAAqC,EACrC,OAAO,GAA4C,EAAE;IAErD,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAClC,MAAM,UAAU,GAAG,UAAU,KAAK,CAAC,CAAC,CAAC,WAAW,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,kCAAkC,CAAC;IAChG,MAAM,WAAW,GAAG,YAAY,CAAC;IAEjC,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,aAAa,EAAQ,CAAC;IACtF,IAAI,aAAa,GAAG,KAAK,CAAC;IAE1B,MAAM,KAAK,GAAiB,EAAE,CAAC;IAC/B,IAAI,QAAQ,GAAsB,IAAI,CAAC;IAEvC;;;;;;OAMG;IACH,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,qGAAqG;IACrG,IAAI,YAAY,GAAmD,IAAI,CAAC;IAExE;;;;;;;OAOG;IACH,SAAS,SAAS,CAAC,UAAwD;QACzE,QAAQ,GAAG,IAAI,CAAC;QAChB,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,KAAK,IAAI,KAAK;YAAE,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC;QACrD,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;YAChB,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;YACjB,OAAO;QACT,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,EAAE,GAAG,CAAC,CAAC;QACX,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;YAC1B,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACtB,EAAE,IAAI,KAAK,CAAC,UAAU,CAAC;QACzB,CAAC;QACD,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;QAEjB,MAAM,GAAG,GAAG,eAAe,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;QAClF,IAAI,GAAG,GAAG,CAAC;YAAE,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED,KAAK,UAAU,WAAW,CAAC,UAAwD;QACjF,MAAM,MAAM,GAAG,CAAC,YAAY,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC,CAAC;QACtD,qGAAqG;QACrG,oDAAoD;QACpD,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,MAAM,IAAI,GAAG,CAAC,OAAe,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,GAAG,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC;QACzG,SAAS,CAAC;YACR,IAAI,SAAS;gBAAE,OAAO;YACtB,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YAC5C,IAAI,IAAI;gBAAE,MAAM;YAChB,+FAA+F;YAC/F,iDAAiD;YACjD,IAAI,OAAe,CAAC;YACpB,IAAI,CAAC;gBACH,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAClF,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,GAAG,wBAAwB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,2BAA2B,CAAC;YACnG,CAAC;YACD,IAAI,SAAS;gBAAE,OAAO;YACtB,oGAAoG;YACpG,yDAAyD;YACzD,IAAI,CAAC;gBACH,IAAI,CAAC,OAAO,CAAC,CAAC;YAChB,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS,GAAG,IAAI,CAAC;gBACjB,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;gBAChC,OAAO;YACT,CAAC;QACH,CAAC;QACD,IAAI,SAAS;YAAE,OAAO;QACtB,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;QACnC,IAAI,SAAS,CAAC,MAAM;YAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,MAAM,WAAW,GAAmD;QAClE,SAAS,CAAC,KAAK,EAAE,UAAU;YACzB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAClB,IAAI,QAAQ;gBAAE,OAAO;YACrB,oGAAoG;YACpG,oGAAoG;YACpG,QAAQ,GAAG,QAAQ,CAAC,GAAG,EAAE;gBACvB,IAAI,CAAC;oBACH,SAAS,CAAC,UAAU,CAAC,CAAC;gBACxB,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;oBACxB,UAAU,EAAE,CAAC;oBACb,OAAO;gBACT,CAAC;gBACD,IAAI,CAAC,aAAa,EAAE,CAAC;oBACnB,aAAa,GAAG,IAAI,CAAC;oBACrB,iGAAiG;oBACjG,+FAA+F;oBAC/F,KAAK,WAAW,CAAC,UAAU,CAAC;yBACzB,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;yBACzC,IAAI,CAAC,UAAU,CAAC,CAAC;gBACtB,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QACD,KAAK,CAAC,KAAK,CAAC,UAAU;YACpB,sEAAsE;YACtE,IAAI,CAAC;gBACH,iGAAiG;gBACjG,IAAI,QAAQ,EAAE,CAAC;oBACb,UAAU,CAAC,QAAQ,CAAC,CAAC;oBACrB,QAAQ,GAAG,IAAI,CAAC;oBAChB,SAAS,CAAC,UAAU,CAAC,CAAC;gBACxB,CAAC;gBACD,mGAAmG;gBACnG,mGAAmG;gBACnG,sGAAsG;gBACtG,gGAAgG;gBAChG,IAAI,CAAC,aAAa,EAAE,CAAC;oBACnB,aAAa,GAAG,IAAI,CAAC;oBACrB,IAAI,SAAS;wBAAE,UAAU,EAAE,CAAC;;wBAE1B,KAAK,WAAW,CAAC,UAAU,CAAC;6BACzB,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;6BACzC,IAAI,CAAC,UAAU,CAAC,CAAC;gBACxB,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,qGAAqG;gBACrG,uGAAuG;gBACvG,SAAS,GAAG,IAAI,CAAC;gBACjB,YAAY,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;gBACvC,UAAU,EAAE,CAAC;gBACb,MAAM,EAAE,EAAE,CAAC;gBACX,OAAO;YACT,CAAC;YAED,MAAM,aAAa,CAAC;YACpB,qGAAqG;YACrG,gGAAgG;YAChG,6DAA6D;YAC7D,IAAI,CAAC;gBACH,IAAI,CAAC,SAAS;oBAAE,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;YAC9D,CAAC;YAAC,MAAM,CAAC;gBACP,mFAAmF;gBACnF,SAAS,GAAG,IAAI,CAAC;gBACjB,YAAY,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACzC,CAAC;oBAAS,CAAC;gBACT,sGAAsG;gBACtG,MAAM,EAAE,EAAE,CAAC;YACb,CAAC;QACH,CAAC;QACD,MAAM,CAAC,MAAM;YACX,SAAS,GAAG,IAAI,CAAC;YACjB,IAAI,QAAQ,EAAE,CAAC;gBACb,UAAU,CAAC,QAAQ,CAAC,CAAC;gBACrB,QAAQ,GAAG,IAAI,CAAC;YAClB,CAAC;YACD,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;YACjB,kGAAkG;YAClG,mEAAmE;YACnE,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YAC7C,4EAA4E;YAC5E,UAAU,EAAE,CAAC;YACb,MAAM,EAAE,EAAE,CAAC;QACb,CAAC;KACF,CAAC;IACF,OAAO,IAAI,eAAe,CAAyB,WAAW,CAAC,CAAC;AAClE,CAAC","sourcesContent":["/**\n * Carrying the flight payload inside the HTML document, so the browser hydrates from bytes it already has\n * rather than fetching the page twice. The reader is `readFlightPayload` in `entry.client.tsx`.\n *\n * The wire format is `rsc-html-stream`'s — a run of `<script>(self.__FLIGHT_DATA||=[]).push(\"…\")</script>`\n * tags — but the implementation is first-party, because that package tests each HTML chunk for the\n * document trailer with `endsWith`: React's byte writer splits any write straddling its 2 kB views, so\n * `</body></html>` can arrive as two chunks and the document ends up with two trailers.\n */\n\n/**\n * {@link Transformer} plus the `cancel` hook the Streams standard added for a cancelled readable side —\n * declared here because the bundled lib types have not caught up with what Node calls.\n *\n * It matters because `cancel` is the only notification that a response ended *without* finishing, and both\n * users of it release a listener that would otherwise outlive the request.\n */\nexport type CancellableTransformer<I, O> = Transformer<I, O> & { cancel?: (reason?: unknown) => void };\n\nconst encoder = new TextEncoder();\n\n/** What React closes an `<html>` document with, and what this module re-emits after the last payload script. */\nconst TRAILER = '</body></html>';\nconst TRAILER_BYTES = encoder.encode(TRAILER);\n\n/**\n * A macrotask boundary: `setImmediate` where there is one, which is the current turn's check phase rather\n * than a timer, and `setTimeout` as the portable fallback. A Node timer has a 1ms floor that every HTML\n * flush would pay — 4.7ms → 3.0ms time-to-last-byte on a 30 kB payload.\n */\ntype TaskHandle = ReturnType<typeof setTimeout> | ReturnType<typeof setImmediate>;\nconst hasSetImmediate = typeof setImmediate === 'function';\nconst schedule: (fn: () => void) => TaskHandle = hasSetImmediate ? setImmediate : (fn) => setTimeout(fn, 0);\nconst unschedule = (handle: TaskHandle): void => {\n if (hasSetImmediate) clearImmediate(handle as ReturnType<typeof setImmediate>);\n else clearTimeout(handle as ReturnType<typeof setTimeout>);\n};\n\n/**\n * Escapes the two sequences that would end a `<script>` element early. Guarded by `includes('<')`, which is\n * far cheaper than two regex passes over 30 kB of payload that usually has no `<` in it. `</script` becomes\n * `</\\script`, not `<\\/script`, which would break the valid JS `0</script/`.\n */\nfunction escapeScript(script: string): string {\n return script.includes('<') ? script.replace(/<!--/g, '<\\\\!--').replace(/<\\/(script)/gi, '</\\\\$1') : script;\n}\n\n/**\n * The bytes of `chunk` as a latin1 string, which is the form `btoa` takes. Sliced because\n * `String.fromCharCode(...chunk)` passes one argument per byte and overflows the stack.\n */\nfunction latin1(chunk: Uint8Array): string {\n let out = '';\n for (let at = 0; at < chunk.length; at += 8192) out += String.fromCharCode(...chunk.subarray(at, at + 8192));\n return out;\n}\n\n/** Whether `buffer`'s first `length` bytes end with the document trailer. */\nfunction endsWithTrailer(buffer: Uint8Array, length: number): boolean {\n if (length < TRAILER_BYTES.length) return false;\n const from = length - TRAILER_BYTES.length;\n for (let i = 0; i < TRAILER_BYTES.length; i++) {\n if (buffer[from + i] !== TRAILER_BYTES[i]) return false;\n }\n return true;\n}\n\nexport function injectFlightPayload(\n rscStream: ReadableStream<Uint8Array>,\n options: { nonce?: string; onDone?: () => void } = {},\n): TransformStream<Uint8Array, Uint8Array> {\n const { nonce, onDone } = options;\n const scriptOpen = `<script${nonce ? ` nonce=\"${nonce}\"` : ''}>(self.__FLIGHT_DATA||=[]).push(`;\n const scriptClose = ')</script>';\n\n const { promise: flightWritten, resolve: flightDone } = Promise.withResolvers<void>();\n let startedFlight = false;\n\n const batch: Uint8Array[] = [];\n let boundary: TaskHandle | null = null;\n\n /**\n * Set once the consumer has gone away, so nothing tries to enqueue into a readable that cannot take it.\n *\n * The `cancel` hook alone cannot set this: per the Streams standard, cancelling the readable after the\n * close algorithm has started skips the transformer's `cancel` entirely — and `flush` awaiting the whole\n * payload is precisely that window. So a failed enqueue counts as the signal too.\n */\n let cancelled = false;\n /** Held so {@link cancelled} can release the teed RSC branch rather than leaving it to be pumped. */\n let flightReader: ReadableStreamDefaultReader<Uint8Array> | null = null;\n\n /**\n * Emits the HTML buffered since the last boundary, holding back the document trailer for\n * {@link TransformStream.flush} to re-emit after the payload scripts.\n *\n * The batch is joined before the trailer is looked for, so one React split across two views is still\n * found. React writes its final flush in one synchronous run, so a trailer split across *batches* is not\n * a shape it produces.\n */\n function emitBatch(controller: TransformStreamDefaultController<Uint8Array>): void {\n boundary = null;\n let total = 0;\n for (const chunk of batch) total += chunk.byteLength;\n if (total === 0) {\n batch.length = 0;\n return;\n }\n\n const joined = new Uint8Array(total);\n let at = 0;\n for (const chunk of batch) {\n joined.set(chunk, at);\n at += chunk.byteLength;\n }\n batch.length = 0;\n\n const end = endsWithTrailer(joined, total) ? total - TRAILER_BYTES.length : total;\n if (end > 0) controller.enqueue(joined.subarray(0, end));\n }\n\n async function writeFlight(controller: TransformStreamDefaultController<Uint8Array>): Promise<void> {\n const reader = (flightReader = rscStream.getReader());\n // `fatal`, so a chunk that split a multi-byte character throws instead of emitting U+FFFD; the catch\n // below falls back to a byte-exact encoding for it.\n const decoder = new TextDecoder('utf-8', { fatal: true });\n const push = (literal: string) => controller.enqueue(encoder.encode(scriptOpen + literal + scriptClose));\n for (;;) {\n if (cancelled) return;\n const { done, value } = await reader.read();\n if (done) break;\n // Only the decode is guarded: a `push` inside the same `try` would answer a dead controller by\n // re-encoding the chunk and enqueueing it again.\n let literal: string;\n try {\n literal = escapeScript(JSON.stringify(decoder.decode(value, { stream: true })));\n } catch {\n literal = `Uint8Array.from(atob(${JSON.stringify(btoa(latin1(value)))}), m => m.codePointAt(0))`;\n }\n if (cancelled) return;\n // A failed enqueue means the consumer is gone: release the RSC branch so `flush` unparks now rather\n // than whenever the payload would have ended on its own.\n try {\n push(literal);\n } catch {\n cancelled = true;\n reader.cancel().catch(() => {});\n return;\n }\n }\n if (cancelled) return;\n const remaining = decoder.decode();\n if (remaining.length) push(escapeScript(JSON.stringify(remaining)));\n }\n\n const transformer: CancellableTransformer<Uint8Array, Uint8Array> = {\n transform(chunk, controller) {\n batch.push(chunk);\n if (boundary) return;\n // A macrotask, not a microtask: React writes a whole flush in one synchronous run but `pipeThrough`\n // delivers it one microtask at a time, and a script injected between two chunks lands inside a tag.\n boundary = schedule(() => {\n try {\n emitBatch(controller);\n } catch (error) {\n controller.error(error);\n flightDone();\n return;\n }\n if (!startedFlight) {\n startedFlight = true;\n // Deliberately not awaited: this runs inside a scheduled callback with nothing to return to, and\n // the chain already routes a write failure to `controller.error` before settling `flightDone`.\n void writeFlight(controller)\n .catch((error) => controller.error(error))\n .then(flightDone);\n }\n });\n },\n async flush(controller) {\n // Both of these have to happen *before* the await, and in this order.\n try {\n // Anything still batched belongs ahead of the payload scripts, which sit at the end of `<body>`.\n if (boundary) {\n unschedule(boundary);\n boundary = null;\n emitBatch(controller);\n }\n // A writable side that closed without ever reaching `transform` — an HTML stream with no chunks at\n // all — leaves nothing to have started the payload, and `flightDone` is only ever called from that\n // chain or from `cancel`. Without this the await below parks on a promise nothing will settle and the\n // response never ends. `cancelled` short-circuits it: there is nowhere to write the payload to.\n if (!startedFlight) {\n startedFlight = true;\n if (cancelled) flightDone();\n else\n void writeFlight(controller)\n .catch((error) => controller.error(error))\n .then(flightDone);\n }\n } catch {\n // The consumer went away while the batch was being emitted, so there is nothing left to write to and\n // nothing to wait for. Settled explicitly rather than left dangling, so the payload chain is released.\n cancelled = true;\n flightReader?.cancel().catch(() => {});\n flightDone();\n onDone?.();\n return;\n }\n\n await flightWritten;\n // That await spans the whole payload, and the consumer can go away inside it — with `cancel` skipped\n // (see `cancelled`), a throwing enqueue is the only signal. Unguarded it rejects `flush`, which\n // nothing owns and which surfaces as an unhandled rejection.\n try {\n if (!cancelled) controller.enqueue(encoder.encode(TRAILER));\n } catch {\n // Nowhere left to put the trailer. A response the client abandoned is not a fault.\n cancelled = true;\n flightReader?.cancel().catch(() => {});\n } finally {\n // A `finally` because `onDone` releases the abort forwarder in `renderComponent`, however this ended.\n onDone?.();\n }\n },\n cancel(reason) {\n cancelled = true;\n if (boundary) {\n unschedule(boundary);\n boundary = null;\n }\n batch.length = 0;\n // Otherwise the teed RSC branch keeps being pumped for a response nobody will read, and the tee's\n // other half buffers every chunk waiting for this one to catch up.\n flightReader?.cancel(reason).catch(() => {});\n // Unparks `flush` if it is waiting on a payload that will now never arrive.\n flightDone();\n onDone?.();\n },\n };\n return new TransformStream<Uint8Array, Uint8Array>(transformer);\n}\n"]}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* combinations — an action id on a GET — are unrepresentable.
|
|
4
4
|
*
|
|
5
5
|
* - `document` — a normal navigation; respond with a full SSR HTML document.
|
|
6
|
-
* - `rsc` — a soft-navigation flight fetch (`
|
|
6
|
+
* - `rsc` — a soft-navigation flight fetch (`RSC: 1`).
|
|
7
7
|
* - `form-action` — a progressive-enhancement `<form>` POST (no JavaScript).
|
|
8
8
|
* - `rsc-action` — a client-initiated server-action call carrying an action id.
|
|
9
9
|
*/
|
|
@@ -17,14 +17,22 @@ export type RenderRequest = {
|
|
|
17
17
|
kind: 'rsc-action';
|
|
18
18
|
actionId: string;
|
|
19
19
|
};
|
|
20
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* Builds the `Request` the client sends to ask a page for its flight payload, optionally carrying a server
|
|
22
|
+
* action.
|
|
23
|
+
*
|
|
24
|
+
* `signal` is for a navigation, which a later one supersedes — an action is never abandoned that way, so its
|
|
25
|
+
* caller passes none.
|
|
26
|
+
*/
|
|
21
27
|
export declare function createRscRequest(urlString: string, action?: {
|
|
22
28
|
id: string;
|
|
23
29
|
body: BodyInit;
|
|
24
|
-
}): Request;
|
|
30
|
+
}, signal?: AbortSignal): Request;
|
|
25
31
|
export declare function parseRenderRequest(request: Request): RenderRequest;
|
|
26
32
|
/** Whether the client asked for a flight payload. For GET paths that only need the boolean, without parsing. */
|
|
27
|
-
export declare function
|
|
33
|
+
export declare function asksForRsc(request: Request): boolean;
|
|
34
|
+
/** The header a response has to `Vary` on, since one page URL answers as either representation. */
|
|
35
|
+
export declare const RSC_VARY_HEADER = "RSC";
|
|
28
36
|
/** True when the response should be a flight payload rather than an HTML document. */
|
|
29
37
|
export declare function wantsRsc(renderRequest: RenderRequest): boolean;
|
|
30
38
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/runtime/request.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/runtime/request.ts"],"names":[],"mappings":"AAgBA;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,GAAG;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,KAAK,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAExI;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAU1H;AAID,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa,CAQlE;AAED,gHAAgH;AAChH,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAEpD;AAED,mGAAmG;AACnG,eAAO,MAAM,eAAe,QAAQ,CAAC;AAErC,sFAAsF;AACtF,wBAAgB,QAAQ,CAAC,aAAa,EAAE,aAAa,GAAG,OAAO,CAE9D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAEzD;AAED,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,aAAa,EAAE,aAAa,GAAG,aAAa,IAAI,OAAO,CAAC,aAAa,EAAE;IAAE,IAAI,EAAE,aAAa,GAAG,YAAY,CAAA;CAAE,CAAC,CAE7I"}
|
package/dist/runtime/request.js
CHANGED
|
@@ -1,15 +1,34 @@
|
|
|
1
1
|
const HEADER_ACTION_ID = 'x-rsc-action';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
/**
|
|
3
|
+
* The header that asks a page URL for its flight payload rather than its HTML document, and the value it
|
|
4
|
+
* carries. One URL answers as either, so this is what the response `Vary`s on.
|
|
5
|
+
*
|
|
6
|
+
* A header of its own rather than `Accept: text/x-component`, which is what this used to be. Content
|
|
7
|
+
* negotiation was the more standards-shaped mechanism and it cost too much: a prerendered page is served
|
|
8
|
+
* `public, max-age=300`, and `Vary: Accept` on a publicly cacheable response is close to a cache-disabling
|
|
9
|
+
* header — real browsers send long `Accept` strings that differ by vendor and version, so a CDN keyed on it
|
|
10
|
+
* stores a copy per variant of the same bytes, and some shared caches decline to store a `Vary` they consider
|
|
11
|
+
* high-cardinality at all. This one has exactly two states.
|
|
12
|
+
*/
|
|
13
|
+
const HEADER_RSC = 'rsc';
|
|
14
|
+
const HEADER_RSC_VALUE = '1';
|
|
15
|
+
/**
|
|
16
|
+
* Builds the `Request` the client sends to ask a page for its flight payload, optionally carrying a server
|
|
17
|
+
* action.
|
|
18
|
+
*
|
|
19
|
+
* `signal` is for a navigation, which a later one supersedes — an action is never abandoned that way, so its
|
|
20
|
+
* caller passes none.
|
|
21
|
+
*/
|
|
22
|
+
export function createRscRequest(urlString, action, signal) {
|
|
5
23
|
const url = new URL(urlString, location.origin);
|
|
6
|
-
const headers = new Headers({
|
|
24
|
+
const headers = new Headers({ [HEADER_RSC]: HEADER_RSC_VALUE });
|
|
7
25
|
if (action)
|
|
8
26
|
headers.set(HEADER_ACTION_ID, action.id);
|
|
9
27
|
return new Request(url, {
|
|
10
28
|
method: action ? 'POST' : 'GET',
|
|
11
29
|
headers,
|
|
12
30
|
body: action?.body,
|
|
31
|
+
signal,
|
|
13
32
|
});
|
|
14
33
|
}
|
|
15
34
|
const FORM_CONTENT_TYPES = /^(?:multipart\/form-data|application\/x-www-form-urlencoded)/i;
|
|
@@ -22,12 +41,14 @@ export function parseRenderRequest(request) {
|
|
|
22
41
|
return { kind: 'form-action' };
|
|
23
42
|
return { kind: 'document' };
|
|
24
43
|
}
|
|
25
|
-
return { kind:
|
|
44
|
+
return { kind: asksForRsc(request) ? 'rsc' : 'document' };
|
|
26
45
|
}
|
|
27
46
|
/** Whether the client asked for a flight payload. For GET paths that only need the boolean, without parsing. */
|
|
28
|
-
export function
|
|
29
|
-
return request.headers.get(
|
|
47
|
+
export function asksForRsc(request) {
|
|
48
|
+
return request.headers.get(HEADER_RSC) === HEADER_RSC_VALUE;
|
|
30
49
|
}
|
|
50
|
+
/** The header a response has to `Vary` on, since one page URL answers as either representation. */
|
|
51
|
+
export const RSC_VARY_HEADER = 'RSC';
|
|
31
52
|
/** True when the response should be a flight payload rather than an HTML document. */
|
|
32
53
|
export function wantsRsc(renderRequest) {
|
|
33
54
|
return renderRequest.kind === 'rsc' || renderRequest.kind === 'rsc-action';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/runtime/request.ts"],"names":[],"mappings":"AAAA,MAAM,gBAAgB,GAAG,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/runtime/request.ts"],"names":[],"mappings":"AAAA,MAAM,gBAAgB,GAAG,cAAc,CAAC;AAExC;;;;;;;;;;GAUG;AACH,MAAM,UAAU,GAAG,KAAK,CAAC;AACzB,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAa7B;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAAiB,EAAE,MAAuC,EAAE,MAAoB;IAC/G,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAChE,IAAI,MAAM;QAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IACrD,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE;QACtB,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK;QAC/B,OAAO;QACP,IAAI,EAAE,MAAM,EAAE,IAAI;QAClB,MAAM;KACP,CAAC,CAAC;AACL,CAAC;AAED,MAAM,kBAAkB,GAAG,+DAA+D,CAAC;AAE3F,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QACvD,IAAI,QAAQ;YAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC;QACtD,IAAI,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;QACvG,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IAC9B,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;AAC5D,CAAC;AAED,gHAAgH;AAChH,MAAM,UAAU,UAAU,CAAC,OAAgB;IACzC,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,gBAAgB,CAAC;AAC9D,CAAC;AAED,mGAAmG;AACnG,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAC;AAErC,sFAAsF;AACtF,MAAM,UAAU,QAAQ,CAAC,aAA4B;IACnD,OAAO,aAAa,CAAC,IAAI,KAAK,KAAK,IAAI,aAAa,CAAC,IAAI,KAAK,YAAY,CAAC;AAC7E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,OAAgB;IAC9C,OAAO,QAAQ,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,eAAe,CAAC,aAA4B;IAC1D,OAAO,aAAa,CAAC,IAAI,KAAK,aAAa,IAAI,aAAa,CAAC,IAAI,KAAK,YAAY,CAAC;AACrF,CAAC","sourcesContent":["const HEADER_ACTION_ID = 'x-rsc-action';\n\n/**\n * The header that asks a page URL for its flight payload rather than its HTML document, and the value it\n * carries. One URL answers as either, so this is what the response `Vary`s on.\n *\n * A header of its own rather than `Accept: text/x-component`, which is what this used to be. Content\n * negotiation was the more standards-shaped mechanism and it cost too much: a prerendered page is served\n * `public, max-age=300`, and `Vary: Accept` on a publicly cacheable response is close to a cache-disabling\n * header — real browsers send long `Accept` strings that differ by vendor and version, so a CDN keyed on it\n * stores a copy per variant of the same bytes, and some shared caches decline to store a `Vary` they consider\n * high-cardinality at all. This one has exactly two states.\n */\nconst HEADER_RSC = 'rsc';\nconst HEADER_RSC_VALUE = '1';\n\n/**\n * The four shapes an incoming render request can take, as a discriminated union so that illegal\n * combinations — an action id on a GET — are unrepresentable.\n *\n * - `document` — a normal navigation; respond with a full SSR HTML document.\n * - `rsc` — a soft-navigation flight fetch (`RSC: 1`).\n * - `form-action` — a progressive-enhancement `<form>` POST (no JavaScript).\n * - `rsc-action` — a client-initiated server-action call carrying an action id.\n */\nexport type RenderRequest = { kind: 'document' } | { kind: 'rsc' } | { kind: 'form-action' } | { kind: 'rsc-action'; actionId: string };\n\n/**\n * Builds the `Request` the client sends to ask a page for its flight payload, optionally carrying a server\n * action.\n *\n * `signal` is for a navigation, which a later one supersedes — an action is never abandoned that way, so its\n * caller passes none.\n */\nexport function createRscRequest(urlString: string, action?: { id: string; body: BodyInit }, signal?: AbortSignal): Request {\n const url = new URL(urlString, location.origin);\n const headers = new Headers({ [HEADER_RSC]: HEADER_RSC_VALUE });\n if (action) headers.set(HEADER_ACTION_ID, action.id);\n return new Request(url, {\n method: action ? 'POST' : 'GET',\n headers,\n body: action?.body,\n signal,\n });\n}\n\nconst FORM_CONTENT_TYPES = /^(?:multipart\\/form-data|application\\/x-www-form-urlencoded)/i;\n\nexport function parseRenderRequest(request: Request): RenderRequest {\n if (request.method === 'POST') {\n const actionId = request.headers.get(HEADER_ACTION_ID);\n if (actionId) return { kind: 'rsc-action', actionId };\n if (FORM_CONTENT_TYPES.test(request.headers.get('content-type') ?? '')) return { kind: 'form-action' };\n return { kind: 'document' };\n }\n return { kind: asksForRsc(request) ? 'rsc' : 'document' };\n}\n\n/** Whether the client asked for a flight payload. For GET paths that only need the boolean, without parsing. */\nexport function asksForRsc(request: Request): boolean {\n return request.headers.get(HEADER_RSC) === HEADER_RSC_VALUE;\n}\n\n/** The header a response has to `Vary` on, since one page URL answers as either representation. */\nexport const RSC_VARY_HEADER = 'RSC';\n\n/** True when the response should be a flight payload rather than an HTML document. */\nexport function wantsRsc(renderRequest: RenderRequest): boolean {\n return renderRequest.kind === 'rsc' || renderRequest.kind === 'rsc-action';\n}\n\n/**\n * {@link wantsRsc} straight off the request, for the error and control-signal paths — reached from Hono's\n * `onError` / `notFound`, so they have no parsed {@link RenderRequest} to hand.\n */\nexport function requestWantsRsc(request: Request): boolean {\n return wantsRsc(parseRenderRequest(request));\n}\n\n/** True when the request carries a server action to run before rendering. */\nexport function isActionRequest(renderRequest: RenderRequest): renderRequest is Extract<RenderRequest, { kind: 'form-action' | 'rsc-action' }> {\n return renderRequest.kind === 'form-action' || renderRequest.kind === 'rsc-action';\n}\n"]}
|
|
@@ -15,12 +15,14 @@ export type PrerenderVariant = 'html' | 'flight';
|
|
|
15
15
|
export declare const VARIANTS: {
|
|
16
16
|
readonly html: {
|
|
17
17
|
readonly file: 'index.html';
|
|
18
|
-
readonly
|
|
18
|
+
readonly headers: {};
|
|
19
19
|
readonly contentType: 'text/html';
|
|
20
20
|
};
|
|
21
21
|
readonly flight: {
|
|
22
22
|
readonly file: 'index.rsc';
|
|
23
|
-
readonly
|
|
23
|
+
readonly headers: {
|
|
24
|
+
readonly RSC: '1';
|
|
25
|
+
};
|
|
24
26
|
readonly contentType: 'text/x-component';
|
|
25
27
|
};
|
|
26
28
|
};
|
|
@@ -41,8 +43,14 @@ export declare function prerenderedRelPath(requestPath: string, variant: Prerend
|
|
|
41
43
|
* A bounded, insertion-ordered cache of prerendered pages, so a site with thousands of them keeps a working set
|
|
42
44
|
* rather than the whole build in memory. Only *hits* are stored — caching misses would let anyone mint entries
|
|
43
45
|
* by requesting paths that don't exist — and the files never change while the server is up.
|
|
46
|
+
*
|
|
47
|
+
* Bounded by **bytes**, not by entry count: a count says nothing about how much memory it stands for, and a
|
|
48
|
+
* page can be any size. At 128 entries — the previous limit — a documentation site with half-megabyte pages
|
|
49
|
+
* retained ~64 MB across the two variants, with nothing about the number to suggest it.
|
|
50
|
+
*
|
|
51
|
+
* A page larger than the whole budget is served and not stored, rather than evicting everything to hold one.
|
|
44
52
|
*/
|
|
45
|
-
export declare function createPageCache(
|
|
53
|
+
export declare function createPageCache(maxBytes?: number): {
|
|
46
54
|
get(key: string): PrerenderedPage | undefined;
|
|
47
55
|
set(key: string, page: PrerenderedPage): void;
|
|
48
56
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prerendered.d.ts","sourceRoot":"","sources":["../../src/server/prerendered.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEjD,eAAO,MAAM,QAAQ;;
|
|
1
|
+
{"version":3,"file":"prerendered.d.ts","sourceRoot":"","sources":["../../src/server/prerendered.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEjD,eAAO,MAAM,QAAQ;;iBAGX,IAAI,EAAE,YAAY;iBAAE,OAAO;iBAAM,WAAW,EAAE,WAAW;;;iBACvD,IAAI,EAAE,WAAW;iBAAE,OAAO;qBAAI,GAAG,EAAE,GAAG;;iBAAI,WAAW,EAAE,kBAAkB;;CACgC,CAAC;AAEtH;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAyB,GAAG,MAAM,GAAG,IAAI,CAKhG;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,MAAM,GAAG,IAAI,CAGhG;AAKD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,QAAQ,SAAsB,GAAG;IAC/D,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAAC;IAC9C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,IAAI,CAAC;CAC/C,CA0BA;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAO7E;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,UAAU,CAAC,WAAW,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,CAM1H;AAED,mGAAmG;AACnG,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,IAAI,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;IAC9B;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB;;;;;;OAMG;IACH,IAAI,EAAE,MAAM,CAAC;CACd"}
|
|
@@ -7,8 +7,10 @@
|
|
|
7
7
|
* into a bundle that has neither.
|
|
8
8
|
*/
|
|
9
9
|
export const VARIANTS = {
|
|
10
|
-
|
|
11
|
-
flight
|
|
10
|
+
// `headers` is what the build asks each representation for, so it stays the same request the browser makes:
|
|
11
|
+
// a document is the default and a flight payload is the `RSC` header. See `runtime/request.ts`.
|
|
12
|
+
html: { file: 'index.html', headers: {}, contentType: 'text/html' },
|
|
13
|
+
flight: { file: 'index.rsc', headers: { RSC: '1' }, contentType: 'text/x-component' },
|
|
12
14
|
};
|
|
13
15
|
/**
|
|
14
16
|
* Where a route's prerendered output lives, relative to the output root — or `null` for a path that cannot be
|
|
@@ -33,20 +35,44 @@ export function prerenderedRelPath(requestPath, variant) {
|
|
|
33
35
|
return null;
|
|
34
36
|
return ssgFilePath(requestPath, variant);
|
|
35
37
|
}
|
|
38
|
+
/** The default cache budget: enough for a large documentation site's working set, small enough to be ignorable. */
|
|
39
|
+
const DEFAULT_CACHE_BYTES = 32 * 1024 * 1024;
|
|
36
40
|
/**
|
|
37
41
|
* A bounded, insertion-ordered cache of prerendered pages, so a site with thousands of them keeps a working set
|
|
38
42
|
* rather than the whole build in memory. Only *hits* are stored — caching misses would let anyone mint entries
|
|
39
43
|
* by requesting paths that don't exist — and the files never change while the server is up.
|
|
44
|
+
*
|
|
45
|
+
* Bounded by **bytes**, not by entry count: a count says nothing about how much memory it stands for, and a
|
|
46
|
+
* page can be any size. At 128 entries — the previous limit — a documentation site with half-megabyte pages
|
|
47
|
+
* retained ~64 MB across the two variants, with nothing about the number to suggest it.
|
|
48
|
+
*
|
|
49
|
+
* A page larger than the whole budget is served and not stored, rather than evicting everything to hold one.
|
|
40
50
|
*/
|
|
41
|
-
export function createPageCache(
|
|
51
|
+
export function createPageCache(maxBytes = DEFAULT_CACHE_BYTES) {
|
|
42
52
|
const pages = new Map();
|
|
53
|
+
let bytes = 0;
|
|
43
54
|
return {
|
|
44
55
|
get: (key) => pages.get(key),
|
|
45
56
|
set(key, page) {
|
|
57
|
+
const size = page.body.byteLength;
|
|
58
|
+
if (size > maxBytes)
|
|
59
|
+
return;
|
|
60
|
+
// Deleted before it is set, so re-setting an existing key moves it to the *back*: `Map.set` on a key it
|
|
61
|
+
// already holds keeps that key's original position, which would leave the entry just stored sitting at
|
|
62
|
+
// the front as the next thing evicted — a store whose eviction could drop the write that caused it.
|
|
63
|
+
const replaced = pages.get(key);
|
|
64
|
+
if (replaced) {
|
|
65
|
+
bytes -= replaced.body.byteLength;
|
|
66
|
+
pages.delete(key);
|
|
67
|
+
}
|
|
46
68
|
pages.set(key, page);
|
|
69
|
+
bytes += size;
|
|
47
70
|
// Insertion-ordered, so the first key is the oldest.
|
|
48
|
-
|
|
49
|
-
pages.
|
|
71
|
+
while (bytes > maxBytes) {
|
|
72
|
+
const oldest = pages.keys().next().value;
|
|
73
|
+
bytes -= pages.get(oldest).body.byteLength;
|
|
74
|
+
pages.delete(oldest);
|
|
75
|
+
}
|
|
50
76
|
},
|
|
51
77
|
};
|
|
52
78
|
}
|