diff --git a/docs/api/rsc/RSCHydratedRouter.md b/docs/api/rsc/RSCHydratedRouter.md index 3e2eeafed7..32cb792d9d 100644 --- a/docs/api/rsc/RSCHydratedRouter.md +++ b/docs/api/rsc/RSCHydratedRouter.md @@ -8,7 +8,7 @@ title: RSCHydratedRouter ## Summary -Hydrates a server rendered `ServerPayload` in the browser. +Hydrates a server rendered `RSCPayload` in the browser. ## Props @@ -18,7 +18,7 @@ Your `react-server-dom-xyz/client`'s `createFromReadableStream` function, used t ### payload -The decoded ServerPayload to hydrate. +The decoded `RSCPayload` to hydrate. ### routeDiscovery diff --git a/docs/api/rsc/RSCStaticRouter.md b/docs/api/rsc/RSCStaticRouter.md index 2d4c17e545..e661d96609 100644 --- a/docs/api/rsc/RSCStaticRouter.md +++ b/docs/api/rsc/RSCStaticRouter.md @@ -8,10 +8,10 @@ title: RSCStaticRouter ## Summary -Pre-renders a `ServerPayload` to HTML. Usually used in `routeRSCServerRequest`'s `renderHTML` callback. +Pre-renders an `RSCPayload` to HTML. Usually used in `routeRSCServerRequest`'s `renderHTML` callback. ## Props ### getPayload -A function that starts decoding of the ServerPayload. Usually passed through from `routeRSCServerRequest`'s `renderHTML`. +A function that starts decoding of the `RSCPayload`. Usually passed through from `routeRSCServerRequest`'s `renderHTML`. diff --git a/docs/api/rsc/getServerStream.md b/docs/api/rsc/getRSCStream.md similarity index 81% rename from docs/api/rsc/getServerStream.md rename to docs/api/rsc/getRSCStream.md index f6ed8827b4..bd1ab0b925 100644 --- a/docs/api/rsc/getServerStream.md +++ b/docs/api/rsc/getRSCStream.md @@ -1,8 +1,8 @@ --- -title: getServerStream +title: getRSCStream --- -# getServerStream +# getRSCStream [MODES: data] diff --git a/docs/api/rsc/matchRSCServerRequest.md b/docs/api/rsc/matchRSCServerRequest.md index 9bceef8cc4..a8c1c868c0 100644 --- a/docs/api/rsc/matchRSCServerRequest.md +++ b/docs/api/rsc/matchRSCServerRequest.md @@ -8,7 +8,7 @@ title: matchRSCServerRequest ## Summary -Matches the given routes to a Request and returns a RSC Response encoding a `ServerPayload` for consumption by a RSC enabled client router. +Matches the given routes to a Request and returns a RSC Response encoding an `RSCPayload` for consumption by a RSC enabled client router. ## Options @@ -26,7 +26,7 @@ A function responsible for decoding form state for progressively enhanceable for ### generateResponse -A function responsible for using your `renderToReadableStream` to generate a Response encoding the `ServerPayload`. +A function responsible for using your `renderToReadableStream` to generate a Response encoding the `RSCPayload`. ### loadServerAction diff --git a/docs/api/rsc/routeRSCServerRequest.md b/docs/api/rsc/routeRSCServerRequest.md index 93852b5d8a..fb54491d4b 100644 --- a/docs/api/rsc/routeRSCServerRequest.md +++ b/docs/api/rsc/routeRSCServerRequest.md @@ -18,11 +18,11 @@ Your `react-server-dom-xyz/client`'s `createFromReadableStream` function, used t ### fetchServer -A function that forwards a `Request` to the RSC handler and returns a `Promise` containing a serialized `ServerPayload`. +A function that forwards a `Request` to the RSC handler and returns a `Promise` containing a serialized `RSCPayload`. ### renderHTML -A function that renders the `ServerPayload` to HTML, usually using a ``. +A function that renders the `RSCPayload` to HTML, usually using a ``. ### request diff --git a/docs/start/rsc/installation.md b/docs/start/rsc/installation.md index cf9064a737..477afd2a51 100644 --- a/docs/start/rsc/installation.md +++ b/docs/start/rsc/installation.md @@ -184,9 +184,9 @@ Create a `src/browser.tsx` file that will act as the entrypoint for hydration. import { startTransition, StrictMode } from "react"; import { hydrateRoot } from "react-dom/client"; import { - type unstable_ServerPayload as ServerPayload, + type unstable_RSCPayload as RSCPayload, unstable_createCallServer as createCallServer, - unstable_getServerStream as getServerStream, + unstable_getRSCStream as getRSCStream, unstable_RSCHydratedRouter as RSCHydratedRouter, } from "react-router"; import { @@ -205,8 +205,8 @@ setServerCallback( ); // Get and decode the initial server payload -createFromReadableStream(getServerStream()).then( - (payload: ServerPayload) => { +createFromReadableStream(getRSCStream()).then( + (payload: RSCPayload) => { startTransition(async () => { hydrateRoot( document, @@ -231,7 +231,7 @@ Create a `src/routes/routes.ts` file that will define our routes with dynamic im ```ts nonumber "use server-entry"; -import type { unstable_ServerRouteObject as ServerRouteObject } from "react-router"; +import type { unstable_RSCRouteConfig as RSCRouteConfig } from "react-router"; import "../browser"; @@ -254,7 +254,7 @@ export function routes() { }, ], }, - ] satisfies ServerRouteObject[]; + ] satisfies RSCRouteConfig; } ``` diff --git a/integration/helpers/rsc-parcel-framework/package.json b/integration/helpers/rsc-parcel-framework/package.json index 8b6fa8c93f..58ef173c44 100644 --- a/integration/helpers/rsc-parcel-framework/package.json +++ b/integration/helpers/rsc-parcel-framework/package.json @@ -28,7 +28,7 @@ "@types/react-dom": "^19.0.3", "@types/react": "^19.0.8", "parcel": "2.15.0", - "parcel-config-react-router-experimental": "1.0.23", + "parcel-config-react-router-experimental": "1.0.24", "typescript": "^5.1.6" }, "dependencies": { diff --git a/integration/helpers/rsc-parcel/src/browser.tsx b/integration/helpers/rsc-parcel/src/browser.tsx index 3a75bec991..1e780871fd 100644 --- a/integration/helpers/rsc-parcel/src/browser.tsx +++ b/integration/helpers/rsc-parcel/src/browser.tsx @@ -2,10 +2,10 @@ import { startTransition, StrictMode } from "react"; import { hydrateRoot } from "react-dom/client"; -import type { unstable_ServerPayload as ServerPayload } from "react-router"; +import type { unstable_RSCPayload as RSCPayload } from "react-router"; import { unstable_createCallServer as createCallServer, - unstable_getServerStream as getServerStream, + unstable_getRSCStream as getRSCStream, unstable_RSCHydratedRouter as RSCHydratedRouter, } from "react-router"; import { @@ -24,7 +24,7 @@ setServerCallback( ); // Get and decode the initial server payload -createFromReadableStream(getServerStream()).then((payload: ServerPayload) => { +createFromReadableStream(getRSCStream()).then((payload: RSCPayload) => { // @ts-expect-error - on 18 types, requires 19. startTransition(async () => { const formState = diff --git a/integration/helpers/rsc-parcel/src/routes.ts b/integration/helpers/rsc-parcel/src/routes.ts index f1f101bcfd..6ea30ad68a 100644 --- a/integration/helpers/rsc-parcel/src/routes.ts +++ b/integration/helpers/rsc-parcel/src/routes.ts @@ -1,4 +1,4 @@ -import type { unstable_ServerRouteObject as ServerRouteObject } from "react-router"; +import type { unstable_RSCRouteConfig as RSCRouteConfig } from "react-router"; export const routes = [ { @@ -13,4 +13,4 @@ export const routes = [ }, ], }, -] satisfies ServerRouteObject[]; +] satisfies RSCRouteConfig; diff --git a/integration/helpers/rsc-vite/src/entry.browser.tsx b/integration/helpers/rsc-vite/src/entry.browser.tsx index 936a025e8f..a6f29cd2fe 100644 --- a/integration/helpers/rsc-vite/src/entry.browser.tsx +++ b/integration/helpers/rsc-vite/src/entry.browser.tsx @@ -7,10 +7,10 @@ import { } from "@hiogawa/vite-rsc/browser"; import { unstable_createCallServer as createCallServer, - unstable_getServerStream as getServerStream, + unstable_getRSCStream as getRSCStream, unstable_RSCHydratedRouter as RSCHydratedRouter, } from "react-router"; -import type { unstable_ServerPayload as ServerPayload } from "react-router"; +import type { unstable_RSCPayload as RSCPayload } from "react-router"; setServerCallback( createCallServer({ @@ -19,7 +19,7 @@ setServerCallback( }) ); -createFromReadableStream(getServerStream()).then((payload) => { +createFromReadableStream(getRSCStream()).then((payload) => { startTransition(() => { hydrateRoot( document, diff --git a/integration/helpers/rsc-vite/src/routes.ts b/integration/helpers/rsc-vite/src/routes.ts index f1f101bcfd..6ea30ad68a 100644 --- a/integration/helpers/rsc-vite/src/routes.ts +++ b/integration/helpers/rsc-vite/src/routes.ts @@ -1,4 +1,4 @@ -import type { unstable_ServerRouteObject as ServerRouteObject } from "react-router"; +import type { unstable_RSCRouteConfig as RSCRouteConfig } from "react-router"; export const routes = [ { @@ -13,4 +13,4 @@ export const routes = [ }, ], }, -] satisfies ServerRouteObject[]; +] satisfies RSCRouteConfig; diff --git a/integration/rsc/rsc-test.ts b/integration/rsc/rsc-test.ts index d0aaf21172..eb4e174523 100644 --- a/integration/rsc/rsc-test.ts +++ b/integration/rsc/rsc-test.ts @@ -209,7 +209,7 @@ implementations.forEach((implementation) => { port, files: { "src/routes.ts": js` - import type { unstable_ServerRouteObject as ServerRouteObject } from "react-router"; + import type { unstable_RSCRouteConfig as RSCRouteConfig } from "react-router"; export const routes = [ { @@ -229,7 +229,7 @@ implementations.forEach((implementation) => { }, ], }, - ] satisfies ServerRouteObject[]; + ] satisfies RSCRouteConfig; `, "src/routes/home.tsx": js` import { Link } from "react-router"; @@ -340,7 +340,7 @@ implementations.forEach((implementation) => { port, files: { "src/routes.ts": js` - import type { unstable_ServerRouteObject as ServerRouteObject } from "react-router"; + import type { unstable_RSCRouteConfig as RSCRouteConfig } from "react-router"; export const routes = [ { @@ -360,7 +360,7 @@ implementations.forEach((implementation) => { }, ], }, - ] satisfies ServerRouteObject[]; + ] satisfies RSCRouteConfig; `, "src/routes/home.tsx": js` import { Link } from "react-router"; @@ -473,7 +473,7 @@ implementations.forEach((implementation) => { port, files: { "src/routes.ts": js` - import type { unstable_ServerRouteObject as ServerRouteObject } from "react-router"; + import type { unstable_RSCRouteConfig as RSCRouteConfig } from "react-router"; export const routes = [ { @@ -493,7 +493,7 @@ implementations.forEach((implementation) => { path: "resource", lazy: () => import("./routes/resource"), }, - ] satisfies ServerRouteObject[]; + ] satisfies RSCRouteConfig; `, "src/routes/resource.tsx": js` export function loader() { diff --git a/packages/react-router/index-react-server.ts b/packages/react-router/index-react-server.ts index 8f2a460aa6..82cce02cee 100644 --- a/packages/react-router/index-react-server.ts +++ b/packages/react-router/index-react-server.ts @@ -7,13 +7,14 @@ export type { DecodeFormStateFunction as unstable_DecodeFormStateFunction, DecodeReplyFunction as unstable_DecodeReplyFunction, LoadServerActionFunction as unstable_LoadServerActionFunction, - ServerManifestPayload as unstable_ServerManifestPayload, - ServerMatch as unstable_ServerMatch, - ServerPayload as unstable_ServerPayload, - ServerRenderPayload as unstable_ServerRenderPayload, - RenderedRoute as ServerRouteManifest, - ServerRouteMatch as unstable_ServerRouteMatch, - ServerRouteObject as unstable_ServerRouteObject, + RSCManifestPayload as unstable_RSCManifestPayload, + RSCMatch as unstable_RSCMatch, + RSCPayload as unstable_RSCPayload, + RSCRenderPayload as unstable_RSCRenderPayload, + RSCRouteManifest as unstable_RSCRouteManifest, + RSCRouteMatch as unstable_RSCRouteMatch, + RSCRouteConfigEntry as unstable_RSCRouteConfigEntry, + RSCRouteConfig as unstable_RSCRouteConfig, } from "./lib/rsc/server.rsc"; // RSC implementation of agnostic APIs diff --git a/packages/react-router/index.ts b/packages/react-router/index.ts index ccfbb4f1c0..63ffe97662 100644 --- a/packages/react-router/index.ts +++ b/packages/react-router/index.ts @@ -292,7 +292,7 @@ export { routeRSCServerRequest as unstable_routeRSCServerRequest, RSCStaticRouter as unstable_RSCStaticRouter, } from "./lib/rsc/server.ssr"; -export { getServerStream as unstable_getServerStream } from "./lib/rsc/html-stream/browser"; +export { getRSCStream as unstable_getRSCStream } from "./lib/rsc/html-stream/browser"; export { RSCDefaultRootErrorBoundary as UNSAFE_RSCDefaultRootErrorBoundary } from "./lib/rsc/errorBoundaries"; // Re-export of RSC types @@ -305,13 +305,14 @@ export type { DecodeFormStateFunction as unstable_DecodeFormStateFunction, DecodeReplyFunction as unstable_DecodeReplyFunction, LoadServerActionFunction as unstable_LoadServerActionFunction, - ServerManifestPayload as unstable_ServerManifestPayload, - ServerMatch as unstable_ServerMatch, - ServerPayload as unstable_ServerPayload, - ServerRenderPayload as unstable_ServerRenderPayload, - RenderedRoute as ServerRouteManifest, - ServerRouteMatch as unstable_ServerRouteMatch, - ServerRouteObject as unstable_ServerRouteObject, + RSCManifestPayload as unstable_RSCManifestPayload, + RSCMatch as unstable_RSCMatch, + RSCPayload as unstable_RSCPayload, + RSCRenderPayload as unstable_RSCRenderPayload, + RSCRouteManifest as unstable_RSCRouteManifest, + RSCRouteMatch as unstable_RSCRouteMatch, + RSCRouteConfigEntry as unstable_RSCRouteConfigEntry, + RSCRouteConfig as unstable_RSCRouteConfig, } from "./lib/rsc/server.rsc"; /////////////////////////////////////////////////////////////////////////////// diff --git a/packages/react-router/lib/rsc/browser.tsx b/packages/react-router/lib/rsc/browser.tsx index 768e81c8ac..908ac645f0 100644 --- a/packages/react-router/lib/rsc/browser.tsx +++ b/packages/react-router/lib/rsc/browser.tsx @@ -13,9 +13,9 @@ import { createBrowserHistory, invariant } from "../router/history"; import type { Router as DataRouter } from "../router/router"; import { createRouter, isMutationMethod } from "../router/router"; import type { - ServerPayload, - RenderedRoute, - ServerRenderPayload, + RSCPayload, + RSCRouteManifest, + RSCRenderPayload, CreateFromReadableStreamFunction, } from "./server.rsc"; import type { @@ -80,7 +80,7 @@ export function createCallServer({ } const payload = (await createFromReadableStream( response.body - )) as ServerPayload; + )) as RSCPayload; if (payload.type === "redirect") { if (payload.reload) { @@ -118,7 +118,7 @@ export function createCallServer({ return; } - let lastMatch: RenderedRoute | undefined; + let lastMatch: RSCRouteManifest | undefined; for (const match of rerender.matches) { window.__router.patchRoutes( lastMatch?.id ?? null, @@ -158,7 +158,7 @@ function createRouterFromPayload({ createFromReadableStream, payload, }: { - payload: ServerPayload; + payload: RSCPayload; createFromReadableStream: CreateFromReadableStreamFunction; fetchImplementation: (request: Request) => Promise; }) { @@ -166,7 +166,7 @@ function createRouterFromPayload({ if (payload.type !== "render") throw new Error("Invalid payload type"); - let patches = new Map(); + let patches = new Map(); payload.patches?.forEach((patch) => { invariant(patch.parentId, "Invalid patch parentId"); if (!patches.has(patch.parentId)) { @@ -255,7 +255,7 @@ function createRouterFromPayload({ return window.__router; } -const renderedRoutesContext = unstable_createContext(); +const renderedRoutesContext = unstable_createContext(); export function getRSCSingleFetchDataStrategy( getRouter: () => DataRouter, @@ -321,7 +321,7 @@ export function getRSCSingleFetchDataStrategy( // with the same ID. This is currently happening in `clientLoader` cases // where we're calling `fetchAndDecode` multiple times. This may be a // sign of a logical error in how we're handling client loader routes. - const renderedRoutesById = new Map(); + const renderedRoutesById = new Map(); for (const route of context.get(renderedRoutesContext)) { if (!renderedRoutesById.has(route.id)) { renderedRoutesById.set(route.id, []); @@ -375,9 +375,7 @@ function getFetchAndDecodeViaRSC( invariant(res.body, "No response body to decode"); try { - const payload = (await createFromReadableStream( - res.body - )) as ServerPayload; + const payload = (await createFromReadableStream(res.body)) as RSCPayload; if (payload.type === "redirect") { return { status: res.status, @@ -438,7 +436,7 @@ export function RSCHydratedRouter({ }: { createFromReadableStream: CreateFromReadableStreamFunction; fetch?: (request: Request) => Promise; - payload: ServerPayload; + payload: RSCPayload; routeDiscovery?: "eager" | "lazy"; }) { if (payload.type !== "render") throw new Error("Invalid payload type"); @@ -590,8 +588,8 @@ type DataRouteObjectWithManifestInfo = DataRouteObject & { }; function createRouteFromServerManifest( - match: RenderedRoute, - payload?: ServerRenderPayload + match: RSCRouteManifest, + payload?: RSCRenderPayload ): DataRouteObjectWithManifestInfo { let hasInitialData = payload && match.id in payload.loaderData; let initialData = payload?.loaderData[match.id]; @@ -757,9 +755,7 @@ async function fetchAndApplyManifestPatches( throw new Error("Unable to fetch new route matches from the server"); } - let payload = (await createFromReadableStream( - response.body - )) as ServerPayload; + let payload = (await createFromReadableStream(response.body)) as RSCPayload; if (payload.type !== "manifest") { throw new Error("Failed to patch routes"); } diff --git a/packages/react-router/lib/rsc/html-stream/browser.ts b/packages/react-router/lib/rsc/html-stream/browser.ts index 91a88c1037..76dfa6d353 100644 --- a/packages/react-router/lib/rsc/html-stream/browser.ts +++ b/packages/react-router/lib/rsc/html-stream/browser.ts @@ -6,7 +6,7 @@ declare global { } } -export function getServerStream() { +export function getRSCStream() { let encoder = new TextEncoder(); let streamController: ReadableStreamDefaultController | null = null; diff --git a/packages/react-router/lib/rsc/server.rsc.ts b/packages/react-router/lib/rsc/server.rsc.ts index 6ae0db950c..ad808abb01 100644 --- a/packages/react-router/lib/rsc/server.rsc.ts +++ b/packages/react-router/lib/rsc/server.rsc.ts @@ -87,7 +87,7 @@ export const replace: typeof baseReplace = (...args) => { return response; }; -type ServerRouteObjectBase = { +type RSCRouteConfigEntryBase = { action?: ActionFunction; clientAction?: ClientActionFunction; clientLoader?: ClientLoaderFunction; @@ -102,12 +102,12 @@ type ServerRouteObjectBase = { shouldRevalidate?: ShouldRevalidateFunction; }; -export type ServerRouteObject = ServerRouteObjectBase & { +export type RSCRouteConfigEntry = RSCRouteConfigEntryBase & { id: string; path?: string; Component?: React.ComponentType; lazy?: () => Promise< - ServerRouteObjectBase & + RSCRouteConfigEntryBase & ( | { default?: React.ComponentType; @@ -124,11 +124,13 @@ export type ServerRouteObject = ServerRouteObjectBase & { index: true; } | { - children?: ServerRouteObject[]; + children?: RSCRouteConfigEntry[]; } ); -export type RenderedRoute = { +export type RSCRouteConfig = Array; + +export type RSCRouteManifest = { clientAction?: ClientActionFunction; clientLoader?: ClientLoaderFunction; element?: React.ReactElement | false; @@ -148,42 +150,42 @@ export type RenderedRoute = { shouldRevalidate?: ShouldRevalidateFunction; }; -export type ServerRouteMatch = RenderedRoute & { +export type RSCRouteMatch = RSCRouteManifest & { params: Params; pathname: string; pathnameBase: string; }; -export type ServerRenderPayload = { +export type RSCRenderPayload = { type: "render"; actionData: Record | null; basename?: string; errors: Record | null; loaderData: Record; location: Location; - matches: ServerRouteMatch[]; + matches: RSCRouteMatch[]; // Additional routes we should patch into the router for subsequent navigations. // Mostly a collection of pathless/index routes that may be needed for complete // matching on upward navigations. Only needed on the initial document request, // for SPA navigations the manifest call will handle these patches. - patches?: RenderedRoute[]; + patches?: RSCRouteManifest[]; nonce?: string; formState?: unknown; }; -export type ServerManifestPayload = { +export type RSCManifestPayload = { type: "manifest"; // Routes we should patch into the router for subsequent navigations. - patches: RenderedRoute[]; + patches: RSCRouteManifest[]; }; -export type ServerActionPayload = { +export type RSCActionPayload = { type: "action"; actionResult: Promise; - rerender?: Promise; + rerender?: Promise; }; -export type ServerRedirectPayload = { +export type RSCRedirectPayload = { type: "redirect"; status: number; location: string; @@ -192,16 +194,16 @@ export type ServerRedirectPayload = { actionResult?: Promise; }; -export type ServerPayload = - | ServerRenderPayload - | ServerManifestPayload - | ServerActionPayload - | ServerRedirectPayload; +export type RSCPayload = + | RSCRenderPayload + | RSCManifestPayload + | RSCActionPayload + | RSCRedirectPayload; -export type ServerMatch = { +export type RSCMatch = { statusCode: number; headers: Headers; - payload: ServerPayload; + payload: RSCPayload; }; export type DecodeActionFunction = ( @@ -235,8 +237,8 @@ export async function matchRSCServerRequest({ loadServerAction?: LoadServerActionFunction; onError?: (error: unknown) => void; request: Request; - routes: ServerRouteObject[]; - generateResponse: (match: ServerMatch) => Response; + routes: RSCRouteConfigEntry[]; + generateResponse: (match: RSCMatch) => Response; }): Promise { let requestUrl = new URL(request.url); @@ -267,7 +269,7 @@ export async function matchRSCServerRequest({ // Explode lazy functions out the routes so we can use middleware // TODO: This isn't ideal but we can't do it through `lazy()` in the router, // and if we move to `lazy: {}` then we lose all the other things from the - // `ServerRouteObject` like `Layout` etc. + // `RSCRouteConfigEntry` like `Layout` etc. let matches = matchRoutes(routes, url.pathname); if (matches) { await Promise.all(matches.map((m) => explodeLazyRoute(m.route))); @@ -306,9 +308,9 @@ export async function matchRSCServerRequest({ } async function generateManifestResponse( - routes: ServerRouteObject[], + routes: RSCRouteConfigEntry[], request: Request, - generateResponse: (match: ServerMatch) => Response + generateResponse: (match: RSCMatch) => Response ) { let url = new URL(request.url); let pathnameParams = url.searchParams.getAll("p"); @@ -333,7 +335,7 @@ async function generateManifestResponse( } return false; }); - let payload: ServerManifestPayload = { + let payload: RSCManifestPayload = { type: "manifest", patches: ( await Promise.all([ @@ -439,7 +441,7 @@ async function processServerAction( async function generateResourceResponse( request: Request, - routes: ServerRouteObject[], + routes: RSCRouteConfigEntry[], routeId: string, onError: ((error: unknown) => void) | undefined ) { @@ -490,14 +492,14 @@ async function generateResourceResponse( async function generateRenderResponse( request: Request, - routes: ServerRouteObject[], + routes: RSCRouteConfigEntry[], isDataRequest: boolean, decodeReply: DecodeReplyFunction | undefined, loadServerAction: LoadServerActionFunction | undefined, decodeAction: DecodeActionFunction | undefined, decodeFormState: DecodeFormStateFunction | undefined, onError: ((error: unknown) => void) | undefined, - generateResponse: (match: ServerMatch) => Response + generateResponse: (match: RSCMatch) => Response ): Promise { // If this is a RR submission, we just want the `actionData` but don't want // to call any loaders or render any components back in the response - that @@ -601,9 +603,9 @@ async function generateRenderResponse( function generateRedirectResponse( response: Response, actionResult: Promise | undefined, - generateResponse: (match: ServerMatch) => Response + generateResponse: (match: RSCMatch) => Response ) { - let payload: ServerRedirectPayload = { + let payload: RSCRedirectPayload = { type: "redirect", location: response.headers.get("Location") || "", reload: response.headers.get("X-Remix-Reload-Document") === "true", @@ -622,8 +624,8 @@ function generateRedirectResponse( } async function generateStaticContextResponse( - routes: ServerRouteObject[], - generateResponse: (match: ServerMatch) => Response, + routes: RSCRouteConfigEntry[], + generateResponse: (match: RSCMatch) => Response, statusCode: number, routeIdsToLoad: string[] | null, isDataRequest: boolean, @@ -660,10 +662,10 @@ async function generateStaticContextResponse( let headers = getDocumentHeadersImpl( staticContext, - (match) => (match as RouteMatch).route.headers + (match) => (match as RouteMatch).route.headers ); - const baseRenderPayload: Omit = { + const baseRenderPayload: Omit = { type: "render", actionData: staticContext.actionData, errors: staticContext.errors, @@ -681,7 +683,7 @@ async function generateStaticContextResponse( staticContext ); - let payload: ServerRenderPayload | ServerActionPayload; + let payload: RSCRenderPayload | RSCActionPayload; if (actionResult) { // Don't await the payload so we can stream down the actionResult immediately @@ -711,8 +713,8 @@ async function generateStaticContextResponse( } async function getRenderPayload( - baseRenderPayload: Omit, - routes: ServerRouteObject[], + baseRenderPayload: Omit, + routes: RSCRouteConfigEntry[], routeIdsToLoad: string[] | null, isDataRequest: boolean, staticContext: StaticHandlerContext @@ -720,7 +722,7 @@ async function getRenderPayload( // Figure out how deep we want to render server components based on any // triggered error boundaries and/or `routeIdsToLoad` let deepestRenderedRouteIdx = staticContext.matches.length - 1; - // Capture parentIds for assignment on the ServerRouteMatch later + // Capture parentIds for assignment on the RSCRouteMatch later let parentIds: Record = {}; staticContext.matches.forEach((m, i) => { @@ -748,7 +750,7 @@ async function getRenderPayload( (!routeIdsToLoad || routeIdsToLoad.includes(match.route.id)) && (!staticContext.errors || !(match.route.id in staticContext.errors)); - return getServerRouteMatch( + return getRSCRouteMatch( staticContext, match, shouldRenderComponent, @@ -774,7 +776,7 @@ async function getRenderPayload( }; } -async function getServerRouteMatch( +async function getRSCRouteMatch( staticContext: StaticHandlerContext, match: AgnosticDataRouteMatch, shouldRenderComponent: boolean, @@ -873,8 +875,8 @@ async function getServerRouteMatch( } async function getManifestRoute( - route: ServerRouteObject & { parentId: string | undefined } -): Promise { + route: RSCRouteConfigEntry & { parentId: string | undefined } +): Promise { await explodeLazyRoute(route); const Layout = (route as any).Layout || React.Fragment; @@ -906,7 +908,7 @@ async function getManifestRoute( }; } -async function explodeLazyRoute(route: ServerRouteObject) { +async function explodeLazyRoute(route: RSCRouteConfigEntry) { if ("lazy" in route && route.lazy) { let { default: lazyDefaultExport, @@ -923,9 +925,9 @@ async function explodeLazyRoute(route: ServerRouteObject) { k !== "path" && k !== "index" && k !== "children" && - route[k as keyof ServerRouteObject] == null + route[k as keyof RSCRouteConfigEntry] == null ) { - route[k as keyof ServerRouteObject] = v; + route[k as keyof RSCRouteConfigEntry] = v; } } route.lazy = undefined; @@ -934,12 +936,12 @@ async function explodeLazyRoute(route: ServerRouteObject) { async function getAdditionalRoutePatches( pathnames: string[], - routes: ServerRouteObject[], + routes: RSCRouteConfigEntry[], matchedRouteIds: string[] -): Promise { +): Promise { let patchRouteMatches = new Map< string, - ServerRouteObject & { parentId: string | undefined } + RSCRouteConfigEntry & { parentId: string | undefined } >(); let matchedPaths = new Set(); diff --git a/packages/react-router/lib/rsc/server.ssr.tsx b/packages/react-router/lib/rsc/server.ssr.tsx index 89ffe709b8..9ac2c70b02 100644 --- a/packages/react-router/lib/rsc/server.ssr.tsx +++ b/packages/react-router/lib/rsc/server.ssr.tsx @@ -6,7 +6,7 @@ import { createStaticRouter, StaticRouterProvider } from "../dom/server"; import { injectRSCPayload } from "./html-stream/server"; import { RSCRouterGlobalErrorBoundary } from "./errorBoundaries"; import type { - ServerPayload, + RSCPayload, CreateFromReadableStreamFunction, } from "./server.rsc"; @@ -21,7 +21,7 @@ export async function routeRSCServerRequest({ fetchServer: (request: Request) => Promise; createFromReadableStream: CreateFromReadableStreamFunction; renderHTML: ( - getPayload: () => Promise + getPayload: () => Promise ) => ReadableStream | Promise>; hydrate?: boolean; }) { @@ -51,10 +51,10 @@ export async function routeRSCServerRequest({ } const body = serverResponse.body; - let payloadPromise: Promise; + let payloadPromise: Promise; const getPayload = async () => { if (payloadPromise) return payloadPromise; - payloadPromise = createFromReadableStream(body) as Promise; + payloadPromise = createFromReadableStream(body) as Promise; return payloadPromise; }; @@ -95,10 +95,10 @@ export async function routeRSCServerRequest({ export function RSCStaticRouter({ getPayload, }: { - getPayload: () => Promise; + getPayload: () => Promise; }) { // @ts-expect-error - need to update the React types - const payload = React.use(getPayload()) as ServerPayload; + const payload = React.use(getPayload()) as RSCPayload; if (payload.type === "redirect") { throw new Response(null, { diff --git a/playground/rsc-parcel-framework/package.json b/playground/rsc-parcel-framework/package.json index 0f60feb652..b3196b9bc1 100644 --- a/playground/rsc-parcel-framework/package.json +++ b/playground/rsc-parcel-framework/package.json @@ -27,7 +27,7 @@ "@types/react-dom": "^19.0.3", "@types/react": "^19.0.8", "parcel": "2.15.0", - "parcel-config-react-router-experimental": "1.0.23" + "parcel-config-react-router-experimental": "1.0.24" }, "dependencies": { "@mjackson/node-fetch-server": "0.6.1", diff --git a/playground/rsc-parcel/src/entry.browser.tsx b/playground/rsc-parcel/src/entry.browser.tsx index 0f4ceceed3..c1b235a45f 100644 --- a/playground/rsc-parcel/src/entry.browser.tsx +++ b/playground/rsc-parcel/src/entry.browser.tsx @@ -4,10 +4,10 @@ import * as React from "react"; import { hydrateRoot } from "react-dom/client"; import { unstable_createCallServer as createCallServer, - unstable_getServerStream as getServerStream, + unstable_getRSCStream as getRSCStream, unstable_RSCHydratedRouter as RSCHydratedRouter, } from "react-router"; -import type { unstable_ServerPayload as ServerPayload } from "react-router"; +import type { unstable_RSCPayload as RSCPayload } from "react-router"; import { createFromReadableStream, encodeReply, @@ -22,8 +22,8 @@ setServerCallback( }) ); -createFromReadableStream(getServerStream(), { assets: "manifest" }).then( - (payload: ServerPayload) => { +createFromReadableStream(getRSCStream(), { assets: "manifest" }).then( + (payload: RSCPayload) => { React.startTransition(() => { hydrateRoot( document, diff --git a/playground/rsc-parcel/src/routes.ts b/playground/rsc-parcel/src/routes.ts index d063f69e08..ef3761c68b 100644 --- a/playground/rsc-parcel/src/routes.ts +++ b/playground/rsc-parcel/src/routes.ts @@ -1,4 +1,4 @@ -import type { unstable_ServerRouteObject as ServerRouteObject } from "react-router"; +import type { unstable_RSCRouteConfig as RSCRouteConfig } from "react-router"; export const routes = [ { @@ -27,4 +27,4 @@ export const routes = [ path: "resource", lazy: () => import("./routes/resource/resource"), }, -] satisfies ServerRouteObject[]; +] satisfies RSCRouteConfig; diff --git a/playground/rsc-vite/src/entry.browser.tsx b/playground/rsc-vite/src/entry.browser.tsx index 936a025e8f..a6f29cd2fe 100644 --- a/playground/rsc-vite/src/entry.browser.tsx +++ b/playground/rsc-vite/src/entry.browser.tsx @@ -7,10 +7,10 @@ import { } from "@hiogawa/vite-rsc/browser"; import { unstable_createCallServer as createCallServer, - unstable_getServerStream as getServerStream, + unstable_getRSCStream as getRSCStream, unstable_RSCHydratedRouter as RSCHydratedRouter, } from "react-router"; -import type { unstable_ServerPayload as ServerPayload } from "react-router"; +import type { unstable_RSCPayload as RSCPayload } from "react-router"; setServerCallback( createCallServer({ @@ -19,7 +19,7 @@ setServerCallback( }) ); -createFromReadableStream(getServerStream()).then((payload) => { +createFromReadableStream(getRSCStream()).then((payload) => { startTransition(() => { hydrateRoot( document, diff --git a/playground/rsc-vite/src/routes.ts b/playground/rsc-vite/src/routes.ts index 1a626c9141..a3c768a97e 100644 --- a/playground/rsc-vite/src/routes.ts +++ b/playground/rsc-vite/src/routes.ts @@ -1,4 +1,4 @@ -import type { unstable_ServerRouteObject as ServerRouteObject } from "react-router"; +import type { unstable_RSCRouteConfig as RSCRouteConfig } from "react-router"; export const routes = [ { @@ -41,4 +41,4 @@ export const routes = [ }, ], }, -] satisfies ServerRouteObject[]; +] satisfies RSCRouteConfig; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index af4f66426c..f35ccbee76 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -519,8 +519,8 @@ importers: specifier: 2.15.0 version: 2.15.0 parcel-config-react-router-experimental: - specifier: 1.0.23 - version: 1.0.23(@parcel/core@2.15.0)(@react-router/dev@packages+react-router-dev)(react-dom@19.1.0(react@19.1.0))(react-router@packages+react-router)(react-server-dom-parcel@19.1.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0) + specifier: 1.0.24 + version: 1.0.24(@parcel/core@2.15.0)(@react-router/dev@packages+react-router-dev)(react-dom@19.1.0(react@19.1.0))(react-router@packages+react-router)(react-server-dom-parcel@19.1.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0) typescript: specifier: ^5.1.6 version: 5.4.5 @@ -1827,8 +1827,8 @@ importers: specifier: 2.15.0 version: 2.15.0 parcel-config-react-router-experimental: - specifier: 1.0.23 - version: 1.0.23(@parcel/core@2.15.0)(@react-router/dev@packages+react-router-dev)(react-dom@19.1.0(react@19.1.0))(react-router@packages+react-router)(react-server-dom-parcel@19.1.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0) + specifier: 1.0.24 + version: 1.0.24(@parcel/core@2.15.0)(@react-router/dev@packages+react-router-dev)(react-dom@19.1.0(react@19.1.0))(react-router@packages+react-router)(react-server-dom-parcel@19.1.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0) playground/rsc-vite: dependencies: @@ -8426,12 +8426,12 @@ packages: pako@1.0.11: resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} - parcel-config-react-router-experimental@1.0.23: - resolution: {integrity: sha512-dVB83T6O/J0hnMzMrA+uBsHHMo65VMm8Kkhs+RCX8aWcEYHJn6yTIyH4pULOtY/de0piIT99FLWQtJPzcPrfmg==} + parcel-config-react-router-experimental@1.0.24: + resolution: {integrity: sha512-EAB/SENw2VxzutwV/DPG7gbE3bPRdlel+G9ZhQrfXHGamDaEG27u5SkClp8JSfzCB7zg7CtOEvNwl91SfpGuyw==} engines: {parcel: '>=2.15.0'} - parcel-resolver-react-router-experimental@1.1.7: - resolution: {integrity: sha512-yRXtGPQYKBjmNaGCyBm74abx1Rr07C6nMn4tJSdjYWR11t6RRg7x4Uslo/GmdCKXagOmqLcukgbRgS787ZP9Kw==} + parcel-resolver-react-router-experimental@1.1.8: + resolution: {integrity: sha512-l+dbly4Jk0lUz/FxAbSdzH0jHNkGWuJJYVHzI3thsqcTdqoR9/puAlmhXk/dwDps9qU708LasyxFam5bvn9gjA==} engines: {parcel: '>=2.15.0'} peerDependencies: '@react-router/dev': '*' @@ -8440,14 +8440,14 @@ packages: react-router: '*' react-server-dom-parcel: '*' - parcel-resolver-react-router-typegen-experimental@1.1.5: - resolution: {integrity: sha512-lQ+YIj5o3S3jVnzGwwNJcvArwGN4/DihelawHU8qnCIP/rRQdA7tMJldZzmjDZ2TGSFqA3+HC94r+HNp8Cpgcw==} + parcel-resolver-react-router-typegen-experimental@1.1.6: + resolution: {integrity: sha512-C5oH1IncdSa4F3onDEL/hSvJDu/svCU7ep45rCkjxpqv7CrIzHsNjXXPc+t3zq4o6e5U5vHuqF5rWexau0fWFA==} engines: {parcel: '>=2.15.0'} peerDependencies: '@react-router/dev': '*' - parcel-transformer-react-router-experimental@1.1.5: - resolution: {integrity: sha512-0xoFzcb7IRT9oJyYBwvS9+M5YUB9wfqBZMy2F0QEBMIDmjTfN+AmbHsmwBKe/lLVKfPSxpmf6M/Kh0D+lD6E2w==} + parcel-transformer-react-router-experimental@1.1.6: + resolution: {integrity: sha512-v8jDcAdSBGO7DNRBlo9IfQgnJcrhwbyV4EhWKbwXAjhGY2S9BCVFJ1PG0txLGFewPa/j6hjZn8sbPgIEIP1iJA==} engines: {parcel: '>=2.15.0'} peerDependencies: react: '*' @@ -18318,12 +18318,12 @@ snapshots: pako@1.0.11: {} - parcel-config-react-router-experimental@1.0.23(@parcel/core@2.15.0)(@react-router/dev@packages+react-router-dev)(react-dom@19.1.0(react@19.1.0))(react-router@packages+react-router)(react-server-dom-parcel@19.1.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0): + parcel-config-react-router-experimental@1.0.24(@parcel/core@2.15.0)(@react-router/dev@packages+react-router-dev)(react-dom@19.1.0(react@19.1.0))(react-router@packages+react-router)(react-server-dom-parcel@19.1.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0): dependencies: '@parcel/config-default': 2.15.0(@parcel/core@2.15.0) - parcel-resolver-react-router-experimental: 1.1.7(@parcel/core@2.15.0)(@react-router/dev@packages+react-router-dev)(react-dom@19.1.0(react@19.1.0))(react-router@packages+react-router)(react-server-dom-parcel@19.1.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0) - parcel-resolver-react-router-typegen-experimental: 1.1.5(@parcel/core@2.15.0)(@react-router/dev@packages+react-router-dev) - parcel-transformer-react-router-experimental: 1.1.5(@parcel/core@2.15.0)(react-dom@19.1.0(react@19.1.0))(react-router@packages+react-router)(react@19.1.0) + parcel-resolver-react-router-experimental: 1.1.8(@parcel/core@2.15.0)(@react-router/dev@packages+react-router-dev)(react-dom@19.1.0(react@19.1.0))(react-router@packages+react-router)(react-server-dom-parcel@19.1.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0) + parcel-resolver-react-router-typegen-experimental: 1.1.6(@parcel/core@2.15.0)(@react-router/dev@packages+react-router-dev) + parcel-transformer-react-router-experimental: 1.1.6(@parcel/core@2.15.0)(react-dom@19.1.0(react@19.1.0))(react-router@packages+react-router)(react@19.1.0) transitivePeerDependencies: - '@parcel/core' - '@react-router/dev' @@ -18335,7 +18335,7 @@ snapshots: - react-server-dom-parcel - supports-color - parcel-resolver-react-router-experimental@1.1.7(@parcel/core@2.15.0)(@react-router/dev@packages+react-router-dev)(react-dom@19.1.0(react@19.1.0))(react-router@packages+react-router)(react-server-dom-parcel@19.1.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0): + parcel-resolver-react-router-experimental@1.1.8(@parcel/core@2.15.0)(@react-router/dev@packages+react-router-dev)(react-dom@19.1.0(react@19.1.0))(react-router@packages+react-router)(react-server-dom-parcel@19.1.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0): dependencies: '@mjackson/node-fetch-server': 0.6.1 '@parcel/plugin': 2.15.0(@parcel/core@2.15.0) @@ -18351,7 +18351,7 @@ snapshots: - napi-wasm - supports-color - parcel-resolver-react-router-typegen-experimental@1.1.5(@parcel/core@2.15.0)(@react-router/dev@packages+react-router-dev): + parcel-resolver-react-router-typegen-experimental@1.1.6(@parcel/core@2.15.0)(@react-router/dev@packages+react-router-dev): dependencies: '@parcel/plugin': 2.15.0(@parcel/core@2.15.0) '@react-router/dev': link:packages/react-router-dev @@ -18359,7 +18359,7 @@ snapshots: - '@parcel/core' - napi-wasm - parcel-transformer-react-router-experimental@1.1.5(@parcel/core@2.15.0)(react-dom@19.1.0(react@19.1.0))(react-router@packages+react-router)(react@19.1.0): + parcel-transformer-react-router-experimental@1.1.6(@parcel/core@2.15.0)(react-dom@19.1.0(react@19.1.0))(react-router@packages+react-router)(react@19.1.0): dependencies: '@babel/core': 7.27.4 '@babel/generator': 7.27.5