UNPKG

@wroud/vite-plugin-ssg

Version:

A Vite plugin for static site generation (SSG) with React. Renders React applications to static HTML for faster load times and improved SEO.

99 lines 3.86 kB
import { fork } from "child_process"; import { fileURLToPath } from "url"; import { deserializeError } from "../utils/error/deserializeError.js"; export async function loadServerApi(module) { let process = fork(fileURLToPath(import.meta.resolve("./run-server-api.js")), [module], { stdio: "inherit", // This automatically forwards stdout/stderr to parent }); let messageId = 0; const activeListeners = new Set(); // Helper function to send message and wait for response const sendMessageAndWaitForResponse = (type, instanceId, args) => { return new Promise((resolve, reject) => { const id = messageId++; const onMessage = (response) => { if (response.messageId !== id) return; process.removeListener("message", onMessage); activeListeners.delete(onMessage); if (response.success) { resolve(response.data); } else { reject(deserializeError(response.error)); } }; activeListeners.add(onMessage); process.on("message", onMessage); process.send({ type, instanceId, messageId: id, args, }); }); }; return { create: async (...args) => { const instanceId = await sendMessageAndWaitForResponse("init", undefined, args); return { async render(htmlTags, timeout) { return sendMessageAndWaitForResponse("render", instanceId, { htmlTags, timeout, }); }, async getPathsToPrerender() { return sendMessageAndWaitForResponse("getPathsToPrerender", instanceId); }, async dispose() { await sendMessageAndWaitForResponse("dispose", instanceId); }, }; }, async dispose() { if (!process) { return; } try { // First try to gracefully terminate by notifying the child process await sendMessageAndWaitForResponse("dispose", undefined); // Clean up any remaining listeners to prevent memory leaks for (const listener of activeListeners) { process.removeListener("message", listener); } activeListeners.clear(); // Check if the process is still running if (process.connected) { // Try SIGTERM first for graceful shutdown process.kill("SIGTERM"); // Set a timeout to force kill if the process doesn't exit await new Promise((resolve, reject) => setTimeout(() => { try { if (!process.killed) { process.kill("SIGKILL"); } } catch (e) { reject(e); } finally { resolve(undefined); } }, 500)); } } catch (error) { console.error("Error disposing server process:", error); // Force kill as a last resort if (process.connected && !process.killed) { process.kill("SIGKILL"); } } finally { process = null; } }, }; } //# sourceMappingURL=loadServerApi.js.map