UNPKG

rwsdk

Version:

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

67 lines (66 loc) 3.16 kB
import { isValidElementType } from "react-is"; import { registerClientReference as baseRegisterClientReference, registerServerReference as baseRegisterServerReference, decodeReply, } from "react-server-dom-webpack/server.edge"; import { getServerModuleExport } from "../imports/worker.js"; import { requestInfo } from "../requestInfo/worker.js"; export function registerServerReference(action, id, name) { if (typeof action !== "function") { return action; } // Note: We no longer need to register in a Map since we use virtual lookup return baseRegisterServerReference(action, id, name); } const isComponent = (target) => isValidElementType(target) && target?.toString().includes("jsx"); export function registerClientReference(ssrModule, id, exportName) { const target = ssrModule[exportName] ?? {}; if (isValidElementType(target)) { // This is the original logic from 'main'. // For React components, we create a serializable reference for the RSC pass. const reference = baseRegisterClientReference({}, id, exportName); const finalDescriptors = Object.getOwnPropertyDescriptors(reference); const idDescriptor = finalDescriptors.$$id; if (idDescriptor) { const originalValue = idDescriptor.value; // Create a new accessor descriptor, NOT by spreading the old one. finalDescriptors.$$id = { enumerable: idDescriptor.enumerable, configurable: idDescriptor.configurable, get() { requestInfo.rw.scriptsToBeLoaded.add(id); return originalValue; }, }; } finalDescriptors.$$async = { value: true }; finalDescriptors.$$isClientReference = { value: true }; // context(justinvdm, 25 Sep 2025): We create a wrapper function to avoid // getting the SSR component's property descriptors - otherwise // this will take precedence over the client reference descriptors const fn = typeof target === "function" ? (...args) => target(...args) : () => null; return Object.defineProperties(fn, finalDescriptors); } // For non-components, return the target object directly for use in SSR. return target; } export async function __smokeTestActionHandler(timestamp) { await new Promise((resolve) => setTimeout(resolve, 0)); return { status: "ok", timestamp }; } export async function rscActionHandler(req) { const url = new URL(req.url); const contentType = req.headers.get("content-type"); const data = contentType?.startsWith("multipart/form-data") ? await req.formData() : await req.text(); const args = (await decodeReply(data, null)); const actionId = url.searchParams.get("__rsc_action_id"); if (import.meta.env.VITE_IS_DEV_SERVER && actionId === "__rsc_hot_update") { return null; } const action = await getServerModuleExport(actionId); if (typeof action !== "function") { throw new Error(`Action ${actionId} is not a function`); } return action(...args); }