vite-plugin-react-server
Version:
Vite plugin for React Server Components (RSC)
105 lines (100 loc) • 2.75 kB
text/typescript
import { toError } from "../error/toError.js";
import type { GenericModuleLoader } from "../types.js";
type ResolvePageResult =
| {
type: "success";
module: Record<string, unknown>;
error?: never;
}
| { type: "error"; error: Error; Page?: never; module?: never }
| { type: "skip"; error?: never; Page?: never; module?: never };
type ResolvePageFn = (options: {
id: string;
exportName: string;
loader: GenericModuleLoader
}) => Promise<ResolvePageResult>;
/**
* Resolves a page component from a module.
*
* During development (ssrLoadModule):
* - Real modules have exports available directly on the module object
* - Virtual modules have exports stored in temporaryReferences
*
* @param options.id - The module ID to resolve
* @param options.exportName - The name of the export to resolve (e.g. 'Page')
* @param options.loader - The loader function to use for loading the module
*
* @returns A result object containing:
* - type: "success" | "error" | "skip"
* - Page: The resolved page component if successful
* - error: Error message if failed
*/
export const resolvePage: ResolvePageFn = async function _resolvePage({
id,
exportName,
loader,
}) {
// Check if this is a stashed page that needs special handling
const pageLoadResult = await (async () => {
try {
return {
type: "success" as const,
key: id,
module: await loader(`${id}#${exportName}`),
};
} catch (error) {
return {
type: "error" as const,
error: error instanceof Error ? error : new Error(String(error)),
};
}
})();
if (pageLoadResult.type !== "success") {
return pageLoadResult;
}
const { module } = pageLoadResult;
if (module == null) {
return {
type: "error" as const,
error: new Error(`Module ${id} not found`),
};
}
const Page = module[exportName];
if (module instanceof Error) {
return {
type: "error" as const,
error: {
name: module.name,
message: module.message,
stack: module.stack,
},
};
} else if (!(exportName in module)) {
if ("error" in module) {
return {
type: "error" as const,
error: toError(module["error"]),
};
}
return {
type: "error" as const,
error: new Error(`Export "${exportName}" not found in module ${id}.`),
};
} else if (!Page) {
return {
type: "error" as const,
error: new Error(
`Export "${exportName}" is null or undefined in module ${id}.`
),
};
} else if (Page instanceof Error) {
return {
type: "error" as const,
error: Page,
};
}
return {
type: "success" as const,
module: module,
};
};