UNPKG

rwsdk

Version:

Build fast, server-driven webapps on Cloudflare with SSR, RSC, and realtime

40 lines (39 loc) 2.08 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { Preloads } from "./preloads.js"; import { Stylesheets } from "./stylesheets.js"; import { createThenableFromReadableStream, renderHtmlStream, } from "rwsdk/__ssr_bridge"; import { stitchDocumentAndAppStreams } from "../lib/stitchDocumentAndAppStreams.js"; export const renderDocumentHtmlStream = async ({ rscPayloadStream, Document, requestInfo, shouldSSR, onError, }) => { // Extract the app node from the RSC payload const rscAppThenable = createThenableFromReadableStream(rscPayloadStream); const { node: innerAppNode } = (await rscAppThenable); // todo(justinvdm, 18 Jun 2025): We can build on this later to allow users // surface context. e.g: // * we assign `user: requestInfo.clientCtx` here // * user populates requestInfo.clientCtx on worker side // * user can import a read only `import { clientCtx } from "rwsdk/client"` // on client side const clientContext = { rw: { ssr: shouldSSR, }, }; // Create the outer document with a marker for injection const documentElement = (_jsxs(Document, { ...requestInfo, children: [_jsx("script", { nonce: requestInfo.rw.nonce, dangerouslySetInnerHTML: { __html: `globalThis.__RWSDK_CONTEXT = ${JSON.stringify(clientContext)}`, } }), _jsx(Stylesheets, { requestInfo: requestInfo }), _jsx(Preloads, { requestInfo: requestInfo }), _jsx("div", { id: "hydrate-root", children: _jsx("div", { id: "rwsdk-app-start" }) })] })); const outerHtmlStream = await renderHtmlStream({ node: documentElement, requestInfo, onError, identifierPrefix: "__RWSDK_DOCUMENT__", }); const appHtmlStream = await renderHtmlStream({ node: innerAppNode, requestInfo, onError, }); // Stitch the streams together const stitchedStream = stitchDocumentAndAppStreams(outerHtmlStream, appHtmlStream, '<div id="rwsdk-app-start"></div>', '<div id="rwsdk-app-end"></div>'); return stitchedStream; };