UNPKG

vite-plugin-react-server

Version:
95 lines (92 loc) 12.4 kB
/** * 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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