vite-plugin-react-server 1.4.1 → 1.4.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 (146) hide show
  1. package/README.md +48 -313
  2. package/dist/package.json +123 -13
  3. package/dist/plugin/bundle/deferredStaticGeneration.js +14 -39
  4. package/dist/plugin/bundle/manifests.js +30 -48
  5. package/dist/plugin/config/autoDiscover/resolveAutoDiscover.d.ts.map +1 -1
  6. package/dist/plugin/config/autoDiscover/resolveAutoDiscover.js +4 -1
  7. package/dist/plugin/config/envPrefixFromConfig.js +12 -7
  8. package/dist/plugin/config/getCondition.d.ts.map +1 -1
  9. package/dist/plugin/config/getCondition.js +7 -5
  10. package/dist/plugin/dev-server/configureReactServer.server.d.ts.map +1 -1
  11. package/dist/plugin/dev-server/configureReactServer.server.js +5 -8
  12. package/dist/plugin/dev-server/plugin.client.d.ts.map +1 -1
  13. package/dist/plugin/dev-server/plugin.client.js +2 -1
  14. package/dist/plugin/dev-server/plugin.server.d.ts.map +1 -1
  15. package/dist/plugin/dev-server/plugin.server.js +2 -36
  16. package/dist/plugin/dev-server/virtualRscHmrPlugin.js +23 -23
  17. package/dist/plugin/environments/createBuildEventPlugin.js +88 -98
  18. package/dist/plugin/environments/createEnvironmentPlugin.js +222 -250
  19. package/dist/plugin/error/index.d.ts +1 -2
  20. package/dist/plugin/error/index.d.ts.map +1 -1
  21. package/dist/plugin/error/index.js +2 -3
  22. package/dist/plugin/error/panicThresholdHandler.js +14 -3
  23. package/dist/plugin/error/setupGlobalErrorHandler.d.ts.map +1 -1
  24. package/dist/plugin/error/setupGlobalErrorHandler.js +23 -16
  25. package/dist/plugin/helpers/createRscRenderHelpers.d.ts +0 -5
  26. package/dist/plugin/helpers/createRscRenderHelpers.d.ts.map +1 -1
  27. package/dist/plugin/helpers/createRscRenderHelpers.js +32 -55
  28. package/dist/plugin/helpers/createSharedLoader.d.ts.map +1 -1
  29. package/dist/plugin/helpers/createSharedLoader.js +4 -2
  30. package/dist/plugin/helpers/headlessStreamReuseHandler.js +30 -22
  31. package/dist/plugin/helpers/headlessStreamState.d.ts +0 -38
  32. package/dist/plugin/helpers/headlessStreamState.d.ts.map +1 -1
  33. package/dist/plugin/helpers/headlessStreamState.js +15 -76
  34. package/dist/plugin/helpers/index.d.ts +0 -3
  35. package/dist/plugin/helpers/index.d.ts.map +1 -1
  36. package/dist/plugin/helpers/index.js +1 -4
  37. package/dist/plugin/helpers/requestInfo.d.ts.map +1 -1
  38. package/dist/plugin/helpers/requestInfo.js +3 -3
  39. package/dist/plugin/helpers/resolveComponent.d.ts.map +1 -1
  40. package/dist/plugin/helpers/resolveComponent.js +4 -2
  41. package/dist/plugin/helpers/workerCleanup.d.ts +1 -12
  42. package/dist/plugin/helpers/workerCleanup.d.ts.map +1 -1
  43. package/dist/plugin/helpers/workerCleanup.js +1 -1
  44. package/dist/plugin/index.client.d.ts +5 -0
  45. package/dist/plugin/index.client.d.ts.map +1 -0
  46. package/dist/plugin/index.client.js +4 -0
  47. package/dist/plugin/index.d.ts +4 -3
  48. package/dist/plugin/index.d.ts.map +1 -1
  49. package/dist/plugin/index.js +10 -5
  50. package/dist/plugin/index.server.d.ts +5 -0
  51. package/dist/plugin/index.server.d.ts.map +1 -0
  52. package/dist/plugin/index.server.js +4 -0
  53. package/dist/plugin/loader/directives/index.d.ts +0 -1
  54. package/dist/plugin/loader/directives/index.d.ts.map +1 -1
  55. package/dist/plugin/loader/directives/index.js +1 -2
  56. package/dist/plugin/metrics/createWorkerStartupMetrics.js +31 -13
  57. package/dist/plugin/orchestrator/createPluginOrchestrator.client.js +41 -38
  58. package/dist/plugin/orchestrator/createPluginOrchestrator.server.js +43 -46
  59. package/dist/plugin/plugin.client.js +2 -2
  60. package/dist/plugin/plugin.server.js +2 -2
  61. package/dist/plugin/react-static/createBuildLoader.client.js +12 -6
  62. package/dist/plugin/react-static/createBuildLoader.server.js +255 -235
  63. package/dist/plugin/react-static/plugin.client.js +684 -770
  64. package/dist/plugin/react-static/plugin.server.js +517 -603
  65. package/dist/plugin/react-static/processCssFilesForPages.js +103 -88
  66. package/dist/plugin/react-static/renderPage.client.js +455 -529
  67. package/dist/plugin/react-static/renderPage.server.js +485 -508
  68. package/dist/plugin/react-static/renderPagesBatched.js +277 -275
  69. package/dist/plugin/react-static/rscToHtmlStream.client.js +48 -29
  70. package/dist/plugin/react-static/rscToHtmlStream.server.js +62 -37
  71. package/dist/plugin/react-static/temporaryReferences.server.js +11 -2
  72. package/dist/plugin/stream/createMainThreadHandlers.js +40 -31
  73. package/dist/plugin/stream/renderRscStream.server.d.ts.map +1 -1
  74. package/dist/plugin/stream/renderRscStream.server.js +127 -144
  75. package/dist/plugin/transformer/createTransformerPlugin.js +226 -265
  76. package/dist/plugin/utils/checkReactVersion.d.ts +7 -0
  77. package/dist/plugin/utils/checkReactVersion.d.ts.map +1 -0
  78. package/dist/plugin/utils/checkReactVersion.js +23 -0
  79. package/dist/plugin/utils/envUrls.node.js +12 -11
  80. package/dist/plugin/vendor/vendor-alias.js +84 -114
  81. package/dist/plugin/vendor/vendor.client.d.ts.map +1 -1
  82. package/dist/plugin/vendor/vendor.client.js +1 -3
  83. package/dist/plugin/worker/rsc/handleRscRender.d.ts.map +1 -1
  84. package/dist/plugin/worker/rsc/handleRscRender.js +3 -1
  85. package/dist/tsconfig.tsbuildinfo +1 -1
  86. package/package.json +123 -13
  87. package/plugin/config/autoDiscover/resolveAutoDiscover.ts +4 -0
  88. package/plugin/config/getCondition.ts +6 -4
  89. package/plugin/dev-server/configureReactServer.server.ts +7 -10
  90. package/plugin/dev-server/plugin.client.ts +2 -0
  91. package/plugin/dev-server/plugin.server.ts +2 -49
  92. package/plugin/error/index.ts +1 -2
  93. package/plugin/error/setupGlobalErrorHandler.ts +24 -25
  94. package/plugin/helpers/createRscRenderHelpers.ts +0 -29
  95. package/plugin/helpers/createSharedLoader.ts +6 -1
  96. package/plugin/helpers/headlessStreamState.ts +0 -69
  97. package/plugin/helpers/index.ts +0 -3
  98. package/plugin/helpers/requestInfo.ts +1 -2
  99. package/plugin/helpers/resolveComponent.ts +6 -1
  100. package/plugin/helpers/workerCleanup.ts +1 -38
  101. package/plugin/index.client.ts +4 -0
  102. package/plugin/index.server.ts +4 -0
  103. package/plugin/index.ts +12 -5
  104. package/plugin/loader/directives/index.ts +0 -1
  105. package/plugin/plugin.client.ts +1 -1
  106. package/plugin/plugin.server.ts +1 -1
  107. package/plugin/stream/renderRscStream.server.ts +3 -0
  108. package/plugin/transformer/README.md +1 -1
  109. package/plugin/utils/checkReactVersion.ts +28 -0
  110. package/plugin/vendor/vendor.client.ts +0 -2
  111. package/plugin/worker/html/README.md +1 -1
  112. package/plugin/worker/rsc/README.md +1 -1
  113. package/plugin/worker/rsc/handleRscRender.ts +2 -0
  114. package/scripts/generate-toc.mjs +27 -294
  115. package/dist/plugin/error/assertPanic.d.ts +0 -2
  116. package/dist/plugin/error/assertPanic.d.ts.map +0 -1
  117. package/dist/plugin/error/assertPanic.js +0 -15
  118. package/dist/plugin/error/directiveError.d.ts +0 -13
  119. package/dist/plugin/error/directiveError.d.ts.map +0 -1
  120. package/dist/plugin/error/directiveError.js +0 -21
  121. package/dist/plugin/error/enhanceError.d.ts +0 -14
  122. package/dist/plugin/error/enhanceError.d.ts.map +0 -1
  123. package/dist/plugin/error/enhanceError.js +0 -24
  124. package/dist/plugin/helpers/createSafePageComponent.d.ts +0 -36
  125. package/dist/plugin/helpers/createSafePageComponent.d.ts.map +0 -1
  126. package/dist/plugin/helpers/createSafePageComponent.js +0 -50
  127. package/dist/plugin/helpers/moduleResolver.d.ts +0 -25
  128. package/dist/plugin/helpers/moduleResolver.d.ts.map +0 -1
  129. package/dist/plugin/helpers/moduleResolver.js +0 -64
  130. package/dist/plugin/helpers/stashReturnValue.d.ts +0 -3
  131. package/dist/plugin/helpers/stashReturnValue.d.ts.map +0 -1
  132. package/dist/plugin/helpers/stashReturnValue.js +0 -23
  133. package/dist/plugin/helpers/workerManager.d.ts +0 -5
  134. package/dist/plugin/helpers/workerManager.d.ts.map +0 -1
  135. package/dist/plugin/helpers/workerManager.js +0 -18
  136. package/dist/plugin/loader/directives/collectExportsFromModule.d.ts +0 -6
  137. package/dist/plugin/loader/directives/collectExportsFromModule.d.ts.map +0 -1
  138. package/dist/plugin/loader/directives/collectExportsFromModule.js +0 -24
  139. package/plugin/error/assertPanic.ts +0 -9
  140. package/plugin/error/directiveError.ts +0 -29
  141. package/plugin/error/enhanceError.ts +0 -41
  142. package/plugin/helpers/createSafePageComponent.ts +0 -64
  143. package/plugin/helpers/moduleResolver.ts +0 -91
  144. package/plugin/helpers/stashReturnValue.ts +0 -19
  145. package/plugin/helpers/workerManager.ts +0 -16
  146. package/plugin/loader/directives/collectExportsFromModule.ts +0 -25
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plugin-react-server",
3
- "version": "1.4.1",
3
+ "version": "1.4.3",
4
4
  "description": "Vite plugin for React Server Components (RSC)",
