vite-plugin-react-server 0.3.9 → 0.3.11

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 (197) hide show
  1. package/dist/client.d.ts +1 -1
  2. package/dist/client.d.ts.map +1 -1
  3. package/dist/client.js +1 -1
  4. package/dist/index.d.ts +3 -6
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +2 -2
  7. package/dist/index.js.map +1 -1
  8. package/dist/package.json +2 -4
  9. package/dist/plugin/assertServerCondition.d.ts +5 -1
  10. package/dist/plugin/assertServerCondition.d.ts.map +1 -1
  11. package/dist/plugin/assertServerCondition.js +1 -3
  12. package/dist/plugin/checkFilesExist.js +10 -7
  13. package/dist/plugin/checkFilesExist.js.map +1 -1
  14. package/dist/plugin/components.js +1 -1
  15. package/dist/plugin/components.js.map +1 -1
  16. package/dist/plugin/config/createModuleIdGenerator.d.ts +11 -0
  17. package/dist/plugin/config/createModuleIdGenerator.d.ts.map +1 -0
  18. package/dist/plugin/config/createModuleIdGenerator.js +44 -0
  19. package/dist/plugin/config/createModuleIdGenerator.js.map +1 -0
  20. package/dist/plugin/config/defaults.d.ts +31 -19
  21. package/dist/plugin/config/defaults.d.ts.map +1 -1
  22. package/dist/plugin/config/defaults.js +22 -27
  23. package/dist/plugin/config/defaults.js.map +1 -1
  24. package/dist/plugin/config/resolveOptions.d.ts +1 -1
  25. package/dist/plugin/config/resolveOptions.d.ts.map +1 -1
  26. package/dist/plugin/config/resolveOptions.js +202 -16
  27. package/dist/plugin/config/resolveOptions.js.map +1 -1
  28. package/dist/plugin/config/resolvePages.d.ts +2 -0
  29. package/dist/plugin/config/resolvePages.d.ts.map +1 -1
  30. package/dist/plugin/config/resolvePages.js.map +1 -1
  31. package/dist/plugin/config/resolveUserConfig.d.ts +2 -2
  32. package/dist/plugin/config/resolveUserConfig.d.ts.map +1 -1
  33. package/dist/plugin/config/resolveUserConfig.js +161 -50
  34. package/dist/plugin/config/resolveUserConfig.js.map +1 -1
  35. package/dist/plugin/helpers/getBundleManifest.d.ts +20 -0
  36. package/dist/plugin/helpers/getBundleManifest.d.ts.map +1 -0
  37. package/dist/plugin/helpers/getBundleManifest.js +43 -0
  38. package/dist/plugin/helpers/getBundleManifest.js.map +1 -0
  39. package/dist/plugin/helpers/getModuleManifest.d.ts +5 -0
  40. package/dist/plugin/helpers/getModuleManifest.d.ts.map +1 -1
  41. package/dist/plugin/helpers/getModuleManifest.js +20 -21
  42. package/dist/plugin/helpers/inputNormalizer.d.ts +15 -1
  43. package/dist/plugin/helpers/inputNormalizer.d.ts.map +1 -1
  44. package/dist/plugin/helpers/inputNormalizer.js +122 -16
  45. package/dist/plugin/helpers/inputNormalizer.js.map +1 -1
  46. package/dist/plugin/helpers/inputNormalizerWorker.d.ts +2 -1
  47. package/dist/plugin/helpers/inputNormalizerWorker.d.ts.map +1 -1
  48. package/dist/plugin/helpers/inputNormalizerWorker.js +10 -7
  49. package/dist/plugin/helpers/tryManifest.d.ts +2 -0
  50. package/dist/plugin/helpers/tryManifest.d.ts.map +1 -1
  51. package/dist/plugin/helpers/tryManifest.js +1 -1
  52. package/dist/plugin/helpers/tryManifest.js.map +1 -1
  53. package/dist/plugin/loader/createBuildLoader.d.ts +6 -2
  54. package/dist/plugin/loader/createBuildLoader.d.ts.map +1 -1
  55. package/dist/plugin/loader/createBuildLoader.js +35 -10
  56. package/dist/plugin/loader/createBuildLoader.js.map +1 -1
  57. package/dist/plugin/loader/createPageLoader.d.ts.map +1 -1
  58. package/dist/plugin/loader/createPageLoader.js +0 -7
  59. package/dist/plugin/plugin.d.ts +0 -1
  60. package/dist/plugin/plugin.d.ts.map +1 -1
  61. package/dist/plugin/plugin.js +2 -1
  62. package/dist/plugin/preserver/plugin.d.ts.map +1 -1
  63. package/dist/plugin/preserver/plugin.js +3 -2
  64. package/dist/plugin/preserver/plugin.js.map +1 -1
  65. package/dist/plugin/react-client/index.d.ts +2 -1
  66. package/dist/plugin/react-client/index.d.ts.map +1 -1
  67. package/dist/plugin/react-client/index.js +19 -1
  68. package/dist/plugin/react-client/index.js.map +1 -0
  69. package/dist/plugin/react-client/plugin.d.ts +2 -2
  70. package/dist/plugin/react-client/plugin.d.ts.map +1 -1
  71. package/dist/plugin/react-client/plugin.js +106 -10
  72. package/dist/plugin/react-client/plugin.js.map +1 -1
  73. package/dist/plugin/react-server/createHandler.d.ts +2 -2
  74. package/dist/plugin/react-server/createHandler.d.ts.map +1 -1
  75. package/dist/plugin/react-server/createHandler.js +5 -5
  76. package/dist/plugin/react-server/createHandler.js.map +1 -1
  77. package/dist/plugin/react-server/createRscStream.d.ts.map +1 -1
  78. package/dist/plugin/react-server/createRscStream.js +15 -1
  79. package/dist/plugin/react-server/createRscStream.js.map +1 -1
  80. package/dist/plugin/react-server/createSsrHandler.d.ts +2 -2
  81. package/dist/plugin/react-server/createSsrHandler.d.ts.map +1 -1
  82. package/dist/plugin/react-server/createSsrHandler.js +5 -12
  83. package/dist/plugin/react-server/index.js +18 -9
  84. package/dist/plugin/react-server/index.js.map +1 -0
  85. package/dist/plugin/react-server/plugin.d.ts.map +1 -1
  86. package/dist/plugin/react-server/plugin.js +133 -127
  87. package/dist/plugin/react-server/plugin.js.map +1 -1
  88. package/dist/plugin/transformer/plugin.d.ts +2 -1
  89. package/dist/plugin/transformer/plugin.d.ts.map +1 -1
  90. package/dist/plugin/transformer/plugin.js +52 -72
  91. package/dist/plugin/transformer/plugin.js.map +1 -1
  92. package/dist/plugin/transformer/transformer-client-components.d.ts +12 -3
  93. package/dist/plugin/transformer/transformer-client-components.d.ts.map +1 -1
  94. package/dist/plugin/transformer/transformer-client-components.js +71 -10
  95. package/dist/plugin/transformer/transformer-client-components.js.map +1 -1
  96. package/dist/plugin/transformer/transformer-server-actions.d.ts +3 -3
  97. package/dist/plugin/transformer/transformer-server-actions.d.ts.map +1 -1
  98. package/dist/plugin/transformer/transformer-server-actions.js +80 -66
  99. package/dist/plugin/transformer/types.d.ts +4 -0
  100. package/dist/plugin/transformer/types.d.ts.map +1 -1
  101. package/dist/plugin/types.d.ts +51 -20
  102. package/dist/plugin/types.d.ts.map +1 -1
  103. package/dist/plugin/worker/html/messageHandler.d.ts.map +1 -1
  104. package/dist/plugin/worker/html/messageHandler.js +37 -23
  105. package/dist/plugin/worker/html/messageHandler.js.map +1 -1
  106. package/dist/plugin/worker/html/plugin.d.ts.map +1 -1
  107. package/dist/plugin/worker/html/plugin.js +10 -5
  108. package/dist/plugin/worker/html/renderPages.d.ts +7 -6
  109. package/dist/plugin/worker/html/renderPages.d.ts.map +1 -1
  110. package/dist/plugin/worker/html/renderPages.js +112 -57
  111. package/dist/plugin/worker/html/renderPages.js.map +1 -1
  112. package/dist/plugin/worker/loader.d.ts +1 -11
  113. package/dist/plugin/worker/loader.d.ts.map +1 -1
  114. package/dist/plugin/worker/loader.js +2 -2
  115. package/dist/plugin/worker/loader.js.map +1 -1
  116. package/dist/plugin/worker/plugin.d.ts +10 -1
  117. package/dist/plugin/worker/plugin.d.ts.map +1 -1
  118. package/dist/plugin/worker/plugin.js +10 -1
  119. package/dist/plugin/worker/types.d.ts +17 -4
  120. package/dist/plugin/worker/types.d.ts.map +1 -1
  121. package/dist/server.d.ts +1 -3
  122. package/dist/server.d.ts.map +1 -1
  123. package/dist/server.js +1 -3
  124. package/dist/server.js.map +1 -1
  125. package/dist/tsconfig.tsbuildinfo +1 -1
  126. package/package.json +2 -4
  127. package/plugin/assertServerCondition.ts +2 -3
  128. package/plugin/checkFilesExist.ts +10 -10
  129. package/plugin/components.tsx +1 -1
  130. package/plugin/config/createModuleIdGenerator.ts +52 -0
  131. package/plugin/config/defaults.ts +24 -15
  132. package/plugin/config/resolveOptions.ts +253 -25
  133. package/plugin/config/resolvePages.ts +1 -1
  134. package/plugin/config/resolveUserConfig.ts +197 -62
  135. package/plugin/helpers/getBundleManifest.ts +75 -0
  136. package/plugin/helpers/getModuleManifest.ts +5 -0
  137. package/plugin/helpers/inputNormalizer.ts +175 -26
  138. package/plugin/helpers/inputNormalizerWorker.ts +13 -8
  139. package/plugin/helpers/tryManifest.ts +2 -0
  140. package/plugin/loader/createBuildLoader.ts +54 -10
  141. package/plugin/loader/createPageLoader.ts +1 -7
  142. package/plugin/plugin.ts +2 -1
  143. package/plugin/preserver/plugin.ts +2 -1
  144. package/plugin/react-client/index.ts +12 -1
  145. package/plugin/react-client/plugin.ts +127 -12
  146. package/plugin/react-server/createHandler.ts +7 -13
  147. package/plugin/react-server/createRscStream.ts +14 -2
  148. package/plugin/react-server/createSsrHandler.ts +7 -26
  149. package/plugin/react-server/plugin.ts +176 -144
  150. package/plugin/transformer/plugin.ts +69 -94
  151. package/plugin/transformer/transformer-client-components.ts +98 -24
  152. package/plugin/transformer/transformer-server-actions.ts +22 -7
  153. package/plugin/transformer/types.ts +4 -0
  154. package/plugin/types.ts +118 -64
  155. package/plugin/worker/html/messageHandler.ts +46 -31
  156. package/plugin/worker/html/plugin.ts +15 -11
  157. package/plugin/worker/html/renderPages.ts +175 -88
  158. package/plugin/worker/loader.ts +4 -13
  159. package/plugin/worker/plugin.ts +10 -1
  160. package/plugin/worker/types.ts +24 -3
  161. package/dist/node_modules/magic-string/dist/magic-string.es.js +0 -1283
  162. package/dist/node_modules/magic-string/dist/magic-string.es.js.map +0 -1
  163. package/dist/plugin/build/createClientBuildConfig.d.ts +0 -3
  164. package/dist/plugin/build/createClientBuildConfig.d.ts.map +0 -1
  165. package/dist/plugin/build/createClientBuildConfig.js +0 -14
  166. package/dist/plugin/build/createServerBuildConfig.d.ts +0 -12
  167. package/dist/plugin/build/createServerBuildConfig.d.ts.map +0 -1
  168. package/dist/plugin/build/createServerBuildConfig.js +0 -40
  169. package/dist/plugin/build/createSharedBuildConfig.d.ts +0 -5
  170. package/dist/plugin/build/createSharedBuildConfig.d.ts.map +0 -1
  171. package/dist/plugin/build/createSharedBuildConfig.js +0 -28
  172. package/dist/plugin/build/mergeInputs.d.ts +0 -9
  173. package/dist/plugin/build/mergeInputs.d.ts.map +0 -1
  174. package/dist/plugin/build/mergeInputs.js +0 -56
  175. package/dist/plugin/config/moduleIdDefault.d.ts +0 -8
  176. package/dist/plugin/config/moduleIdDefault.d.ts.map +0 -1
  177. package/dist/plugin/config/moduleIdDefault.js +0 -23
  178. package/dist/plugin/config/moduleIdDefault.js.map +0 -1
  179. package/dist/plugin/helpers/getModuleManifest.js.map +0 -1
  180. package/dist/plugin/react-server/createDevMiddleware.d.ts +0 -8
  181. package/dist/plugin/react-server/createDevMiddleware.d.ts.map +0 -1
  182. package/dist/plugin/react-server/createDevMiddleware.js +0 -68
  183. package/dist/plugin/react-server/createDevServer.d.ts +0 -4
  184. package/dist/plugin/react-server/createDevServer.d.ts.map +0 -1
  185. package/dist/plugin/react-server/createDevServer.js +0 -4
  186. package/dist/plugin/react-server/createReactNodeStreamer.d.ts +0 -10
  187. package/dist/plugin/react-server/createReactNodeStreamer.d.ts.map +0 -1
  188. package/dist/plugin/react-server/createReactNodeStreamer.js +0 -7
  189. package/dist/plugin/transformer/transformer-server-actions.js.map +0 -1
  190. package/plugin/build/createClientBuildConfig.ts +0 -21
  191. package/plugin/build/createServerBuildConfig.ts +0 -66
  192. package/plugin/build/createSharedBuildConfig.ts +0 -35
  193. package/plugin/build/mergeInputs.ts +0 -58
  194. package/plugin/config/moduleIdDefault.ts +0 -23
  195. package/plugin/react-server/createDevMiddleware.ts +0 -91
  196. package/plugin/react-server/createDevServer.ts +0 -9
  197. package/plugin/react-server/createReactNodeStreamer.ts +0 -26
