UNPKG

vite-plugin-react-server

Version:
184 lines (164 loc) 5.96 kB
import type { CreateHandlerOptions, PanicThreshold } from "../types.js"; import { cleanObject } from "./cleanObject.js"; import { processForSerialization } from "./serializeUserOptions.js"; /** * Serializable handler options that can be safely passed to workers * * This extracts only the serializable parts of CreateHandlerOptions, * excluding functions, React components, and other non-serializable data. * * WHAT'S INCLUDED: * - All primitive values (strings, numbers, booleans) * - Configuration objects (build, userOptions, etc.) * - File paths and URLs * - CSS data (cssFiles, globalCss) * * WHAT'S EXCLUDED: * - React components (PageComponent, RootComponent, HtmlComponent) * - Functions (loader, normalizer, onEvent, onMetrics) * - Logger instances * - Module IDs and autoDiscover functions */ export interface SerializableHandlerOptions { // Core identification id?: string; route: string; url: string; // File paths pagePath: string; propsPath?: string; rootPath?: string; htmlPath?: string; // Export names pageExportName: string; propsExportName: string; rootExportName: string; htmlExportName: string; // Module configuration projectRoot: string; moduleRootPath: string; moduleBaseURL: string; moduleBasePath: string; moduleBase?: string; publicOrigin: string; // Build configuration build: CreateHandlerOptions["build"]; dev: CreateHandlerOptions["dev"]; // CSS configuration css: CreateHandlerOptions["css"]; // Auto-discovery configuration autoDiscover?: CreateHandlerOptions["autoDiscover"] // CSS data cssFiles?: Map<string, any>; globalCss?: Map<string, any>; // Page props (must be serializable) pageProps: any; // Panic threshold panicThreshold: PanicThreshold; // Timeouts htmlTimeout?: number; // Stream options clientPipeableStreamOptions?: Omit<NonNullable<CreateHandlerOptions["clientPipeableStreamOptions"]>, `on${string}` | 'filterStackFrame'>; serverPipeableStreamOptions?: Omit<NonNullable<CreateHandlerOptions["serverPipeableStreamOptions"]>, `on${string}`>; } /** * Creates serializable handler options from full CreateHandlerOptions * * This function strips out non-serializable parts (React components, functions) * and returns only the data that can be safely passed to workers. * * @param options - Full CreateHandlerOptions object * @returns Serializable options for worker communication */ export function createSerializableHandlerOptions( options: Partial<CreateHandlerOptions> ): SerializableHandlerOptions { const { // Extract serializable parts id, route, url, pagePath, propsPath, rootPath, htmlPath, pageExportName, propsExportName, rootExportName, htmlExportName, projectRoot, moduleRootPath, moduleBaseURL, moduleBasePath, moduleBase, build, cssFiles, globalCss, pageProps, css, autoDiscover, clientPipeableStreamOptions, serverPipeableStreamOptions, ...rest } = options; const result: any = { route: route || "", url: url || "", }; // Only include properties if they exist if (typeof id === 'string') result.id = id; if (typeof pagePath === 'string') result.pagePath = pagePath; if (typeof propsPath === 'string') result.propsPath = propsPath; if (typeof rootPath === 'string') result.rootPath = rootPath; if (typeof htmlPath === 'string') result.htmlPath = htmlPath; if (typeof pageExportName === 'string') result.pageExportName = pageExportName; if (typeof propsExportName === 'string') result.propsExportName = propsExportName; if (typeof rootExportName === 'string') result.rootExportName = rootExportName; if (typeof htmlExportName === 'string') result.htmlExportName = htmlExportName; if (typeof projectRoot === 'string') result.projectRoot = projectRoot; if (typeof moduleRootPath === 'string') result.moduleRootPath = moduleRootPath; if (typeof moduleBaseURL === 'string') result.moduleBaseURL = moduleBaseURL; if (typeof moduleBasePath === 'string') result.moduleBasePath = moduleBasePath; if (typeof moduleBase === 'string') result.moduleBase = moduleBase; if (build != null) { // Clean the build object to remove functions that can't be cloned const cleanedBuild = cleanObject(build, new Set([ "entryFile", "chunkFile", "assetFile" ])); result.build = processForSerialization(cleanedBuild); } // Clean the entire options object to remove other non-serializable functions const cleanedOptions = cleanObject(rest, new Set([ "normalizer", "loader", "onEvent", "onMetrics" ])); const processedRest = processForSerialization(cleanedOptions); if (css != null) result.css = css; if (autoDiscover != null) { // Clean the autoDiscover object to remove functions that can't be cloned const cleanedAutoDiscover = cleanObject(autoDiscover); result.autoDiscover = processForSerialization(cleanedAutoDiscover); } if (cssFiles != null) result.cssFiles = cssFiles; if (globalCss != null) result.globalCss = globalCss; if (pageProps != null) result.pageProps = pageProps; if (clientPipeableStreamOptions != null) { // Use the existing helper to clean the object - this will handle all non-function properties const cleanedClientOptions = cleanObject(clientPipeableStreamOptions); result.clientPipeableStreamOptions = processForSerialization(cleanedClientOptions); } if (serverPipeableStreamOptions != null) { // Use the existing helper to clean the object - this will handle all non-function properties const cleanedServerOptions = cleanObject(serverPipeableStreamOptions); result.serverPipeableStreamOptions = processForSerialization(cleanedServerOptions); } // Include any other serializable properties using existing helper return { ...result, ...processedRest, }; }