vite-plugin-react-server
Version:
Vite plugin for React Server Components (RSC)
127 lines (124 loc) • 14.9 kB
JavaScript
/**
* vite-plugin-react-server
* Copyright (c) Nico Brinkkemper
* MIT License
*/
import { createModuleResolutionMetrics } from '../metrics/createModuleResolutionMetrics.js';
import { performance } from 'node:perf_hooks';
async function resolveComponents(options) {
const {
route,
pagePath,
propsPath,
rootPath,
htmlPath,
pageExportName,
propsExportName,
rootExportName,
htmlExportName,
rscWorker,
worker: workerProp,
onMetrics,
logger,
verbose
} = options;
const worker = rscWorker ?? workerProp;
if (!worker) {
throw new Error(
"RSC Worker is required for client-side component resolution"
);
}
const resolutionStartTime = performance.now();
if (verbose) {
logger?.info(
`[resolveComponents.client] Resolving components for route: ${route}`
);
logger?.info(`[resolveComponents.client] pagePath: ${pagePath}`);
logger?.info(`[resolveComponents.client] propsPath: ${propsPath}`);
logger?.info(`[resolveComponents.client] rootPath: ${rootPath}`);
logger?.info(`[resolveComponents.client] htmlPath: ${htmlPath}`);
}
const resolveMessage = {
type: "RESOLVE_COMPONENTS",
id: `${route}-resolve-${Date.now()}`,
route,
streamType: "rsc",
rscVariant: "rsc-full",
// We'll determine this based on htmlPath later
pagePath,
propsPath,
rootPath,
htmlPath,
pageExportName,
propsExportName,
rootExportName,
htmlExportName
};
try {
await new Promise((resolve, reject) => {
const timeout = setTimeout(() => {
reject(new Error(`Component resolution timeout for route: ${route}`));
}, 3e3);
const messageHandler = (message) => {
if (message.type === "COMPONENTS_RESOLVED" && message.id === resolveMessage.id) {
clearTimeout(timeout);
worker.off("message", messageHandler);
resolve(message);
} else if (message.type === "ERROR" && message.id === resolveMessage.id) {
clearTimeout(timeout);
worker.off("message", messageHandler);
reject(
new Error(
`Component resolution failed: ${message.error?.message || "Unknown error"}`
)
);
}
};
worker.on("message", messageHandler);
worker.postMessage(resolveMessage);
});
const resolutionTime = performance.now() - resolutionStartTime;
if (verbose) {
logger?.info(
`[resolveComponents.client] Components resolved for route: ${route} in ${resolutionTime.toFixed(
2
)}ms`
);
}
if (onMetrics) {
const moduleResolutionMetric = createModuleResolutionMetrics({
route,
workerType: "rsc",
resolutionTime,
fromMainThread: false,
fromRscWorker: true,
fromHtmlWorker: false,
description: `Component resolution for route ${route} on RSC worker`
});
onMetrics(moduleResolutionMetric);
}
return {
resolutionTime
};
} catch (error) {
const resolutionTime = performance.now() - resolutionStartTime;
logger?.error(
`[resolveComponents.client] Failed to resolve components for route ${route}: ${error}`
);
if (onMetrics) {
const moduleResolutionMetric = createModuleResolutionMetrics({
route,
workerType: "rsc",
resolutionTime,
fromMainThread: false,
fromRscWorker: true,
fromHtmlWorker: false,
description: `Component resolution failed for route ${route} on RSC worker`
});
onMetrics(moduleResolutionMetric);
}
throw error;
}
}
export { resolveComponents };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzb2x2ZUNvbXBvbmVudHMuY2xpZW50LmpzIiwic291cmNlcyI6WyIuLi8uLi8uLi9wbHVnaW4vaGVscGVycy9yZXNvbHZlQ29tcG9uZW50cy5jbGllbnQudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBXb3JrZXIgfSBmcm9tIFwibm9kZTp3b3JrZXJfdGhyZWFkc1wiO1xuaW1wb3J0IHR5cGUge1xuICBSZXNvbHZlQ29tcG9uZW50c01lc3NhZ2UsXG4gIENvbXBvbmVudHNSZXNvbHZlZE1lc3NhZ2UsXG59IGZyb20gXCIuLi93b3JrZXIvcnNjL3R5cGVzLmpzXCI7XG5pbXBvcnQgeyBjcmVhdGVNb2R1bGVSZXNvbHV0aW9uTWV0cmljcyB9IGZyb20gXCIuLi9tZXRyaWNzL2NyZWF0ZU1vZHVsZVJlc29sdXRpb25NZXRyaWNzLmpzXCI7XG5pbXBvcnQgeyBwZXJmb3JtYW5jZSB9IGZyb20gXCJub2RlOnBlcmZfaG9va3NcIjtcblxuZXhwb3J0IGludGVyZmFjZSBSZXNvbHZlQ29tcG9uZW50c09wdGlvbnMge1xuICByb3V0ZTogc3RyaW5nO1xuICBwYWdlUGF0aD86IHN0cmluZztcbiAgcHJvcHNQYXRoPzogc3RyaW5nO1xuICByb290UGF0aD86IHN0cmluZztcbiAgaHRtbFBhdGg/OiBzdHJpbmc7XG4gIHBhZ2VFeHBvcnROYW1lPzogc3RyaW5nO1xuICBwcm9wc0V4cG9ydE5hbWU/OiBzdHJpbmc7XG4gIHJvb3RFeHBvcnROYW1lPzogc3RyaW5nO1xuICBodG1sRXhwb3J0TmFtZT86IHN0cmluZztcbiAgd29ya2VyPzogV29ya2VyO1xuICByc2NXb3JrZXI/OiBXb3JrZXI7XG4gIG9uTWV0cmljcz86IChtZXRyaWNzOiBhbnkpID0+IHZvaWQ7XG4gIGxvZ2dlcj86IGFueTtcbiAgdmVyYm9zZT86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb2x2ZWRDb21wb25lbnRzIHtcbiAgcmVzb2x1dGlvblRpbWU6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBSZXNvbHZlcyBjb21wb25lbnRzIHVzaW5nIHRoZSBSU0Mgd29ya2VyIGZvciBjbGllbnQtc2lkZSByZW5kZXJpbmdcbiAqXG4gKiBUaGlzIGZ1bmN0aW9uOlxuICogMS4gU2VuZHMgYSBSRVNPTFZFX0NPTVBPTkVOVFMgbWVzc2FnZSB0byB0aGUgUlNDIHdvcmtlclxuICogMi4gUlNDIHdvcmtlciByZXNvbHZlcyBjb21wb25lbnRzIHVzaW5nIGJ1aWx0IHBhdGhzIGZyb20gbWFuaWZlc3RcbiAqIDMuIFJldHVybnMgcmVzb2x2ZWQgY29tcG9uZW50cyB3aXRoIHByb3BlciBidWlsdCBwYXRoc1xuICogNC4gVHJhY2tzIHJlc29sdXRpb24gbWV0cmljc1xuICpcbiAqIFRoaXMgc2VwYXJhdGVzIGNvbXBvbmVudCByZXNvbHV0aW9uIGZyb20gUlNDIGdlbmVyYXRpb24sIG1ha2luZyB0aGVcbiAqIHN1YnNlcXVlbnQgUlNDIHJlbmRlciBjb21wbGV0ZWx5IHN5bmNocm9ub3VzLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZUNvbXBvbmVudHMoXG4gIG9wdGlvbnM6IFJlc29sdmVDb21wb25lbnRzT3B0aW9uc1xuKTogUHJvbWlzZTxSZXNvbHZlZENvbXBvbmVudHM+IHtcbiAgY29uc3Qge1xuICAgIHJvdXRlLFxuICAgIHBhZ2VQYXRoLFxuICAgIHByb3BzUGF0aCxcbiAgICByb290UGF0aCxcbiAgICBodG1sUGF0aCxcbiAgICBwYWdlRXhwb3J0TmFtZSxcbiAgICBwcm9wc0V4cG9ydE5hbWUsXG4gICAgcm9vdEV4cG9ydE5hbWUsXG4gICAgaHRtbEV4cG9ydE5hbWUsXG4gICAgcnNjV29ya2VyLFxuICAgIHdvcmtlcjogd29ya2VyUHJvcCxcbiAgICBvbk1ldHJpY3MsXG4gICAgbG9nZ2VyLFxuICAgIHZlcmJvc2UsXG4gIH0gPSBvcHRpb25zO1xuXG4gIGNvbnN0IHdvcmtlciA9IHJzY1dvcmtlciA/PyB3b3JrZXJQcm9wO1xuXG4gIGlmICghd29ya2VyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgXCJSU0MgV29ya2VyIGlzIHJlcXVpcmVkIGZvciBjbGllbnQtc2lkZSBjb21wb25lbnQgcmVzb2x1dGlvblwiXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IHJlc29sdXRpb25TdGFydFRpbWUgPSBwZXJmb3JtYW5jZS5ub3coKTtcblxuICBpZiAodmVyYm9zZSkge1xuICAgIGxvZ2dlcj8uaW5mbyhcbiAgICAgIGBbcmVzb2x2ZUNvbXBvbmVudHMuY2xpZW50XSBSZXNvbHZpbmcgY29tcG9uZW50cyBmb3Igcm91dGU6ICR7cm91dGV9YFxuICAgICk7XG4gICAgbG9nZ2VyPy5pbmZvKGBbcmVzb2x2ZUNvbXBvbmVudHMuY2xpZW50XSBwYWdlUGF0aDogJHtwYWdlUGF0aH1gKTtcbiAgICBsb2dnZXI/LmluZm8oYFtyZXNvbHZlQ29tcG9uZW50cy5jbGllbnRdIHByb3BzUGF0aDogJHtwcm9wc1BhdGh9YCk7XG4gICAgbG9nZ2VyPy5pbmZvKGBbcmVzb2x2ZUNvbXBvbmVudHMuY2xpZW50XSByb290UGF0aDogJHtyb290UGF0aH1gKTtcbiAgICBsb2dnZXI/LmluZm8oYFtyZXNvbHZlQ29tcG9uZW50cy5jbGllbnRdIGh0bWxQYXRoOiAke2h0bWxQYXRofWApO1xuICB9XG5cbiAgLy8gU2VuZCBSRVNPTFZFX0NPTVBPTkVOVFMgbWVzc2FnZSB0byBSU0Mgd29ya2VyXG4gIGNvbnN0IHJlc29sdmVNZXNzYWdlOiBSZXNvbHZlQ29tcG9uZW50c01lc3NhZ2UgPSB7XG4gICAgdHlwZTogXCJSRVNPTFZFX0NPTVBPTkVOVFNcIixcbiAgICBpZDogYCR7cm91dGV9LXJlc29sdmUtJHtEYXRlLm5vdygpfWAsXG4gICAgcm91dGUsXG4gICAgc3RyZWFtVHlwZTogXCJyc2NcIixcbiAgICByc2NWYXJpYW50OiBcInJzYy1mdWxsXCIsIC8vIFdlJ2xsIGRldGVybWluZSB0aGlzIGJhc2VkIG9uIGh0bWxQYXRoIGxhdGVyXG4gICAgcGFnZVBhdGgsXG4gICAgcHJvcHNQYXRoLFxuICAgIHJvb3RQYXRoLFxuICAgIGh0bWxQYXRoLFxuICAgIHBhZ2VFeHBvcnROYW1lLFxuICAgIHByb3BzRXhwb3J0TmFtZSxcbiAgICByb290RXhwb3J0TmFtZSxcbiAgICBodG1sRXhwb3J0TmFtZSxcbiAgfTtcblxuICB0cnkge1xuICAgIC8vIFNlbmQgbWVzc2FnZSB0byB3b3JrZXIgYW5kIHdhaXQgZm9yIHJlc3BvbnNlXG4gICAgYXdhaXQgbmV3IFByb21pc2U8Q29tcG9uZW50c1Jlc29sdmVkTWVzc2FnZT4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3QgdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICByZWplY3QobmV3IEVycm9yKGBDb21wb25lbnQgcmVzb2x1dGlvbiB0aW1lb3V0IGZvciByb3V0ZTogJHtyb3V0ZX1gKSk7XG4gICAgICB9LCAzMDAwKTsgLy8gMyBzZWNvbmQgdGltZW91dFxuXG4gICAgICBjb25zdCBtZXNzYWdlSGFuZGxlciA9IChtZXNzYWdlOiBhbnkpID0+IHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIG1lc3NhZ2UudHlwZSA9PT0gXCJDT01QT05FTlRTX1JFU09MVkVEXCIgJiZcbiAgICAgICAgICBtZXNzYWdlLmlkID09PSByZXNvbHZlTWVzc2FnZS5pZFxuICAgICAgICApIHtcbiAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAgICAgd29ya2VyLm9mZihcIm1lc3NhZ2VcIiwgbWVzc2FnZUhhbmRsZXIpO1xuICAgICAgICAgIHJlc29sdmUobWVzc2FnZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgbWVzc2FnZS50eXBlID09PSBcIkVSUk9SXCIgJiZcbiAgICAgICAgICBtZXNzYWdlLmlkID09PSByZXNvbHZlTWVzc2FnZS5pZFxuICAgICAgICApIHtcbiAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAgICAgd29ya2VyLm9mZihcIm1lc3NhZ2VcIiwgbWVzc2FnZUhhbmRsZXIpO1xuICAgICAgICAgIHJlamVjdChcbiAgICAgICAgICAgIG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgYENvbXBvbmVudCByZXNvbHV0aW9uIGZhaWxlZDogJHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmVycm9yPy5tZXNzYWdlIHx8IFwiVW5rbm93biBlcnJvclwiXG4gICAgICAgICAgICAgIH1gXG4gICAgICAgICAgICApXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgd29ya2VyLm9uKFwibWVzc2FnZVwiLCBtZXNzYWdlSGFuZGxlcik7XG4gICAgICB3b3JrZXIucG9zdE1lc3NhZ2UocmVzb2x2ZU1lc3NhZ2UpO1xuICAgIH0pO1xuXG4gICAgY29uc3QgcmVzb2x1dGlvblRpbWUgPSBwZXJmb3JtYW5jZS5ub3coKSAtIHJlc29sdXRpb25TdGFydFRpbWU7XG5cbiAgICBpZiAodmVyYm9zZSkge1xuICAgICAgbG9nZ2VyPy5pbmZvKFxuICAgICAgICBgW3Jlc29sdmVDb21wb25lbnRzLmNsaWVudF0gQ29tcG9uZW50cyByZXNvbHZlZCBmb3Igcm91dGU6ICR7cm91dGV9IGluICR7cmVzb2x1dGlvblRpbWUudG9GaXhlZChcbiAgICAgICAgICAyXG4gICAgICAgICl9bXNgXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIEVtaXQgcmVzb2x1dGlvbiBtZXRyaWNzXG4gICAgaWYgKG9uTWV0cmljcykge1xuICAgICAgY29uc3QgbW9kdWxlUmVzb2x1dGlvbk1ldHJpYyA9IGNyZWF0ZU1vZHVsZVJlc29sdXRpb25NZXRyaWNzKHtcbiAgICAgICAgcm91dGUsXG4gICAgICAgIHdvcmtlclR5cGU6IFwicnNjXCIsXG4gICAgICAgIHJlc29sdXRpb25UaW1lLFxuICAgICAgICBmcm9tTWFpblRocmVhZDogZmFsc2UsXG4gICAgICAgIGZyb21Sc2NXb3JrZXI6IHRydWUsXG4gICAgICAgIGZyb21IdG1sV29ya2VyOiBmYWxzZSxcbiAgICAgICAgZGVzY3JpcHRpb246IGBDb21wb25lbnQgcmVzb2x1dGlvbiBmb3Igcm91dGUgJHtyb3V0ZX0gb24gUlNDIHdvcmtlcmAsXG4gICAgICB9KTtcbiAgICAgIG9uTWV0cmljcyhtb2R1bGVSZXNvbHV0aW9uTWV0cmljKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgcmVzb2x1dGlvblRpbWUsXG4gICAgfTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjb25zdCByZXNvbHV0aW9uVGltZSA9IHBlcmZvcm1hbmNlLm5vdygpIC0gcmVzb2x1dGlvblN0YXJ0VGltZTtcbiAgICBsb2dnZXI/LmVycm9yKFxuICAgICAgYFtyZXNvbHZlQ29tcG9uZW50cy5jbGllbnRdIEZhaWxlZCB0byByZXNvbHZlIGNvbXBvbmVudHMgZm9yIHJvdXRlICR7cm91dGV9OiAke2Vycm9yfWBcbiAgICApO1xuXG4gICAgLy8gRW1pdCBlcnJvciBtZXRyaWNzXG4gICAgaWYgKG9uTWV0cmljcykge1xuICAgICAgY29uc3QgbW9kdWxlUmVzb2x1dGlvbk1ldHJpYyA9IGNyZWF0ZU1vZHVsZVJlc29sdXRpb25NZXRyaWNzKHtcbiAgICAgICAgcm91dGUsXG4gICAgICAgIHdvcmtlclR5cGU6IFwicnNjXCIsXG4gICAgICAgIHJlc29sdXRpb25UaW1lLFxuICAgICAgICBmcm9tTWFpblRocmVhZDogZmFsc2UsXG4gICAgICAgIGZyb21Sc2NXb3JrZXI6IHRydWUsXG4gICAgICAgIGZyb21IdG1sV29ya2VyOiBmYWxzZSxcbiAgICAgICAgZGVzY3JpcHRpb246IGBDb21wb25lbnQgcmVzb2x1dGlvbiBmYWlsZWQgZm9yIHJvdXRlICR7cm91dGV9IG9uIFJTQyB3b3JrZXJgLFxuICAgICAgfSk7XG4gICAgICBvbk1ldHJpY3MobW9kdWxlUmVzb2x1dGlvbk1ldHJpYyk7XG4gICAgfVxuXG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbn1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7OztB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