5
5
  "type": "module",
6
6
  "main": "./dist/plugin/index.js",
@@ -40,7 +40,10 @@
40
40
  "default": "./dist/plugin/utils/index.server.js"
41
41
  },
42
42
  "./metrics": "./dist/plugin/metrics/index.js",
43
- "./stream": "./dist/plugin/stream/index.js",
43
+ "./stream": {
44
+ "react-server": "./dist/plugin/stream/index.server.js",
45
+ "default": "./dist/plugin/stream/index.client.js"
46
+ },
44
47
  "./stream/client": "./dist/plugin/stream/index.client.js",
45
48
  "./stream/server": "./dist/plugin/stream/index.server.js",
46
49
  "./env": {
@@ -48,25 +51,128 @@
48
51
  },
49
52
  "./config": "./dist/plugin/config/index.js",
50
53
  "./error": "./dist/plugin/error/index.js",
51
- "./vendor": "./dist/plugin/vendor/index.js",
54
+ "./vendor": {
55
+ "react-server": "./dist/plugin/vendor/vendor.server.js",
56
+ "default": "./dist/plugin/vendor/vendor.client.js"
57
+ },
52
58
  "./vendor.server": "./dist/plugin/vendor/vendor.server.js",
53
59
  "./vendor.client": "./dist/plugin/vendor/vendor.client.js",
