UNPKG

@redwoodjs/sdk

Version:

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

57 lines (56 loc) 2.52 kB
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime"; import { clientWebpackRequire } from "./imports/client"; // NOTE: `react-server-dom-webpack` uses this global to load modules, // so we need to define it here before importing "react-server-dom-webpack." globalThis.__webpack_require__ = clientWebpackRequire; export const fetchTransport = (transportContext) => { const fetchCallServer = async (id, args) => { const { createFromFetch, encodeReply } = await import("react-server-dom-webpack/client.browser"); const url = new URL(window.location.href); url.searchParams.set("__rsc", ""); if (id != null) { url.searchParams.set("__rsc_action_id", id); } const streamData = createFromFetch(fetch(url, { method: "POST", body: args != null ? await encodeReply(args) : null, }), { callServer: fetchCallServer }); transportContext.setRscPayload(streamData); const result = await streamData; return result.actionResult; }; return fetchCallServer; }; export const initClient = async ({ transport = fetchTransport, } = {}) => { const transportContext = { setRscPayload: () => { }, }; const callServer = transport(transportContext); globalThis.__rsc_callServer = callServer; const rootEl = document.getElementById("root"); if (!rootEl) { throw new Error('no element with id "root"'); } const React = await import("react"); const { hydrateRoot } = await import("react-dom/client"); // @ts-ignore: todo(peterp, 2024-11-27): Type these properly. const { createFromReadableStream, createFromFetch, encodeReply } = await import("react-server-dom-webpack/client.browser"); const { rscStream } = await import("rsc-html-stream/client"); let rscPayload; rscPayload ??= createFromReadableStream(rscStream, { callServer, }); function Content() { const [streamData, setStreamData] = React.useState(rscPayload); const [_isPending, startTransition] = React.useTransition(); transportContext.setRscPayload = (v) => startTransition(() => setStreamData(v)); return _jsx(_Fragment, { children: React.use(streamData).node }); } hydrateRoot(rootEl, _jsx(Content, {})); if (import.meta.hot) { import.meta.hot.on("rsc:update", (e) => { console.log("[rw-sdk] hot update", e.file); callServer("__rsc_hot_update", [e.file]); }); } };