Skip to content

Commit b95cf3f

Browse files
authored
Add JSDocs for RSC apis (#14019)
1 parent c02cf7a commit b95cf3f

File tree

8 files changed

+324
-16
lines changed

8 files changed

+324
-16
lines changed

.eslintrc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@
2828
"packages/react-router/lib/dom/ssr/components.tsx",
2929
"packages/react-router/lib/dom/ssr/server.tsx",
3030
"packages/react-router/lib/dom-export/hydrated-router.tsx",
31-
"packages/react-router/lib/dom/server.tsx"
31+
"packages/react-router/lib/dom/server.tsx",
32+
"packages/react-router/lib/rsc/browser.tsx",
33+
"packages/react-router/lib/rsc/server.rsc.ts",
34+
"packages/react-router/lib/rsc/server.ssr.tsx",
35+
"packages/react-router/lib/rsc/html-stream/browser.ts",
3236
],
3337
"plugins": ["jsdoc"],
3438
"rules": {

.github/workflows/docs.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ jobs:
5555
pnpm run docs:jsdoc --path packages/react-router/lib/dom/ssr/server.tsx --write
5656
pnpm run docs:jsdoc --path packages/react-router/lib/dom-export/hydrated-router.tsx --write
5757
pnpm run docs:jsdoc --path packages/react-router/lib/dom/server.tsx --write
58+
pnpm run docs:jsdoc --path packages/react-router/lib/rsc/browser.tsx --write
59+
pnpm run docs:jsdoc --path packages/react-router/lib/rsc/server.rsc.ts --write
60+
pnpm run docs:jsdoc --path packages/react-router/lib/rsc/server.ssr.tsx --write
61+
pnpm run docs:jsdoc --path packages/react-router/lib/rsc/html-stream/browser.ts --write
5862
5963
- name: 💪 Commit
6064
run: |

packages/react-router/index.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,12 +290,16 @@ export { href } from "./lib/href";
290290
export type {
291291
BrowserCreateFromReadableStreamFunction as unstable_BrowserCreateFromReadableStreamFunction,
292292
EncodeReplyFunction as unstable_EncodeReplyFunction,
293+
RSCHydratedRouterProps as unstable_RSCHydratedRouterProps,
293294
} from "./lib/rsc/browser";
294295
export {
295296
createCallServer as unstable_createCallServer,
296297
RSCHydratedRouter as unstable_RSCHydratedRouter,
297298
} from "./lib/rsc/browser";
298-
export type { SSRCreateFromReadableStreamFunction as unstable_SSRCreateFromReadableStreamFunction } from "./lib/rsc/server.ssr";
299+
export type {
300+
SSRCreateFromReadableStreamFunction as unstable_SSRCreateFromReadableStreamFunction,
301+
RSCStaticRouterProps as unstable_RSCStaticRouterProps,
302+
} from "./lib/rsc/server.ssr";
299303
export {
300304
routeRSCServerRequest as unstable_routeRSCServerRequest,
301305
RSCStaticRouter as unstable_RSCStaticRouter,

packages/react-router/lib/rsc/browser.tsx

Lines changed: 111 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,40 @@ type WindowWithRouterGlobals = Window &
6161
__routerActionID: number;
6262
};
6363

64+
/**
65+
* Create a React `callServer` implementation for React Router.
66+
*
67+
* @example
68+
* import {
69+
* createFromReadableStream,
70+
* createTemporaryReferenceSet,
71+
* encodeReply,
72+
* setServerCallback,
73+
* } from "@vitejs/plugin-rsc/browser";
74+
* import { unstable_createCallServer as createCallServer } from "react-router";
75+
*
76+
* setServerCallback(
77+
* createCallServer({
78+
* createFromReadableStream,
79+
* createTemporaryReferenceSet,
80+
* encodeReply,
81+
* })
82+
* );
83+
*
84+
* @name unstable_createCallServer
85+
* @public
86+
* @category RSC
87+
* @mode data
88+
* @param opts Options
89+
* @param opts.createFromReadableStream Your `react-server-dom-xyz/client`'s
90+
* `createFromReadableStream`. Used to decode payloads from the server.
91+
* @param opts.createTemporaryReferenceSet A function that creates a temporary
92+
* reference set for the RSC payload.
93+
* @param opts.encodeReply Your `react-server-dom-xyz/client`'s `encodeReply`.
94+
* Used when sending payloads to the server.
95+
* @param opts.fetch Optional fetch implementation. Defaults to global `fetch`.
96+
* @returns A function that can be used to call server actions.
97+
*/
6498
export function createCallServer({
6599
createFromReadableStream,
66100
createTemporaryReferenceSet,
@@ -460,19 +494,89 @@ function getFetchAndDecodeViaRSC(
460494
};
461495
}
462496

497+
/**
498+
* Props for the `unstable_RSCHydratedRouter` component.
499+
* @name unstable_RSCHydratedRouterProps
500+
*/
501+
export interface RSCHydratedRouterProps {
502+
/**
503+
* Your `react-server-dom-xyz/client`'s `createFromReadableStream` function,
504+
* used to decode payloads from the server.
505+
*/
506+
createFromReadableStream: BrowserCreateFromReadableStreamFunction;
507+
/**
508+
* Optional fetch implementation. Defaults to global `fetch`.
509+
*/
510+
fetch?: (request: Request) => Promise<Response>;
511+
/**
512+
* The decoded `RSCPayload` to hydrate.
513+
*/
514+
payload: RSCPayload;
515+
/**
516+
* `eager` or `lazy` - Determines if links are eagerly discovered, or delayed
517+
* until clicked.
518+
*/
519+
routeDiscovery?: "eager" | "lazy";
520+
/**
521+
* A function that returns an `unstable_InitialContext` object
522+
* (`Map<RouterContext, unknown>`), for use in client loaders, actions and
523+
* middleware.
524+
*/
525+
unstable_getContext?: RouterInit["unstable_getContext"];
526+
}
527+
528+
/**
529+
* Hydrates a server rendered `RSCPayload` in the browser.
530+
*
531+
* @example
532+
* import { startTransition, StrictMode } from "react";
533+
* import { hydrateRoot } from "react-dom/client";
534+
* import {
535+
* unstable_getRSCStream as getRSCStream,
536+
* unstable_RSCHydratedRouter as RSCHydratedRouter,
537+
* } from "react-router";
538+
* import type { unstable_RSCPayload as RSCPayload } from "react-router";
539+
*
540+
* createFromReadableStream(getRSCStream()).then(
541+
* (payload: RSCServerPayload) => {
542+
* startTransition(async () => {
543+
* hydrateRoot(
544+
* document,
545+
* <StrictMode>
546+
* <RSCHydratedRouter
547+
* createFromReadableStream={
548+
* createFromReadableStream
549+
* }
550+
* payload={payload}
551+
* />
552+
* </StrictMode>,
553+
* {
554+
* formState: await getFormState(payload),
555+
* }
556+
* );
557+
* });
558+
* }
559+
* );
560+
*
561+
* @name unstable_RSCHydratedRouter
562+
* @public
563+
* @category RSC
564+
* @mode data
565+
* @param props Props
566+
* @param {unstable_RSCHydratedRouterProps.createFromReadableStream} props.createFromReadableStream n/a
567+
* @param {unstable_RSCHydratedRouterProps.fetch} props.fetch n/a
568+
* @param {unstable_RSCHydratedRouterProps.payload} props.payload n/a
569+
* @param {unstable_RSCHydratedRouterProps.routeDiscovery} props.routeDiscovery n/a
570+
* @param {unstable_RSCHydratedRouterProps.unstable_getContext} props.unstable_getContext n/a
571+
* @returns A hydrated router that can be used to navigate and render routes.
572+
*/
463573
export function RSCHydratedRouter({
464574
createFromReadableStream,
465575
fetch: fetchImplementation = fetch,
466576
payload,
467577
routeDiscovery = "eager",
468578
unstable_getContext,
469-
}: {
470-
createFromReadableStream: BrowserCreateFromReadableStreamFunction;
471-
fetch?: (request: Request) => Promise<Response>;
472-
payload: RSCPayload;
473-
routeDiscovery?: "eager" | "lazy";
474-
unstable_getContext?: RouterInit["unstable_getContext"];
475-
}) {
579+
}: RSCHydratedRouterProps) {
476580
if (payload.type !== "render") throw new Error("Invalid payload type");
477581

478582
let router = React.useMemo(

packages/react-router/lib/rsc/html-stream/browser.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,42 @@ declare global {
66
}
77
}
88

9-
export function getRSCStream() {
9+
/**
10+
* Get the prerendered RSC stream for hydration. Usually passed directly to your
11+
* `react-server-dom-xyz/client`'s `createFromReadableStream`.
12+
*
13+
* @example
14+
* import { startTransition, StrictMode } from "react";
15+
* import { hydrateRoot } from "react-dom/client";
16+
* import {
17+
* unstable_getRSCStream as getRSCStream,
18+
* unstable_RSCHydratedRouter as RSCHydratedRouter,
19+
* } from "react-router";
20+
* import type { unstable_RSCPayload as RSCPayload } from "react-router";
21+
*
22+
* createFromReadableStream(getRSCStream()).then(
23+
* (payload: RSCServerPayload) => {
24+
* startTransition(async () => {
25+
* hydrateRoot(
26+
* document,
27+
* <StrictMode>
28+
* <RSCHydratedRouter ...props />
29+
* </StrictMode>,
30+
* {
31+
* // Options
32+
* }
33+
* );
34+
* });
35+
* }
36+
* );
37+
*
38+
* @name unstable_getRSCStream
39+
* @public
40+
* @category RSC
41+
* @mode data
42+
* @returns A `ReadableStream` that contains the RSC data for hydration.
43+
*/
44+
export function getRSCStream(): ReadableStream<any> {
1045
let encoder = new TextEncoder();
1146
let streamController: ReadableStreamDefaultController<Uint8Array> | null =
1247
null;

packages/react-router/lib/rsc/server.rsc.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,67 @@ export type DecodeReplyFunction = (
245245

246246
export type LoadServerActionFunction = (id: string) => Promise<Function>;
247247

248+
/**
249+
* Matches the given routes to a Request and returns a RSC Response encoding an
250+
* `RSCPayload` for consumption by a RSC enabled client router.
251+
*
252+
* @example
253+
* import {
254+
* createTemporaryReferenceSet,
255+
* decodeAction,
256+
* decodeReply,
257+
* loadServerAction,
258+
* renderToReadableStream,
259+
* } from "@vitejs/plugin-rsc/rsc";
260+
* import { unstable_matchRSCServerRequest as matchRSCServerRequest } from "react-router";
261+
*
262+
* matchRSCServerRequest({
263+
* createTemporaryReferenceSet,
264+
* decodeAction,
265+
* decodeFormState,
266+
* decodeReply,
267+
* loadServerAction,
268+
* request,
269+
* routes: routes(),
270+
* generateResponse(match) {
271+
* return new Response(
272+
* renderToReadableStream(match.payload),
273+
* {
274+
* status: match.statusCode,
275+
* headers: match.headers,
276+
* }
277+
* );
278+
* },
279+
* });
280+
*
281+
* @name unstable_matchRSCServerRequest
282+
* @public
283+
* @category RSC
284+
* @mode data
285+
* @param opts Options
286+
* @param opts.basename The basename to use when matching the request.
287+
* @param opts.decodeAction Your `react-server-dom-xyz/server`'s `decodeAction`
288+
* function, responsible for loading a server action.
289+
* @param opts.decodeReply Your `react-server-dom-xyz/server`'s `decodeReply`
290+
* function, used to decode the server function's arguments and bind them to the
291+
* implementation for invocation by the router.
292+
* @param opts.decodeFormState A function responsible for decoding form state for
293+
* progressively enhanceable forms with `useActionState` using your
294+
* `react-server-dom-xyz/server`'s `decodeFormState`.
295+
* @param opts.generateResponse A function responsible for using your
296+
* `renderToReadableStream` to generate a Response encoding the `RSCPayload`.
297+
* @param opts.loadServerAction Your `react-server-dom-xyz/server`'s
298+
* `loadServerAction` function, used to load a server action by ID.
299+
* @param opts.request The request to match against.
300+
* @param opts.requestContext An instance of `unstable_RouterContextProvider`
301+
* that should be created per request, to be passed to loaders, actions and middleware.
302+
* @param opts.routes Your route definitions.
303+
* @param opts.createTemporaryReferenceSet A function that returns a temporary
304+
* reference set for the request, used to track temporary references in the RSC stream.
305+
* @param opts.onError An optional error handler that will be called with any
306+
* errors that occur during the request processing.
307+
* @returns A Response that contains the RSC data for hydration.
308+
*/
248309
export async function matchRSCServerRequest({
249310
createTemporaryReferenceSet,
250311
basename,

0 commit comments

Comments
 (0)