54
60
  "./vendor.static": "./dist/plugin/vendor/vendor.static.js",
55
61
  "./file-preserver": "./dist/plugin/file-preserver/plugin.js",
56
62
  "./loader": "./dist/plugin/loader/index.js",
57
63
  "./helpers": "./dist/plugin/helpers/index.js",
58
- "./helpers/resolveStreamElements": "./dist/plugin/helpers/resolveStreamElements.js",
59
- "./dev-server": "./dist/plugin/dev-server/index.js",
60
- "./dev-server/configureReactServer": "./dist/plugin/dev-server/configureReactServer.js",
61
- "./dev-server/handleServerAction": "./dist/plugin/dev-server/handleServerAction.js",
62
- "./stream/handleRscStream": "./dist/plugin/stream/handleRscStream.js",
63
- "./stream/createRscStream": "./dist/plugin/stream/createRscStream.js",
64
- "./dev-server/restartWorker": "./dist/plugin/dev-server/restartWorker.js",
65
- "./dev-server/cleanupServerAction": "./dist/plugin/dev-server/cleanupServerAction.js",
64
+ "./helpers/resolveStreamElements": {
65
+ "react-server": "./dist/plugin/helpers/resolveStreamElements.server.js",
66
+ "default": "./dist/plugin/helpers/resolveStreamElements.client.js"
67
+ },
68
+ "./dev-server": {
69
+ "react-server": "./dist/plugin/dev-server/index.server.js",
70
+ "default": "./dist/plugin/dev-server/index.client.js"
71
+ },
72
+ "./dev-server/configureReactServer": {
73
+ "react-server": "./dist/plugin/dev-server/configureReactServer.server.js",
74
+ "default": "./dist/plugin/dev-server/configureReactServer.client.js"
75
+ },
76
+ "./dev-server/handleServerAction": {
77
+ "react-server": "./dist/plugin/dev-server/handleServerAction.server.js",
78
+ "default": "./dist/plugin/dev-server/handleServerAction.client.js"
79
+ },
80
+ "./stream/handleRscStream": {
81
+ "react-server": "./dist/plugin/stream/handleRscStream.server.js",
82
+ "default": "./dist/plugin/stream/handleRscStream.client.js"
83
+ },
84
+ "./stream/createRscStream": {
85
+ "react-server": "./dist/plugin/stream/createRscStream.server.js",
86
+ "default": "./dist/plugin/stream/createRscStream.client.js"
87
+ },
88
+ "./dev-server/restartWorker": {
89
+ "react-server": "./dist/plugin/dev-server/restartWorker.server.js",
90
+ "default": "./dist/plugin/dev-server/restartWorker.client.js"
91
+ },
92
+ "./dev-server/cleanupServerAction": {
93
+ "react-server": "./dist/plugin/dev-server/cleanupServerAction.server.js",
94
+ "default": "./dist/plugin/dev-server/cleanupServerAction.client.js"
95
+ },
66
96
  "./env-loader": "./dist/plugin/loader/env-loader.js",
