vite-plugin-react-server 0.1.0

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 (158) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +289 -0
  3. package/dist/build/createBuildConfig.d.ts +12 -0
  4. package/dist/build/createBuildConfig.d.ts.map +1 -0
  5. package/dist/build/createBuildConfig.js +55 -0
  6. package/dist/build/createBuildConfig.js.map +1 -0
  7. package/dist/checkFilesExist.d.ts +8 -0
  8. package/dist/checkFilesExist.d.ts.map +1 -0
  9. package/dist/checkFilesExist.js +61 -0
  10. package/dist/checkFilesExist.js.map +1 -0
  11. package/dist/collect-css-manifest.d.ts +4 -0
  12. package/dist/collect-css-manifest.d.ts.map +1 -0
  13. package/dist/collect-css-manifest.js +57 -0
  14. package/dist/collect-css-manifest.js.map +1 -0
  15. package/dist/components.d.ts +13 -0
  16. package/dist/components.d.ts.map +1 -0
  17. package/dist/components.js +13 -0
  18. package/dist/components.js.map +1 -0
  19. package/dist/copy-dir.d.ts +4 -0
  20. package/dist/copy-dir.d.ts.map +1 -0
  21. package/dist/getEnv.d.ts +19 -0
  22. package/dist/getEnv.d.ts.map +1 -0
  23. package/dist/getEnv.js +76 -0
  24. package/dist/getEnv.js.map +1 -0
  25. package/dist/helpers/normalizedRelativePath.d.ts +9 -0
  26. package/dist/helpers/normalizedRelativePath.d.ts.map +1 -0
  27. package/dist/helpers/normalizedRelativePath.js +31 -0
  28. package/dist/helpers/normalizedRelativePath.js.map +1 -0
  29. package/dist/helpers/tryManifest.d.ts +8 -0
  30. package/dist/helpers/tryManifest.d.ts.map +1 -0
  31. package/dist/html/createPageLoader.d.ts +26 -0
  32. package/dist/html/createPageLoader.d.ts.map +1 -0
  33. package/dist/html/createPageLoader.js +70 -0
  34. package/dist/html/createPageLoader.js.map +1 -0
  35. package/dist/index.d.ts +3 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +5 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/manifest.d.ts +6 -0
  40. package/dist/manifest.d.ts.map +1 -0
  41. package/dist/module-graph.d.ts +10 -0
  42. package/dist/module-graph.d.ts.map +1 -0
  43. package/dist/options.d.ts +86 -0
  44. package/dist/options.d.ts.map +1 -0
  45. package/dist/options.js +251 -0
  46. package/dist/options.js.map +1 -0
  47. package/dist/plugin.d.ts +8 -0
  48. package/dist/plugin.d.ts.map +1 -0
  49. package/dist/plugin.js +31 -0
  50. package/dist/plugin.js.map +1 -0
  51. package/dist/react-client/plugin.d.ts +4 -0
  52. package/dist/react-client/plugin.d.ts.map +1 -0
  53. package/dist/react-client/plugin.js +28 -0
  54. package/dist/react-client/plugin.js.map +1 -0
  55. package/dist/react-server/createDevMiddleware.d.ts +8 -0
  56. package/dist/react-server/createDevMiddleware.d.ts.map +1 -0
  57. package/dist/react-server/createDevServer.d.ts +4 -0
  58. package/dist/react-server/createDevServer.d.ts.map +1 -0
  59. package/dist/react-server/createHandler.d.ts +23 -0
  60. package/dist/react-server/createHandler.d.ts.map +1 -0
  61. package/dist/react-server/createHandler.js +110 -0
  62. package/dist/react-server/createHandler.js.map +1 -0
  63. package/dist/react-server/createReactNodeStreamer.d.ts +10 -0
  64. package/dist/react-server/createReactNodeStreamer.d.ts.map +1 -0
  65. package/dist/react-server/createRscStream.d.ts +4 -0
  66. package/dist/react-server/createRscStream.d.ts.map +1 -0
  67. package/dist/react-server/createRscStream.js +47 -0
  68. package/dist/react-server/createRscStream.js.map +1 -0
  69. package/dist/react-server/createSsrHandler.d.ts +4 -0
  70. package/dist/react-server/createSsrHandler.d.ts.map +1 -0
  71. package/dist/react-server/plugin.d.ts +8 -0
  72. package/dist/react-server/plugin.d.ts.map +1 -0
  73. package/dist/react-server/plugin.js +298 -0
  74. package/dist/react-server/plugin.js.map +1 -0
  75. package/dist/resolvePage.d.ts +19 -0
  76. package/dist/resolvePage.d.ts.map +1 -0
  77. package/dist/resolvePage.js +44 -0
  78. package/dist/resolvePage.js.map +1 -0
  79. package/dist/resolveProps.d.ts +19 -0
  80. package/dist/resolveProps.d.ts.map +1 -0
  81. package/dist/resolveProps.js +90 -0
  82. package/dist/resolveProps.js.map +1 -0
  83. package/dist/server.d.ts +2 -0
  84. package/dist/server.d.ts.map +1 -0
  85. package/dist/transformer/index.d.ts +28 -0
  86. package/dist/transformer/index.d.ts.map +1 -0
  87. package/dist/transformer/index.js +54 -0
  88. package/dist/transformer/index.js.map +1 -0
  89. package/dist/transformer/preserveDirectives.d.ts +4 -0
  90. package/dist/transformer/preserveDirectives.d.ts.map +1 -0
  91. package/dist/transformer/preserveDirectives.js +72 -0
  92. package/dist/transformer/preserveDirectives.js.map +1 -0
  93. package/dist/transformer/preserver.d.ts +2 -0
  94. package/dist/transformer/preserver.d.ts.map +1 -0
  95. package/dist/transformer/transformer.d.ts +30 -0
  96. package/dist/transformer/transformer.d.ts.map +1 -0
  97. package/dist/transformer/transformer.js +80 -0
  98. package/dist/transformer/transformer.js.map +1 -0
  99. package/dist/transformer/types.d.ts +15 -0
  100. package/dist/transformer/types.d.ts.map +1 -0
  101. package/dist/types.d.ts +197 -0
  102. package/dist/types.d.ts.map +1 -0
  103. package/dist/worker/createHtmlStream.d.ts +7 -0
  104. package/dist/worker/createHtmlStream.d.ts.map +1 -0
  105. package/dist/worker/createWorker.d.ts +3 -0
  106. package/dist/worker/createWorker.d.ts.map +1 -0
  107. package/dist/worker/createWorker.js +33 -0
  108. package/dist/worker/createWorker.js.map +1 -0
  109. package/dist/worker/loader.d.ts +15 -0
  110. package/dist/worker/loader.d.ts.map +1 -0
  111. package/dist/worker/renderPages.d.ts +18 -0
  112. package/dist/worker/renderPages.d.ts.map +1 -0
  113. package/dist/worker/renderPages.js +99 -0
  114. package/dist/worker/renderPages.js.map +1 -0
  115. package/dist/worker/types.d.ts +31 -0
  116. package/dist/worker/types.d.ts.map +1 -0
  117. package/dist/worker/worker.d.ts +7 -0
  118. package/dist/worker/worker.d.ts.map +1 -0
  119. package/package.json +116 -0
  120. package/src/build/createBuildConfig.ts +74 -0
  121. package/src/checkFilesExist.ts +67 -0
  122. package/src/collect-css-manifest.ts +76 -0
  123. package/src/components.tsx +14 -0
  124. package/src/copy-dir.ts +27 -0
  125. package/src/getEnv.ts +135 -0
  126. package/src/helpers/normalizedRelativePath.ts +59 -0
  127. package/src/helpers/tryManifest.ts +23 -0
  128. package/src/html/createPageLoader.ts +99 -0
  129. package/src/index.ts +4 -0
  130. package/src/manifest.ts +24 -0
  131. package/src/module-graph.ts +48 -0
  132. package/src/options.ts +351 -0
  133. package/src/plugin.ts +31 -0
  134. package/src/react-client/plugin.ts +34 -0
  135. package/src/react-server/createDevMiddleware.ts +75 -0
  136. package/src/react-server/createDevServer.ts +10 -0
  137. package/src/react-server/createHandler.ts +144 -0
  138. package/src/react-server/createReactNodeStreamer.ts +25 -0
  139. package/src/react-server/createRscStream.ts +52 -0
  140. package/src/react-server/createSsrHandler.ts +147 -0
  141. package/src/react-server/plugin.ts +349 -0
  142. package/src/resolvePage.ts +65 -0
  143. package/src/resolveProps.ts +122 -0
  144. package/src/server.tsx +0 -0
  145. package/src/transformer/README.md +44 -0
  146. package/src/transformer/index.ts +112 -0
  147. package/src/transformer/preserveDirectives.ts +100 -0
  148. package/src/transformer/preserver.ts +47 -0
  149. package/src/transformer/transformer.ts +123 -0
  150. package/src/transformer/types.ts +15 -0
  151. package/src/types.ts +245 -0
  152. package/src/worker/createHtmlStream.ts +76 -0
  153. package/src/worker/createWorker.ts +39 -0
  154. package/src/worker/loader.ts +16 -0
  155. package/src/worker/renderPages.ts +144 -0
  156. package/src/worker/types.ts +38 -0
  157. package/src/worker/worker.tsx +136 -0
  158. package/tsconfig.json +79 -0