@@ -1,10 +1,23 @@
1
- import { mkdirSync } from "node:fs";
1
+ import { appendFile, mkdirSync } from "node:fs";
2
2
  import { mkdir, writeFile } from "node:fs/promises";
3
- import { dirname, join, resolve as resolvePath } from "node:path";
3
+ import { dirname, join, resolve, resolve as resolvePath } from "node:path";
4
4
  import { Transform } from "node:stream";
5
5
  import type { Worker } from "node:worker_threads";
6
6
  import { createHandler } from "../../react-server/createHandler.js";
7
- import type { ResolvedUserConfig, StreamPluginOptions } from "../../types.js";
7
+ import type { ResolvedUserConfig, ResolvedUserOptions } from "../../types.js";
8
+ import type {
9
+ HtmlWorkerMessage,
10
+ HtmlWorkerResponse,
11
+ WorkerRscChunkMessage,
12
+ } from "../types.js";
13
+ import type { Manifest } from "vite";
14
+ import type {
15
+ EmittedFile,
16
+ EmittedPrebuiltChunk,
17
+ PluginContext,
18
+ ResolvedId,
19
+ } from "rollup";
20
+ import { createInputNormalizer } from "../../helpers/inputNormalizer.js";
8
21
 
9
22
  interface PipeableStreamOptions {
10
23
  bootstrapModules?: string[];
@@ -24,18 +37,10 @@ interface PipeableStreamOptions {
24
37
  }
25
38
 
26
39
  type RenderPagesOptions = {
27
- pluginOptions: Required<
28
- Pick<
29
- StreamPluginOptions,
30
- "moduleBase" | "moduleBasePath" | "moduleBaseURL" | "projectRoot"
31
- >
32
- > &
33
- Pick<
34
- StreamPluginOptions,
35
- "Page" | "props" | "build" | "Html" | "pageExportName" | "propsExportName"
36
- >;
40
+ pluginOptions: ResolvedUserOptions;
37
41
  userConfig: ResolvedUserConfig;
38
- manifest: Record<string, { file: string }>;
42
+ clientManifest: Manifest;
43
+ serverManifest: Manifest;
39
44
  worker: Worker;
40
45
  pipableStreamOptions?: PipeableStreamOptions;
41
46
  loader: (id: string) => Promise<Record<string, any>>;
@@ -46,96 +51,153 @@ type RenderPagesOptions = {
46
51
  };
47
52
 
48
53
  export async function renderPages(
54
+ pluginContext: PluginContext,
49
55
  routes: string[],
50
56
  options: RenderPagesOptions
51
57
  ) {
52
- console.log("[renderPages] Starting render for routes:", routes);
58
+ const root =
59
+ pluginContext.environment.config.root ??
60
+ options.userConfig.root ??
61
+ options.pluginOptions.projectRoot ??
62
+ process.cwd();
63
+ const outDir =
64
+ pluginContext.environment.config.build.outDir ??
65
+ options.userConfig.build.outDir ??
66
+ options.pluginOptions.build.outDir;
67
+ const assetsDir =
68
+ pluginContext.environment.config.build.assetsDir ??
69
+ options.userConfig.build.assetsDir ??
70
+ options.pluginOptions.build.assetsDir;
53
71
 
54
- const destinationRoot = resolvePath(options.userConfig.root, options.userConfig.build.outDir);
72
+ const isServer = outDir.endsWith(options.pluginOptions.build.server);
73
+ const isClient = outDir.endsWith(options.pluginOptions.build.client);
74
+ if (!isServer && !isClient) {
75
+ throw new Error("Invalid outDir directory");
76
+ }
77
+
78
+ const destinationRoot = isServer
79
+ ? resolvePath(
80
+ root,
81
+ options.pluginOptions.build.outDir,
82
+ options.pluginOptions.build.client
83
+ )
84
+ : join(root, outDir);
55
85
  const failedRoutes = new Map<string, Error>();
56
- const moduleRootPath = join(destinationRoot, options.moduleBasePath);
57
- const moduleBaseURL = options.moduleBaseURL;
58
- const htmlRoot = join(
59
- options.userConfig.root,
60
- options.userConfig.build.outDir
61
- );
86
+ const moduleRootPath =
87
+ join(
88
+ root,
89
+ options.pluginOptions.build.outDir,
90
+ options.pluginOptions.build.client
91
+ ) + "/";
92
+ const moduleBaseURL = `file://${root}`;
93
+ const htmlRoot = destinationRoot;
94
+ const rscRoot = destinationRoot;
62
95
  const streamStarted = new Set<string>();
63
96
  const completedRoutes = new Set<string>();
64
97
  const htmlContent = new Map<string, string>();
98
+ const transforms = new Map<string, Transform>();
65
99
  const writePromises = new Map<string, Promise<void>>();
100
+ const pipableStreamOptions = options.pipableStreamOptions ?? {};
101
+ pipableStreamOptions.importMap = pipableStreamOptions?.importMap ?? {};
102
+ pipableStreamOptions.importMap.imports =
103
+ pipableStreamOptions.importMap.imports ?? {};
104
+ if (!("react" in pipableStreamOptions.importMap.imports)) {
105
+ pipableStreamOptions.importMap.imports["react"] = 'https://esm.sh/react@experimental?pin=v124&dev'
106
+ }
107
+ if (!("react-dom" in pipableStreamOptions.importMap.imports)) {
108
+ pipableStreamOptions.importMap.imports["react-dom"] = 'https://esm.sh/react-dom@experimental?pin=v124&dev'
109
+ }
110
+ if (!("react-dom/" in pipableStreamOptions.importMap.imports)) {
111
+ pipableStreamOptions.importMap.imports["react-dom/"] = 'https://esm.sh/react-dom@experimental&pin=v124&dev/'
112
+ }
113
+ if (!("react-server-dom-esm/client.browser" in pipableStreamOptions.importMap.imports)) {
114
+ pipableStreamOptions.importMap.imports["react-server-dom-esm/client.browser"] = `/node_modules/react-server-dom-esm/esm/react-server-dom-esm-client.browser.${options.userConfig.mode}.js`
115
+ }
116
+ // Find matching client components by their source paths
117
+ for (const [key, serverEntry] of Object.entries(options.serverManifest)) {
118
+ // Skip non-client components
119
+ if (!key.includes(".client.")) continue;
66
120
 
67
- // Create a promise that resolves when all routes are complete
68
- const allRoutesComplete = new Promise<void>((resolve, reject) => {
121
+ // Find matching client entry by source path
122
+ const clientEntry = Object.entries(options.clientManifest).find(
123
+ ([_, entry]) => entry.src === serverEntry.src
124
+ );
69
125
 
126
+ if (!clientEntry) continue;
70
127
 
71
- options.worker.on("message", function messageHandler(msg: any) {
72
- switch (msg.type) {
73
- case "SHELL_READY": {
74
- streamStarted.add(msg.id);
75
- break;
76
- }
77
- case "HTML_READY": {
78
- htmlContent.set(msg.id, msg.html);
79
- break;
80
- }
81
- case "ALL_READY": {
82
- completedRoutes.add(msg.id);
83
-
84
- if (completedRoutes.size === routes.length) {
85
- options.worker.removeListener("message", messageHandler);
128
+ const [_, entry] = clientEntry;
129
+ const serverPath = serverEntry.src as string;
130
+ const clientPath = entry.file
131
+
132
+ pipableStreamOptions.importMap.imports[serverPath] = '/' + clientPath;
133
+
134
+ }
135
+ for(const [key, value] of Object.entries(options.clientManifest)) {
136
+ if(value.isEntry) {
137
+ if(Array.isArray(pipableStreamOptions.bootstrapModules)) {
138
+ pipableStreamOptions.bootstrapModules.push('/'+value.file);
139
+ } else {
140
+ pipableStreamOptions.bootstrapModules = ['/'+value.file];
141
+ }
142
+ }
143
+ }
144
+
145
+ // Remove the initial empty file writes - we'll create directories as needed
146
+ await mkdir(htmlRoot, { recursive: true });
147
+ await mkdir(rscRoot, { recursive: true });
148
+
149
+ try {
150
+ const allRoutesComplete = new Promise<void>((resolve) => {
151
+ options.worker.on("message", (msg: HtmlWorkerResponse) => {
152
+ switch (msg.type) {
153
+ case "ALL_READY": {
154
+ const { id, html, outputPath } = msg;
155
+ mkdirSync(dirname(outputPath), { recursive: true });
86
156
 
87
- // Write all HTML files
88
- for (const [route, html] of htmlContent) {
89
- const outputPath = route === '/'
90
- ? join(htmlRoot, 'index.html')
91
- : join(htmlRoot, route, 'index.html');
92
- mkdirSync(dirname(outputPath), { recursive: true });
93
- const writePromise = writeFile(outputPath, html)
94
- .catch(error => {
95
- failedRoutes.set(route, error as Error);
96
- });
97
- writePromises.set(route, writePromise);
98
- }
99
-
100
- // Wait for all files to be written
101
- Promise.all(writePromises.values())
102
- .then(() => resolve())
103
- .catch(reject);
157
+ const writePromise = writeFile(outputPath, html)
158
+ .then(() => {
159
+ completedRoutes.add(id);
160
+ writePromises.delete(id);
161
+
162
+ // Only resolve when all routes are complete
163
+ if (completedRoutes.size === routes.length) {
164
+ resolve();
165
+ }
166
+ })
167
+ .catch((error) => {
168
+ failedRoutes.set(id, error as Error);
169
+ });
170
+
171
+ writePromises.set(id, writePromise);
172
+ break;
104
173
  }
105
- break;
106
- }
107
- case "ERROR": {
108
- console.error("[renderPages] Worker error:", msg.error);
109
- if (msg.id) {
174
+ case "ERROR": {
110
175
  failedRoutes.set(msg.id, new Error(msg.error));
176
+ break;
111
177
  }
112
- break;
113
178
  }
114
- }
179
+ });
115
180
  });
116
- });
117
-
118
- try {
119
- await mkdir(htmlRoot, { recursive: true });
120
181
 
121
182
  const renderPromises = routes.map(async (route) => {
122
-
123
183
  try {
124
184
  const result = await createHandler(route, options.pluginOptions, {
125
185
  loader: options.loader,
126
- manifest: options.manifest,
186
+ clientManifest: options.clientManifest,
187
+ serverManifest: options.serverManifest,
188
+ pipableStreamOptions: options.pipableStreamOptions,
127
189
  });
128
190
 
129
191
  if (result.type !== "success") {
130
- console.log("[renderPages] Handler failed:", result);
192
+ failedRoutes.set(route, new Error(`Handler failed for ${route}`));
131
193
  return;
132
194
  }
133
195
 
134
- const htmlOutputPath = route === '/'
135
- ? resolvePath(htmlRoot, 'index.html')
136
- : resolvePath(htmlRoot, route, 'index.html');
196
+ const htmlOutputPath = route === "/"
197
+ ? join(htmlRoot, "index.html")
198
+ : join(htmlRoot, route, "index.html");
137
199
 
138
- const transform = new Transform({
200
+ transforms.set(route, new Transform({
139
201
  transform(chunk, _encoding, callback) {
140
202
  options.worker.postMessage({
141
203
  type: "RSC_CHUNK",
@@ -143,10 +205,26 @@ export async function renderPages(
143
205
  chunk: chunk,
144
206
  moduleRootPath: moduleRootPath,
145
207
  moduleBaseURL: moduleBaseURL,
146
- htmlOutputPath,
208
+ htmlOutputPath: htmlOutputPath,
147
209
  outDir: options.userConfig.build.outDir,
148
- pipableStreamOptions: options.pipableStreamOptions ?? {},
149
- });
210
+ pipableStreamOptions: pipableStreamOptions,
211
+ clientManifest: options.clientManifest,
212
+ serverManifest: options.serverManifest,
213
+ } satisfies WorkerRscChunkMessage);
214
+
215
+ const rscOutputPath = route === "/"
216
+ ? join(rscRoot, "index.rsc")
217
+ : join(rscRoot, route, "index.rsc");
218
+
219
+ mkdirSync(dirname(rscOutputPath), { recursive: true });
220
+
221
+ // Track RSC file write
222
+ const writePromise = writeFile(rscOutputPath, chunk)
223
+ .catch((error) => {
224
+ failedRoutes.set(route, error as Error);
225
+ });
226
+
227
+ writePromises.set(`${route}:rsc`, writePromise);
150
228
  callback(null, chunk);
151
229
  },
152
230
  flush(callback) {
@@ -155,28 +233,37 @@ export async function renderPages(
155
233
  id: route,
156
234
  });
157
235
  callback();
158
- }
159
- });
160
-
161
- result.stream.pipe(transform);
236
+ },
237
+ }));
162
238
 
239
+ result.stream.pipe(transforms.get(route) as Transform);
240
+ await new Promise<void>((resolve) => {
241
+ transforms.get(route)?.on("finish", resolve);
242
+ });
163
243
  } catch (error) {
164
244
  failedRoutes.set(route, error as Error);
165
245
  }
166
246
  });
167
247
 
168
- // Wait for both the render promises and all routes to complete
169
- await Promise.all([
170
- Promise.all(renderPromises),
171
- allRoutesComplete
172
- ]);
248
+ // Wait for everything to complete
249
+ await Promise.all(renderPromises);
250
+ await Promise.all(writePromises.values());
251
+ await allRoutesComplete;
173
252
 
174
253
  } finally {
175
- await options.worker.terminate();
254
+ for (const transform of transforms.values()) {
255
+ transform.destroy();
256
+ }
257
+ transforms.clear();
258
+ writePromises.clear();
259
+
260
+ options.worker.postMessage({
261
+ type: "SHUTDOWN",
262
+ });
176
263
  }
177
264
 
178
265
  return {
179
266
  failedRoutes,
180
- completedRoutes
267
+ completedRoutes,
181
268
  };
182
269
  }
@@ -1,16 +1,7 @@
1
+
1
2
  /**
2
- * Extension point for custom module loading in the worker thread.
3
- * This file can be overridden via the plugin options:
4
- *
5
- * ```ts
6
- * reactStreamPlugin({
7
- * loaderPath: './my-custom-loader.ts'
8
- * })
9
- * ```
10
- *
11
- * The default loader provides basic module loading functionality.
12
- * Override this if you need custom module resolution or transformation.
3
+ * Not used currently
13
4
  */
14
- export function load(id: string) {
15
- return import(id);
5
+ export async function load(id: string) {
6
+ return await import(id);
16
7
  }
@@ -4,7 +4,16 @@ import { reactHtmlWorkerPlugin } from "./html/plugin.js"
4
4
  import { reactRscWorkerPlugin } from "./rsc/plugin.js"
5
5
 
6
6
  /**
7
- * This plugin can be used to create your own worker paths. By default, prebuild workers are used.
7
+ * This plugin can be used to create your own worker paths. This build should be separated from the main build.
8
+ *
9
+ *
10
+ * ```ts
11
+ * @example
12
+ *export reactWorkerPluginConfig = {
13
+ * htmlWorkerPath: './workers/html.tsx',
14
+ * rscWorkerPath: './workers/rsc.tsx',
15
+ * }
16
+ * ```
8
17
  *
9
18
  * @param options
10
19
  * @returns
@@ -1,4 +1,6 @@
1
- interface PipeableStreamOptions {
1
+ import type { Manifest } from "vite";
2
+
3
+ export interface PipeableStreamOptions {
2
4
  bootstrapModules?: string[];
3
5
  bootstrapScripts?: string[];
4
6
  bootstrapScriptContent?: string;
@@ -47,6 +49,8 @@ export interface WorkerRscChunkMessage {
47
49
  outDir: string;
48
50
  htmlOutputPath: string;
49
51
  pipableStreamOptions: PipeableStreamOptions;
52
+ clientManifest: Manifest; // Add client manifest
53
+ serverManifest: Manifest; // Add server manifest
50
54
  }
51
55
 
52
56
  export interface ShutdownMessage {
@@ -54,6 +58,18 @@ export interface ShutdownMessage {
54
58
  id: string;
55
59
  }
56
60
 
61
+ export interface ShellReadyMessage {
62
+ type: "SHELL_READY";
63
+ id: string;
64
+ }
65
+
66
+ export interface AllReadyMessage {
67
+ type: "ALL_READY";
68
+ id: string;
69
+ outputPath: string;
70
+ html: string;
71
+ }
72
+
57
73
  export interface RscRenderMessage {
58
74
  type: "RSC_RENDER";
59
75
  id: string;
@@ -71,7 +87,7 @@ export interface RscCompleteMessage {
71
87
  outputPath: string;
72
88
  }
73
89
 
74
- export interface RscErrorMessage {
90
+ export interface WorkerErrorMessage {
75
91
  type: "ERROR";
76
92
  id: string;
77
93
  error: string;
@@ -109,6 +125,11 @@ export type HtmlWorkerMessage =
109
125
  | RscEndMessage
110
126
  | ShutdownMessage;
111
127
 
128
+ export type HtmlWorkerResponse =
129
+ | ShellReadyMessage
130
+ | AllReadyMessage
131
+ | WorkerErrorMessage
132
+
112
133
  export type RscWorkerMessage =
113
134
  | RscRenderMessage
114
135
  | RscEndMessage
@@ -118,7 +139,7 @@ export type RscWorkerMessage =
118
139
 
119
140
  export type RscWorkerResponse =
120
141
  | RscCompleteMessage
121
- | RscErrorMessage
142
+ | WorkerErrorMessage
122
143
  | RscWroteFileMessage
123
144
  | ClientReferenceMessage
124
145
  | ServerReferenceMessage;