67
97
  "./css-loader": "./dist/plugin/loader/css-loader.js",
68
98
  "./directives": "./dist/plugin/loader/directives/index.js",
69
- "./register": "./dist/plugin/vendor/register-vendor.js"
99
+ "./register": "./dist/plugin/vendor/register-vendor.js",
100
+ "./config/createHandlerOptions": {
101
+ "react-server": "./dist/plugin/config/createHandlerOptions.server.js",
102
+ "default": "./dist/plugin/config/createHandlerOptions.client.js"
103
+ },
104
+ "./dev-server/configureRequestHandler": {
105
+ "react-server": "./dist/plugin/dev-server/configureRequestHandler.server.js",
106
+ "default": "./dist/plugin/dev-server/configureRequestHandler.client.js"
107
+ },
108
+ "./env/plugin": {
109
+ "react-server": "./dist/plugin/env/plugin.server.js",
110
+ "default": "./dist/plugin/env/plugin.client.js"
111
+ },
112
+ "./helpers/handleServerAction": {
113
+ "react-server": "./dist/plugin/helpers/handleServerAction.server.js",
114
+ "default": "./dist/plugin/helpers/handleServerAction.client.js"
115
+ },
116
+ "./orchestrator/createPluginOrchestrator": {
117
+ "react-server": "./dist/plugin/orchestrator/createPluginOrchestrator.server.js",
118
+ "default": "./dist/plugin/orchestrator/createPluginOrchestrator.client.js"
119
+ },
120
+ "./plugin": {
121
+ "react-server": "./dist/plugin/plugin.server.js",
122
+ "default": "./dist/plugin/plugin.client.js"
123
+ },
124
+ "./react-client": {
125
+ "react-server": "./dist/plugin/react-client/index.server.js",
126
+ "default": "./dist/plugin/react-client/index.client.js"
127
+ },
128
+ "./react-client/plugin": {
129
+ "react-server": "./dist/plugin/react-client/plugin.server.js",
130
+ "default": "./dist/plugin/react-client/plugin.client.js"
131
+ },
132
+ "./react-server/plugin": {
133
+ "react-server": "./dist/plugin/react-server/plugin.server.js",
134
+ "default": "./dist/plugin/react-server/plugin.client.js"
135
+ },
136
+ "./react-static/createBuildLoader": {
137
+ "react-server": "./dist/plugin/react-static/createBuildLoader.server.js",
138
+ "default": "./dist/plugin/react-static/createBuildLoader.client.js"
139
+ },
140
+ "./react-static": {
141
+ "react-server": "./dist/plugin/react-static/index.server.js",
142
+ "default": "./dist/plugin/react-static/index.client.js"
143
+ },
144
+ "./react-static/plugin": {
145
+ "react-server": "./dist/plugin/react-static/plugin.server.js",
146
+ "default": "./dist/plugin/react-static/plugin.client.js"
147
+ },
148
+ "./react-static/renderPage": {
149
+ "react-server": "./dist/plugin/react-static/renderPage.server.js",
150
+ "default": "./dist/plugin/react-static/renderPage.client.js"
151
+ },
152
+ "./react-static/rscToHtmlStream": {
153
+ "react-server": "./dist/plugin/react-static/rscToHtmlStream.server.js",
154
+ "default": "./dist/plugin/react-static/rscToHtmlStream.client.js"
155
+ },
156
+ "./react-static/temporaryReferences": {
157
+ "react-server": "./dist/plugin/react-static/temporaryReferences.server.js",
158
+ "default": "./dist/plugin/react-static/temporaryReferences.client.js"
159
+ },
160
+ "./stream/createFromNodeStream": {
161
+ "react-server": "./dist/plugin/stream/createFromNodeStream.server.js",
162
+ "default": "./dist/plugin/stream/createFromNodeStream.client.js"
163
+ },
164
+ "./stream/createHtmlStream": {
165
+ "react-server": "./dist/plugin/stream/createHtmlStream.server.js",
166
+ "default": "./dist/plugin/stream/createHtmlStream.client.js"
167
+ },
168
+ "./stream/createRenderToPipeableStreamHandler": {
169
+ "react-server": "./dist/plugin/stream/createRenderToPipeableStreamHandler.server.js",
170
+ "default": "./dist/plugin/stream/createRenderToPipeableStreamHandler.client.js"
171
+ },
172
+ "./transformer/plugin": {
173
+ "react-server": "./dist/plugin/transformer/plugin.server.js",
174
+ "default": "./dist/plugin/transformer/plugin.client.js"
175
+ }
70
176
  },
