UNPKG

vite-plugin-react-server

Version:
113 lines (110 loc) 3.65 kB
/** * vite-plugin-react-server * Copyright (c) Nico Brinkkemper * MIT License */ import { PassThrough } from 'node:stream'; import { parentPort } from 'node:worker_threads'; import * as ReactDOMServer from 'react-dom/server'; import 'react'; import { createFromNodeStream } from 'react-server-dom-esm/client.node'; const activeRenders = /* @__PURE__ */ new Map(); const htmlContent = /* @__PURE__ */ new Map(); const htmlPromises = /* @__PURE__ */ new Map(); const messageHandler = async (message) => { try { switch (message.type) { case "RSC_CHUNK": { const { id, chunk, moduleRootPath, moduleBaseURL, htmlOutputPath, pipableStreamOptions } = message; const render = activeRenders.get(id); if (!render) { activeRenders.set(id, { chunks: [chunk], id, complete: false, rendered: false, moduleRootPath, moduleBaseURL, outDir: "", htmlOutputPath, pipableStreamOptions }); } else { render.chunks = [...render.chunks, chunk]; } break; } case "RSC_END": { const { id } = message; const render = activeRenders.get(id); if (!render) { throw new Error(`No render state found for ${id}`); } render.complete = true; const rscStream = new PassThrough(); for (const chunk of render.chunks) { rscStream.write(chunk); } rscStream.end(); const reactElements = await createFromNodeStream( rscStream, render.moduleRootPath, render.moduleBaseURL ); const htmlPromise = new Promise((resolve) => { const collectStream = new PassThrough(); let html = ""; collectStream.on("data", (chunk) => { html += chunk.toString(); }); collectStream.on("end", () => { resolve(html); render.rendered = true; parentPort?.postMessage({ type: "ALL_READY", id, html, outputPath: render.htmlOutputPath }); }); const stream = ReactDOMServer.renderToPipeableStream( reactElements, { ...render.pipableStreamOptions, // Calculate relative paths based on route depth bootstrapModules: render.pipableStreamOptions?.bootstrapModules?.map((path) => { if (!path) return path; if (render.moduleBaseURL && render.moduleBaseURL !== "") { return new URL(path, render.moduleBaseURL).toString(); } const depth = id.split("/").filter(Boolean).length; const prefix = depth > 0 ? "../".repeat(depth) : "/"; return path.startsWith("/") ? prefix + path.slice(1) : prefix + path; }), onShellReady() { parentPort?.postMessage({ type: "SHELL_READY", id }); } } ); stream.pipe(collectStream); }); htmlPromises.set(id, htmlPromise); rscStream.destroy(); activeRenders.delete(id); htmlContent.delete(id); htmlPromises.delete(id); break; } case "SHUTDOWN": { console.log("Received shutdown signal"); parentPort?.close(); break; } } } catch (error) { console.error("Error in messageHandler:", error); throw error; } }; export { messageHandler }; //# sourceMappingURL=messageHandler.js.map