UNPKG

rwsdk

Version:

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

70 lines (69 loc) 3.11 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, hydrateRootOptions, } = {}) => { const React = await import("react"); const { hydrateRoot } = await import("react-dom/client"); const transportContext = { setRscPayload: () => { }, }; let transportCallServer = transport(transportContext); const callServer = (id, args) => transportCallServer(id, args); const upgradeToRealtime = async ({ key } = {}) => { const { realtimeTransport } = await import("./lib/realtime/client"); const createRealtimeTransport = realtimeTransport({ key }); transportCallServer = createRealtimeTransport(transportContext); }; globalThis.__rsc_callServer = callServer; globalThis.__rw = { callServer, upgradeToRealtime, }; const rootEl = document.getElementById("hydrate-root"); if (!rootEl) { throw new Error('no element with id "hydrate-root"'); } let rscPayload; // context(justinvdm, 18 Jun 2025): We inject the RSC payload // unless render(Document, [...], { rscPayload: false }) was used. if (globalThis.__FLIGHT_DATA) { const { createFromReadableStream } = await import("react-server-dom-webpack/client.browser"); const { rscStream } = await import("rsc-html-stream/client"); 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, {}), hydrateRootOptions); if (import.meta.hot) { import.meta.hot.on("rsc:update", (e) => { console.log("[rwsdk] hot update", e.file); callServer("__rsc_hot_update", [e.file]); }); } };