71
177
  "typesVersions": {
72
178
  "*": {
@@ -288,7 +394,6 @@
288
394
  "supports-color": "^10.0.0",
289
395
  "ts-node": "^10.9.2",
290
396
  "tslib": "^2.8.1",
291
- "tsx": "^4.19.2",
292
397
  "typescript": "^5.7.3",
293
398
  "typescript-eslint": "^8.33.1",
294
399
  "vite": "^6.3.5",
@@ -298,5 +403,10 @@
298
403
  "bin": {
299
404
  "check-react-version": "./scripts/check-react-version.mjs",
300
405
  "patch": "./bin/patch.mjs"
406
+ },
407
+ "dependencies": {
408
+ "acorn": "^8.16.0",
409
+ "picocolors": "^1.1.1",
410
+ "tsx": "^4.21.0"
301
411
  }
302
412
  }
@@ -177,6 +177,10 @@ export const resolveAutoDiscover: ResolveAutoDiscoverFn =
177
177
  ...clientEntry,
178
178
  ...cssInputs,
179
179
  };
180
+ // If no client entries found, fall back to index.html so SSR environment has inputs
181
+ if (Object.keys(clientInputsCollection).length === 0) {
182
+ Object.assign(clientInputsCollection, indexHtmlInputs);
183
+ }
180
184
 
181
185
  const serverInputsCollection = {
182
186
  ...clientInputsCollection,
@@ -203,9 +203,10 @@ export function assertReactServer(): asserts this is {
203
203
  const currentCondition = getCurrentCondition();
204
204
  if (currentCondition !== "react-server") {
205
205
  // Debug-only: avoid Node-only APIs to keep this file browser-safe
206
- throw new Error(
207
- `Condition mismatch, should be react-server. Set NODE_OPTIONS="--conditions=react-server" or --conditions=react-server`
206
+ console.warn(
207
+ `[vite-plugin-react-server] Condition mismatch: expected react-server. Set NODE_OPTIONS="--conditions=react-server"`
208
208
  );
209
+ return; // Don't throw — Vite 7 may load both condition variants during config bundling
209
210
  }
210
211
  }
211
212
 
@@ -215,9 +216,10 @@ export function assertNonReactServer(): asserts this is {
215
216
  const currentCondition = getCurrentCondition();
216
217
  if (currentCondition === "react-server") {
217
218
  // Debug-only: avoid Node-only APIs to keep this file browser-safe
218
- throw new Error(
219
- `Condition mismatch, should not be react-server. Remove NODE_OPTIONS="--conditions=react-server" or --conditions=react-server`
219
+ console.warn(
220
+ `[vite-plugin-react-server] Condition mismatch: unexpected react-server condition on this module.`
220
221
  );
222
+ return; // Don't throw — Vite 7 may load both condition variants during config bundling
221
223
  }
222
224
  }
223
225
 
@@ -78,16 +78,8 @@ export const configureReactServer: ConfigureReactServerFn =
78
78
  }
79
79
  activeStreams.clear();
80
80
  activeControllers.clear();
81
- });
82
-
83
- // Handle restart completion
84
- server.ws.on("full-reload", () => {
85
- isRestarting = false;
86
- logger.info("[vite-plugin-react-server] ✅ Server restart completed");
87
- });
88
81
 
