vite-plugin-react-server 0.3.0 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/README.md +73 -40
  2. package/dist/assertServerCondition.d.ts +2 -0
  3. package/dist/assertServerCondition.d.ts.map +1 -0
  4. package/dist/bin/patch.js +51 -0
  5. package/dist/bin/patch.js.map +1 -0
  6. package/dist/build/createBuildConfig.d.ts +7 -6
  7. package/dist/build/createBuildConfig.d.ts.map +1 -1
  8. package/dist/build/mergeInputs.d.ts +5 -0
  9. package/dist/build/mergeInputs.d.ts.map +1 -0
  10. package/dist/helpers/inputNormalizer.d.ts +6 -0
  11. package/dist/helpers/inputNormalizer.d.ts.map +1 -0
  12. package/dist/helpers/normalizedRelativePath.d.ts +3 -1
  13. package/dist/helpers/normalizedRelativePath.d.ts.map +1 -1
  14. package/dist/helpers/tryManifest.d.ts +10 -3
  15. package/dist/helpers/tryManifest.d.ts.map +1 -1
  16. package/dist/html/createPageLoader.d.ts.map +1 -1
  17. package/dist/index.js +1 -1
  18. package/dist/options.d.ts +13 -8
  19. package/dist/options.d.ts.map +1 -1
  20. package/dist/plugin.d.ts +2 -7
  21. package/dist/plugin.d.ts.map +1 -1
  22. package/dist/react-client/plugin.js +1 -1
  23. package/dist/react-server/plugin.d.ts.map +1 -1
  24. package/dist/react-server/plugin.js +108 -61
  25. package/dist/react-server/plugin.js.map +1 -1
  26. package/dist/src/build/createBuildConfig.js +44 -0
  27. package/dist/src/build/createBuildConfig.js.map +1 -0
  28. package/dist/src/build/mergeInputs.js +16 -0
  29. package/dist/src/build/mergeInputs.js.map +1 -0
  30. package/dist/src/checkFilesExist.js.map +1 -0
  31. package/dist/src/collect-css-manifest.js.map +1 -0
  32. package/dist/src/components.js.map +1 -0
  33. package/dist/src/getEnv.js.map +1 -0
  34. package/dist/src/helpers/inputNormalizer.js +11 -0
  35. package/dist/src/helpers/inputNormalizer.js.map +1 -0
  36. package/dist/src/helpers/normalizedRelativePath.js +34 -0
  37. package/dist/src/helpers/normalizedRelativePath.js.map +1 -0
  38. package/dist/src/helpers/tryManifest.js +27 -0
  39. package/dist/src/helpers/tryManifest.js.map +1 -0
  40. package/dist/{html → src/html}/createPageLoader.js +3 -1
  41. package/dist/src/html/createPageLoader.js.map +1 -0
  42. package/dist/{options.js → src/options.js} +80 -24
  43. package/dist/src/options.js.map +1 -0
  44. package/dist/src/react-server/createHandler.js.map +1 -0
  45. package/dist/src/react-server/createRscStream.js.map +1 -0
  46. package/dist/src/resolvePage.js.map +1 -0
  47. package/dist/src/resolveProps.js.map +1 -0
  48. package/dist/src/worker/createHtmlStream.js +62 -0
  49. package/dist/src/worker/createHtmlStream.js.map +1 -0
  50. package/dist/{worker → src/worker}/createWorker.js +9 -8
  51. package/dist/src/worker/createWorker.js.map +1 -0
  52. package/dist/src/worker/renderPages.js.map +1 -0
  53. package/dist/types.d.ts +7 -2
  54. package/dist/types.d.ts.map +1 -1
  55. package/dist/worker/createWorker.d.ts +8 -1
  56. package/dist/worker/createWorker.d.ts.map +1 -1
  57. package/dist/worker/loader.js +7 -0
  58. package/dist/worker/loader.js.map +1 -0
  59. package/dist/worker/worker.js +112 -0
  60. package/dist/worker/worker.js.map +1 -0
  61. package/package.json +108 -111
  62. package/patches/react-server-dom-esm+0.0.1.patch +14519 -0
  63. package/src/assertServerCondition.ts +13 -0
  64. package/src/build/createBuildConfig.ts +27 -44
  65. package/src/build/mergeInputs.ts +42 -0
  66. package/src/helpers/inputNormalizer.ts +22 -0
  67. package/src/helpers/normalizedRelativePath.ts +25 -25
  68. package/src/helpers/tryManifest.ts +19 -5
  69. package/src/html/createPageLoader.ts +2 -0
  70. package/src/options.ts +119 -47
  71. package/src/plugin.ts +4 -30
  72. package/src/react-server/createSsrHandler.ts +1 -1
  73. package/src/react-server/plugin.ts +116 -56
  74. package/src/types.ts +19 -1
  75. package/src/worker/createWorker.ts +12 -7
  76. package/tsconfig.json +2 -0
  77. package/dist/build/createBuildConfig.js +0 -55
  78. package/dist/build/createBuildConfig.js.map +0 -1
  79. package/dist/checkFilesExist.js.map +0 -1
  80. package/dist/collect-css-manifest.js.map +0 -1
  81. package/dist/components.js.map +0 -1
  82. package/dist/getEnv.js.map +0 -1
  83. package/dist/helpers/normalizedRelativePath.js +0 -31
  84. package/dist/helpers/normalizedRelativePath.js.map +0 -1
  85. package/dist/html/createPageLoader.js.map +0 -1
  86. package/dist/options.js.map +0 -1
  87. package/dist/plugin.js +0 -31
  88. package/dist/plugin.js.map +0 -1
  89. package/dist/react-server/createHandler.js.map +0 -1
  90. package/dist/react-server/createRscStream.js.map +0 -1
  91. package/dist/resolvePage.js.map +0 -1
  92. package/dist/resolveProps.js.map +0 -1
  93. package/dist/transformer/index.js +0 -54
  94. package/dist/transformer/index.js.map +0 -1
  95. package/dist/transformer/preserveDirectives.js +0 -72
  96. package/dist/transformer/preserveDirectives.js.map +0 -1
  97. package/dist/transformer/transformer.js +0 -80
  98. package/dist/transformer/transformer.js.map +0 -1
  99. package/dist/worker/createWorker.js.map +0 -1
  100. package/dist/worker/renderPages.js.map +0 -1
  101. /package/dist/{checkFilesExist.js → src/checkFilesExist.js} +0 -0
  102. /package/dist/{collect-css-manifest.js → src/collect-css-manifest.js} +0 -0
  103. /package/dist/{components.js → src/components.js} +0 -0
  104. /package/dist/{getEnv.js → src/getEnv.js} +0 -0
  105. /package/dist/{react-server → src/react-server}/createHandler.js +0 -0
  106. /package/dist/{react-server → src/react-server}/createRscStream.js +0 -0
  107. /package/dist/{resolvePage.js → src/resolvePage.js} +0 -0
  108. /package/dist/{resolveProps.js → src/resolveProps.js} +0 -0
  109. /package/dist/{worker → src/worker}/renderPages.js +0 -0
@@ -1,24 +1,26 @@
1
- import { readFileSync } from "node:fs";
2
- import { resolve } from "node:path";
1
+ import "node:fs";
2
+ import { relative, join, resolve } from "node:path";
3
3
  import { performance } from "node:perf_hooks";
4
4
  import "node:worker_threads";
5
5
  import { createLogger } from "vite";
6
- import { createBuildConfig } from "../build/createBuildConfig.js";
7
- import { checkFilesExist } from "../checkFilesExist.js";
8
- import { getEnv } from "../getEnv.js";
9
- import { createPageLoader } from "../html/createPageLoader.js";
10
- import { renderPages } from "../worker/renderPages.js";
11
- import { resolveOptions, resolvePages, resolveUserConfig } from "../options.js";
12
- import { createWorker } from "../worker/createWorker.js";
13
- import { createHandler } from "./createHandler.js";
14
- let pageSet;
15
- let pageMap;
6
+ import { createBuildConfig } from "../src/build/createBuildConfig.js";
7
+ import { checkFilesExist } from "../src/checkFilesExist.js";
8
+ import { getEnv } from "../src/getEnv.js";
9
+ import { createPageLoader } from "../src/html/createPageLoader.js";
10
+ import { renderPages } from "../src/worker/renderPages.js";
11
+ import { resolveOptions, resolvePages, resolveUserConfig } from "../src/options.js";
12
+ import { createWorker } from "../src/worker/createWorker.js";
13
+ import { createHandler } from "../src/react-server/createHandler.js";
14
+ import { tryManifest } from "../src/helpers/tryManifest.js";
15
+ let files;
16
+ let env;
16
17
  let worker;
17
18
  let config;
18
19
  let cssModules = /* @__PURE__ */ new Set();
19
20
  let clientComponents = /* @__PURE__ */ new Map();
20
21
  let define;
21
22
  let buildCssFiles = /* @__PURE__ */ new Set();
