vite-plugin-react-server
Version:
Vite plugin for React Server Components (RSC)
95 lines (92 loc) • 12.4 kB
JavaScript
/**
* vite-plugin-react-server
* Copyright (c) Nico Brinkkemper
* MIT License
*/
import { workerData } from 'node:worker_threads';
import { createCssProps } from '../../helpers/createCssProps.js';
import { relative } from 'node:path';
import { ReactDOMServer } from '../../vendor/vendor.server.js';
import { getModuleRef } from '../../helpers/moduleRefs.js';
const cssFiles = /* @__PURE__ */ new Map();
const moduleIds = /* @__PURE__ */ new Map();
const temporaryReferences = ReactDOMServer.createTemporaryReferenceSet();
const cachedComponentIds = /* @__PURE__ */ new Set();
const hmrState = /* @__PURE__ */ new Map();
if (workerData) {
if (workerData.hmrPort) {
workerData.hmrPort.on(
"message",
(msg) => {
if (msg.type === "HMR_UPDATE") {
const normalizedPath = relative(
workerData.userOptions?.projectRoot,
msg.path
);
hmrState.set(normalizedPath, {
timestamp: Date.now(),
invalidated: true,
routes: msg.routes || []
});
} else if (msg.type === "HMR_ACCEPT") {
const normalizedPath = relative(
workerData.userOptions?.projectRoot,
msg.path
);
hmrState.delete(normalizedPath);
}
}
);
}
} else {
throw new Error("This module must be run with workerData");
}
function addCssFileContent(id, code, userOptions) {
if (typeof code !== "string") {
throw new Error(
`Expected css to be loaded as a string, but got ${typeof code}`
);
}
cssFiles.set(
id,
createCssProps({
id,
code,
userOptions
})
);
}
function isModuleInvalidated(path) {
const state = hmrState.get(path);
return state?.invalidated || false;
}
function addModuleId(id, url) {
moduleIds.set(id, url);
}
function cacheComponent(id, component) {
const moduleRef = getModuleRef(id);
temporaryReferences.set(moduleRef, component);
cachedComponentIds.add(id);
}
function getCachedComponent(id) {
const moduleRef = getModuleRef(id);
return temporaryReferences.get(moduleRef);
}
function hasCachedComponent(id) {
const moduleRef = getModuleRef(id);
return temporaryReferences.has(moduleRef);
}
function clearCachedComponent(id) {
const moduleRef = getModuleRef(id);
temporaryReferences.delete(moduleRef);
cachedComponentIds.delete(id);
}
function clearAllCachedComponents() {
for (const id of cachedComponentIds) {
const moduleRef = getModuleRef(id);
temporaryReferences.delete(moduleRef);
}
cachedComponentIds.clear();
}
export { addCssFileContent, addModuleId, cacheComponent, clearAllCachedComponents, clearCachedComponent, cssFiles, getCachedComponent, hasCachedComponent, hmrState, isModuleInvalidated, moduleIds, temporaryReferences };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGUuc2VydmVyLmpzIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wbHVnaW4vd29ya2VyL3JzYy9zdGF0ZS5zZXJ2ZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgd29ya2VyRGF0YSB9IGZyb20gXCJub2RlOndvcmtlcl90aHJlYWRzXCI7XG5pbXBvcnQgeyBjcmVhdGVDc3NQcm9wcyB9IGZyb20gXCIuLi8uLi9oZWxwZXJzL2NyZWF0ZUNzc1Byb3BzLmpzXCI7XG5pbXBvcnQgdHlwZSB7IENzc0NvbnRlbnQsIFJlc29sdmVkVXNlck9wdGlvbnMsIEhtclN0YXRlIH0gZnJvbSBcIi4uLy4uL3R5cGVzLmpzXCI7XG5pbXBvcnQgdHlwZSB7IFBhc3NUaHJvdWdoIH0gZnJvbSBcIm5vZGU6c3RyZWFtXCI7XG5pbXBvcnQgeyByZWxhdGl2ZSB9IGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IFJlYWN0RE9NU2VydmVyIH0gZnJvbSBcIi4uLy4uL3ZlbmRvci92ZW5kb3Iuc2VydmVyLmpzXCI7XG5pbXBvcnQgeyBnZXRNb2R1bGVSZWYgfSBmcm9tIFwiLi4vLi4vaGVscGVycy9tb2R1bGVSZWZzLmpzXCI7XG5cbi8vIFRyYWNrIGFjdGl2ZSBSU0Mgc3RyZWFtc1xuZXhwb3J0IGNvbnN0IGFjdGl2ZVN0cmVhbXMgPSBuZXcgTWFwPHN0cmluZywgUGFzc1Rocm91Z2g+KCk7XG5cbi8vIFRyYWNrIENTUyBmaWxlc1xuZXhwb3J0IGNvbnN0IGNzc0ZpbGVzID0gbmV3IE1hcDxzdHJpbmcsIENzc0NvbnRlbnQ+KCk7XG5cbi8vIFRyYWNrIG1vZHVsZSBJRHNcbmV4cG9ydCBjb25zdCBtb2R1bGVJZHMgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpO1xuXG4vLyBUcmFjayByZXNvbHZlZCBjb21wb25lbnRzIGNhY2hlIHVzaW5nIFdlYWtNYXAgZm9yIGJldHRlciBtZW1vcnkgbWFuYWdlbWVudFxuZXhwb3J0IGNvbnN0IHRlbXBvcmFyeVJlZmVyZW5jZXMgPSBSZWFjdERPTVNlcnZlci5jcmVhdGVUZW1wb3JhcnlSZWZlcmVuY2VTZXQoKTtcblxuLy8gVHJhY2sgYWxsIGNhY2hlZCBjb21wb25lbnQgSURzIHNvIHdlIGNhbiBjbGVhciB0aGVtIG9uIEhNUlxuLy8gVGhpcyBpcyBuZWNlc3NhcnkgYmVjYXVzZSB0ZW1wb3JhcnlSZWZlcmVuY2VzIGRvZXNuJ3Qgc3VwcG9ydCBpdGVyYXRpb25cbmNvbnN0IGNhY2hlZENvbXBvbmVudElkcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG5leHBvcnQgY29uc3QgaG1yU3RhdGUgPSBuZXcgTWFwPHN0cmluZywgSG1yU3RhdGU+KCk7XG5cbmlmICh3b3JrZXJEYXRhKSB7XG4gIGlmICh3b3JrZXJEYXRhLmhtclBvcnQpIHtcbiAgICB3b3JrZXJEYXRhLmhtclBvcnQub24oXG4gICAgICBcIm1lc3NhZ2VcIixcbiAgICAgIChtc2c6IHsgdHlwZTogc3RyaW5nOyBwYXRoOiBzdHJpbmc7IHJvdXRlcz86IHN0cmluZ1tdIH0pID0+IHtcbiAgICAgICAgaWYgKG1zZy50eXBlID09PSBcIkhNUl9VUERBVEVcIikge1xuICAgICAgICAgIC8vIE5vcm1hbGl6ZSB0aGUgcGF0aCByZWxhdGl2ZSB0byBwcm9qZWN0IHJvb3RcbiAgICAgICAgICBjb25zdCBub3JtYWxpemVkUGF0aCA9IHJlbGF0aXZlKFxuICAgICAgICAgICAgd29ya2VyRGF0YS51c2VyT3B0aW9ucz8ucHJvamVjdFJvb3QsXG4gICAgICAgICAgICBtc2cucGF0aFxuICAgICAgICAgICk7XG4gICAgICAgICAgaG1yU3RhdGUuc2V0KG5vcm1hbGl6ZWRQYXRoLCB7XG4gICAgICAgICAgICB0aW1lc3RhbXA6IERhdGUubm93KCksXG4gICAgICAgICAgICBpbnZhbGlkYXRlZDogdHJ1ZSxcbiAgICAgICAgICAgIHJvdXRlczogbXNnLnJvdXRlcyB8fCBbXSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBcbiAgICAgICAgICAvLyBDUklUSUNBTDogQ2xlYXIgY29tcG9uZW50IGNhY2hlIGZvciBpbnZhbGlkYXRlZCBtb2R1bGVzXG4gICAgICAgICAgLy8gVGhpcyBlbnN1cmVzIGZpbGUgY2hhbmdlcyBhcmUgcGlja2VkIHVwIGltbWVkaWF0ZWx5XG4gICAgICAgICAgLy8gV2UgbmVlZCB0byBjbGVhciBhbGwgY2FjaGVkIGNvbXBvbmVudHMgdGhhdCBtaWdodCB1c2UgdGhpcyBmaWxlXG4gICAgICAgICAgLy8gU2luY2Ugd2UgY2FuJ3QgaXRlcmF0ZSB0ZW1wb3JhcnlSZWZlcmVuY2VzLCB3ZSdsbCByZWx5IG9uIHRoZVxuICAgICAgICAgIC8vIGNhY2hlIGNoZWNrcyBpbiBtZXNzYWdlSGFuZGxlciB0byBza2lwIGludmFsaWRhdGVkIG1vZHVsZXNcbiAgICAgICAgfSBlbHNlIGlmIChtc2cudHlwZSA9PT0gXCJITVJfQUNDRVBUXCIpIHtcbiAgICAgICAgICAvLyBOb3JtYWxpemUgdGhlIHBhdGggcmVsYXRpdmUgdG8gcHJvamVjdCByb290XG4gICAgICAgICAgY29uc3Qgbm9ybWFsaXplZFBhdGggPSByZWxhdGl2ZShcbiAgICAgICAgICAgIHdvcmtlckRhdGEudXNlck9wdGlvbnM/LnByb2plY3RSb290LFxuICAgICAgICAgICAgbXNnLnBhdGhcbiAgICAgICAgICApO1xuICAgICAgICAgIGhtclN0YXRlLmRlbGV0ZShub3JtYWxpemVkUGF0aCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICApO1xuICB9XG59IGVsc2Uge1xuICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIG1vZHVsZSBtdXN0IGJlIHJ1biB3aXRoIHdvcmtlckRhdGFcIik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRDc3NGaWxlQ29udGVudChcbiAgaWQ6IHN0cmluZyxcbiAgY29kZTogc3RyaW5nLFxuICB1c2VyT3B0aW9uczogUGljazxcbiAgICBSZXNvbHZlZFVzZXJPcHRpb25zLFxuICAgIHwgXCJwcm9qZWN0Um9vdFwiXG4gICAgfCBcIm1vZHVsZUJhc2VVUkxcIlxuICAgIHwgXCJtb2R1bGVCYXNlUGF0aFwiXG4gICAgfCBcIm1vZHVsZVJvb3RQYXRoXCJcbiAgICB8IFwiY3NzXCJcbiAgICB8IFwibm9ybWFsaXplclwiXG4gICAgfCBcIm1vZHVsZUlEXCJcbiAgICB8IFwicHVibGljT3JpZ2luXCJcbiAgPlxuKSB7XG4gIGlmICh0eXBlb2YgY29kZSAhPT0gXCJzdHJpbmdcIikge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBFeHBlY3RlZCBjc3MgdG8gYmUgbG9hZGVkIGFzIGEgc3RyaW5nLCBidXQgZ290ICR7dHlwZW9mIGNvZGV9YFxuICAgICk7XG4gIH1cbiAgY3NzRmlsZXMuc2V0KFxuICAgIGlkLFxuICAgIGNyZWF0ZUNzc1Byb3BzKHtcbiAgICAgIGlkLFxuICAgICAgY29kZSxcbiAgICAgIHVzZXJPcHRpb25zLFxuICAgIH0pXG4gICk7XG59XG5cbi8vIEhlbHBlciB0byBjaGVjayBpZiBhIG1vZHVsZSBpcyBpbnZhbGlkYXRlZFxuZXhwb3J0IGZ1bmN0aW9uIGlzTW9kdWxlSW52YWxpZGF0ZWQocGF0aDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGNvbnN0IHN0YXRlID0gaG1yU3RhdGUuZ2V0KHBhdGgpO1xuICByZXR1cm4gc3RhdGU/LmludmFsaWRhdGVkIHx8IGZhbHNlO1xufVxuXG4vLyBIZWxwZXIgdG8gY2xlYXIgSE1SIHN0YXRlIGZvciBhIG1vZHVsZVxuZXhwb3J0IGZ1bmN0aW9uIGNsZWFySG1yU3RhdGUocGF0aDogc3RyaW5nKTogdm9pZCB7XG4gIGhtclN0YXRlLmRlbGV0ZShwYXRoKTtcbn1cblxuLy8gSGVscGVyIHRvIGdldCBhbGwgaW52YWxpZGF0ZWQgbW9kdWxlc1xuZXhwb3J0IGZ1bmN0aW9uIGdldEludmFsaWRhdGVkTW9kdWxlcygpOiBzdHJpbmdbXSB7XG4gIHJldHVybiBBcnJheS5mcm9tKGhtclN0YXRlLmVudHJpZXMoKSlcbiAgICAuZmlsdGVyKChbLCBzdGF0ZV0pID0+IHN0YXRlLmludmFsaWRhdGVkKVxuICAgIC5tYXAoKFtwYXRoXSkgPT4gcGF0aCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRNb2R1bGVJZChpZDogc3RyaW5nLCB1cmw6IHN0cmluZykge1xuICBtb2R1bGVJZHMuc2V0KGlkLCB1cmwpO1xufVxuXG4vLyBIZWxwZXIgdG8gY2FjaGUgYSByZXNvbHZlZCBjb21wb25lbnRcbmV4cG9ydCBmdW5jdGlvbiBjYWNoZUNvbXBvbmVudChpZDogc3RyaW5nLCBjb21wb25lbnQ6IGFueSkge1xuICBjb25zdCBtb2R1bGVSZWYgPSBnZXRNb2R1bGVSZWYoaWQpO1xuICB0ZW1wb3JhcnlSZWZlcmVuY2VzLnNldChtb2R1bGVSZWYsIGNvbXBvbmVudCk7XG4gIC8vIFRyYWNrIHRoZSBJRCBzbyB3ZSBjYW4gY2xlYXIgaXQgbGF0ZXJcbiAgY2FjaGVkQ29tcG9uZW50SWRzLmFkZChpZCk7XG59XG5cbi8vIEhlbHBlciB0byBnZXQgYSBjYWNoZWQgY29tcG9uZW50XG5leHBvcnQgZnVuY3Rpb24gZ2V0Q2FjaGVkQ29tcG9uZW50KGlkOiBzdHJpbmcpOiBhbnkge1xuICBjb25zdCBtb2R1bGVSZWYgPSBnZXRNb2R1bGVSZWYoaWQpO1xuICByZXR1cm4gdGVtcG9yYXJ5UmVmZXJlbmNlcy5nZXQobW9kdWxlUmVmKTtcbn1cblxuLy8gSGVscGVyIHRvIGNoZWNrIGlmIGEgY29tcG9uZW50IGlzIGNhY2hlZFxuZXhwb3J0IGZ1bmN0aW9uIGhhc0NhY2hlZENvbXBvbmVudChpZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGNvbnN0IG1vZHVsZVJlZiA9IGdldE1vZHVsZVJlZihpZCk7XG4gIHJldHVybiB0ZW1wb3JhcnlSZWZlcmVuY2VzLmhhcyhtb2R1bGVSZWYpO1xufVxuXG4vLyBIZWxwZXIgdG8gY2xlYXIgYSBjYWNoZWQgY29tcG9uZW50XG5leHBvcnQgZnVuY3Rpb24gY2xlYXJDYWNoZWRDb21wb25lbnQoaWQ6IHN0cmluZyk6IHZvaWQge1xuICBjb25zdCBtb2R1bGVSZWYgPSBnZXRNb2R1bGVSZWYoaWQpO1xuICB0ZW1wb3JhcnlSZWZlcmVuY2VzLmRlbGV0ZShtb2R1bGVSZWYpO1xuICBjYWNoZWRDb21wb25lbnRJZHMuZGVsZXRlKGlkKTtcbn1cblxuLy8gSGVscGVyIHRvIGNsZWFyIGFsbCBjYWNoZWQgY29tcG9uZW50cyAoZm9yIEhNUilcbmV4cG9ydCBmdW5jdGlvbiBjbGVhckFsbENhY2hlZENvbXBvbmVudHMoKTogdm9pZCB7XG4gIC8vIENsZWFyIGFsbCB0cmFja2VkIGNvbXBvbmVudCBJRHMgZnJvbSB0ZW1wb3JhcnlSZWZlcmVuY2VzXG4gIGZvciAoY29uc3QgaWQgb2YgY2FjaGVkQ29tcG9uZW50SWRzKSB7XG4gICAgY29uc3QgbW9kdWxlUmVmID0gZ2V0TW9kdWxlUmVmKGlkKTtcbiAgICB0ZW1wb3JhcnlSZWZlcmVuY2VzLmRlbGV0ZShtb2R1bGVSZWYpO1xuICB9XG4gIGNhY2hlZENvbXBvbmVudElkcy5jbGVhcigpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TW9kdWxlSWQoaWQ6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBtb2R1bGVJZHMuZ2V0KGlkKTtcbn1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQVlhLE1BQUEsUUFBQSx1QkFBZSxHQUF3QjtBQUd2QyxNQUFBLFNBQUEsdUJBQWdCLEdBQW9CO0FBR3BDLE1BQUEsbUJBQUEsR0FBc0IsZUFBZSwyQkFBNEI7QUFJOUUsTUFBTSxrQkFBQSx1QkFBeUIsR0FBWSxFQUFBO0FBRTlCLE1BQUEsUUFBQSx1QkFBZSxHQUFzQjtBQUVsRCxJQUFJLFVBQVksRUFBQTtBQUNkLEVBQUEsSUFBSSxXQUFXLE9BQVMsRUFBQTtBQUN0QixJQUFBLFVBQUEsQ0FBVyxPQUFRLENBQUEsRUFBQTtBQUFBLE1BQ2pCLFNBQUE7QUFBQSxNQUNBLENBQUMsR0FBMkQsS0FBQTtBQUMxRCxRQUFJLElBQUEsR0FBQSxDQUFJLFNBQVMsWUFBYyxFQUFBO0FBRTdCLFVBQUEsTUFBTSxjQUFpQixHQUFBLFFB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