89
- // Fallback: reset restart flag after a timeout
90
- server.ws.on("restart", () => {
82
+ // Fallback: reset restart flag after a timeout
91
83
  setTimeout(() => {
92
84
  if (isRestarting) {
93
85
  isRestarting = false;
@@ -98,6 +90,12 @@ export const configureReactServer: ConfigureReactServerFn =
98
90
  }, 5000); // 5 second timeout
99
91
  });
100
92
 
93
+ // Handle restart completion
94
+ server.ws.on("full-reload", () => {
95
+ isRestarting = false;
96
+ logger.info("[vite-plugin-react-server] ✅ Server restart completed");
97
+ });
98
+
101
99
  const loader = async (id: string) => {
102
100
  const [moduleID, exportName] = id.split("#");
103
101
 
@@ -550,7 +548,6 @@ export const configureReactServer: ConfigureReactServerFn =
550
548
 
551
549
  res.statusCode = 500;
552
550
  res.setHeader("Content-Type", "text/x-component; charset=utf-8");
553
- res.setHeader("Content-Length", "0"); // Will be updated after streaming
554
551
 
555
552
  // Note: Worker cleanup is handled by the response close handler
556
553
  }
@@ -95,6 +95,8 @@ export const vitePluginReactDevServer: VitePluginFn = function _vitePluginReactS
95
95
 
96
96
  // Skip client components — let @vitejs/plugin-react handle them with Fast Refresh
97
97
  const isClientFile = isSourceFile && (() => {
98
+ // Check filename pattern (.client.tsx, etc.) — matches isClientComponentByName
99
+ if (/\.client\.(js|ts|jsx|tsx)$/.test(file)) return true;
98
100
  try {
99
101
  const head = readFileSync(file, 'utf-8').slice(0, 200);
100
102
  return /^\s*["']use client["']/.test(head.split('\n')[0]);
@@ -44,6 +44,8 @@ export const vitePluginReactDevServer = function _vitePluginReactServerDevServer
44
44
  if (envName === 'client') {
45
45
  // Check if it's a client component — let Fast Refresh handle it
46
46
  const isClient = (file.endsWith('.tsx') || file.endsWith('.ts') || file.endsWith('.jsx') || file.endsWith('.js')) && (() => {
47
+ // Check filename pattern (.client.tsx, .client.ts, etc.) — matches isClientComponentByName
48
+ if (/\.client\.(js|ts|jsx|tsx)$/.test(file)) return true;
47
49
  try {
48
50
  const head = readFileSync(file, 'utf-8').slice(0, 200);
49
51
  return /^\s*["']use client["']/.test(head.split('\n')[0]);
@@ -77,55 +79,6 @@ export const vitePluginReactDevServer = function _vitePluginReactServerDevServer
77
79
  }
78
80
  return [];
79
81
  },
80
- handleHotUpdate({ file, server }: { file: string; server: ViteDevServer }) {
81
- const moduleBase = userOptions.moduleBase || "src";
82
- const projectRoot = userOptions.projectRoot || server.config.root;
83
- const normalizedFile = file.replace(projectRoot, '').replace(/^\/+/, '');
84
- const isSourceFile = normalizedFile.startsWith(moduleBase + '/') &&
85
- (file.endsWith('.tsx') || file.endsWith('.ts') || file.endsWith('.jsx') || file.endsWith('.js'));
86
-
87
- // Skip client components — let @vitejs/plugin-react handle them
88
- // with Fast Refresh (preserves component-level state).
89
- const isClientFile = isSourceFile && (() => {
90
- try {
91
- const head = readFileSync(file, 'utf-8').slice(0, 200);
92
- return /^\s*["']use client["']/.test(head.split('\n')[0]);
93
- } catch { return false; }
94
- })();
95
-
96
- if (isSourceFile && !isClientFile) {
97
- server.config.logger.info(`[vite-plugin-react-server] File changed (RSC refetch): ${normalizedFile}`);
98
-
99
- // Send custom HMR event so client can refetch RSC stream
100
- server.ws.send({
101
- type: 'custom',
102
- event: 'vite-plugin-react-server:server-component-update',
103
- data: {
104
- file: normalizedFile,
105
- path: file,
106
- },
107
- });
108
-
109
- // Invalidate the server module so next request gets fresh content
110
- const mod = server.environments['server']?.moduleGraph?.getModulesByFile(file);
111
- if (mod) {
112
- for (const m of mod) {
113
- server.environments['server']?.moduleGraph?.invalidateModule(m);
114
- }
115
- }
116
-
117
- // Return empty array to prevent Vite's default full-page reload
118
- // The client will refetch the RSC stream via the custom event
119
- return [];
120
- }
121
-
122
- if (isClientFile) {
123
- // Client components are handled by @vitejs/plugin-react (Fast Refresh)
124
- // or Vite's client-side HMR. Return empty to prevent the server
125
- // environment from triggering a full page reload.
126
- return [];
127
- }
128
- },
129
82
  };
130
83
 
131
84
  const serverPlugin = {
@@ -1,6 +1,5 @@
1
1
  export { toError } from "./toError.js";
2
2
  export { logError } from "./logError.js";
3
- export { enhanceError, createContextualError } from "./enhanceError.js";
4
3
  export { handleError } from "./handleError.js";
5
4
  export { shouldPanic, PANIC_SYMBOL, isPanic } from "./shouldPanic.js";
6
- export { assertPanic } from "./assertPanic.js";
5
+ export { shouldCausePanic, handlePanicThreshold, isPanicError } from "./panicThresholdHandler.js";
@@ -4,12 +4,13 @@ import type {
4
4
  } from "./types.js";
5
5
 
6
6
  let isGlobalHandlerSetup = false;
7
+ let uncaughtExceptionHandler: ((error: Error) => void) | null = null;
8
+ let unhandledRejectionHandler: ((reason: unknown, promise: Promise<unknown>) => void) | null = null;
7
9
 
8
10
  export const setupGlobalErrorHandler: SetupGlobalErrorHandlerFn =
9
11
  function _setupGlobalErrorHandler(options) {
10
12
  const { panicThreshold, logger, verbose = false } = options;
11
13
 
12
- // Set up global error handling for all panic threshold levels
13
14
  if (isGlobalHandlerSetup) {
14
15
  return;
15
16
  }
@@ -20,39 +21,32 @@ export const setupGlobalErrorHandler: SetupGlobalErrorHandlerFn =
20
21
  );
21
22
  }
22
23
 
23
- // Set up our error handlers
24
- process.on("uncaughtException", (error: Error) => {
24
+ uncaughtExceptionHandler = (error: Error) => {
25
25
  if (verbose) {
26
26
  logger.info(
27
27
  `Global error handler caught uncaught exception: ${error.message}`
28
28
  );
29
29
  }
30
30
 
31
- // Handle the error gracefully based on panic threshold
32
31
  logger.warn(
33
32
  `Uncaught exception handled by panic threshold (${panicThreshold}): ${error.message}`
34
33
  );
34
+ };
35
35
 
36
- // Don't call process.exit - let the error be handled gracefully
37
- });
38
-
39
- process.on(
40
- "unhandledRejection",
41
- (reason: unknown, _promise: Promise<unknown>) => {
42
- if (verbose) {
43
- logger.info(
44
- `Global error handler caught unhandled rejection: ${reason}`
45
- );
46
- }
47
-
48
- // Handle the rejection gracefully based on panic threshold
49
- logger.warn(
50
- `Unhandled rejection handled by panic threshold (${panicThreshold}): ${reason}`
36
+ unhandledRejectionHandler = (reason: unknown, _promise: Promise<unknown>) => {
37
+ if (verbose) {
38
+ logger.info(
39
+ `Global error handler caught unhandled rejection: ${reason}`
51
40
  );
52
-
53
- // Don't call process.exit - let the rejection be handled gracefully
54
41
  }
55
- );
42
+
43
+ logger.warn(
44
+ `Unhandled rejection handled by panic threshold (${panicThreshold}): ${reason}`
45
+ );
46
+ };
47
+
48
+ process.on("uncaughtException", uncaughtExceptionHandler);
49
+ process.on("unhandledRejection", unhandledRejectionHandler);
56
50
 
57
51
  isGlobalHandlerSetup = true;
58
52
  };
@@ -63,9 +57,14 @@ export const cleanupGlobalErrorHandler: CleanupGlobalErrorHandlerFn =
63
57
  return;
64
58
  }
65
59
 
66
- // Remove our handlers
67
- process.removeAllListeners("uncaughtException");
68
- process.removeAllListeners("unhandledRejection");
60
+ if (uncaughtExceptionHandler) {
61
+ process.removeListener("uncaughtException", uncaughtExceptionHandler);
62
+ uncaughtExceptionHandler = null;
63
+ }
64
+ if (unhandledRejectionHandler) {
65
+ process.removeListener("unhandledRejection", unhandledRejectionHandler);
66
+ unhandledRejectionHandler = null;
67
+ }
69
68
 
70
69
  isGlobalHandlerSetup = false;
71
70
  };
@@ -46,32 +46,3 @@ export function createReactElement(
46
46
  /**
47
47
  * Pure function for storing headless stream data
48
48
  */
49
- export function storeHeadlessStreamData(
50
- context: RscRenderContext,
51
- finalOptions: CreateHandlerOptions
52
- ): void {
53
- // Determine if this is a headless stream by checking if htmlPath is empty
54
- const isHeadless = finalOptions.htmlPath === "";
55
-
56
- if (
57
- context.headlessStreamElements &&
58
- isHeadless &&
59
- !context.headlessStreamErrors?.has(context.route)
60
- ) {
61
- // Store the rendered elements for reuse
62
- const element = createElementWithReact(React, {
63
- ...finalOptions,
64
- Html: React.Fragment,
65
- as: React.Fragment,
66
- });
67
- context.headlessStreamElements.set(context.id, {
68
- elements: element,
69
- errored: false,
70
- });
71
- }
72
- }
73
-
74
- export const createRscRenderHelpers = {
75
- createReactElement,
76
- storeHeadlessStreamData,
77
- };
@@ -146,7 +146,12 @@ export async function createSharedLoader({
146
146
  throw new Error(`Module "${moduleId}" has no exports, can't find ${exportName}`);
147
147
  }
148
148
  if (exportName && !(exportName in result)) {
149
- throw new Error(`Module "${moduleId}" does not export "${exportName}"`);
149
+ throw new Error(
150
+ `Module "${moduleId}" does not export "${exportName}". ` +
151
+ (exportName !== 'default'
152
+ ? `Did you use \`export default\`? Use \`export function ${exportName}(...)\` or set pageExportName: "default" in your plugin config.`
153
+ : `The module does not have a default export.`)
154
+ );
150
155
  }
151
156
 
152
157
  return result;
@@ -51,72 +51,3 @@ export function hasHeadlessStreamError(
51
51
  ): boolean {
52
52
  return state.errors.has(route);
53
53
  }
54
-
55
- /**
56
- * Gets the headless stream error for a route.
57
- *
58
- * @param state - The headless stream state
59
- * @param route - The route to get the error for
60
- * @returns The error if it exists, undefined otherwise
61
- */
62
- export function getHeadlessStreamError(
63
- state: HeadlessStreamState,
64
- route: string
65
- ): Error | undefined {
66
- return state.errors.get(route);
67
- }
68
-
69
- /**
70
- * Stores headless stream elements for reuse.
71
- *
72
- * @param state - The headless stream state
73
- * @param streamId - The stream ID
74
- * @param data - The stream data to store
75
- */
76
- export function storeHeadlessStreamElements(
77
- state: HeadlessStreamState,
78
- streamId: string,
79
- data: HeadlessStreamData
80
- ): void {
81
- state.elements.set(streamId, data);
82
- }
83
-
84
- /**
85
- * Gets headless stream elements for reuse.
86
- *
87
- * @param state - The headless stream state
88
- * @param streamId - The stream ID
89
- * @returns The stream data if it exists, undefined otherwise
90
- */
91
- export function getHeadlessStreamElements(
92
- state: HeadlessStreamState,
93
- streamId: string
94
- ): HeadlessStreamData | undefined {
95
- return state.elements.get(streamId);
96
- }
97
-
98
- /**
99
- * Cleans up headless stream elements after use.
100
- *
101
- * @param state - The headless stream state
102
- * @param streamId - The stream ID to clean up
103
- */
104
- export function cleanupHeadlessStreamElements(
105
- state: HeadlessStreamState,
106
- streamId: string
107
- ): void {
108
- state.elements.delete(streamId);
109
- }
110
-
111
- /**
112
- * Clears all headless stream errors for a route.
113
- *
114
- * @param state - The headless stream state
115
- * @param route - The route to clear errors for
116
- */
117
- export function clearHeadlessStreamErrors(
118
- state: HeadlessStreamState,
119
- route: string
120
- ): void {
121
- state.errors.delete(route);
122
- }
@@ -35,11 +35,8 @@ export * from "./getBundleManifest.js";
35
35
 
36
36
  // Module handling
37
37
  export * from "./moduleRefs.js";
38
- export * from "./moduleResolver.js";
39
38
 
40
39
  // Utility functions
41
- export * from "./stashReturnValue.js";
42
- export * from "./workerManager.js";
43
40
 
44
41
  // Unified render helpers
45
42
  export * from "./validateRscRenderMessage.js";
@@ -118,7 +118,6 @@ export function requestInfo(
118
118
  hasHtmlHeader ||
119
119
  (isFolder &&
120
120
  !hasRscHeader &&
121
- !hasRscQueryParam &&
122
121
  !isRsc &&
123
122
  !isJsRequest &&
124
123
  !isFormActionRequest));
@@ -181,7 +180,7 @@ export function requestInfo(
181
180
  if (mimeType) {
182
181
  contentType = mimeType + "; charset=utf-8";
183
182
  } else {
184
- contentType = "application/octet-stream; charset=utf-8";
183
+ contentType = "application/octet-stream";
185
184
  }
186
185
  }
187
186
 
@@ -77,7 +77,12 @@ export async function resolveComponent<T = RootComponentType | HtmlComponentType
77
77
  }
78
78
  return {
79
79
  type: "error",
80
- error: new Error(`Export "${moduleExportName}" not found in module ${modulePath}.`),
80
+ error: new Error(
81
+ `Export "${moduleExportName}" not found in module ${modulePath}. ` +
82
+ (moduleExportName !== "default"
83
+ ? `Did you use \`export default\`? Use \`export function ${moduleExportName}(...)\` or set pageExportName: "default" in your plugin config.`
84
+ : `The module does not have a default export.`)
85
+ ),
81
86
  };
82
87
  }
83
88
 
@@ -1,4 +1,4 @@
1
- import type { Worker, MessagePort } from "node:worker_threads";
1
+ import type { Worker } from "node:worker_threads";
2
2
 
3
3
  /**
4
4
  * Centralized worker cleanup utilities
@@ -45,41 +45,4 @@ export function cleanupWorker(
45
45
  }
46
46
  }
47
47
 
48
- /**
49
- * Safely cleans up MessagePorts with consistent error handling
50
- */
51
- export function cleanupMessagePorts(
52
- ports: (MessagePort | null | undefined)[],
53
- options: { logErrors?: boolean } = {}
54
- ): void {
55
- const { logErrors = false } = options;
56
-
57
- for (const port of ports) {
58
- if (!port) continue;
59
-
60
- try {
61
- // Remove onmessage handlers (property assignment cleanup)
62
- (port as any).onmessage = null;
63
- // Close the port
64
- port.close();
65
- } catch (error) {
66
- if (logErrors) {
67
- console.warn('[workerCleanup] Error during MessagePort cleanup:', error);
68
- }
69
- // Always ignore cleanup errors
70
- }
71
- }
72
- }
73
48
 
74
- /**
75
- * Comprehensive cleanup for worker + MessagePorts combination
76
- * This is the most common cleanup pattern in the codebase
77
- */
78
- export function cleanupWorkerAndPorts(
79
- worker: Worker | null | undefined,
80
- ports: (MessagePort | null | undefined)[],
81
- options: WorkerCleanupOptions = {}
82
- ): void {
83
- cleanupMessagePorts(ports, { logErrors: options.logErrors });
84
- cleanupWorker(worker, options);
85
- }
@@ -0,0 +1,4 @@
1
+ export { vitePluginReactServer } from './plugin.client.js';
2
+ export { vitePluginReactServer as vitePluginReactClient } from './plugin.client.js';
3
+ export { createPluginOrchestrator } from './orchestrator/createPluginOrchestrator.client.js';
4
+ export { getCondition } from './config/getCondition.js';
@@ -0,0 +1,4 @@
1
+ export { vitePluginReactServer } from './plugin.server.js';
2
+ export { vitePluginReactServer as vitePluginReactClient } from './plugin.server.js';
3
+ export { createPluginOrchestrator } from './orchestrator/createPluginOrchestrator.server.js';
4
+ export { getCondition } from './config/getCondition.js';