@@ -0,0 +1,4 @@
1
+ import { type ViteDevServer } from "vite";
2
+ import type { RequestHandler, StreamPluginOptions } from "../types.js";
3
+ export declare function createSsrHandler(options: Required<Pick<StreamPluginOptions, "Page" | "props" | "build" | "Html" | "pageExportName" | "propsExportName">> & Required<Pick<StreamPluginOptions, "moduleBase" | "moduleBasePath" | "moduleBaseURL" | "projectRoot">> & Pick<StreamPluginOptions, "workerPath">, server: ViteDevServer, clientComponents: Map<string, string>): RequestHandler;
4
+ //# sourceMappingURL=createSsrHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createSsrHandler.d.ts","sourceRoot":"","sources":["../../src/react-server/createSsrHandler.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAMvE,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,QAAQ,CACf,IAAI,CACF,mBAAmB,EACnB,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,gBAAgB,GAAG,iBAAiB,CAC3E,CACF,GACC,QAAQ,CACN,IAAI,CACF,mBAAmB,EACnB,YAAY,GAAG,gBAAgB,GAAG,eAAe,GAAG,aAAa,CAClE,CACF,GACD,IAAI,CAAC,mBAAmB,EAAE,YAAY,CAAC,EACzC,MAAM,EAAE,aAAa,EACrB,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GACpC,cAAc,CAsHhB"}
@@ -0,0 +1,8 @@
1
+ import type { Plugin as RollupPlugin } from "rollup";
2
+ import type { Plugin as VitePlugin } from "vite";
3
+ import type { ReactStreamPluginMeta } from "../types.js";
4
+ import { type StreamPluginOptions } from "../types.js";
5
+ export declare function reactStreamPlugin(options?: StreamPluginOptions): Promise<VitePlugin & RollupPlugin & {
6
+ meta: ReactStreamPluginMeta;
7
+ }>;
8
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/react-server/plugin.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,QAAQ,CAAC;AACrD,OAAO,KAAK,EAAY,MAAM,IAAI,UAAU,EAAE,MAAM,MAAM,CAAC;AAa3D,OAAO,KAAK,EAAe,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AA0BvD,wBAAsB,iBAAiB,CACrC,OAAO,GAAE,mBAA+C,GACvD,OAAO,CAAC,UAAU,GAAG,YAAY,GAAG;IAAE,IAAI,EAAE,qBAAqB,CAAA;CAAE,CAAC,CA4StE"}
@@ -0,0 +1,298 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ import { performance } from "node:perf_hooks";
4
+ import "node:worker_threads";
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;
16
+ let worker;
17
+ let config;
18
+ let cssModules = /* @__PURE__ */ new Set();
19
+ let clientComponents = /* @__PURE__ */ new Map();
20
+ let define;
21
+ let buildCssFiles = /* @__PURE__ */ new Set();
22
+ async function reactStreamPlugin(options = {}) {
23
+ const timing = {
24
+ start: performance.now()
25
+ };
26
+ const resolvedOptions = resolveOptions(options);
27
+ if (resolvedOptions.type === "error") {
28
+ console.error(
29
+ "[vite-react-stream:server] Error resolving userOptions. Please check your userOptions."
30
+ );
31
+ throw resolvedOptions.error;
32
+ }
33
+ const { userOptions } = resolvedOptions;
34
+ return {
35
+ name: "vite:react-stream",
36
+ meta: {
37
+ timing
38
+ },
39
+ api: {
40
+ addCssFile(path) {
41
+ buildCssFiles.add(path);
42
+ }
43
+ },
44
+ configResolved(resolvedConfig) {
45
+ if (resolvedConfig.command === "build") {
46
+ timing.configResolved = performance.now();
47
+ console.log("[vite-react-stream] Starting build...");
48
+ }
49
+ config = resolvedConfig;
50
+ },
51
+ async configureServer(server) {
52
+ if (server.config.root) {
53
+ console.log(
54
+ "[vite-react-stream] Root dir changed",
55
+ server.config.root,
56
+ server.config.root
57
+ );
58
+ }
59
+ const activeStreams = /* @__PURE__ */ new Set();
60
+ server.ws.on("restart", (path) => {
61
+ console.log(
62
+ "[vite-react-stream] 🔧 Plugin changed, preparing for restart:",
63
+ path
64
+ );
65
+ for (const res of activeStreams) {
66
+ res.writeHead(503, {
67
+ "Content-Type": "text/x-component",
68
+ "Retry-After": "1"
69
+ });
70
+ res.end('{"error":"Server restarting..."}');
71
+ }
72
+ activeStreams.clear();
73
+ });
74
+ server.ws.on("connection", (socket, req) => {
75
+ console.log("[vite-react-stream] hooking up ws connection");
76
+ });
77
+ server.ws.on("listening", () => {
78
+ console.log("[vite-react-stream] hooking up ws listening");
79
+ });
80
+ server.middlewares.use(async (req, res, next) => {
81
+ if (req.headers.accept !== "text/x-component") return next();
82
+ console.log("[vite-react-stream] middleware called");
83
+ try {
84
+ const handler = await createHandler(
85
+ req.url ?? "",
86
+ {
87
+ Page: userOptions.Page,
88
+ props: userOptions.props,
89
+ build: userOptions.build,
90
+ Html: ({ children }) => children,
91
+ pageExportName: userOptions.pageExportName,
92
+ propsExportName: userOptions.propsExportName,
93
+ moduleBase: userOptions.moduleBase,
94
+ moduleBasePath: userOptions.moduleBasePath,
95
+ projectRoot: server.config.root
96
+ },
97
+ {
98
+ cssFiles: Array.from(cssModules),
99
+ logger: createLogger(),
100
+ loader: server.ssrLoadModule,
101
+ moduleGraph: server.moduleGraph
102
+ }
103
+ );
104
+ handler?.stream?.pipe(res);
105
+ } finally {
106
+ res.on("close", () => {
107
+ console.log("[vite-react-stream] ➖ Stream closed for:", req.url);
108
+ activeStreams.delete(res);
109
+ });
110
+ }
111
+ });
112
+ },
113
+ async config(config2, configEnv) {
114
+ const resolvedPages = await resolvePages(userOptions.build.pages);
115
+ if (resolvedPages.type === "error") {
116
+ throw resolvedPages.error;
117
+ }
118
+ const { pages } = resolvedPages;
119
+ const resolvedConfig = resolveUserConfig(
120
+ "react-server",
121
+ pages,
122
+ config2,
123
+ configEnv,
124
+ userOptions
125
+ );
126
+ if (resolvedConfig.type === "error") {
127
+ throw resolvedConfig.error;
128
+ }
129
+ 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
+ );
141
+ const buildConfig = createBuildConfig({
142
+ root: config2.root ?? process.cwd(),
143
+ base: config2.base ?? envResult.publicUrl,
144
+ outDir: config2.build?.outDir ?? "dist/server",
145
+ entries
146
+ });
147
+ return {
148
+ ...buildConfig,
149
+ define,
150
+ plugins: config2.plugins
151
+ };
152
+ },
153
+ async buildStart() {
154
+ timing.buildStart = performance.now();
155
+ },
156
+ async closeBundle() {
157
+ if (!config) return;
158
+ console.log("RSC CLOSE BUNDLE CALLED");
159
+ if (!pageSet?.size) return;
160
+ timing.renderStart = performance.now();
161
+ 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"
190
+ );
191
+ const routes = Array.from(pageMap.keys());
192
+ const indexEntry = clientManifest["index.html"];
193
+ if (!indexEntry) {
194
+ throw new Error("root /index.html not found");
195
+ }
196
+ await renderPages(routes, {
197
+ pipableStreamOptions: {
198
+ bootstrapModules: ["/" + indexEntry.file]
199
+ },
200
+ outDir: config.build.outDir,
201
+ clientCss: indexEntry.css?.map((css) => "/" + css) ?? [],
202
+ pluginOptions: {
203
+ Page: userOptions.Page,
204
+ props: userOptions.props,
205
+ build: userOptions.build,
206
+ Html: userOptions.Html,
207
+ pageExportName: userOptions.pageExportName,
208
+ propsExportName: userOptions.propsExportName,
209
+ moduleBase: userOptions.moduleBase,
210
+ moduleBasePath: userOptions.moduleBasePath,
211
+ moduleBaseURL: userOptions.moduleBaseURL,
212
+ projectRoot: config.root
213
+ },
214
+ worker,
215
+ manifest: clientManifest,
216
+ loader: createPageLoader({
217
+ manifest,
218
+ root: config.root,
219
+ outDir: config.build.outDir,
220
+ moduleBase: userOptions.moduleBase,
221
+ alwaysRegisterServer: false,
222
+ alwaysRegisterClient: false,
223
+ registerServer: [],
224
+ registerClient: Object.keys(clientManifest).filter(
225
+ (key) => key.endsWith(".client.tsx") && clientManifest[key].isEntry
226
+ )
227
+ }),
228
+ onCssFile: (path) => buildCssFiles.add(path)
229
+ });
230
+ console.log("[vite-react-stream] Render complete");
231
+ console.log("[vite-react-stream] Terminating worker");
232
+ if (worker) await worker.terminate();
233
+ timing.renderEnd = performance.now();
234
+ timing.total = (timing.renderEnd - timing.start) / 1e3;
235
+ const stats = {
236
+ htmlFiles: routes.length,
237
+ clientComponents: clientComponents.size,
238
+ cssFiles: cssModules.size,
239
+ totalRoutes: routes.length,
240
+ timing: {
241
+ config: ((timing.configResolved ?? 0) - timing.start) / 1e3,
242
+ build: ((timing.buildStart ?? 0) - (timing.configResolved ?? 0)) / 1e3,
243
+ render: ((timing.renderEnd ?? 0) - (timing.renderStart ?? 0)) / 1e3,
244
+ total: (timing.renderEnd ?? 0 - timing.start) / 1e3
245
+ }
246
+ };
247
+ const formatDuration = (seconds) => {
248
+ if (seconds < 1e-3) {
249
+ return `${(seconds * 1e6).toFixed(0)}μs`;
250
+ }
251
+ if (seconds < 1) {
252
+ return `${(seconds * 1e3).toFixed(0)}ms`;
253
+ }
254
+ return `${seconds.toFixed(2)}s`;
255
+ };
256
+ console.log("\n[vite-react-stream] Build Summary:");
257
+ console.log("─".repeat(50));
258
+ console.log(`📄 Generated ${stats.htmlFiles} HTML files`);
259
+ console.log(`🎯 Processed ${stats.clientComponents} client components`);
260
+ console.log(`🎨 Included ${stats.cssFiles} CSS files`);
261
+ console.log(`🛣️ Total routes: ${stats.totalRoutes}`);
262
+ console.log("─".repeat(50));
263
+ console.log("⏱️ Timing:");
264
+ console.log(` Config: ${formatDuration(stats.timing.config)}`);
265
+ console.log(` Build: ${formatDuration(stats.timing.build)}`);
266
+ console.log(` Render: ${formatDuration(stats.timing.render)}`);
267
+ console.log(" ".repeat(12));
268
+ console.log(` Total: ${formatDuration(stats.timing.total)}`);
269
+ console.log("─".repeat(50));
270
+ } catch (error) {
271
+ console.error("[vite-react-stream] Build failed:", error);
272
+ throw error;
273
+ }
274
+ },
275
+ async buildEnd(error) {
276
+ if (error) {
277
+ console.error("[vite-react-stream] Build error:", error);
278
+ }
279
+ if (worker) await worker.terminate();
280
+ },
281
+ handleHotUpdate({ file }) {
282
+ if (file.endsWith(".css")) {
283
+ cssModules.add(file);
284
+ }
285
+ },
286
+ transform(code, id) {
287
+ if ((id.includes(".client") || code.startsWith('"use client"') || code.startsWith("use client")) && !id.includes("node_modules")) {
288
+ console.log("[vite-react-stream] Client component added", id);
289
+ clientComponents.set(id, code);
290
+ }
291
+ return { code };
292
+ }
293
+ };
294
+ }
295
+ export {
296
+ reactStreamPlugin
297
+ };
298
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +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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"}
@@ -0,0 +1,19 @@
1
+ type ResolvePageOptions = {
2
+ pageModule: Record<string, any>;
3
+ path: string;
4
+ url: string;
5
+ exportName: string;
6
+ };
7
+ type ResolvePageResult = {
8
+ type: "success";
9
+ key: string;
10
+ Page: any;
11
+ } | {
12
+ type: "error";
13
+ error: Error;
14
+ } | {
15
+ type: "skip";
16
+ };
17
+ export declare function resolvePage({ pageModule, path, url, exportName, }: ResolvePageOptions): Promise<ResolvePageResult>;
18
+ export {};
19
+ //# sourceMappingURL=resolvePage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolvePage.d.ts","sourceRoot":"","sources":["../src/resolvePage.ts"],"names":[],"mappings":"AAAA,KAAK,kBAAkB,GAAG;IACxB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,KAAK,iBAAiB,GAClB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,GAAG,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAErB,wBAAsB,WAAW,CAAC,EAChC,UAAU,EACV,IAAI,EACJ,GAAG,EACH,UAAU,GACX,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA+CjD"}
@@ -0,0 +1,44 @@
1
+ async function resolvePage({
2
+ pageModule,
3
+ path,
4
+ url,
5
+ exportName
6
+ }) {
7
+ if (!pageModule) {
8
+ return {
9
+ type: "error",
10
+ error: new Error(`pageModule is ${typeof pageModule}`)
11
+ };
12
+ }
13
+ const keys = typeof pageModule === "object" && pageModule != null ? Object.keys(pageModule) : [];
14
+ const found = keys.find((v) => v === exportName || v === url || v === path);
15
+ if (found) {
16
+ if (typeof pageModule[found] === "function") {
17
+ return {
18
+ type: "success",
19
+ key: found,
20
+ Page: pageModule[found]
21
+ };
22
+ } else {
23
+ if (typeof pageModule === "object" && pageModule != null && Object.keys(pageModule).includes("type"))
24
+ return pageModule;
25
+ return {
26
+ type: "error",
27
+ [exportName]: () => found,
28
+ error: pageModule[found]["error"]
29
+ };
30
+ }
31
+ }
32
+ if (keys.includes("type")) return pageModule;
33
+ return {
34
+ type: "error",
35
+ error: new Error(
36
+ `Could not find Page export "${exportName}" in "${path}". ${typeof pageModule === "object" && pageModule != null ? keys.length ? "Available exports: " + keys.join(", ") : "The object was defined but has no properties." : "typeof pageModule =" + typeof pageModule}`,
37
+ { cause: pageModule }
38
+ )
39
+ };
40
+ }
41
+ export {
42
+ resolvePage
43
+ };
44
+ //# sourceMappingURL=resolvePage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolvePage.js","sources":["../src/resolvePage.ts"],"sourcesContent":["type ResolvePageOptions = {\n pageModule: Record<string, any>;\n path: string;\n url: string;\n exportName: string;\n};\n\ntype ResolvePageResult =\n | { type: \"success\"; key: string; Page: any }\n | { type: \"error\"; error: Error }\n | { type: \"skip\" };\n\nexport async function resolvePage({\n pageModule,\n path,\n url,\n exportName,\n}: ResolvePageOptions): Promise<ResolvePageResult> {\n if (!pageModule) {\n return {\n type: \"error\",\n error: new Error(`pageModule is ${typeof pageModule}`),\n };\n }\n const keys =\n typeof pageModule === \"object\" && pageModule != null\n ? Object.keys(pageModule)\n : [];\n const found = keys.find((v) => v === exportName || v === url || v === path);\n if (found) {\n if (typeof pageModule[found] === \"function\") {\n return {\n type: \"success\",\n key: found,\n Page: pageModule[found],\n };\n } else {\n if (\n typeof pageModule === \"object\" &&\n pageModule != null &&\n Object.keys(pageModule).includes(\"type\")\n )\n return pageModule as ResolvePageResult;\n return {\n type: \"error\",\n [exportName]: () => found,\n error: pageModule[found][\"error\"],\n };\n }\n }\n if (keys.includes(\"type\")) return pageModule as ResolvePageResult;\n return {\n type: \"error\",\n error: new Error(\n `Could not find Page export \"${exportName}\" in \"${path}\". ${\n typeof pageModule === \"object\" && pageModule != null\n ? keys.length\n ? \"Available exports: \" + keys.join(\", \")\n : \"The object was defined but has no properties.\"\n : \"typeof pageModule =\" + typeof pageModule\n }`,\n { cause: pageModule }\n ),\n };\n}\n"],"names":[],"mappings":"AAYA,eAAsB,YAAY;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAmD;AACjD,MAAI,CAAC,YAAY;AACR,WAAA;AAAA,MACL,MAAM;AAAA,MACN,OAAO,IAAI,MAAM,iBAAiB,OAAO,UAAU,EAAE;AAAA,IACvD;AAAA,EAAA;AAEI,QAAA,OACJ,OAAO,eAAe,YAAY,cAAc,OAC5C,OAAO,KAAK,UAAU,IACtB,CAAC;AACD,QAAA,QAAQ,KAAK,KAAK,CAAC,MAAM,MAAM,cAAc,MAAM,OAAO,MAAM,IAAI;AAC1E,MAAI,OAAO;AACT,QAAI,OAAO,WAAW,KAAK,MAAM,YAAY;AACpC,aAAA;AAAA,QACL,MAAM;AAAA,QACN,KAAK;AAAA,QACL,MAAM,WAAW,KAAK;AAAA,MACxB;AAAA,IAAA,OACK;AAEH,UAAA,OAAO,eAAe,YACtB,cAAc,QACd,OAAO,KAAK,UAAU,EAAE,SAAS,MAAM;AAEhC,eAAA;AACF,aAAA;AAAA,QACL,MAAM;AAAA,QACN,CAAC,UAAU,GAAG,MAAM;AAAA,QACpB,OAAO,WAAW,KAAK,EAAE,OAAO;AAAA,MAClC;AAAA,IAAA;AAAA,EACF;AAEF,MAAI,KAAK,SAAS,MAAM,EAAU,QAAA;AAC3B,SAAA;AAAA,IACL,MAAM;AAAA,IACN,OAAO,IAAI;AAAA,MACT,+BAA+B,UAAU,SAAS,IAAI,MACpD,OAAO,eAAe,YAAY,cAAc,OAC5C,KAAK,SACH,wBAAwB,KAAK,KAAK,IAAI,IACtC,kDACF,wBAAwB,OAAO,UACrC;AAAA,MACA,EAAE,OAAO,WAAW;AAAA,IAAA;AAAA,EAExB;AACF;"}
@@ -0,0 +1,19 @@
1
+ type ResolvePropsOptions = {
2
+ propsModule: Record<string, any>;
3
+ path: string;
4
+ exportName: string;
5
+ url: string;
6
+ };
7
+ type ResolvePropsResult = {
8
+ type: "success";
9
+ key: string;
10
+ props: any;
11
+ } | {
12
+ type: "error";
13
+ error: Error;
14
+ } | {
15
+ type: "skip";
16
+ };
17
+ export declare function resolveProps({ propsModule, path, exportName, url, }: ResolvePropsOptions): Promise<ResolvePropsResult>;
18
+ export {};
19
+ //# sourceMappingURL=resolveProps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveProps.d.ts","sourceRoot":"","sources":["../src/resolveProps.ts"],"names":[],"mappings":"AAAA,KAAK,mBAAmB,GAAG;IACzB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,KAAK,kBAAkB,GACnB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,GAAG,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAMrB,wBAAsB,YAAY,CAAC,EACjC,WAAW,EACX,IAAI,EACJ,UAAU,EACV,GAAG,GACJ,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAoGnD"}
@@ -0,0 +1,90 @@
1
+ function isFunction(value) {
2
+ return typeof value === "function";
3
+ }
4
+ async function resolveProps({
5
+ propsModule,
6
+ path,
7
+ exportName,
8
+ url
9
+ }) {
10
+ if (!propsModule) {
11
+ return {
12
+ type: "error",
13
+ error: new Error(`propsModule is ${typeof propsModule}`)
14
+ };
15
+ }
16
+ if (typeof propsModule !== "object") {
17
+ return {
18
+ type: "error",
19
+ error: new Error(
20
+ `propsModule must be an object, got ${typeof propsModule}`
21
+ )
22
+ };
23
+ }
24
+ const keys = Object.keys(propsModule);
25
+ const found = keys.find((v) => v === exportName || v === url || v === path);
26
+ if (found) {
27
+ const value = propsModule[found];
28
+ try {
29
+ if (isFunction(value)) {
30
+ const props = await value(url);
31
+ return {
32
+ type: "success",
33
+ key: found,
34
+ props
35
+ };
36
+ }
37
+ if (value && typeof value.then === "function") {
38
+ const props = await value;
39
+ return {
40
+ type: "success",
41
+ key: found,
42
+ props
43
+ };
44
+ }
45
+ if (typeof value === "object" && value !== null) {
46
+ return {
47
+ type: "success",
48
+ key: found,
49
+ props: value
50
+ };
51
+ }
52
+ console.warn(found, "error in resolveProps", propsModule, url, path);
53
+ return {
54
+ type: "error",
55
+ error: new Error(
56
+ `Expected props export "${exportName}" in "${path}" to be a function, promise, or object that resolves to props, instead got typeof ${typeof value}.`
57
+ )
58
+ };
59
+ } catch (error) {
60
+ console.warn(found, "error in resolveProps", propsModule, url, path);
61
+ return {
62
+ type: "error",
63
+ error
64
+ };
65
+ }
66
+ }
67
+ const commonjs = keys.find((v) => v === "exports");
68
+ if (!!commonjs) {
69
+ const exportKeys = commonjs["exports"] ? Object.keys(commonjs["exports"]) : [];
70
+ const foundCommonJS = exportKeys.find(
71
+ (v) => v === exportName || v === url || v === path
72
+ );
73
+ return {
74
+ type: "error",
75
+ error: new Error(
76
+ `Expected props export "${exportName}" in "${path}", but instead got "exports" with ${!!foundCommonJS ? foundCommonJS.toString() : exportKeys.length ? exportKeys.join(", ") : "no keys"}, this will not work. Make sure to set esModule: true in rollupOptions.output`
77
+ )
78
+ };
79
+ }
80
+ return {
81
+ type: "error",
82
+ error: new Error(
83
+ `Could not find props export "${exportName}" in "${path}". ${keys.length ? "Available exports: " + keys.join(", ") : "The object was defined but has no properties."}`
84
+ )
85
+ };
86
+ }
87
+ export {
88
+ resolveProps
89
+ };
90
+ //# sourceMappingURL=resolveProps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveProps.js","sources":["../src/resolveProps.ts"],"sourcesContent":["type ResolvePropsOptions = {\n propsModule: Record<string, any>;\n path: string;\n exportName: string;\n url: string;\n};\n\ntype ResolvePropsResult =\n | { type: \"success\"; key: string; props: any }\n | { type: \"error\"; error: Error }\n | { type: \"skip\" };\n\nfunction isFunction(value: any) {\n return typeof value === \"function\";\n}\n\nexport async function resolveProps({\n propsModule,\n path,\n exportName,\n url,\n}: ResolvePropsOptions): Promise<ResolvePropsResult> {\n if (!propsModule) {\n return {\n type: \"error\",\n error: new Error(`propsModule is ${typeof propsModule}`),\n };\n }\n\n if (typeof propsModule !== \"object\") {\n return {\n type: \"error\",\n error: new Error(\n `propsModule must be an object, got ${typeof propsModule}`\n ),\n };\n }\n\n const keys = Object.keys(propsModule);\n const found = keys.find((v) => v === exportName || v === url || v === path);\n if (found) {\n const value = propsModule[found];\n\n try {\n // If it's a function, call it with the URL\n if (isFunction(value)) {\n const props = await value(url);\n return {\n type: \"success\",\n key: found,\n props,\n };\n }\n\n // If it's a promise, await it\n if (value && typeof value.then === \"function\") {\n const props = await value;\n return {\n type: \"success\",\n key: found,\n props,\n };\n }\n\n // If it's a plain object, use it directly\n if (typeof value === \"object\" && value !== null) {\n return {\n type: \"success\",\n key: found,\n props: value,\n };\n }\n\n console.warn(found, \"error in resolveProps\", propsModule, url, path);\n return {\n type: \"error\",\n error: new Error(\n `Expected props export \"${exportName}\" in \"${path}\" to be a function, promise, or object that resolves to props, instead got typeof ${typeof value}.`\n ),\n };\n } catch (error) {\n console.warn(found, \"error in resolveProps\", propsModule, url, path);\n return {\n type: \"error\",\n error: error as Error,\n };\n }\n }\n const commonjs = keys.find((v) => v === \"exports\");\n\n if (!!commonjs) {\n const exportKeys = (commonjs as unknown as { exports: any })[\"exports\"]\n ? Object.keys((commonjs as unknown as { exports: any })[\"exports\"])\n : [];\n const foundCommonJS = exportKeys.find(\n (v) => v === exportName || v === url || v === path\n );\n return {\n type: \"error\",\n error: new Error(\n `Expected props export \"${exportName}\" in \"${path}\", but instead got \"exports\" with ${\n !!foundCommonJS\n ? foundCommonJS.toString()\n : exportKeys.length\n ? exportKeys.join(\", \")\n : \"no keys\"\n }, this will not work. Make sure to set esModule: true in rollupOptions.output`\n ),\n };\n }\n\n return {\n type: \"error\",\n error: new Error(\n `Could not find props export \"${exportName}\" in \"${path}\". ${\n keys.length\n ? \"Available exports: \" + keys.join(\", \")\n : \"The object was defined but has no properties.\"\n }`\n ),\n };\n}\n"],"names":[],"mappings":"AAYA,SAAS,WAAW,OAAY;AAC9B,SAAO,OAAO,UAAU;AAC1B;AAEA,eAAsB,aAAa;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAqD;AACnD,MAAI,CAAC,aAAa;AACT,WAAA;AAAA,MACL,MAAM;AAAA,MACN,OAAO,IAAI,MAAM,kBAAkB,OAAO,WAAW,EAAE;AAAA,IACzD;AAAA,EAAA;AAGE,MAAA,OAAO,gBAAgB,UAAU;AAC5B,WAAA;AAAA,MACL,MAAM;AAAA,MACN,OAAO,IAAI;AAAA,QACT,sCAAsC,OAAO,WAAW;AAAA,MAAA;AAAA,IAE5D;AAAA,EAAA;AAGI,QAAA,OAAO,OAAO,KAAK,WAAW;AAC9B,QAAA,QAAQ,KAAK,KAAK,CAAC,MAAM,MAAM,cAAc,MAAM,OAAO,MAAM,IAAI;AAC1E,MAAI,OAAO;AACH,UAAA,QAAQ,YAAY,KAAK;AAE3B,QAAA;AAEE,UAAA,WAAW,KAAK,GAAG;AACf,cAAA,QAAQ,MAAM,MAAM,GAAG;AACtB,eAAA;AAAA,UACL,MAAM;AAAA,UACN,KAAK;AAAA,UACL;AAAA,QACF;AAAA,MAAA;AAIF,UAAI,SAAS,OAAO,MAAM,SAAS,YAAY;AAC7C,cAAM,QAAQ,MAAM;AACb,eAAA;AAAA,UACL,MAAM;AAAA,UACN,KAAK;AAAA,UACL;AAAA,QACF;AAAA,MAAA;AAIF,UAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AACxC,eAAA;AAAA,UACL,MAAM;AAAA,UACN,KAAK;AAAA,UACL,OAAO;AAAA,QACT;AAAA,MAAA;AAGF,cAAQ,KAAK,OAAO,yBAAyB,aAAa,KAAK,IAAI;AAC5D,aAAA;AAAA,QACL,MAAM;AAAA,QACN,OAAO,IAAI;AAAA,UACT,0BAA0B,UAAU,SAAS,IAAI,qFAAqF,OAAO,KAAK;AAAA,QAAA;AAAA,MAEtJ;AAAA,aACO,OAAO;AACd,cAAQ,KAAK,OAAO,yBAAyB,aAAa,KAAK,IAAI;AAC5D,aAAA;AAAA,QACL,MAAM;AAAA,QACN;AAAA,MACF;AAAA,IAAA;AAAA,EACF;AAEF,QAAM,WAAW,KAAK,KAAK,CAAC,MAAM,MAAM,SAAS;AAE7C,MAAA,CAAC,CAAC,UAAU;AACR,UAAA,aAAc,SAAyC,SAAS,IAClE,OAAO,KAAM,SAAyC,SAAS,CAAC,IAChE,CAAC;AACL,UAAM,gBAAgB,WAAW;AAAA,MAC/B,CAAC,MAAM,MAAM,cAAc,MAAM,OAAO,MAAM;AAAA,IAChD;AACO,WAAA;AAAA,MACL,MAAM;AAAA,MACN,OAAO,IAAI;AAAA,QACT,0BAA0B,UAAU,SAAS,IAAI,qCAC/C,CAAC,CAAC,gBACE,cAAc,aACd,WAAW,SACX,WAAW,KAAK,IAAI,IACpB,SACN;AAAA,MAAA;AAAA,IAEJ;AAAA,EAAA;AAGK,SAAA;AAAA,IACL,MAAM;AAAA,IACN,OAAO,IAAI;AAAA,MACT,gCAAgC,UAAU,SAAS,IAAI,MACrD,KAAK,SACD,wBAAwB,KAAK,KAAK,IAAI,IACtC,+CACN;AAAA,IAAA;AAAA,EAEJ;AACF;"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,28 @@
1
+ import type { Plugin } from "vite";
2
+ import type { ViteReactClientTransformOptions } from "./types.js";
3
+ /**
4
+ * Plugin for transforming React Client Components.
5
+ *
6
+ * Core responsibilities:
7
+ * 1. Detects "use client" directives
8
+ * 2. Transforms client components for RSC boundaries
9
+ * 3. Adds client reference metadata for RSC
10
+ *
11
+ * When a component is marked with "use client", it:
12
+ * - Gets transformed into a client reference
13
+ * - Maintains module ID for RSC boundaries
14
+ * - Preserves class/function behavior
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * export default defineConfig({
19
+ * plugins: [
20
+ * viteReactClientTransformPlugin({
21
+ * projectRoot: process.cwd(),
22
+ * })
23
+ * ]
24
+ * });
25
+ * ```
26
+ */
27
+ export declare function viteReactClientTransformPlugin(options?: ViteReactClientTransformOptions): Plugin;
28
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/transformer/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAInC,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,YAAY,CAAC;AAGlE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,wBAAgB,8BAA8B,CAC5C,OAAO,CAAC,EAAE,+BAA+B,GACxC,MAAM,CAgDR"}