23
+ let root = process.cwd();
22
24
  async function reactStreamPlugin(options = {}) {
23
25
  const timing = {
24
26
  start: performance.now()
@@ -92,7 +94,7 @@ async function reactStreamPlugin(options = {}) {
92
94
  propsExportName: userOptions.propsExportName,
93
95
  moduleBase: userOptions.moduleBase,
94
96
  moduleBasePath: userOptions.moduleBasePath,
95
- projectRoot: server.config.root
97
+ projectRoot: server.config.root ?? userOptions.projectRoot
96
98
  },
97
99
  {
98
100
  cssFiles: Array.from(cssModules),
@@ -116,9 +118,17 @@ async function reactStreamPlugin(options = {}) {
116
118
  throw resolvedPages.error;
117
119
  }
118
120
  const { pages } = resolvedPages;
121
+ env = getEnv(config2, configEnv);
122
+ define = env.define;
123
+ files = await checkFilesExist(
124
+ pages,
125
+ userOptions,
126
+ config2.root ?? userOptions.projectRoot
127
+ );
128
+ root = config2.root ?? userOptions.projectRoot;
119
129
  const resolvedConfig = resolveUserConfig(
120
130
  "react-server",
121
- pages,
131
+ [...pages, userOptions.workerPath, userOptions.loaderPath],
122
132
  config2,
123
133
  configEnv,
124
134
  userOptions
@@ -127,22 +137,45 @@ async function reactStreamPlugin(options = {}) {
127
137
  throw resolvedConfig.error;
128
138
  }
129
139
  const { userConfig } = resolvedConfig;
130
- const envResult = getEnv(userConfig, configEnv);
131
- const files = await checkFilesExist(pages, userOptions, userConfig.root);
132
- pageSet = files.pageSet;
133
- pageMap = files.pageMap;
134
- define = envResult.define;
135
- const entries = Array.from(
136
- (/* @__PURE__ */ new Set([
137
- ...Array.from(files.pageSet.values()),
138
- ...Array.from(files.propsSet.values())
139
- ])).values()
140
+ console.log({
141
+ worker: userOptions.workerPath,
142
+ loader: userOptions.loaderPath
143
+ });
144
+ const entriesClient = Object.fromEntries([
145
+ ...Array.from(files.pageMap.entries()).map(([key, value]) => [
146
+ key,
147
+ relative(root, value)
148
+ ]),
149
+ ...Array.from(files.propsMap.entries()).map(([key, value]) => [
150
+ key,
151
+ relative(root, value)
152
+ ])
153
+ ]);
154
+ const entriesResolved = Object.fromEntries(
155
+ Object.entries(entriesClient).map(
156
+ ([key, entry]) => {
157
+ if (typeof entry !== "string") {
158
+ return [key, entry];
159
+ }
160
+ return [key, entry];
161
+ }
162
+ )
140
163
  );
164
+ const serverEntries = {
165
+ ...entriesResolved,
166
+ ["worker/worker"]: userOptions.workerPath,
167
+ ["worker/loader"]: userOptions.loaderPath
168
+ };
141
169
  const buildConfig = createBuildConfig({
142
- root: config2.root ?? process.cwd(),
143
- base: config2.base ?? envResult.publicUrl,
144
- outDir: config2.build?.outDir ?? "dist/server",
145
- entries
170
+ input: serverEntries,
171
+ userConfig,
172
+ userOptions,
173
+ root,
174
+ moduleBaseExceptions: [
175
+ userOptions.workerPath,
176
+ userOptions.loaderPath,
177
+ ...userOptions.moduleBaseExceptions
178
+ ]
146
179
  });
147
180
  return {
148
181
  ...buildConfig,
@@ -156,39 +189,53 @@ async function reactStreamPlugin(options = {}) {
156
189
  async closeBundle() {
157
190
  if (!config) return;
158
191
  console.log("RSC CLOSE BUNDLE CALLED");
159
- if (!pageSet?.size) return;
192
+ if (!files.pageSet.size) return;
160
193
  timing.renderStart = performance.now();
161
194
  try {
162
- const manifest = JSON.parse(
163
- readFileSync(
164
- resolve(
165
- config.root,
166
- config.build.outDir,
167
- ".vite",
168
- "manifest.json"
169
- ),
170
- "utf-8"
171
- )
172
- );
173
- const clientManifest = JSON.parse(
174
- readFileSync(
175
- resolve(
176
- config.root,
177
- userOptions.build.client,
178
- ".vite",
179
- "manifest.json"
180
- ),
181
- "utf-8"
182
- )
183
- );
184
- if (!worker)
185
- worker = await createWorker(
186
- config.root,
187
- config.build.outDir,
188
- "worker.js",
189
- process.env["NODE_ENV"] === "development" ? "development" : "production"
195
+ const resolvedServerManifest = tryManifest({
196
+ root,
197
+ outDir: userOptions.build.server,
198
+ ssrManifest: false
199
+ });
200
+ if (resolvedServerManifest.type === "error") {
201
+ console.error(
202
+ "[vite-react-stream] Server Build failed, can not build without a server manifest. Please set `manifest: true` in your vite config.",
203
+ resolvedServerManifest.error
204
+ );
205
+ return;
206
+ }
207
+ const { manifest: serverManifest } = resolvedServerManifest;
208
+ const workerPath = serverManifest[userOptions.workerPath]?.file ?? serverManifest[relative(root, userOptions.workerPath)]?.file ?? serverManifest[relative(
209
+ join(root, userOptions.build.server),
210
+ userOptions.workerPath
211
+ )]?.file;
212
+ if (!workerPath) {
213
+ console.log(serverManifest, userOptions.build.server);
214
+ throw new Error(
215
+ `Worker path not found in server manifest, tried: ${userOptions.workerPath}, ${relative(root, userOptions.workerPath)}, ${join(root, userOptions.build.server, userOptions.workerPath)}`
190
216
  );
191
- const routes = Array.from(pageMap.keys());
217
+ }
218
+ console.log("workerPath", workerPath);
219
+ const resolvedClientManifest = tryManifest({
220
+ root,
221
+ outDir: userOptions.build.client,
222
+ ssrManifest: false
223
+ });
224
+ if (resolvedClientManifest.type === "error") {
225
+ console.error(
226
+ "[vite-react-stream] Server Build failed, can not build without a client manifest. Make sure to run the client build before the server build and set `manifest: true` in your vite config.",
227
+ resolvedClientManifest.error
228
+ );
229
+ return;
230
+ }
231
+ const { manifest: clientManifest } = resolvedClientManifest;
232
+ if (!worker)
233
+ worker = await createWorker({
234
+ workerPath: join(root, userOptions.build.server, workerPath),
235
+ nodePath: process.env["NODE_PATH"] ?? resolve(root, "node_modules"),
236
+ mode: process.env["NODE_ENV"] === "development" ? "development" : "production"
237
+ });
238
+ const routes = Array.from(files.pageMap.keys());
192
239
  const indexEntry = clientManifest["index.html"];
193
240
  if (!indexEntry) {
194
241
  throw new Error("root /index.html not found");
@@ -209,19 +256,19 @@ async function reactStreamPlugin(options = {}) {
209
256
  moduleBase: userOptions.moduleBase,
210
257
  moduleBasePath: userOptions.moduleBasePath,
211
258
  moduleBaseURL: userOptions.moduleBaseURL,
212
- projectRoot: config.root
259
+ projectRoot: root
213
260
  },
214
261
  worker,
215
262
  manifest: clientManifest,
216
263
  loader: createPageLoader({
217
- manifest,
264
+ manifest: clientManifest,
218
265
  root: config.root,
219
266
  outDir: config.build.outDir,
220
267
  moduleBase: userOptions.moduleBase,
221
268
  alwaysRegisterServer: false,
222
269
  alwaysRegisterClient: false,
223
270
  registerServer: [],
224
- registerClient: Object.keys(clientManifest).filter(
271
+ registerClient: Object.keys(resolvedClientManifest).filter(
225
272
  (key) => key.endsWith(".client.tsx") && clientManifest[key].isEntry
226
273
  )
227
274
  }),
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sources":["../../src/react-server/plugin.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport type { ServerResponse } from \"node:http\";\nimport { resolve as resolvePath } from \"node:path\";\nimport { performance } from \"node:perf_hooks\";\nimport { Worker } from \"node:worker_threads\";\nimport type { Plugin as RollupPlugin } from \"rollup\";\nimport type { Manifest, Plugin as VitePlugin } from \"vite\";\nimport {\n createLogger,\n type ResolvedConfig,\n type UserConfig,\n type ViteDevServer,\n} from \"vite\";\nimport { createBuildConfig } from \"../build/createBuildConfig.js\";\nimport { checkFilesExist } from \"../checkFilesExist.js\";\nimport { getEnv } from \"../getEnv.js\";\nimport { createPageLoader } from \"../html/createPageLoader.js\";\nimport { renderPages } from \"../worker/renderPages.js\";\nimport { resolveOptions, resolvePages, resolveUserConfig } from \"../options.js\";\nimport type { BuildTiming, ReactStreamPluginMeta } from \"../types.js\";\nimport { type StreamPluginOptions } from \"../types.js\";\nimport { createWorker } from \"../worker/createWorker.js\";\nimport { createHandler } from \"./createHandler.js\";\n\nlet pageSet: Set<string>;\nlet pageMap: Map<string, string>;\nlet worker: Worker;\nlet config: ResolvedConfig;\nlet cssModules = new Set<string>();\nlet clientComponents = new Map<string, string>();\nlet define: Record<string, string>;\nlet buildCssFiles = new Set<string>();\n\ninterface BuildStats {\n htmlFiles: number;\n clientComponents: number;\n cssFiles: number;\n totalRoutes: number;\n timing: {\n config: number;\n build: number;\n render: number;\n total: number;\n };\n}\n\nexport async function reactStreamPlugin(\n options: StreamPluginOptions = {} as StreamPluginOptions\n): Promise<VitePlugin & RollupPlugin & { meta: ReactStreamPluginMeta }> {\n const timing: BuildTiming = {\n start: performance.now(),\n };\n const resolvedOptions = resolveOptions(options);\n if (resolvedOptions.type === \"error\") {\n console.error(\n \"[vite-react-stream:server] Error resolving userOptions. Please check your userOptions.\"\n );\n throw resolvedOptions.error;\n }\n const { userOptions } = resolvedOptions;\n return {\n name: \"vite:react-stream\",\n meta: {\n timing,\n } as ReactStreamPluginMeta,\n api: {\n addCssFile(path: string) {\n buildCssFiles.add(path);\n },\n },\n configResolved(resolvedConfig) {\n if (resolvedConfig.command === \"build\") {\n timing.configResolved = performance.now();\n console.log(\"[vite-react-stream] Starting build...\");\n }\n config = resolvedConfig;\n },\n async configureServer(server: ViteDevServer) {\n if (server.config.root) {\n console.log(\n \"[vite-react-stream] Root dir changed\",\n server.config.root,\n server.config.root\n );\n }\n\n const activeStreams = new Set<ServerResponse>();\n\n // Handle Vite server restarts\n server.ws.on(\"restart\", (path) => {\n console.log(\n \"[vite-react-stream] 🔧 Plugin changed, preparing for restart:\",\n path\n );\n\n // Close streams with restart message\n for (const res of activeStreams) {\n res.writeHead(503, {\n \"Content-Type\": \"text/x-component\",\n \"Retry-After\": \"1\",\n });\n res.end('{\"error\":\"Server restarting...\"}');\n }\n activeStreams.clear();\n });\n\n server.ws.on(\"connection\", (socket, req) => {\n console.log(\"[vite-react-stream] hooking up ws connection\");\n });\n\n server.ws.on(\"listening\", () => {\n console.log(\"[vite-react-stream] hooking up ws listening\");\n });\n\n server.middlewares.use(async (req, res, next) => {\n if (req.headers.accept !== \"text/x-component\") return next();\n console.log(\"[vite-react-stream] middleware called\");\n try {\n const handler = await createHandler(\n req.url ?? \"\",\n {\n Page: userOptions.Page,\n props: userOptions.props,\n build: userOptions.build,\n Html: ({ children }) => children,\n pageExportName: userOptions.pageExportName,\n propsExportName: userOptions.propsExportName,\n moduleBase: userOptions.moduleBase,\n moduleBasePath: userOptions.moduleBasePath,\n projectRoot: server.config.root,\n },\n {\n cssFiles: Array.from(cssModules),\n logger: createLogger(),\n loader: server.ssrLoadModule,\n moduleGraph: server.moduleGraph,\n }\n );\n handler?.stream?.pipe(res);\n } finally {\n res.on(\"close\", () => {\n console.log(\"[vite-react-stream] ➖ Stream closed for:\", req.url);\n activeStreams.delete(res);\n });\n }\n });\n },\n\n async config(config, configEnv): Promise<UserConfig> {\n const resolvedPages = await resolvePages(userOptions.build.pages);\n if(resolvedPages.type === 'error') {\n throw resolvedPages.error;\n }\n const { pages } = resolvedPages;\n const resolvedConfig = resolveUserConfig(\n \"react-server\",\n pages,\n config,\n configEnv,\n userOptions\n );\n if(resolvedConfig.type === \"error\") {\n throw resolvedConfig.error;\n }\n const { userConfig } = resolvedConfig;\n\n const envResult = getEnv(userConfig, configEnv);\n const files = await checkFilesExist(pages, userOptions, userConfig.root);\n pageSet = files.pageSet;\n pageMap = files.pageMap;\n define = envResult.define;\n const entries = Array.from(\n new Set([\n ...Array.from(files.pageSet.values()),\n ...Array.from(files.propsSet.values()),\n ]).values()\n );\n\n const buildConfig = createBuildConfig({\n root: config.root ?? process.cwd(),\n base: config.base ?? envResult.publicUrl,\n outDir: config.build?.outDir ?? \"dist/server\",\n entries,\n });\n return {\n ...buildConfig,\n define,\n plugins: config.plugins,\n };\n },\n async buildStart() {\n timing.buildStart = performance.now();\n },\n async closeBundle() {\n if(!config) return;\n console.log(\"RSC CLOSE BUNDLE CALLED\");\n if (!pageSet?.size) return;\n timing.renderStart = performance.now();\n\n try {\n const manifest = JSON.parse(\n readFileSync(\n resolvePath(\n config.root,\n config.build.outDir,\n \".vite\",\n \"manifest.json\"\n ),\n \"utf-8\"\n )\n ) as Manifest;\n const clientManifest = JSON.parse(\n readFileSync(\n resolvePath(\n config.root,\n userOptions.build.client,\n \".vite\",\n \"manifest.json\"\n ),\n \"utf-8\"\n )\n ) as Manifest;\n // Create a single worker for all routes\n if (!worker)\n worker = await createWorker(\n config.root,\n config.build.outDir,\n \"worker.js\",\n process.env[\"NODE_ENV\"] === \"development\" ? \"development\" : \"production\"\n );\n // this is based on the user config - the routes should lead to a page and props but the rendering is agnostic of that\n const routes = Array.from(pageMap.keys());\n const indexEntry = clientManifest[\"index.html\"];\n if (!indexEntry) {\n throw new Error(\"root /index.html not found\");\n }\n await renderPages(routes, {\n pipableStreamOptions: {\n bootstrapModules: [\"/\" + indexEntry.file],\n },\n outDir: config.build.outDir,\n clientCss: indexEntry.css?.map((css) => \"/\" + css) ?? [],\n pluginOptions: {\n Page: userOptions.Page,\n props: userOptions.props,\n build: userOptions.build,\n Html: userOptions.Html,\n pageExportName: userOptions.pageExportName,\n propsExportName: userOptions.propsExportName,\n moduleBase: userOptions.moduleBase,\n moduleBasePath: userOptions.moduleBasePath,\n moduleBaseURL: userOptions.moduleBaseURL,\n projectRoot: config.root,\n },\n worker: worker,\n manifest: clientManifest as Manifest,\n loader: createPageLoader({\n manifest,\n root: config.root,\n outDir: config.build.outDir,\n moduleBase: userOptions.moduleBase,\n alwaysRegisterServer: false,\n alwaysRegisterClient: false,\n registerServer: [],\n registerClient: Object.keys(clientManifest).filter(\n (key) =>\n key.endsWith(\".client.tsx\") && clientManifest[key].isEntry\n ),\n }),\n onCssFile: (path) => buildCssFiles.add(path),\n });\n console.log(\"[vite-react-stream] Render complete\");\n console.log(\"[vite-react-stream] Terminating worker\");\n if (worker) await worker.terminate();\n\n timing.renderEnd = performance.now();\n timing.total = (timing.renderEnd - timing.start) / 1000;\n\n // Collect stats\n const stats: BuildStats = {\n htmlFiles: routes.length,\n clientComponents: clientComponents.size,\n cssFiles: cssModules.size,\n totalRoutes: routes.length,\n timing: {\n config: ((timing.configResolved ?? 0) - timing.start) / 1000,\n build:\n ((timing.buildStart ?? 0) - (timing.configResolved ?? 0)) / 1000,\n render:\n ((timing.renderEnd ?? 0) - (timing.renderStart ?? 0)) / 1000,\n total: (timing.renderEnd ?? 0 - timing.start) / 1000,\n },\n };\n\n // Format duration helper\n const formatDuration = (seconds: number) => {\n if (seconds < 0.001) {\n return `${(seconds * 1000000).toFixed(0)}μs`;\n }\n if (seconds < 1) {\n return `${(seconds * 1000).toFixed(0)}ms`;\n }\n return `${seconds.toFixed(2)}s`;\n };\n\n console.log(\"\\n[vite-react-stream] Build Summary:\");\n console.log(\"─\".repeat(50));\n console.log(`📄 Generated ${stats.htmlFiles} HTML files`);\n console.log(`🎯 Processed ${stats.clientComponents} client components`);\n console.log(`🎨 Included ${stats.cssFiles} CSS files`);\n console.log(`🛣️ Total routes: ${stats.totalRoutes}`);\n console.log(\"─\".repeat(50));\n console.log(\"⏱️ Timing:\");\n console.log(` Config: ${formatDuration(stats.timing.config)}`);\n console.log(` Build: ${formatDuration(stats.timing.build)}`);\n console.log(` Render: ${formatDuration(stats.timing.render)}`);\n console.log(\" \".repeat(12));\n console.log(` Total: ${formatDuration(stats.timing.total)}`);\n console.log(\"─\".repeat(50));\n } catch (error) {\n console.error(\"[vite-react-stream] Build failed:\", error);\n throw error;\n }\n },\n async buildEnd(error) {\n if (error) {\n console.error(\"[vite-react-stream] Build error:\", error);\n }\n if (worker) await worker.terminate();\n },\n handleHotUpdate({ file }) {\n if (file.endsWith(\".css\")) {\n cssModules.add(file);\n }\n },\n transform(code: string, id: string) {\n if (\n (id.includes(\".client\") ||\n code.startsWith('\"use client\"') ||\n code.startsWith(\"use client\")) &&\n !id.includes(\"node_modules\")\n ) {\n console.log(\"[vite-react-stream] Client component added\", id);\n clientComponents.set(id, code);\n }\n return { code };\n },\n };\n}\n"],"names":["config","resolvePath"],"mappings":"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"}
1
+ {"version":3,"file":"plugin.js","sources":["../../src/react-server/plugin.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport type { ServerResponse } from \"node:http\";\nimport { join, relative, resolve, resolve as resolvePath } from \"node:path\";\nimport { performance } from \"node:perf_hooks\";\nimport { Worker } from \"node:worker_threads\";\nimport type { Plugin as RollupPlugin } from \"rollup\";\nimport type { Manifest, Plugin as VitePlugin } from \"vite\";\nimport {\n createLogger,\n type ResolvedConfig,\n type UserConfig,\n type ViteDevServer,\n} from \"vite\";\nimport { createBuildConfig } from \"../build/createBuildConfig.js\";\nimport { checkFilesExist } from \"../checkFilesExist.js\";\nimport { getEnv } from \"../getEnv.js\";\nimport { createPageLoader } from \"../html/createPageLoader.js\";\nimport { renderPages } from \"../worker/renderPages.js\";\nimport { resolveOptions, resolvePages, resolveUserConfig } from \"../options.js\";\nimport type { BuildTiming, ReactStreamPluginMeta } from \"../types.js\";\nimport { type StreamPluginOptions } from \"../types.js\";\nimport { createWorker } from \"../worker/createWorker.js\";\nimport { createHandler } from \"./createHandler.js\";\nimport { tryManifest } from \"../helpers/tryManifest.js\";\nimport { createNormalizedRelativePath } from \"../helpers/normalizedRelativePath.js\";\n\nlet files: Awaited<ReturnType<typeof checkFilesExist>>;\nlet env: Awaited<ReturnType<typeof getEnv>>;\nlet worker: Worker;\nlet config: ResolvedConfig;\nlet cssModules = new Set<string>();\nlet clientComponents = new Map<string, string>();\nlet define: Record<string, string>;\nlet buildCssFiles = new Set<string>();\nlet root: string = process.cwd();\n\ninterface BuildStats {\n htmlFiles: number;\n clientComponents: number;\n cssFiles: number;\n totalRoutes: number;\n timing: {\n config: number;\n build: number;\n render: number;\n total: number;\n };\n}\n\nexport async function reactStreamPlugin(\n options: StreamPluginOptions = {} as StreamPluginOptions\n): Promise<VitePlugin & RollupPlugin & { meta: ReactStreamPluginMeta }> {\n const timing: BuildTiming = {\n start: performance.now(),\n };\n const resolvedOptions = resolveOptions(options);\n if (resolvedOptions.type === \"error\") {\n console.error(\n \"[vite-react-stream:server] Error resolving userOptions. Please check your userOptions.\"\n );\n throw resolvedOptions.error;\n }\n const { userOptions } = resolvedOptions;\n return {\n name: \"vite:react-stream\",\n meta: {\n timing,\n } as ReactStreamPluginMeta,\n api: {\n addCssFile(path: string) {\n buildCssFiles.add(path);\n },\n },\n configResolved(resolvedConfig) {\n if (resolvedConfig.command === \"build\") {\n timing.configResolved = performance.now();\n console.log(\"[vite-react-stream] Starting build...\");\n }\n config = resolvedConfig;\n },\n async configureServer(server: ViteDevServer) {\n if (server.config.root) {\n console.log(\n \"[vite-react-stream] Root dir changed\",\n server.config.root,\n server.config.root\n );\n }\n\n const activeStreams = new Set<ServerResponse>();\n\n // Handle Vite server restarts\n server.ws.on(\"restart\", (path) => {\n console.log(\n \"[vite-react-stream] 🔧 Plugin changed, preparing for restart:\",\n path\n );\n\n // Close streams with restart message\n for (const res of activeStreams) {\n res.writeHead(503, {\n \"Content-Type\": \"text/x-component\",\n \"Retry-After\": \"1\",\n });\n res.end('{\"error\":\"Server restarting...\"}');\n }\n activeStreams.clear();\n });\n\n server.ws.on(\"connection\", (socket, req) => {\n console.log(\"[vite-react-stream] hooking up ws connection\");\n });\n\n server.ws.on(\"listening\", () => {\n console.log(\"[vite-react-stream] hooking up ws listening\");\n });\n\n server.middlewares.use(async (req, res, next) => {\n if (req.headers.accept !== \"text/x-component\") return next();\n console.log(\"[vite-react-stream] middleware called\");\n try {\n const handler = await createHandler(\n req.url ?? \"\",\n {\n Page: userOptions.Page,\n props: userOptions.props,\n build: userOptions.build,\n Html: ({ children }) => children,\n pageExportName: userOptions.pageExportName,\n propsExportName: userOptions.propsExportName,\n moduleBase: userOptions.moduleBase,\n moduleBasePath: userOptions.moduleBasePath,\n projectRoot: server.config.root ?? userOptions.projectRoot,\n },\n {\n cssFiles: Array.from(cssModules),\n logger: createLogger(),\n loader: server.ssrLoadModule,\n moduleGraph: server.moduleGraph,\n }\n );\n handler?.stream?.pipe(res);\n } finally {\n res.on(\"close\", () => {\n console.log(\"[vite-react-stream] ➖ Stream closed for:\", req.url);\n activeStreams.delete(res);\n });\n }\n });\n },\n\n async config(config, configEnv): Promise<UserConfig> {\n const resolvedPages = await resolvePages(userOptions.build.pages);\n if (resolvedPages.type === \"error\") {\n throw resolvedPages.error;\n }\n const { pages } = resolvedPages;\n env = getEnv(config, configEnv);\n define = env.define;\n files = await checkFilesExist(\n pages,\n userOptions,\n config.root ?? userOptions.projectRoot\n );\n root = config.root ?? userOptions.projectRoot;\n const resolvedConfig = resolveUserConfig(\n \"react-server\",\n [...pages, userOptions.workerPath, userOptions.loaderPath],\n config,\n configEnv,\n userOptions\n );\n if (resolvedConfig.type === \"error\") {\n throw resolvedConfig.error;\n }\n const { userConfig } = resolvedConfig;\n console.log({\n worker: userOptions.workerPath,\n loader: userOptions.loaderPath,\n });\n const entriesClient = Object.fromEntries([\n ...Array.from(files.pageMap.entries()).map(([key, value]) => [\n key,\n relative(root, value),\n ]),\n ...Array.from(files.propsMap.entries()).map(([key, value]) => [\n key,\n relative(root, value),\n ]),\n ]);\n const entriesResolved = Object.fromEntries(\n (Object.entries(entriesClient) as [string, string][]).map(\n ([key, entry]) => {\n if (typeof entry !== \"string\") {\n return [key, entry];\n }\n\n return [key, entry];\n }\n )\n );\n const serverEntries = {\n ...entriesResolved,\n [\"worker/worker\"]: userOptions.workerPath,\n [\"worker/loader\"]: userOptions.loaderPath,\n };\n\n const buildConfig = createBuildConfig({\n input: serverEntries,\n userConfig: userConfig,\n userOptions: userOptions,\n root,\n moduleBaseExceptions: [\n userOptions.workerPath,\n userOptions.loaderPath,\n ...userOptions.moduleBaseExceptions,\n ],\n });\n return {\n ...buildConfig,\n define,\n plugins: config.plugins,\n };\n },\n async buildStart() {\n timing.buildStart = performance.now();\n },\n async closeBundle() {\n if (!config) return;\n console.log(\"RSC CLOSE BUNDLE CALLED\");\n if (!files.pageSet.size) return;\n timing.renderStart = performance.now();\n\n try {\n const resolvedServerManifest = tryManifest({\n root,\n outDir: userOptions.build.server,\n ssrManifest: false,\n });\n if (resolvedServerManifest.type === \"error\") {\n console.error(\n \"[vite-react-stream] Server Build failed, can not build without a server manifest. Please set `manifest: true` in your vite config.\",\n resolvedServerManifest.error\n );\n return;\n }\n const { manifest: serverManifest } = resolvedServerManifest;\n\n // get worker path from server manifest\n const workerPath =\n serverManifest[userOptions.workerPath]?.file ??\n serverManifest[relative(root, userOptions.workerPath)]?.file ??\n serverManifest[\n relative(\n join(root, userOptions.build.server),\n userOptions.workerPath\n )\n ]?.file;\n if (!workerPath) {\n console.log(serverManifest, userOptions.build.server);\n throw new Error(\n `Worker path not found in server manifest, tried: ${userOptions.workerPath}, ${relative(root, userOptions.workerPath)}, ${join(root, userOptions.build.server, userOptions.workerPath)}`\n );\n }\n console.log(\"workerPath\", workerPath);\n // client\n const resolvedClientManifest = tryManifest({\n root,\n outDir: userOptions.build.client,\n ssrManifest: false,\n });\n if (resolvedClientManifest.type === \"error\") {\n console.error(\n \"[vite-react-stream] Server Build failed, can not build without a client manifest. Make sure to run the client build before the server build and set `manifest: true` in your vite config.\",\n resolvedClientManifest.error\n );\n return;\n }\n const { manifest: clientManifest } = resolvedClientManifest;\n\n // Create a single worker for all routes\n if (!worker)\n worker = await createWorker({\n workerPath: join(root, userOptions.build.server, workerPath),\n nodePath: process.env[\"NODE_PATH\"] ?? resolve(root, \"node_modules\"),\n mode:\n process.env[\"NODE_ENV\"] === \"development\"\n ? \"development\"\n : \"production\",\n });\n // this is based on the user config - the routes should lead to a page and props but the rendering is agnostic of that\n const routes = Array.from(files.pageMap.keys());\n const indexEntry = clientManifest[\"index.html\"];\n if (!indexEntry) {\n throw new Error(\"root /index.html not found\");\n }\n await renderPages(routes, {\n pipableStreamOptions: {\n bootstrapModules: [\"/\" + indexEntry.file],\n },\n outDir: config.build.outDir,\n clientCss: indexEntry.css?.map((css) => \"/\" + css) ?? [],\n pluginOptions: {\n Page: userOptions.Page,\n props: userOptions.props,\n build: userOptions.build,\n Html: userOptions.Html,\n pageExportName: userOptions.pageExportName,\n propsExportName: userOptions.propsExportName,\n moduleBase: userOptions.moduleBase,\n moduleBasePath: userOptions.moduleBasePath,\n moduleBaseURL: userOptions.moduleBaseURL,\n projectRoot: root,\n },\n worker: worker,\n manifest: clientManifest,\n loader: createPageLoader({\n manifest: clientManifest,\n root: config.root,\n outDir: config.build.outDir,\n moduleBase: userOptions.moduleBase,\n alwaysRegisterServer: false,\n alwaysRegisterClient: false,\n registerServer: [],\n registerClient: Object.keys(resolvedClientManifest).filter(\n (key) =>\n key.endsWith(\".client.tsx\") && clientManifest[key].isEntry\n ),\n }),\n onCssFile: (path) => buildCssFiles.add(path),\n });\n console.log(\"[vite-react-stream] Render complete\");\n console.log(\"[vite-react-stream] Terminating worker\");\n if (worker) await worker.terminate();\n\n timing.renderEnd = performance.now();\n timing.total = (timing.renderEnd - timing.start) / 1000;\n\n // Collect stats\n const stats: BuildStats = {\n htmlFiles: routes.length,\n clientComponents: clientComponents.size,\n cssFiles: cssModules.size,\n totalRoutes: routes.length,\n timing: {\n config: ((timing.configResolved ?? 0) - timing.start) / 1000,\n build:\n ((timing.buildStart ?? 0) - (timing.configResolved ?? 0)) / 1000,\n render:\n ((timing.renderEnd ?? 0) - (timing.renderStart ?? 0)) / 1000,\n total: (timing.renderEnd ?? 0 - timing.start) / 1000,\n },\n };\n\n // Format duration helper\n const formatDuration = (seconds: number) => {\n if (seconds < 0.001) {\n return `${(seconds * 1000000).toFixed(0)}μs`;\n }\n if (seconds < 1) {\n return `${(seconds * 1000).toFixed(0)}ms`;\n }\n return `${seconds.toFixed(2)}s`;\n };\n\n console.log(\"\\n[vite-react-stream] Build Summary:\");\n console.log(\"─\".repeat(50));\n console.log(`📄 Generated ${stats.htmlFiles} HTML files`);\n console.log(`🎯 Processed ${stats.clientComponents} client components`);\n console.log(`🎨 Included ${stats.cssFiles} CSS files`);\n console.log(`🛣️ Total routes: ${stats.totalRoutes}`);\n console.log(\"─\".repeat(50));\n console.log(\"⏱️ Timing:\");\n console.log(` Config: ${formatDuration(stats.timing.config)}`);\n console.log(` Build: ${formatDuration(stats.timing.build)}`);\n console.log(` Render: ${formatDuration(stats.timing.render)}`);\n console.log(\" \".repeat(12));\n console.log(` Total: ${formatDuration(stats.timing.total)}`);\n console.log(\"─\".repeat(50));\n } catch (error) {\n console.error(\"[vite-react-stream] Build failed:\", error);\n throw error;\n }\n },\n async buildEnd(error) {\n if (error) {\n console.error(\"[vite-react-stream] Build error:\", error);\n }\n if (worker) await worker.terminate();\n },\n handleHotUpdate({ file }) {\n if (file.endsWith(\".css\")) {\n cssModules.add(file);\n }\n },\n transform(code: string, id: string) {\n if (\n (id.includes(\".client\") ||\n code.startsWith('\"use client\"') ||\n code.startsWith(\"use client\")) &&\n !id.includes(\"node_modules\")\n ) {\n console.log(\"[vite-react-stream] Client component added\", id);\n clientComponents.set(id, code);\n }\n return { code };\n },\n };\n}\n"],"names":["config"],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { mergeInputs } from "./mergeInputs.js";
2
+ import { createInputNormalizer } from "../helpers/inputNormalizer.js";
3
+ function createBuildConfig({
4
+ root,
5
+ input,
6
+ userOptions,
7
+ userConfig,
8
+ moduleBaseExceptions
9
+ }) {
10
+ const { output, input: inputConfig, ...restRollupOptions } = userConfig.build.rollupOptions ?? {};
11
+ let mergedInputs = mergeInputs(input, inputConfig);
12
+ let inputNormalizer = createInputNormalizer({
13
+ root
14
+ });
15
+ if (typeof mergedInputs === "object" && mergedInputs != null) {
16
+ mergedInputs = Object.fromEntries(Object.entries(mergedInputs).map(inputNormalizer));
17
+ }
18
+ const config = {
19
+ configFile: false,
20
+ ...userConfig,
21
+ build: {
22
+ ...userConfig.build,
23
+ rollupOptions: {
24
+ input: mergedInputs,
25
+ output: {
26
+ format: "esm",
27
+ preserveModules: true,
28
+ hoistTransitiveImports: false,
29
+ esModule: true,
30
+ entryFileNames: "[name].js",
31
+ chunkFileNames: "[name].js",
32
+ assetFileNames: "[name][extname]",
33
+ ...output
34
+ },
35
+ ...restRollupOptions
36
+ }
37
+ }
38
+ };
39
+ return config;
40
+ }
41
+ export {
42
+ createBuildConfig
43
+ };
44
+ //# sourceMappingURL=createBuildConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createBuildConfig.js","sources":["../../../src/build/createBuildConfig.ts"],"sourcesContent":["import type { InlineConfig } from \"vite\";\nimport type { ResolvedUserConfig, ResolvedUserOptions } from \"../types.js\";\nimport type { InputOption } from \"rollup\";\nimport { mergeInputs } from \"./mergeInputs.js\";\nimport { createInputNormalizer } from \"../helpers/inputNormalizer.js\";\n\ntype CreateBuildConfigOptions = {\n input: InputOption;\n userOptions: ResolvedUserOptions;\n userConfig: ResolvedUserConfig;\n root: string;\n moduleBaseExceptions: string[];\n};\n\n\nexport function createBuildConfig({\n root,\n input,\n userOptions,\n userConfig,\n moduleBaseExceptions\n}: CreateBuildConfigOptions) {\n const { output, input: inputConfig, ...restRollupOptions } =\n userConfig.build.rollupOptions ?? {};\n\n let mergedInputs = mergeInputs(input, inputConfig);\n\n let inputNormalizer = createInputNormalizer({\n root,\n });\n if(typeof mergedInputs === 'object' && mergedInputs != null) {\n mergedInputs = Object.fromEntries(Object.entries(mergedInputs).map(inputNormalizer));\n }\n const config: InlineConfig = {\n configFile: false,\n ...userConfig,\n build: {\n ...userConfig.build,\n rollupOptions: {\n input: mergedInputs,\n output: {\n format: \"esm\",\n preserveModules: true,\n hoistTransitiveImports: false,\n esModule: true,\n entryFileNames: \"[name].js\",\n chunkFileNames: \"[name].js\",\n assetFileNames: \"[name][extname]\",\n ...output,\n },\n ...restRollupOptions,\n },\n },\n };\n\n return config;\n}\n"],"names":[],"mappings":";;AAeO,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA6B;AACrB,QAAA,EAAE,QAAQ,OAAO,aAAa,GAAG,sBACrC,WAAW,MAAM,iBAAiB,CAAC;AAEjC,MAAA,eAAe,YAAY,OAAO,WAAW;AAEjD,MAAI,kBAAkB,sBAAsB;AAAA,IAC1C;AAAA,EAAA,CACD;AACD,MAAG,OAAO,iBAAiB,YAAY,gBAAgB,MAAM;AAC5C,mBAAA,OAAO,YAAY,OAAO,QAAQ,YAAY,EAAE,IAAI,eAAe,CAAC;AAAA,EAAA;AAErF,QAAM,SAAuB;AAAA,IAC3B,YAAY;AAAA,IACZ,GAAG;AAAA,IACH,OAAO;AAAA,MACL,GAAG,WAAW;AAAA,MACd,eAAe;AAAA,QACb,OAAO;AAAA,QACP,QAAQ;AAAA,UACN,QAAQ;AAAA,UACR,iBAAiB;AAAA,UACjB,wBAAwB;AAAA,UACxB,UAAU;AAAA,UACV,gBAAgB;AAAA,UAChB,gBAAgB;AAAA,UAChB,gBAAgB;AAAA,UAChB,GAAG;AAAA,QACL;AAAA,QACA,GAAG;AAAA,MAAA;AAAA,IACL;AAAA,EAEJ;AAEO,SAAA;AACT;"}
@@ -0,0 +1,16 @@
1
+ const mergeAsArray = (entries) => {
2
+ return Array.isArray(entries) ? entries : typeof entries === "object" && entries != null ? Object.values(entries) : typeof entries === "string" ? [entries] : [];
3
+ };
4
+ const mergeAsObject = (entries) => {
5
+ return Array.isArray(entries) ? Object.fromEntries(entries.map((entry) => [entry, entry])) : typeof entries === "object" && entries != null ? entries : typeof entries === "string" ? { [entries]: entries } : {};
6
+ };
7
+ const mergeInputs = (input, input2) => {
8
+ if (!input2) return input;
9
+ return Array.isArray(input) ? [...input, ...mergeAsArray(input2)] : typeof input === "string" ? [input, ...mergeAsArray(input2)] : input != null && typeof input2 === "object" && input2 != null ? { ...input, ...mergeAsObject(input2) } : input != null ? input : Array.isArray(input2) ? input2 : typeof input2 === "object" && input2 != null ? input2 : typeof input2 === "string" ? input2 : [];
10
+ };
11
+ export {
12
+ mergeAsArray,
13
+ mergeAsObject,
14
+ mergeInputs
15
+ };
16
+ //# sourceMappingURL=mergeInputs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mergeInputs.js","sources":["../../../src/build/mergeInputs.ts"],"sourcesContent":["import type { InputOption } from \"rollup\";\n\nexport const mergeAsArray = (entries: InputOption) => {\n return Array.isArray(entries)\n ? entries\n : typeof entries === \"object\" && entries != null\n ? Object.values(entries)\n : typeof entries === \"string\"\n ? [entries]\n : [];\n};\nexport const mergeAsObject = (entries: InputOption) => {\n return Array.isArray(entries)\n ? Object.fromEntries(entries.map((entry) => [entry, entry]))\n : typeof entries === \"object\" && entries != null\n ? entries\n : typeof entries === \"string\"\n ? { [entries]: entries }\n : {};\n};\n\nexport const mergeInputs = (\n input: InputOption,\n input2: InputOption | undefined\n) => {\n if (!input2) return input;\n return Array.isArray(input)\n ? [...input, ...mergeAsArray(input2)]\n : typeof input === \"string\"\n ? [input, ...mergeAsArray(input2)]\n : input != null && typeof input2 === \"object\" && input2 != null\n ? { ...input, ...mergeAsObject(input2) }\n : input != null\n ? input\n : Array.isArray(input2)\n ? input2\n : typeof input2 === \"object\" && input2 != null\n ? input2\n : typeof input2 === \"string\"\n ? input2\n : [];\n};\n"],"names":[],"mappings":"AAEa,MAAA,eAAe,CAAC,YAAyB;AAC7C,SAAA,MAAM,QAAQ,OAAO,IACxB,UACA,OAAO,YAAY,YAAY,WAAW,OAC1C,OAAO,OAAO,OAAO,IACrB,OAAO,YAAY,WACnB,CAAC,OAAO,IACR,CAAC;AACP;AACa,MAAA,gBAAgB,CAAC,YAAyB;AACrD,SAAO,MAAM,QAAQ,OAAO,IACxB,OAAO,YAAY,QAAQ,IAAI,CAAC,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC,IACzD,OAAO,YAAY,YAAY,WAAW,OAC1C,UACA,OAAO,YAAY,WACnB,EAAE,CAAC,OAAO,GAAG,YACb,CAAC;AACP;AAEa,MAAA,cAAc,CACzB,OACA,WACG;AACC,MAAA,CAAC,OAAe,QAAA;AACb,SAAA,MAAM,QAAQ,KAAK,IACtB,CAAC,GAAG,OAAO,GAAG,aAAa,MAAM,CAAC,IAClC,OAAO,UAAU,WACjB,CAAC,OAAO,GAAG,aAAa,MAAM,CAAC,IAC/B,SAAS,QAAQ,OAAO,WAAW,YAAY,UAAU,OACzD,EAAE,GAAG,OAAO,GAAG,cAAc,MAAM,EAAA,IACnC,SAAS,OACT,QACA,MAAM,QAAQ,MAAM,IACpB,SACA,OAAO,WAAW,YAAY,UAAU,OACxC,SACA,OAAO,WAAW,WAClB,SACA,CAAC;AACP;"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkFilesExist.js","sources":["../../src/checkFilesExist.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { StreamPluginOptions } from \"./types.js\";\n\nexport async function checkFilesExist(\n pages: string[],\n options: Pick<StreamPluginOptions, \"Page\" | \"props\">,\n root: string\n) {\n const errors: string[] = [];\n const pageSet = new Set<string>();\n const pageMap = new Map<string, string>();\n // Check if files exist when string paths are provided\n if (typeof options.Page === \"string\") {\n const pagePath = resolve(root, options.Page);\n pageMap.set(options.Page, pagePath);\n if (!pageSet.has(pagePath)) {\n if (!existsSync(pagePath)) {\n errors.push(`Page file not found: ${pagePath}`);\n }\n pageSet.add(pagePath);\n }\n } else if (typeof options.Page === \"function\" && pages) {\n for (const page of pages) {\n const pagePath = options.Page(resolve(root, page));\n pageMap.set(page, pagePath);\n if (pageSet.has(pagePath)) {\n continue;\n }\n if (!existsSync(pagePath)) {\n errors.push(`Page file not found: ${pagePath}`);\n }\n pageSet.add(pagePath);\n }\n }\n\n const propsSet = new Set<string>();\n const propsMap = new Map<string, string>();\n if (typeof options.props === \"string\") {\n const propsPath = resolve(root, options.props);\n propsMap.set(options.props, propsPath);\n if (!propsSet.has(propsPath)) {\n if (!existsSync(propsPath)) {\n errors.push(`Props file not found: ${propsPath}`);\n }\n propsSet.add(propsPath);\n }\n } else if (typeof options.props === \"function\" && pages) {\n for (const page of pages) {\n const propsPath = options.props(resolve(root, page));\n propsMap.set(page, propsPath);\n if (propsSet.has(propsPath)) {\n continue;\n }\n if (!existsSync(propsPath)) {\n errors.push(`Props file not found: ${propsPath}`);\n }\n propsSet.add(propsPath);\n }\n }\n\n if (errors.length) {\n throw new Error(\"React Stream Plugin Validation:\\n\" + errors.join(\"\\n\"));\n }\n\n return { pageMap, pageSet, propsMap, propsSet };\n}\n"],"names":[],"mappings":";;AAIsB,eAAA,gBACpB,OACA,SACA,MACA;AACA,QAAM,SAAmB,CAAC;AACpB,QAAA,8BAAc,IAAY;AAC1B,QAAA,8BAAc,IAAoB;AAEpC,MAAA,OAAO,QAAQ,SAAS,UAAU;AACpC,UAAM,WAAW,QAAQ,MAAM,QAAQ,IAAI;AACnC,YAAA,IAAI,QAAQ,MAAM,QAAQ;AAClC,QAAI,CAAC,QAAQ,IAAI,QAAQ,GAAG;AACtB,UAAA,CAAC,WAAW,QAAQ,GAAG;AAClB,eAAA,KAAK,wBAAwB,QAAQ,EAAE;AAAA,MAAA;AAEhD,cAAQ,IAAI,QAAQ;AAAA,IAAA;AAAA,EAEb,WAAA,OAAO,QAAQ,SAAS,cAAc,OAAO;AACtD,eAAW,QAAQ,OAAO;AACxB,YAAM,WAAW,QAAQ,KAAK,QAAQ,MAAM,IAAI,CAAC;AACzC,cAAA,IAAI,MAAM,QAAQ;AACtB,UAAA,QAAQ,IAAI,QAAQ,GAAG;AACzB;AAAA,MAAA;AAEE,UAAA,CAAC,WAAW,QAAQ,GAAG;AAClB,eAAA,KAAK,wBAAwB,QAAQ,EAAE;AAAA,MAAA;AAEhD,cAAQ,IAAI,QAAQ;AAAA,IAAA;AAAA,EACtB;AAGI,QAAA,+BAAe,IAAY;AAC3B,QAAA,+BAAe,IAAoB;AACrC,MAAA,OAAO,QAAQ,UAAU,UAAU;AACrC,UAAM,YAAY,QAAQ,MAAM,QAAQ,KAAK;AACpC,aAAA,IAAI,QAAQ,OAAO,SAAS;AACrC,QAAI,CAAC,SAAS,IAAI,SAAS,GAAG;AACxB,UAAA,CAAC,WAAW,SAAS,GAAG;AACnB,eAAA,KAAK,yBAAyB,SAAS,EAAE;AAAA,MAAA;AAElD,eAAS,IAAI,SAAS;AAAA,IAAA;AAAA,EAEf,WAAA,OAAO,QAAQ,UAAU,cAAc,OAAO;AACvD,eAAW,QAAQ,OAAO;AACxB,YAAM,YAAY,QAAQ,MAAM,QAAQ,MAAM,IAAI,CAAC;AAC1C,eAAA,IAAI,MAAM,SAAS;AACxB,UAAA,SAAS,IAAI,SAAS,GAAG;AAC3B;AAAA,MAAA;AAEE,UAAA,CAAC,WAAW,SAAS,GAAG;AACnB,eAAA,KAAK,yBAAyB,SAAS,EAAE;AAAA,MAAA;AAElD,eAAS,IAAI,SAAS;AAAA,IAAA;AAAA,EACxB;AAGF,MAAI,OAAO,QAAQ;AACjB,UAAM,IAAI,MAAM,sCAAsC,OAAO,KAAK,IAAI,CAAC;AAAA,EAAA;AAGzE,SAAO,EAAE,SAAS,SAAS,UAAU,SAAS;AAChD;"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collect-css-manifest.js","sources":["../../src/collect-css-manifest.ts"],"sourcesContent":["import type { Manifest, ModuleGraph } from \"vite\";\n\nexport async function collectModuleGraphCss(\n moduleGraph: ModuleGraph,\n pagePath: string\n) {\n if (!pagePath) return new Map<string, string>();\n\n const cssFiles = new Map<string, string>();\n const pageModule = await moduleGraph.getModuleByUrl(pagePath, true);\n if (!pageModule) {\n return new Map<string, string>();\n }\n const seen = new Set<string>();\n const walkModule = (mod: any) => {\n if (!mod?.id || seen.has(mod.id)) return;\n seen.add(mod.id);\n if (mod?.id?.endsWith(\".css\")) {\n cssFiles.set(mod?.url, mod?.id);\n }\n mod?.importedModules?.forEach((imp: any) => walkModule(imp));\n };\n walkModule(pageModule);\n return cssFiles;\n}\n\nexport function collectManifestCss(\n manifest: Manifest,\n root: string,\n pagePath: string,\n onCss?: (path: string) => void\n) {\n const relativePagePath = pagePath.startsWith(root + \"/\")\n ? pagePath.slice(root.length + 1)\n : pagePath;\n if (!relativePagePath) return new Map<string, string>();\n const cssFiles = new Map<string, string>();\n const seen = new Set<string>();\n\n const walkManifestEntry = (id: string) => {\n if (seen.has(id)) return;\n seen.add(id);\n if (id.endsWith(\".css\")) {\n cssFiles.set(id, id);\n onCss?.(id);\n return;\n }\n // Get the manifest entry\n const entry = manifest[id];\n if (!entry) return;\n\n // Add direct CSS\n if (entry.css) {\n entry.css.forEach((css: string) => {\n cssFiles.set(entry.file, css);\n onCss?.(css);\n });\n }\n\n // Walk imports recursively\n if (entry.imports) {\n entry.imports.forEach((imp: string) => walkManifestEntry(imp));\n }\n\n // Also check dynamicImports\n if (entry.dynamicImports) {\n entry.dynamicImports.forEach((imp: string) => walkManifestEntry(imp));\n }\n };\n\n if (manifest[relativePagePath]) {\n walkManifestEntry(relativePagePath);\n }\n\n return cssFiles;\n}\n"],"names":[],"mappings":"AAEsB,eAAA,sBACpB,aACA,UACA;AACA,MAAI,CAAC,SAAiB,QAAA,oBAAI,IAAoB;AAExC,QAAA,+BAAe,IAAoB;AACzC,QAAM,aAAa,MAAM,YAAY,eAAe,UAAU,IAAI;AAClE,MAAI,CAAC,YAAY;AACf,+BAAW,IAAoB;AAAA,EAAA;AAE3B,QAAA,2BAAW,IAAY;AACvB,QAAA,aAAa,CAAC,QAAa;AAC/B,QAAI,CAAC,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,EAAG;AAC7B,SAAA,IAAI,IAAI,EAAE;AACf,QAAI,KAAK,IAAI,SAAS,MAAM,GAAG;AAC7B,eAAS,IAAI,KAAK,KAAK,KAAK,EAAE;AAAA,IAAA;AAEhC,SAAK,iBAAiB,QAAQ,CAAC,QAAa,WAAW,GAAG,CAAC;AAAA,EAC7D;AACA,aAAW,UAAU;AACd,SAAA;AACT;AAEO,SAAS,mBACd,UACA,MACA,UACA,OACA;AACM,QAAA,mBAAmB,SAAS,WAAW,OAAO,GAAG,IACnD,SAAS,MAAM,KAAK,SAAS,CAAC,IAC9B;AACJ,MAAI,CAAC,iBAAyB,QAAA,oBAAI,IAAoB;AAChD,QAAA,+BAAe,IAAoB;AACnC,QAAA,2BAAW,IAAY;AAEvB,QAAA,oBAAoB,CAAC,OAAe;AACpC,QAAA,KAAK,IAAI,EAAE,EAAG;AAClB,SAAK,IAAI,EAAE;AACP,QAAA,GAAG,SAAS,MAAM,GAAG;AACd,eAAA,IAAI,IAAI,EAAE;AACnB,cAAQ,EAAE;AACV;AAAA,IAAA;AAGI,UAAA,QAAQ,SAAS,EAAE;AACzB,QAAI,CAAC,MAAO;AAGZ,QAAI,MAAM,KAAK;AACP,YAAA,IAAI,QAAQ,CAAC,QAAgB;AACxB,iBAAA,IAAI,MAAM,MAAM,GAAG;AAC5B,gBAAQ,GAAG;AAAA,MAAA,CACZ;AAAA,IAAA;AAIH,QAAI,MAAM,SAAS;AACjB,YAAM,QAAQ,QAAQ,CAAC,QAAgB,kBAAkB,GAAG,CAAC;AAAA,IAAA;AAI/D,QAAI,MAAM,gBAAgB;AACxB,YAAM,eAAe,QAAQ,CAAC,QAAgB,kBAAkB,GAAG,CAAC;AAAA,IAAA;AAAA,EAExE;AAEI,MAAA,SAAS,gBAAgB,GAAG;AAC9B,sBAAkB,gBAAgB;AAAA,EAAA;AAG7B,SAAA;AACT;"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components.js","sources":["../../src/components.tsx"],"sourcesContent":["import { createElement } from 'react';\n\n/**\n * A component that emits <link> tags for CSS files during streaming.\n * The high precedence ensures they bubble up to the document head.\n */\nexport function CssCollector({ url }: { url: string }) {\n return createElement('link', {\n key: url,\n rel: 'stylesheet',\n href: url,\n precedence: 'high'\n });\n} "],"names":[],"mappings":";AAMgB,SAAA,aAAa,EAAE,OAAwB;AACrD,SAAO,cAAc,QAAQ;AAAA,IAC3B,KAAK;AAAA,IACL,KAAK;AAAA,IACL,MAAM;AAAA,IACN,YAAY;AAAA,EAAA,CACb;AACH;"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getEnv.js","sources":["../../src/getEnv.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { ConfigEnv, UserConfig } from \"vite\";\nimport { loadEnv } from \"vite\";\nimport { DEFAULT_CONFIG } from \"./options.js\";\n\n/**\n * Get environment variables for Vite, sets defaults to ensure the server can start with BASE_URL and PUBLIC_URL\n *\n * @param config - Vite configuration object\n * @param { isPreview: boolean } - Object containing a boolean indicating if the environment is for preview\n * @returns An object containing the environment variables\n */\nexport function getEnv(config: UserConfig, configEnv: ConfigEnv) {\n const isLocal =\n config.mode === \"development\"\n\n const envName = isLocal\n ? `${config.mode}.local`\n : config.mode\n ? config.mode\n : \"production\";\n const environmentName = config.mode ?? envName ?? \"production\";\n\n const env = loadEnv(\n environmentName,\n config.envDir ?? config.root ?? process.cwd(),\n config.envPrefix ?? DEFAULT_CONFIG.ENV_PREFIX ?? \"VITE_\"\n );\n\n // Get server config\n const serverConfig = config.server || {};\n const previewConfig = config.preview || {};\n const host = configEnv.isPreview\n ? previewConfig.host ?? DEFAULT_CONFIG.PREVIEW_HOST\n : serverConfig.host ?? DEFAULT_CONFIG.DEV_HOST;\n let previewPort = previewConfig.port ?? DEFAULT_CONFIG.PREVIEW_PORT;\n let devPort = serverConfig.port ?? DEFAULT_CONFIG.DEV_PORT;\n\n let homepage = env[\"VITE_BASE_URL\"]\n if (configEnv.command === \"build\" && (!homepage || homepage === \"\")) {\n try {\n const packageJson = JSON.parse(\n readFileSync(resolve(config.root ?? \"\", \"package.json\"), \"utf-8\")\n );\n homepage = packageJson.homepage ?? \"\";\n if (!homepage || homepage === \"\") {\n console.warn(\n \"[RSC] 🔧 For production builds, please set 'homepage' in package.json, or set VITE_BASE_URL in your environment\"\n );\n }\n } catch (e) {\n console.error(e);\n }\n }\n\n let baseUrl =\n env[\"VITE_BASE_URL\"] && env[\"VITE_PUBLIC_URL\"] !== \"\"\n ? env[\"VITE_BASE_URL\"]\n : configEnv.isPreview\n ? `http://${host}:${previewPort}`\n : configEnv.command === \"serve\"\n ? `http://${host}:${devPort}`\n : homepage;\n\n let publicUrl =\n env[\"VITE_PUBLIC_URL\"] && env[\"VITE_PUBLIC_URL\"] !== \"\"\n ? env[\"VITE_PUBLIC_URL\"]\n : \"\";\n\n // Determine port and host based on mode\n const port = configEnv.isPreview\n ? previewConfig.port || DEFAULT_CONFIG.PREVIEW_PORT // Preview server\n : serverConfig.port || DEFAULT_CONFIG.DEV_PORT; // Dev server\n\n // Build base URL\n if (configEnv.isPreview && `http://${host}:${port}` !== baseUrl) {\n console.log(\n `VITE_BASE_URL: \\\"${baseUrl}\\\" wasn't configured correctly for this server, overriding to: \\\"http://${host}:${port}\\\"`\n );\n baseUrl = `http://${host}:${port}`;\n }\n\n const envPrefix =\n typeof config.envPrefix === \"string\"\n ? config.envPrefix\n : Array.isArray(config.envPrefix)\n ? config.envPrefix[0]\n : DEFAULT_CONFIG.ENV_PREFIX;\n\n const nodeProcessEnv = {\n NODE_ENV: configEnv.command === \"build\" ? \"production\" : \"development\",\n };\n const defineProcess = Object.entries(nodeProcessEnv)\n .map(([key, value]) => {\n switch (key) {\n case \"NODE_ENV\":\n const isDev =\n value === \"\"\n ? configEnv.command === \"build\"\n ? false\n : true\n : value === \"development\";\n return [`import.meta.env.DEV`, JSON.stringify(isDev)];\n default:\n return null;\n }\n })\n .filter(Array.isArray);\n\n const defineImportMeta = Object.entries(env).map(([key, value]) => [\n `import.meta.env.${key}`,\n key === \"VITE_BASE_URL\"\n ? value\n ? JSON.stringify(value)\n : JSON.stringify(baseUrl)\n : key === \"VITE_PUBLIC_URL\"\n ? value\n ? JSON.stringify(value)\n : JSON.stringify(publicUrl)\n : JSON.stringify(value),\n ]);\n const define = Object.fromEntries([...defineProcess, ...defineImportMeta]);\n\n return {\n baseUrl,\n publicUrl,\n port,\n host,\n envPrefix,\n environmentName,\n env,\n define,\n };\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { relative } from "node:path";
2
+ const createInputNormalizer = ({
3
+ root = process.cwd()
4
+ } = {}) => ([key, path]) => [
5
+ key,
6
+ path.startsWith(root) ? relative(root, path) : path.startsWith("/") ? path : `/${path}`
7
+ ];
8
+ export {
9
+ createInputNormalizer
10
+ };
11
+ //# sourceMappingURL=inputNormalizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inputNormalizer.js","sources":["../../../src/helpers/inputNormalizer.ts"],"sourcesContent":["import { relative } from \"node:path\";\n\ntype NormalizedInputOptions = {\n // will automatically remove this part\n root?: string;\n};\n\nexport const createInputNormalizer =\n (\n {\n root = process.cwd(),\n }: NormalizedInputOptions = {} as NormalizedInputOptions\n ) =>\n ([key, path]: [string, string]) =>\n [\n key,\n path.startsWith(root)\n ? relative(root, path)\n : path.startsWith(\"/\")\n ? path\n : `/${path}`,\n ];\n"],"names":[],"mappings":";AAOO,MAAM,wBACX,CACE;AAAA,EACE,OAAO,QAAQ,IAAI;AACrB,IAA4B,OAE9B,CAAC,CAAC,KAAK,IAAI,MACT;AAAA,EACE;AAAA,EACA,KAAK,WAAW,IAAI,IAChB,SAAS,MAAM,IAAI,IACnB,KAAK,WAAW,GAAG,IACnB,OACA,IAAI,IAAI;AACd;"}
@@ -0,0 +1,34 @@
1
+ import { normalizePath } from "vite";
2
+ const createNormalizedRelativePath = (options = {
3
+ root: process.cwd(),
4
+ outDir: "dist",
5
+ moduleBase: "src",
6
+ noLeadingSlash: false,
7
+ noTrailingSlash: false,
8
+ moduleBaseExceptions: []
9
+ }) => {
10
+ let base = options.noLeadingSlash && options.moduleBase.startsWith("/") ? options.moduleBase.slice(1) : options.moduleBase;
11
+ if (options.noTrailingSlash && base.endsWith("/")) {
12
+ base = base.slice(0, -1);
13
+ }
14
+ const removeOutDir = (path) => options.outDir === path ? path.slice(options.outDir.length) : path;
15
+ const removeRoot = (path) => {
16
+ const relative = path.startsWith(options.root) ? path.slice(options.root.length) : path;
17
+ return relative;
18
+ };
19
+ const ensureModuleBase = (path) => {
20
+ let transformed = path;
21
+ if (options.noLeadingSlash && path.startsWith("/")) {
22
+ transformed = path.slice(1);
23
+ }
24
+ if (options.noTrailingSlash && transformed.endsWith("/")) {
25
+ transformed = transformed.slice(0, -1);
26
+ }
27
+ return transformed;
28
+ };
29
+ return (path) => ensureModuleBase(removeOutDir(removeRoot(normalizePath(path))));
30
+ };
31
+ export {
32
+ createNormalizedRelativePath
33
+ };
34
+ //# sourceMappingURL=normalizedRelativePath.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalizedRelativePath.js","sources":["../../../src/helpers/normalizedRelativePath.ts"],"sourcesContent":["import { normalizePath } from \"vite\";\n\ntype NormalizedRelativePathOptions = {\n // will automatically remove this part\n root: string;\n // will automatically see this as a optional extra part of the rootDir that will be removed\n outDir: string;\n // will ensure it always starts with this path, if it does not it will be added\n moduleBase: string;\n // will ensure it never starts with a leading /, which in some cases is needed (vite entry), other cases it is not for example from project root /\n noLeadingSlash: boolean;\n // will ensure it never ends with a trailing /\n noTrailingSlash: boolean;\n // allowed exception to moduleBase rules\n moduleBaseExceptions: string[];\n};\n\nexport const createNormalizedRelativePath = (\n options: NormalizedRelativePathOptions = {\n root: process.cwd(),\n outDir: \"dist\",\n moduleBase: \"src\",\n noLeadingSlash: false,\n noTrailingSlash: false,\n moduleBaseExceptions: [],\n }\n) => {\n let base =\n options.noLeadingSlash && options.moduleBase.startsWith(\"/\")\n ? options.moduleBase.slice(1)\n : options.moduleBase;\n if (options.noTrailingSlash && base.endsWith(\"/\")) {\n base = base.slice(0, -1);\n }\n const removeOutDir = (path: string) =>\n (options.outDir as string) === path\n ? path.slice(options.outDir.length)\n : path;\n\n const removeRoot = (path: string) => {\n const relative = path.startsWith(options.root)\n ? path.slice(options.root.length)\n : path;\n return relative;\n };\n\n const ensureModuleBase = (path: string) => {\n let transformed = path;\n if (options.noLeadingSlash && path.startsWith(\"/\")) {\n transformed = path.slice(1);\n }\n if (options.noTrailingSlash && transformed.endsWith(\"/\")) {\n transformed = transformed.slice(0, -1);\n }\n return transformed;\n };\n\n return (path: string) => ensureModuleBase(removeOutDir(removeRoot(normalizePath(path))));\n};\n"],"names":[],"mappings":";AAiBa,MAAA,+BAA+B,CAC1C,UAAyC;AAAA,EACvC,MAAM,QAAQ,IAAI;AAAA,EAClB,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,sBAAsB,CAAA;AACxB,MACG;AACH,MAAI,OACF,QAAQ,kBAAkB,QAAQ,WAAW,WAAW,GAAG,IACvD,QAAQ,WAAW,MAAM,CAAC,IAC1B,QAAQ;AACd,MAAI,QAAQ,mBAAmB,KAAK,SAAS,GAAG,GAAG;AAC1C,WAAA,KAAK,MAAM,GAAG,EAAE;AAAA,EAAA;AAEnB,QAAA,eAAe,CAAC,SACnB,QAAQ,WAAsB,OAC3B,KAAK,MAAM,QAAQ,OAAO,MAAM,IAChC;AAEA,QAAA,aAAa,CAAC,SAAiB;AAC7B,UAAA,WAAW,KAAK,WAAW,QAAQ,IAAI,IACzC,KAAK,MAAM,QAAQ,KAAK,MAAM,IAC9B;AACG,WAAA;AAAA,EACT;AAEM,QAAA,mBAAmB,CAAC,SAAiB;AACzC,QAAI,cAAc;AAClB,QAAI,QAAQ,kBAAkB,KAAK,WAAW,GAAG,GAAG;AACpC,oBAAA,KAAK,MAAM,CAAC;AAAA,IAAA;AAE5B,QAAI,QAAQ,mBAAmB,YAAY,SAAS,GAAG,GAAG;AAC1C,oBAAA,YAAY,MAAM,GAAG,EAAE;AAAA,IAAA;AAEhC,WAAA;AAAA,EACT;AAEO,SAAA,CAAC,SAAiB,iBAAiB,aAAa,WAAW,cAAc,IAAI,CAAC,CAAC,CAAC;AACzF;"}
@@ -0,0 +1,27 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ function tryManifest(options) {
4
+ const manifestPath = resolve(
5
+ options.root,
6
+ options.outDir,
7
+ ".vite",
8
+ options.ssrManifest ? "ssr-manifest.json" : "manifest.json"
9
+ );
10
+ try {
11
+ const result = JSON.parse(readFileSync(manifestPath, "utf-8"));
12
+ return {
13
+ type: "success",
14
+ manifest: result
15
+ };
16
+ } catch (e) {
17
+ console.log("No manifest found", manifestPath);
18
+ return {
19
+ type: "error",
20
+ error: e
21
+ };
22
+ }
23
+ }
24
+ export {
25
+ tryManifest
26
+ };
27
+ //# sourceMappingURL=tryManifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tryManifest.js","sources":["../../../src/helpers/tryManifest.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { Manifest } from \"vite\";\n\ntype TryManifestOptions<SSR extends boolean> = {\n root: string;\n outDir: string;\n ssrManifest: SSR;\n};\n\nexport function tryManifest<SSR extends boolean>(options: TryManifestOptions<SSR>): {\n type: \"success\";\n manifest: SSR extends true ? Record<string, string[]> : Manifest;\n} | {\n type: \"error\";\n error: Error;\n} {\n const manifestPath = resolve(\n options.root,\n options.outDir,\n \".vite\",\n options.ssrManifest ? \"ssr-manifest.json\" : \"manifest.json\"\n );\n try {\n const result= JSON.parse(readFileSync(manifestPath, \"utf-8\"));\n return {\n type: \"success\",\n manifest: result,\n }\n } catch (e) {\n console.log(\"No manifest found\", manifestPath);\n return {\n type: \"error\",\n error: e as Error,\n }\n }\n}\n"],"names":[],"mappings":";;AAUO,SAAS,YAAiC,SAM/C;AACA,QAAM,eAAe;AAAA,IACnB,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR;AAAA,IACA,QAAQ,cAAc,sBAAsB;AAAA,EAC9C;AACI,MAAA;AACF,UAAM,SAAS,KAAK,MAAM,aAAa,cAAc,OAAO,CAAC;AACtD,WAAA;AAAA,MACL,MAAM;AAAA,MACN,UAAU;AAAA,IACZ;AAAA,WACO,GAAG;AACF,YAAA,IAAI,qBAAqB,YAAY;AACtC,WAAA;AAAA,MACL,MAAM;AAAA,MACN,OAAO;AAAA,IACT;AAAA,EAAA;AAEJ;"}
@@ -39,7 +39,9 @@ const createPageLoader = ({
39
39
  root,
40
40
  outDir,
41
41
  moduleBase,
42
- noLeadingSlash: true
42
+ noLeadingSlash: true,
43
+ noTrailingSlash: true,
44
+ moduleBaseExceptions: []
43
45
  });
44
46
  return async (id) => {
45
47
  const normalizedId = pathNormalizer(id);
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createPageLoader.js","sources":["../../../src/html/createPageLoader.ts"],"sourcesContent":["import { resolve as resolvePath } from \"node:path\";\nimport { load } from \"react-server-dom-esm/node-loader\";\nimport {\n registerClientReference,\n registerServerReference,\n} from \"react-server-dom-esm/server.node\";\nimport { createNormalizedRelativePath } from \"../helpers/normalizedRelativePath.js\";\n\ntype CreatePageLoaderOptions = {\n manifest: Record<string, { file: string }>;\n root: string;\n outDir: string;\n moduleBase: string;\n registerServer?: string[];\n registerClient?: string[];\n alwaysRegisterServer?: boolean;\n alwaysRegisterClient?: boolean;\n};\n\ntype CreateDefaultLoaderOptions = {\n id: string;\n registerServer?: string[];\n registerClient?: string[];\n alwaysRegisterServer?: boolean;\n alwaysRegisterClient?: boolean;\n};\n\nexport const createDefaultLoader = ({\n id,\n registerServer,\n registerClient,\n alwaysRegisterServer = false,\n alwaysRegisterClient = false,\n}: CreateDefaultLoaderOptions) => {\n const mapper = ([key, value]: [string, any]) => {\n try {\n if (\n registerClient?.includes(key) ||\n (alwaysRegisterClient && typeof value === \"function\")\n ) {\n return [key, registerClientReference(value, id, key)];\n }\n if (\n registerServer?.includes(key) ||\n (alwaysRegisterServer && typeof value === \"function\")\n ) {\n return [key, registerServerReference(value, id, key)];\n }\n return [key, value];\n } catch (e) {\n console.error(\"[RSC] Error registering reference:\", key, value, e);\n return [key, value];\n }\n };\n return async (url: string) =>\n Object.fromEntries(Object.entries(await import(url)).map(mapper));\n};\n\nexport const createPageLoader = ({\n manifest,\n root,\n outDir,\n moduleBase,\n registerServer,\n registerClient,\n alwaysRegisterServer,\n alwaysRegisterClient,\n}: CreatePageLoaderOptions) => {\n const pathNormalizer = createNormalizedRelativePath({\n root,\n outDir,\n moduleBase,\n noLeadingSlash: true,\n noTrailingSlash: true,\n moduleBaseExceptions: [],\n });\n return async (id: string) => {\n const normalizedId = pathNormalizer(id);\n const entry =\n normalizedId in manifest\n ? manifest[normalizedId]\n : Object.values(manifest).find((entry) => entry.file === normalizedId);\n if (!entry) {\n throw new Error(\n `Could not find manifest entry for ${id}, ${normalizedId} from ${root}`\n );\n }\n const loaderResult = await load(\n resolvePath(root, outDir, entry.file),\n { format: \"module\" },\n createDefaultLoader({\n id,\n registerServer,\n registerClient,\n alwaysRegisterServer,\n alwaysRegisterClient,\n })\n );\n return loaderResult;\n };\n};\n"],"names":["entry","resolvePath"],"mappings":";;;;AA2BO,MAAM,sBAAsB,CAAC;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA,uBAAuB;AAAA,EACvB,uBAAuB;AACzB,MAAkC;AAChC,QAAM,SAAS,CAAC,CAAC,KAAK,KAAK,MAAqB;AAC1C,QAAA;AACF,UACE,gBAAgB,SAAS,GAAG,KAC3B,wBAAwB,OAAO,UAAU,YAC1C;AACA,eAAO,CAAC,KAAK,wBAAwB,OAAO,IAAI,GAAG,CAAC;AAAA,MAAA;AAEtD,UACE,gBAAgB,SAAS,GAAG,KAC3B,wBAAwB,OAAO,UAAU,YAC1C;AACA,eAAO,CAAC,KAAK,wBAAwB,OAAO,IAAI,GAAG,CAAC;AAAA,MAAA;AAE/C,aAAA,CAAC,KAAK,KAAK;AAAA,aACX,GAAG;AACV,cAAQ,MAAM,sCAAsC,KAAK,OAAO,CAAC;AAC1D,aAAA,CAAC,KAAK,KAAK;AAAA,IAAA;AAAA,EAEtB;AACA,SAAO,OAAO,QACZ,OAAO,YAAY,OAAO,QAAQ,MAAM,OAAO,IAAI,EAAE,IAAI,MAAM,CAAC;AACpE;AAEO,MAAM,mBAAmB,CAAC;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAA+B;AAC7B,QAAM,iBAAiB,6BAA6B;AAAA,IAClD;AAAA,IACA;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,sBAAsB,CAAA;AAAA,EAAC,CACxB;AACD,SAAO,OAAO,OAAe;AACrB,UAAA,eAAe,eAAe,EAAE;AACtC,UAAM,QACJ,gBAAgB,WACZ,SAAS,YAAY,IACrB,OAAO,OAAO,QAAQ,EAAE,KAAK,CAACA,WAAUA,OAAM,SAAS,YAAY;AACzE,QAAI,CAAC,OAAO;AACV,YAAM,IAAI;AAAA,QACR,qCAAqC,EAAE,KAAK,YAAY,SAAS,IAAI;AAAA,MACvE;AAAA,IAAA;AAEF,UAAM,eAAe,MAAM;AAAA,MACzBC,QAAY,MAAM,QAAQ,MAAM,IAAI;AAAA,MACpC,EAAE,QAAQ,SAAS;AAAA,MACnB,oBAAoB;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACD,CAAA;AAAA,IACH;AACO,WAAA;AAAA,EACT;AACF;"}