vite-plugin-react-server 1.1.13 → 1.1.15

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 (171) hide show
  1. package/dist/package.json +3 -1
  2. package/dist/plugin/config/defaults.d.ts +2 -2
  3. package/dist/plugin/config/defaults.d.ts.map +1 -1
  4. package/dist/plugin/config/defaults.js +2 -2
  5. package/dist/plugin/config/defaults.js.map +1 -1
  6. package/dist/plugin/config/resolveOptions.d.ts.map +1 -1
  7. package/dist/plugin/config/resolveOptions.js +101 -75
  8. package/dist/plugin/config/resolveOptions.js.map +1 -1
  9. package/dist/plugin/config/resolveUserConfig.d.ts.map +1 -1
  10. package/dist/plugin/config/resolveUserConfig.js +27 -5
  11. package/dist/plugin/config/resolveUserConfig.js.map +1 -1
  12. package/dist/plugin/error/toError.d.ts.map +1 -1
  13. package/dist/plugin/error/toError.js +0 -1
  14. package/dist/plugin/error/toError.js.map +1 -1
  15. package/dist/plugin/helpers/collectManifestCss.d.ts +1 -2
  16. package/dist/plugin/helpers/collectManifestCss.d.ts.map +1 -1
  17. package/dist/plugin/helpers/collectManifestCss.js +3 -5
  18. package/dist/plugin/helpers/collectManifestCss.js.map +1 -1
  19. package/dist/plugin/helpers/collectViteModuleGraphCss.d.ts +1 -1
  20. package/dist/plugin/helpers/collectViteModuleGraphCss.d.ts.map +1 -1
  21. package/dist/plugin/helpers/collectViteModuleGraphCss.js +6 -2
  22. package/dist/plugin/helpers/collectViteModuleGraphCss.js.map +1 -1
  23. package/dist/plugin/helpers/createCssProps.d.ts +1 -1
  24. package/dist/plugin/helpers/createCssProps.d.ts.map +1 -1
  25. package/dist/plugin/helpers/createCssProps.js +11 -32
  26. package/dist/plugin/helpers/createCssProps.js.map +1 -1
  27. package/dist/plugin/helpers/createRscStream.d.ts.map +1 -1
  28. package/dist/plugin/helpers/createRscStream.js +1 -0
  29. package/dist/plugin/helpers/createRscStream.js.map +1 -1
  30. package/dist/plugin/helpers/inputNormalizer.d.ts +1 -8
  31. package/dist/plugin/helpers/inputNormalizer.d.ts.map +1 -1
  32. package/dist/plugin/helpers/inputNormalizer.js +2 -5
  33. package/dist/plugin/helpers/inputNormalizer.js.map +1 -1
  34. package/dist/plugin/loader/createDefaultLoader.d.ts.map +1 -1
  35. package/dist/plugin/loader/createDefaultLoader.js +68 -4
  36. package/dist/plugin/loader/css-loader.development.d.ts +2 -15
  37. package/dist/plugin/loader/css-loader.development.d.ts.map +1 -1
  38. package/dist/plugin/loader/css-loader.development.js +16 -15
  39. package/dist/plugin/loader/css-loader.development.js.map +1 -1
  40. package/dist/plugin/loader/css-loader.production.d.ts +1 -1
  41. package/dist/plugin/loader/css-loader.production.d.ts.map +1 -1
  42. package/dist/plugin/loader/css-loader.production.js +1 -1
  43. package/dist/plugin/loader/css-loader.production.js.map +1 -1
  44. package/dist/plugin/loader/env-loader.development.d.ts +1 -0
  45. package/dist/plugin/loader/env-loader.development.d.ts.map +1 -1
  46. package/dist/plugin/loader/env-loader.development.js +17 -9
  47. package/dist/plugin/loader/handleExports.d.ts +1 -0
  48. package/dist/plugin/loader/handleExports.d.ts.map +1 -1
  49. package/dist/plugin/loader/handleExports.js +27 -8
  50. package/dist/plugin/loader/handleExports.js.map +1 -1
  51. package/dist/plugin/loader/react-loader.server.d.ts +2 -2
  52. package/dist/plugin/loader/react-loader.server.d.ts.map +1 -1
  53. package/dist/plugin/loader/react-loader.server.js +88 -26
  54. package/dist/plugin/loader/sourceMap.d.ts.map +1 -1
  55. package/dist/plugin/loader/sourceMap.js +1 -1
  56. package/dist/plugin/loader/transformModuleIfNeeded.d.ts.map +1 -1
  57. package/dist/plugin/loader/transformModuleIfNeeded.js +1 -1
  58. package/dist/plugin/loader/transformModuleIfNeeded.js.map +1 -1
  59. package/dist/plugin/loader/transformModuleWithPreservedFunctions.d.ts.map +1 -1
  60. package/dist/plugin/loader/transformModuleWithPreservedFunctions.js +86 -13
  61. package/dist/plugin/loader/transformModuleWithPreservedFunctions.js.map +1 -1
  62. package/dist/plugin/plugin.client.d.ts.map +1 -1
  63. package/dist/plugin/plugin.client.js +0 -1
  64. package/dist/plugin/plugin.client.js.map +1 -1
  65. package/dist/plugin/react-client/configureWorkerRequestHandler.d.ts.map +1 -1
  66. package/dist/plugin/react-client/configureWorkerRequestHandler.js +81 -5
  67. package/dist/plugin/react-client/configureWorkerRequestHandler.js.map +1 -1
  68. package/dist/plugin/react-client/createMessageHandlers.d.ts.map +1 -1
  69. package/dist/plugin/react-client/createMessageHandlers.js +3 -0
  70. package/dist/plugin/react-client/createMessageHandlers.js.map +1 -1
  71. package/dist/plugin/react-client/createWorkerStream.d.ts +2 -2
  72. package/dist/plugin/react-client/createWorkerStream.d.ts.map +1 -1
  73. package/dist/plugin/react-client/createWorkerStream.js +13 -2
  74. package/dist/plugin/react-client/createWorkerStream.js.map +1 -1
  75. package/dist/plugin/react-client/handleWorkerRscStream.d.ts.map +1 -1
  76. package/dist/plugin/react-client/handleWorkerRscStream.js +10 -3
  77. package/dist/plugin/react-client/handleWorkerRscStream.js.map +1 -1
  78. package/dist/plugin/react-client/restartWorker.d.ts.map +1 -1
  79. package/dist/plugin/react-client/restartWorker.js +2 -1
  80. package/dist/plugin/react-client/restartWorker.js.map +1 -1
  81. package/dist/plugin/react-server/configureReactServer.d.ts.map +1 -1
  82. package/dist/plugin/react-server/configureReactServer.js +1 -2
  83. package/dist/plugin/react-server/configureReactServer.js.map +1 -1
  84. package/dist/plugin/react-server/handleServerAction.d.ts.map +1 -1
  85. package/dist/plugin/react-server/handleServerAction.js +0 -16
  86. package/dist/plugin/react-server/handleServerAction.js.map +1 -1
  87. package/dist/plugin/react-static/createBuildLoader.d.ts.map +1 -0
  88. package/dist/plugin/react-static/createBuildLoader.js.map +1 -0
  89. package/dist/plugin/react-static/plugin.d.ts.map +1 -1
  90. package/dist/plugin/react-static/plugin.js +9 -12
  91. package/dist/plugin/react-static/plugin.js.map +1 -1
  92. package/dist/plugin/react-static/temporaryReferences.d.ts.map +1 -0
  93. package/dist/plugin/react-static/temporaryReferences.js.map +1 -0
  94. package/dist/plugin/transformer/plugin.server.js +2 -2
  95. package/dist/plugin/transformer/plugin.server.js.map +1 -1
  96. package/dist/plugin/types.d.ts +20 -3
  97. package/dist/plugin/types.d.ts.map +1 -1
  98. package/dist/plugin/worker/rsc/handleRender.d.ts.map +1 -1
  99. package/dist/plugin/worker/rsc/handleRender.js +1 -0
  100. package/dist/plugin/worker/rsc/handleRender.js.map +1 -1
  101. package/dist/plugin/worker/rsc/handlers.d.ts +3 -0
  102. package/dist/plugin/worker/rsc/handlers.d.ts.map +1 -0
  103. package/dist/plugin/worker/rsc/handlers.js +225 -0
  104. package/dist/plugin/worker/rsc/handlers.js.map +1 -0
  105. package/dist/plugin/worker/rsc/messageHandler.d.ts.map +1 -1
  106. package/dist/plugin/worker/rsc/messageHandler.js +4 -110
  107. package/dist/plugin/worker/rsc/messageHandler.js.map +1 -1
  108. package/dist/plugin/worker/rsc/rsc-worker.development.js +14 -16
  109. package/dist/plugin/worker/rsc/rsc-worker.development.js.map +1 -1
  110. package/dist/plugin/worker/rsc/state.d.ts +1 -2
  111. package/dist/plugin/worker/rsc/state.d.ts.map +1 -1
  112. package/dist/plugin/worker/rsc/state.js +1 -2
  113. package/dist/plugin/worker/rsc/state.js.map +1 -1
  114. package/dist/plugin/worker/rsc/userOptions.d.ts +2 -0
  115. package/dist/plugin/worker/rsc/userOptions.d.ts.map +1 -0
  116. package/dist/plugin/worker/rsc/userOptions.js +17 -0
  117. package/dist/plugin/worker/rsc/userOptions.js.map +1 -0
  118. package/dist/plugin/worker/types.d.ts +2 -1
  119. package/dist/plugin/worker/types.d.ts.map +1 -1
  120. package/dist/tsconfig.tsbuildinfo +1 -1
  121. package/package.json +5 -1
  122. package/plugin/config/defaults.tsx +5 -2
  123. package/plugin/config/resolveOptions.ts +106 -91
  124. package/plugin/config/resolveUserConfig.ts +29 -5
  125. package/plugin/error/toError.ts +0 -2
  126. package/plugin/helpers/collectManifestCss.ts +2 -6
  127. package/plugin/helpers/collectViteModuleGraphCss.ts +6 -0
  128. package/plugin/helpers/createCssProps.tsx +17 -46
  129. package/plugin/helpers/createRscStream.tsx +1 -0
  130. package/plugin/helpers/inputNormalizer.ts +4 -13
  131. package/plugin/loader/createDefaultLoader.ts +80 -4
  132. package/plugin/loader/css-loader.development.ts +17 -34
  133. package/plugin/loader/css-loader.production.ts +2 -4
  134. package/plugin/loader/env-loader.development.ts +38 -15
  135. package/plugin/loader/handleExports.ts +36 -13
  136. package/plugin/loader/react-loader.server.ts +110 -32
  137. package/plugin/loader/sourceMap.ts +1 -1
  138. package/plugin/loader/transformModuleIfNeeded.ts +2 -2
  139. package/plugin/loader/transformModuleWithPreservedFunctions.ts +128 -21
  140. package/plugin/plugin.client.ts +0 -2
  141. package/plugin/react-client/configureWorkerRequestHandler.ts +104 -4
  142. package/plugin/react-client/createMessageHandlers.ts +3 -0
  143. package/plugin/react-client/createWorkerStream.ts +15 -1
  144. package/plugin/react-client/handleWorkerRscStream.ts +12 -3
  145. package/plugin/react-client/restartWorker.ts +1 -0
  146. package/plugin/react-server/configureReactServer.ts +1 -2
  147. package/plugin/react-server/handleServerAction.ts +1 -19
  148. package/plugin/react-static/plugin.ts +9 -12
  149. package/plugin/transformer/plugin.server.ts +2 -2
  150. package/plugin/types.ts +31 -2
  151. package/plugin/worker/rsc/handleRender.ts +1 -0
  152. package/plugin/worker/rsc/handlers.ts +246 -0
  153. package/plugin/worker/rsc/messageHandler.tsx +3 -118
  154. package/plugin/worker/rsc/rsc-worker.development.ts +18 -20
  155. package/plugin/worker/rsc/state.ts +2 -6
  156. package/plugin/worker/rsc/userOptions.ts +8 -0
  157. package/plugin/worker/types.ts +2 -0
  158. package/dist/plugin/loader/createBuildLoader.d.ts.map +0 -1
  159. package/dist/plugin/loader/createBuildLoader.js.map +0 -1
  160. package/dist/plugin/loader/plugin.d.ts +0 -22
  161. package/dist/plugin/loader/plugin.d.ts.map +0 -1
  162. package/dist/plugin/loader/plugin.js +0 -27
  163. package/dist/plugin/loader/temporaryReferences.d.ts.map +0 -1
  164. package/dist/plugin/loader/temporaryReferences.js.map +0 -1
  165. package/plugin/loader/plugin.ts +0 -33
  166. /package/dist/plugin/{loader → react-static}/createBuildLoader.d.ts +0 -0
  167. /package/dist/plugin/{loader → react-static}/createBuildLoader.js +0 -0
  168. /package/dist/plugin/{loader → react-static}/temporaryReferences.d.ts +0 -0
  169. /package/dist/plugin/{loader → react-static}/temporaryReferences.js +0 -0
  170. /package/plugin/{loader → react-static}/createBuildLoader.ts +0 -0
  171. /package/plugin/{loader → react-static}/temporaryReferences.ts +0 -0
@@ -1,28 +1,73 @@
1
1
  import { transformModuleIfNeeded } from "./transformModuleIfNeeded.js";
2
- import { hydrateUserOptions } from "../helpers/index.js";
3
- import { resolveOptions } from "../config/index.js";
4
2
  import { fileURLToPath } from "node:url";
5
3
  import { join } from "node:path";
4
+ import { resolveOptions } from "../config/resolveOptions.js";
5
+ import { hydrateUserOptions } from "../helpers/index.js";
6
6
  let userOptions;
7
7
  let loaderPort;
8
8
  export async function initialize(data) {
9
- const userOptionsResult = resolveOptions(hydrateUserOptions(data.userOptions));
10
- loaderPort = data.port;
11
- loaderPort.postMessage({ type: "INITIALIZED_REACT_LOADER", id: data.id });
12
- if (userOptionsResult.type === "error") {
13
- throw userOptionsResult.error;
9
+ if (userOptions?.verbose) {
10
+ console.log("[react-loader] Initializing with options:", data.id);
11
+ }
12
+ const resolvedUserOptions = resolveOptions(hydrateUserOptions(data.userOptions));
13
+ if (resolvedUserOptions.type === "error") {
14
+ throw new Error(resolvedUserOptions.error.message);
14
15
  }
15
- userOptions = userOptionsResult.userOptions;
16
+ userOptions = resolvedUserOptions.userOptions;
17
+ loaderPort = data.port;
18
+ loaderPort.postMessage({
19
+ type: "INITIALIZED_REACT_LOADER",
20
+ id: data.id,
21
+ });
16
22
  }
17
23
  export async function load(url, context, nextLoad) {
24
+ if (userOptions?.verbose) {
25
+ console.log("[react-loader] Attempting to load:", url);
26
+ console.log("[react-loader] Context:", {
27
+ format: context.format,
28
+ conditions: context.conditions,
29
+ });
30
+ }
18
31
  const { format } = context;
19
- if (format === "module") {
32
+ if (format === "module" || format === "module-typescript") {
33
+ if (userOptions?.verbose) {
34
+ console.log("[react-loader] Loading module:", url);
35
+ }
20
36
  const result = await nextLoad(url, context);
21
- const source = typeof result.source === 'string' ? result.source :
22
- result.source instanceof Uint8Array ? new TextDecoder().decode(result.source) :
23
- String(result.source);
37
+ if (userOptions?.verbose) {
38
+ console.log("[react-loader] Next load result:", {
39
+ format: result.format,
40
+ shortCircuit: result.shortCircuit,
41
+ source: typeof result.source,
42
+ });
43
+ }
44
+ const source = typeof result.source === "string"
45
+ ? result.source
46
+ : result.source instanceof Uint8Array
47
+ ? new TextDecoder().decode(result.source)
48
+ : String(result.source);
49
+ const isServer = userOptions?.autoDiscover?.isServerFunctionCode(source);
50
+ const isClient = userOptions?.autoDiscover?.isClientComponentCode(source);
51
+ if (userOptions?.verbose) {
52
+ console.log("[react-loader] Module analysis:", {
53
+ url,
54
+ isServer,
55
+ isClient,
56
+ sourceLength: source.length,
57
+ sourcePreview: source.slice(0, 100) + "...",
58
+ });
59
+ }
60
+ if (!isServer && !isClient) {
61
+ if (userOptions?.verbose) {
62
+ console.log("[react-loader] Skipping non-server/non-client module:", url);
63
+ }
64
+ return result;
65
+ }
24
66
  // Handle file URLs
25
67
  const filePath = url.startsWith("file://") ? fileURLToPath(url) : url;
68
+ if (userOptions?.verbose) {
69
+ console.log("[react-loader] File path:", filePath);
70
+ }
26
71
  // Normalize the URL using the same logic as plugin.server.ts
27
72
  let moduleID = filePath;
28
73
  let finalID = filePath;
@@ -30,18 +75,22 @@ export async function load(url, context, nextLoad) {
30
75
  const [, value] = userOptions.normalizer(filePath);
31
76
  moduleID = join(userOptions.moduleBasePath, value);
32
77
  finalID = userOptions.moduleID(moduleID);
78
+ if (userOptions?.verbose) {
79
+ console.log("[react-loader] Normalized IDs:", { moduleID, finalID });
80
+ }
33
81
  }
82
+ const transformed = transformModuleIfNeeded(source, finalID, isServer, isClient, true // isServerEnvironment
83
+ );
34
84
  if (userOptions?.verbose) {
35
- console.log("[react-loader] moduleID:", moduleID);
36
- console.log("[react-loader] finalID:", finalID);
37
- }
38
- const transformed = transformModuleIfNeeded(source, finalID, userOptions?.autoDiscover?.isServerFunction(source), userOptions?.autoDiscover?.isClientComponent(source), true);
39
- if (userOptions?.verbose) {
40
- console.log("[react-loader] Transformed source:", transformed);
85
+ console.log("[react-loader] Transformation result:", {
86
+ originalLength: source.length,
87
+ transformedLength: transformed.length,
88
+ wasTransformed: source !== transformed,
89
+ });
41
90
  }
42
91
  if (loaderPort) {
43
92
  if (userOptions?.verbose) {
44
- console.log("[react-loader] Sending SERVER_MODULE message:", { id: finalID, url: filePath });
93
+ console.log("[react-loader] Sending SERVER_MODULE message");
45
94
  }
46
95
  loaderPort.postMessage({
47
96
  type: "SERVER_MODULE",
@@ -51,19 +100,32 @@ export async function load(url, context, nextLoad) {
51
100
  });
52
101
  }
53
102
  // If we have a source map, update it to point to the transformed source
54
- const map = result.map ? {
55
- ...result.map,
56
- sourcesContent: [transformed],
57
- mappings: result.map.mappings
58
- } : null;
103
+ const map = result.map
104
+ ? {
105
+ ...result.map,
106
+ sourcesContent: [transformed],
107
+ mappings: result.map.mappings,
108
+ }
109
+ : null;
59
110
  return {
60
111
  ...result,
61
112
  source: transformed,
62
- map
113
+ map,
63
114
  };
64
115
  }
116
+ if (userOptions?.verbose) {
117
+ console.log("[react-loader] Skipping non-module format:", format);
118
+ }
65
119
  return nextLoad(url, context);
66
120
  }
67
121
  export async function resolve(specifier, context, nextResolve) {
68
- return nextResolve(specifier, context);
122
+ if (userOptions?.verbose) {
123
+ console.log("[react-loader] Resolving:", specifier);
124
+ console.log("[react-loader] Resolve context:", context);
125
+ }
126
+ const result = await nextResolve(specifier, context);
127
+ if (userOptions?.verbose) {
128
+ console.log("[react-loader] Resolve result:", result);
129
+ }
130
+ return result;
69
131
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sourceMap.d.ts","sourceRoot":"","sources":["../../../plugin/loader/sourceMap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAIvD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAuB3E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,SAAS,CAgBzG;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,GAAG,MAAM,CAQjF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAqBpH;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAOtH;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,CAUrF"}
1
+ {"version":3,"file":"sourceMap.d.ts","sourceRoot":"","sources":["../../../plugin/loader/sourceMap.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAGvD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAuB3E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,SAAS,CAgBzG;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,GAAG,MAAM,CAQjF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAqBpH;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAOtH;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,CAUrF"}
@@ -1,4 +1,4 @@
1
- import createMappingsSerializer from 'webpack-sources/lib/helpers/createMappingsSerializer.js';
1
+ import { createMappingsSerializer } from "../source-map/createMappingsSerializer.js";
2
2
  import { basename } from "path";
3
3
  /**
4
4
  * Creates a basic source map for a module
@@ -1 +1 @@
1
- {"version":3,"file":"transformModuleIfNeeded.d.ts","sourceRoot":"","sources":["../../../plugin/loader/transformModuleIfNeeded.ts"],"names":[],"mappings":"AAKA,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,gBAAgB,GAAE,OAAO,GAAG,gBAAgB,GAAG,IAA4D,EAC3G,iBAAiB,GAAE,OAAO,GAAG,gBAAgB,GAAG,IAA6D,EAC7G,mBAAmB,UAAoC,UAsBxD"}
1
+ {"version":3,"file":"transformModuleIfNeeded.d.ts","sourceRoot":"","sources":["../../../plugin/loader/transformModuleIfNeeded.ts"],"names":[],"mappings":"AAKA,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,gBAAgB,GAAE,OAAO,GAAG,gBAAgB,GAAG,IAA0E,EACzH,iBAAiB,GAAE,OAAO,GAAG,gBAAgB,GAAG,IAAiE,EACjH,mBAAmB,UAAoC,UAsBxD"}
@@ -8,7 +8,7 @@ import { transformModuleWithPreservedFunctions } from './transformModuleWithPres
8
8
  import { parse } from './parse.js';
9
9
  import { DEFAULT_CONFIG } from '../config/defaults.js';
10
10
 
11
- function transformModuleIfNeeded(source, moduleId, isServerFunction = DEFAULT_CONFIG.AUTO_DISCOVER.isServerFunction(source), isClientComponent = DEFAULT_CONFIG.AUTO_DISCOVER.isClientComponent(source), isServerEnvironment = getCondition() === "react-server") {
11
+ function transformModuleIfNeeded(source, moduleId, isServerFunction = DEFAULT_CONFIG.AUTO_DISCOVER.isServerFunctionCode(source, moduleId), isClientComponent = DEFAULT_CONFIG.AUTO_DISCOVER.isClientComponentCode(source), isServerEnvironment = getCondition() === "react-server") {
12
12
  const ast = parse(source);
13
13
  if (isServerEnvironment && !isServerFunction && !isClientComponent || !isServerEnvironment && isClientComponent) {
14
14
  return source;
@@ -1 +1 @@
1
- {"version":3,"file":"transformModuleIfNeeded.js","sources":["../../../plugin/loader/transformModuleIfNeeded.ts"],"sourcesContent":["import { getCondition } from \"../config/getCondition.js\";\nimport { transformModuleWithPreservedFunctions } from \"./transformModuleWithPreservedFunctions.js\";\nimport { parse } from \"./parse.js\";\nimport { DEFAULT_CONFIG } from \"../config/defaults.js\";\n\nexport function transformModuleIfNeeded(\n source: string,\n moduleId: string,\n isServerFunction: boolean | RegExpMatchArray | null = DEFAULT_CONFIG.AUTO_DISCOVER.isServerFunction(source),\n isClientComponent: boolean | RegExpMatchArray | null = DEFAULT_CONFIG.AUTO_DISCOVER.isClientComponent(source),\n isServerEnvironment = getCondition() === \"react-server\"\n) {\n // Parse source and handle source maps\n const ast = parse(source); \n\n // Handle environment-specific cases\n if (\n (isServerEnvironment && !isServerFunction && !isClientComponent) ||\n (!isServerEnvironment && isClientComponent)\n ) {\n return source\n }\n\n const result = transformModuleWithPreservedFunctions(\n source,\n moduleId,\n ast,\n isServerFunction,\n isClientComponent\n );\n\n return result\n}\n"],"names":[],"mappings":";;;;;;;;;;AAKO,SAAS,wBACd,MACA,EAAA,QAAA,EACA,mBAAsD,cAAe,CAAA,aAAA,CAAc,iBAAiB,MAAM,CAAA,EAC1G,iBAAuD,GAAA,cAAA,CAAe,cAAc,iBAAkB,CAAA,MAAM,GAC5G,mBAAsB,GAAA,YAAA,OAAmB,cACzC,EAAA;AAEA,EAAM,MAAA,GAAA,GAAM,MAAM,MAAM,CAAA;AAGxB,EAAA,IACG,uBAAuB,CAAC,gBAAA,IAAoB,CAAC,iBAC7C,IAAA,CAAC,uBAAuB,iBACzB,EAAA;AACA,IAAO,OAAA,MAAA;AAAA;AAGT,EAAA,MAAM,MAAS,GAAA,qCAAA;AAAA,IACb,MAAA;AAAA,IACA,QAAA;AAAA,IACA,GAAA;AAAA,IACA,gBAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAO,OAAA,MAAA;AACT;;;;"}
1
+ {"version":3,"file":"transformModuleIfNeeded.js","sources":["../../../plugin/loader/transformModuleIfNeeded.ts"],"sourcesContent":["import { getCondition } from \"../config/getCondition.js\";\nimport { transformModuleWithPreservedFunctions } from \"./transformModuleWithPreservedFunctions.js\";\nimport { parse } from \"./parse.js\";\nimport { DEFAULT_CONFIG } from \"../config/defaults.js\";\n\nexport function transformModuleIfNeeded(\n source: string,\n moduleId: string,\n isServerFunction: boolean | RegExpMatchArray | null = DEFAULT_CONFIG.AUTO_DISCOVER.isServerFunctionCode(source, moduleId),\n isClientComponent: boolean | RegExpMatchArray | null = DEFAULT_CONFIG.AUTO_DISCOVER.isClientComponentCode(source),\n isServerEnvironment = getCondition() === \"react-server\"\n) {\n // Parse source and handle source maps\n const ast = parse(source); \n\n // Handle environment-specific cases\n if (\n (isServerEnvironment && !isServerFunction && !isClientComponent) ||\n (!isServerEnvironment && isClientComponent)\n ) {\n return source\n }\n\n const result = transformModuleWithPreservedFunctions(\n source,\n moduleId,\n ast,\n isServerFunction,\n isClientComponent\n );\n\n return result\n}\n"],"names":[],"mappings":";;;;;;;;;;AAKO,SAAS,wBACd,MACA,EAAA,QAAA,EACA,mBAAsD,cAAe,CAAA,aAAA,CAAc,qBAAqB,MAAQ,EAAA,QAAQ,GACxH,iBAAuD,GAAA,cAAA,CAAe,cAAc,qBAAsB,CAAA,MAAM,GAChH,mBAAsB,GAAA,YAAA,OAAmB,cACzC,EAAA;AAEA,EAAM,MAAA,GAAA,GAAM,MAAM,MAAM,CAAA;AAGxB,EAAA,IACG,uBAAuB,CAAC,gBAAA,IAAoB,CAAC,iBAC7C,IAAA,CAAC,uBAAuB,iBACzB,EAAA;AACA,IAAO,OAAA,MAAA;AAAA;AAGT,EAAA,MAAM,MAAS,GAAA,qCAAA;AAAA,IACb,MAAA;AAAA,IACA,QAAA;AAAA,IACA,GAAA;AAAA,IACA,gBAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAO,OAAA,MAAA;AACT;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"transformModuleWithPreservedFunctions.d.ts","sourceRoot":"","sources":["../../../plugin/loader/transformModuleWithPreservedFunctions.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AASD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qCAAqC,CACnD,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,EAChB,gBAAgB,EAAE,OAAO,GAAG,gBAAgB,GAAG,IAAI,EACnD,iBAAiB,EAAE,OAAO,GAAG,gBAAgB,GAAG,IAAI,GACnD,MAAM,CA2DR"}
1
+ {"version":3,"file":"transformModuleWithPreservedFunctions.d.ts","sourceRoot":"","sources":["../../../plugin/loader/transformModuleWithPreservedFunctions.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG1C,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AASD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qCAAqC,CACnD,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,EAChB,gBAAgB,EAAE,OAAO,GAAG,gBAAgB,GAAG,IAAI,EACnD,iBAAiB,EAAE,OAAO,GAAG,gBAAgB,GAAG,IAAI,GACnD,MAAM,CAqKR"}
@@ -4,48 +4,121 @@
4
4
  * MIT License
5
5
  */
6
6
  import { handleExports } from './handleExports.js';
7
+ import createMappingsSerializer from 'webpack-sources/lib/helpers/createMappingsSerializer.js';
7
8
 
8
9
  function createClientReferenceError(name) {
9
10
  return `Attempted to call ${name}() from the server but ${name} is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.`;
10
11
  }
11
12
  function transformModuleWithPreservedFunctions(source, moduleId, program, isServerFunction, isClientComponent) {
12
- const { exportNames, exports } = handleExports(source, program, isServerFunction, isClientComponent);
13
+ let sourceWithoutDirective = source;
14
+ let directiveEnd = 0;
15
+ for (const node of program.body) {
16
+ if (node.type !== "ExpressionStatement") {
17
+ break;
18
+ }
19
+ let directive = null;
20
+ if ("directive" in node && typeof node.directive === "string") {
21
+ directive = node.directive;
22
+ } else if (node.expression.type === "Literal" && typeof node.expression.value === "string" && (node.expression.value === "use server" || node.expression.value === "use client")) {
23
+ directive = node.expression.value;
24
+ }
25
+ if (directive && "start" in node && "end" in node) {
26
+ directiveEnd = node.end;
27
+ }
28
+ }
29
+ if (directiveEnd > 0) {
30
+ sourceWithoutDirective = source.slice(directiveEnd).trim();
31
+ }
32
+ const { exportNames, exports } = handleExports(
33
+ sourceWithoutDirective,
34
+ program,
35
+ isServerFunction,
36
+ isClientComponent
37
+ );
13
38
  const moduleIdLiteral = JSON.stringify(moduleId);
14
- if (isServerFunction) {
15
- const imports = ['import { registerServerReference } from "react-server-dom-esm/server.node";'];
39
+ if (Boolean(isServerFunction)) {
40
+ const imports = [
41
+ 'import { registerServerReference } from "react-server-dom-esm/server.node";'
42
+ ];
16
43
  const registrations = [];
17
44
  for (const name of exportNames) {
18
45
  const exportInfo = exports.get(name);
19
46
  if (exportInfo) {
20
47
  const exportName = name === "default" && exportInfo.localName ? exportInfo.localName : name;
21
48
  registrations.push(
22
- `registerServerReference(${exportName}, ${moduleIdLiteral}, ${JSON.stringify(name)});`
49
+ `registerServerReference(${exportName}, ${moduleIdLiteral}, ${JSON.stringify(
50
+ name
51
+ )});`
23
52
  );
24
53
  }
25
54
  }
26
- const newSource = [...imports, source].join("\n\n");
27
- const finalSource = newSource + "\n\n" + registrations.join("\n");
28
- return finalSource;
55
+ const newSource = [...imports, sourceWithoutDirective, ...registrations].join("\n\n");
56
+ let mappings = "";
57
+ const createMapping = createMappingsSerializer();
58
+ let generatedLine = 1;
59
+ createMapping(generatedLine, 0, 0, 0, 0, -1);
60
+ generatedLine++;
61
+ for (let i = 0; i < registrations.length; i++) {
62
+ createMapping(generatedLine, 0, 0, 1, 0, -1);
63
+ generatedLine++;
64
+ }
65
+ const sourceLines = source.split("\n");
66
+ for (let i = 0; i < sourceLines.length; i++) {
67
+ createMapping(generatedLine, 0, 0, i + 1, 0, -1);
68
+ generatedLine++;
69
+ }
70
+ const sourceMap = {
71
+ version: 3,
72
+ file: moduleId,
73
+ sources: [moduleId],
74
+ sourcesContent: [newSource],
75
+ // Use transformed source content
76
+ mappings,
77
+ sourceRoot: "",
78
+ names: []
79
+ };
80
+ return newSource + "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + Buffer.from(JSON.stringify(sourceMap)).toString("base64");
29
81
  }
30
- if (isClientComponent) {
31
- const imports = ['import { registerClientReference } from "react-server-dom-esm/server.node";'];
82
+ if (!!isClientComponent) {
83
+ const imports = [
84
+ 'import { registerClientReference } from "react-server-dom-esm/server.node";'
85
+ ];
32
86
  const declarations = [];
33
87
  for (const name of exportNames) {
34
88
  const errorMessage = createClientReferenceError(name);
35
89
  if (name === "default") {
36
90
  declarations.push(`export default registerClientReference(function() {
37
- throw new Error("${errorMessage}");
91
+ throw new Error("${errorMessage}");
38
92
  }, ${moduleIdLiteral}, "default");`);
39
93
  } else {
40
94
  declarations.push(`export const ${name} = registerClientReference(function() {
41
- throw new Error("${errorMessage}");
95
+ throw new Error("${errorMessage}");
42
96
  }, ${moduleIdLiteral}, ${JSON.stringify(name)});`);
43
97
  }
44
98
  }
45
99
  const newSource = [...imports, ...declarations].join("\n\n");
46
- return newSource;
100
+ let mappings = "";
101
+ const createMapping = createMappingsSerializer();
102
+ let generatedLine = 1;
103
+ createMapping(generatedLine, 0, 0, 0, 0, -1);
104
+ generatedLine++;
105
+ for (let i = 0; i < declarations.length; i++) {
106
+ createMapping(generatedLine, 0, 0, 1, 0, -1);
107
+ generatedLine++;
108
+ }
109
+ const sourceMap = {
110
+ version: 3,
111
+ file: moduleId,
112
+ sources: [moduleId],
113
+ sourcesContent: [newSource],
114
+ // Use transformed source content
115
+ mappings,
116
+ sourceRoot: "",
117
+ names: []
118
+ };
119
+ return newSource + "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + Buffer.from(JSON.stringify(sourceMap)).toString("base64");
47
120
  }
48
- return source;
121
+ throw new Error("Invalid module type");
49
122
  }
50
123
 
51
124
  export { transformModuleWithPreservedFunctions };
@@ -1 +1 @@
1
- {"version":3,"file":"transformModuleWithPreservedFunctions.js","sources":["../../../plugin/loader/transformModuleWithPreservedFunctions.ts"],"sourcesContent":["/**\n * # RSC Boundary Handling\n *\n * This file provides the core transformation logic for React Server Components (RSC) boundaries.\n *\n * - **Server Loader**: Always strips implementation for client modules, exports error-throwing references.\n * - **Client Loader**: Always strips implementation for server modules, exports error-throwing references.\n * - **Browser**: Only client modules are passed through as-is.\n *\n * All transformations are handled by `transformModuleWithPreservedFunctions` for consistency.\n *\n * ## Error Behavior\n *\n * - If a client component is imported on the server, the export is a function that throws a clear error.\n * - If a server action is imported on the client, the export is a function that throws a clear error.\n *\n * This ensures that implementation details are never leaked across boundaries and errors are easy to debug.\n */\nimport { handleExports } from \"./handleExports.js\";\nimport type { Program } from \"./types.js\";\n\nexport interface TransformOptions {\n id: string;\n exportNames: string[];\n beforeExports: string;\n afterExports: string;\n isServerModule?: boolean;\n isClientModule?: boolean;\n program?: Program;\n}\n\n/**\n * Creates a client reference error message\n */\nfunction createClientReferenceError(name: string): string {\n return `Attempted to call ${name}() from the server but ${name} is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.`;\n}\n\n/**\n * Transforms a module for RSC boundaries.\n * - Server modules: exports are wrapped with server references while preserving functionality.\n * - Client modules: exports are replaced with client references or errors, depending on environment.\n * - Only the correct references are exported; implementation is never leaked across boundaries.\n *\n * @param source - The original module source code.\n * @param moduleId - The module's unique identifier.\n * @param url - The module's URL.\n * @param program - The parsed AST.\n * @param map - The source map for the source code.\n * @param isServerFunction - Whether the module is a server function.\n * @param isClientComponent - Whether the module is a client component.\n * @returns The transformed source code.\n */\nexport function transformModuleWithPreservedFunctions(\n source: string,\n moduleId: string,\n program: Program,\n isServerFunction: boolean | RegExpMatchArray | null,\n isClientComponent: boolean | RegExpMatchArray | null,\n): string {\n\n // Get export names and create module ID literal\n const { exportNames, exports } = handleExports(source, program, isServerFunction, isClientComponent);\n const moduleIdLiteral = JSON.stringify(moduleId);\n\n // For server modules in server environment, register server references\n if (isServerFunction) {\n const imports = ['import { registerServerReference } from \"react-server-dom-esm/server.node\";'];\n const registrations: string[] = [];\n\n // Register each export\n for (const name of exportNames) {\n const exportInfo = exports.get(name);\n if (exportInfo) {\n // For default exports, use the localName if available\n const exportName = name === \"default\" && exportInfo.localName ? exportInfo.localName : name;\n // Register all exports in server modules\n registrations.push(\n `registerServerReference(${exportName}, ${moduleIdLiteral}, ${JSON.stringify(name)});`\n );\n }\n }\n\n // Create new source with registrations\n // First, add the imports at the top\n const newSource = [...imports, source].join(\"\\n\\n\");\n // Then, add the registrations at the end\n const finalSource = newSource + \"\\n\\n\" + registrations.join(\"\\n\");\n\n return finalSource;\n }\n\n // For client modules in server environment, register client references\n if (isClientComponent) {\n const imports = ['import { registerClientReference } from \"react-server-dom-esm/server.node\";'];\n const declarations: string[] = [];\n\n for (const name of exportNames) {\n const errorMessage = createClientReferenceError(name);\n if (name === \"default\") {\n declarations.push(`export default registerClientReference(function() {\n throw new Error(\"${errorMessage}\");\n}, ${moduleIdLiteral}, \"default\");`);\n } else {\n declarations.push(`export const ${name} = registerClientReference(function() {\n throw new Error(\"${errorMessage}\");\n}, ${moduleIdLiteral}, ${JSON.stringify(name)});`);\n }\n }\n\n // Create new source with declarations\n const newSource = [...imports, ...declarations].join(\"\\n\\n\");\n\n return newSource;\n }\n\n // For other cases, return original source\n return source;\n}\n"],"names":[],"mappings":";;;;;;;AAkCA,SAAS,2BAA2B,IAAsB,EAAA;AACxD,EAAO,OAAA,CAAA,kBAAA,EAAqB,IAAI,CAAA,uBAAA,EAA0B,IAAI,CAAA,kKAAA,CAAA;AAChE;AAiBO,SAAS,qCACd,CAAA,MAAA,EACA,QACA,EAAA,OAAA,EACA,kBACA,iBACQ,EAAA;AAGR,EAAM,MAAA,EAAE,aAAa,OAAQ,EAAA,GAAI,cAAc,MAAQ,EAAA,OAAA,EAAS,kBAAkB,iBAAiB,CAAA;AACnG,EAAM,MAAA,eAAA,GAAkB,IAAK,CAAA,SAAA,CAAU,QAAQ,CAAA;AAG/C,EAAA,IAAI,gBAAkB,EAAA;AACpB,IAAM,MAAA,OAAA,GAAU,CAAC,6EAA6E,CAAA;AAC9F,IAAA,MAAM,gBAA0B,EAAC;AAGjC,IAAA,KAAA,MAAW,QAAQ,WAAa,EAAA;AAC9B,MAAM,MAAA,UAAA,GAAa,OAAQ,CAAA,GAAA,CAAI,IAAI,CAAA;AACnC,MAAA,IAAI,UAAY,EAAA;AAEd,QAAA,MAAM,aAAa,IAAS,KAAA,SAAA,IAAa,UAAW,CAAA,SAAA,GAAY,WAAW,SAAY,GAAA,IAAA;AAEvF,QAAc,aAAA,CAAA,IAAA;AAAA,UACZ,CAAA,wBAAA,EAA2B,UAAU,CAAK,EAAA,EAAA,eAAe,KAAK,IAAK,CAAA,SAAA,CAAU,IAAI,CAAC,CAAA,EAAA;AAAA,SACpF;AAAA;AACF;AAKF,IAAA,MAAM,YAAY,CAAC,GAAG,SAAS,MAAM,CAAA,CAAE,KAAK,MAAM,CAAA;AAElD,IAAA,MAAM,WAAc,GAAA,SAAA,GAAY,MAAS,GAAA,aAAA,CAAc,KAAK,IAAI,CAAA;AAEhE,IAAO,OAAA,WAAA;AAAA;AAIT,EAAA,IAAI,iBAAmB,EAAA;AACrB,IAAM,MAAA,OAAA,GAAU,CAAC,6EAA6E,CAAA;AAC9F,IAAA,MAAM,eAAyB,EAAC;AAEhC,IAAA,KAAA,MAAW,QAAQ,WAAa,EAAA;AAC9B,MAAM,MAAA,YAAA,GAAe,2BAA2B,IAAI,CAAA;AACpD,MAAA,IAAI,SAAS,SAAW,EAAA;AACtB,QAAA,YAAA,CAAa,IAAK,CAAA,CAAA;AAAA,mBAAA,EACL,YAAY,CAAA;AAAA,GAAA,EAC5B,eAAe,CAAe,aAAA,CAAA,CAAA;AAAA,OACtB,MAAA;AACL,QAAa,YAAA,CAAA,IAAA,CAAK,gBAAgB,IAAI,CAAA;AAAA,mBAAA,EACzB,YAAY,CAAA;AAAA,GAAA,EAC5B,eAAe,CAAK,EAAA,EAAA,IAAA,CAAK,SAAU,CAAA,IAAI,CAAC,CAAI,EAAA,CAAA,CAAA;AAAA;AAC3C;AAIF,IAAM,MAAA,SAAA,GAAY,CAAC,GAAG,OAAA,EAAS,GAAG,YAAY,CAAA,CAAE,KAAK,MAAM,CAAA;AAE3D,IAAO,OAAA,SAAA;AAAA;AAIT,EAAO,OAAA,MAAA;AACT;;;;"}
1
+ {"version":3,"file":"transformModuleWithPreservedFunctions.js","sources":["../../../plugin/loader/transformModuleWithPreservedFunctions.ts"],"sourcesContent":["/**\n * # RSC Boundary Handling\n *\n * This file provides the core transformation logic for React Server Components (RSC) boundaries.\n *\n * - **Server Loader**: Always strips implementation for client modules, exports error-throwing references.\n * - **Client Loader**: Always strips implementation for server modules, exports error-throwing references.\n * - **Browser**: Only client modules are passed through as-is.\n *\n * All transformations are handled by `transformModuleWithPreservedFunctions` for consistency.\n *\n * ## Error Behavior\n *\n * - If a client component is imported on the server, the export is a function that throws a clear error.\n * - If a server action is imported on the client, the export is a function that throws a clear error.\n *\n * This ensures that implementation details are never leaked across boundaries and errors are easy to debug.\n */\nimport { handleExports } from \"./handleExports.js\";\nimport type { Program } from \"./types.js\";\nimport createMappingsSerializer from \"webpack-sources/lib/helpers/createMappingsSerializer.js\";\n\nexport interface TransformOptions {\n id: string;\n exportNames: string[];\n beforeExports: string;\n afterExports: string;\n isServerModule?: boolean;\n isClientModule?: boolean;\n program?: Program;\n}\n\n/**\n * Creates a client reference error message\n */\nfunction createClientReferenceError(name: string): string {\n return `Attempted to call ${name}() from the server but ${name} is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.`;\n}\n\n/**\n * Transforms a module for RSC boundaries.\n * - Server modules: exports are wrapped with server references while preserving functionality.\n * - Client modules: exports are replaced with client references or errors, depending on environment.\n * - Only the correct references are exported; implementation is never leaked across boundaries.\n *\n * @param source - The original module source code.\n * @param moduleId - The module's unique identifier.\n * @param url - The module's URL.\n * @param program - The parsed AST.\n * @param map - The source map for the source code.\n * @param isServerFunction - Whether the module is a server function.\n * @param isClientComponent - Whether the module is a client component.\n * @returns The transformed source code.\n */\nexport function transformModuleWithPreservedFunctions(\n source: string,\n moduleId: string,\n program: Program,\n isServerFunction: boolean | RegExpMatchArray | null,\n isClientComponent: boolean | RegExpMatchArray | null\n): string {\n // Find and remove directives using AST\n let sourceWithoutDirective = source;\n let directiveEnd = 0;\n \n // Only look at top-level directives\n for (const node of program.body) {\n if (node.type !== \"ExpressionStatement\") {\n break;\n }\n\n let directive: string | null = null;\n if (\"directive\" in node && typeof node.directive === \"string\") {\n directive = node.directive;\n } else if (\n node.expression.type === \"Literal\" &&\n typeof node.expression.value === \"string\" &&\n (node.expression.value === \"use server\" || node.expression.value === \"use client\")\n ) {\n directive = node.expression.value;\n }\n\n if (directive && \"start\" in node && \"end\" in node) {\n directiveEnd = node.end;\n }\n }\n\n // Remove the directive and any whitespace after it\n if (directiveEnd > 0) {\n sourceWithoutDirective = source.slice(directiveEnd).trim();\n }\n\n // Get export names and create module ID literal\n const { exportNames, exports } = handleExports(\n sourceWithoutDirective,\n program,\n isServerFunction,\n isClientComponent\n );\n const moduleIdLiteral = JSON.stringify(moduleId);\n\n // For server modules in server environment, register server references\n if (Boolean(isServerFunction)) {\n const imports = [\n 'import { registerServerReference } from \"react-server-dom-esm/server.node\";',\n ];\n const registrations: string[] = [];\n\n // Register each export\n for (const name of exportNames) {\n const exportInfo = exports.get(name);\n if (exportInfo) {\n // For default exports, use the localName if available\n const exportName =\n name === \"default\" && exportInfo.localName\n ? exportInfo.localName\n : name;\n // Register all exports in server modules\n registrations.push(\n `registerServerReference(${exportName}, ${moduleIdLiteral}, ${JSON.stringify(\n name\n )});`\n );\n }\n }\n\n // Create new source with registrations\n // First, add the imports at the top\n const newSource = [...imports, sourceWithoutDirective, ...registrations].join(\"\\n\\n\");\n\n // Handle source maps\n let mappings = \"\";\n const createMapping = createMappingsSerializer();\n let generatedLine = 1;\n\n // Map the import line to the first line of the original source\n createMapping(generatedLine, 0, 0, 0, 0, -1);\n generatedLine++;\n\n // Map the registration lines to the first line of the original source\n for (let i = 0; i < registrations.length; i++) {\n createMapping(generatedLine, 0, 0, 1, 0, -1);\n generatedLine++;\n }\n\n // Map the original source lines, skipping the directive line\n const sourceLines = source.split(\"\\n\");\n for (let i = 0; i < sourceLines.length; i++) {\n createMapping(generatedLine, 0, 0, i + 1, 0, -1); // +1 because we skip directive line\n generatedLine++;\n }\n\n // Add source map to the output with original source content\n const sourceMap = {\n version: 3,\n file: moduleId,\n sources: [moduleId],\n sourcesContent: [newSource], // Use transformed source content\n mappings,\n sourceRoot: \"\",\n names: [],\n };\n\n return (\n newSource +\n \"\\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,\" +\n Buffer.from(JSON.stringify(sourceMap)).toString(\"base64\")\n );\n // end of server module\n }\n if (!!isClientComponent) {\n // For client modules in server environment, register client references\n const imports = [\n 'import { registerClientReference } from \"react-server-dom-esm/server.node\";',\n ];\n const declarations: string[] = [];\n\n for (const name of exportNames) {\n const errorMessage = createClientReferenceError(name);\n if (name === \"default\") {\n declarations.push(`export default registerClientReference(function() {\nthrow new Error(\"${errorMessage}\");\n}, ${moduleIdLiteral}, \"default\");`);\n } else {\n declarations.push(`export const ${name} = registerClientReference(function() {\nthrow new Error(\"${errorMessage}\");\n}, ${moduleIdLiteral}, ${JSON.stringify(name)});`);\n }\n }\n // Create new source with declarations\n const newSource = [...imports, ...declarations].join(\"\\n\\n\");\n\n // Handle source maps for client modules\n let mappings = \"\";\n const createMapping = createMappingsSerializer();\n let generatedLine = 1;\n\n // Map the import line to the first line of the original source\n createMapping(generatedLine, 0, 0, 0, 0, -1);\n generatedLine++;\n\n // Map the declaration lines to the first line of the original source\n for (let i = 0; i < declarations.length; i++) {\n createMapping(generatedLine, 0, 0, 1, 0, -1);\n generatedLine++;\n }\n\n // Add source map to the output with original source content\n const sourceMap = {\n version: 3,\n file: moduleId,\n sources: [moduleId],\n sourcesContent: [newSource], // Use transformed source content\n mappings,\n sourceRoot: \"\",\n names: [],\n };\n\n return (\n newSource +\n \"\\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,\" +\n Buffer.from(JSON.stringify(sourceMap)).toString(\"base64\")\n );\n }\n throw new Error(\"Invalid module type\");\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.client.d.ts","sourceRoot":"","sources":["../../plugin/plugin.client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,mBAAmB,EACnB,YAAY,EACZ,WAAW,EACZ,MAAM,aAAa,CAAC;AAKrB,wBAAgB,qBAAqB,CACnC,CAAC,SAAS,WAAW,GAAG,WAAW,EACnC,SAAS,SAAS,YAAY,GAAG,YAAY,EAC7C,OAAO,GAAS,mBAAmB,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,OAAO,MAAM,EAAE,MAAM,EAAE,CAO5E"}
1
+ {"version":3,"file":"plugin.client.d.ts","sourceRoot":"","sources":["../../plugin/plugin.client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,mBAAmB,EACnB,YAAY,EACZ,WAAW,EACZ,MAAM,aAAa,CAAC;AAIrB,wBAAgB,qBAAqB,CACnC,CAAC,SAAS,WAAW,GAAG,WAAW,EACnC,SAAS,SAAS,YAAY,GAAG,YAAY,EAC7C,OAAO,GAAS,mBAAmB,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,OAAO,MAAM,EAAE,MAAM,EAAE,CAM5E"}
@@ -10,7 +10,6 @@ import { envPlugin } from './env.js';
10
10
  function vitePluginReactServer(options = {}) {
11
11
  return [
12
12
  envPlugin(),
13
- //reactTransformPlugin(options),
14
13
  reactClientPlugin(options),
15
14
  reactPreservePlugin(options)
16
15
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.client.js","sources":["../../plugin/plugin.client.ts"],"sourcesContent":["import { reactPreservePlugin } from \"./preserver/plugin.js\";\nimport type {\n StreamPluginOptions,\n InlineCssOpt,\n PagePropOpt,\n} from \"../types.js\";\nimport { reactClientPlugin } from \"./react-client/plugin.js\";\nimport { envPlugin } from \"./env/plugin.js\";\n//import { reactTransformPlugin } from \"./transformer/plugin.client.js\";\n\nexport function vitePluginReactServer<\n T extends PagePropOpt = PagePropOpt,\n InlineCSS extends InlineCssOpt = InlineCssOpt\n>(options = {} as StreamPluginOptions<T, InlineCSS>): import(\"vite\").Plugin[] {\n return [\n envPlugin(),\n //reactTransformPlugin(options),\n reactClientPlugin(options),\n reactPreservePlugin(options),\n ];\n}\n"],"names":[],"mappings":";;;;;;;;;AAUO,SAAS,qBAAA,CAGd,OAAU,GAAA,EAAkE,EAAA;AAC5E,EAAO,OAAA;AAAA,IACL,SAAU,EAAA;AAAA;AAAA,IAEV,kBAAkB,OAAO,CAAA;AAAA,IACzB,oBAAoB,OAAO;AAAA,GAC7B;AACF;;;;"}
1
+ {"version":3,"file":"plugin.client.js","sources":["../../plugin/plugin.client.ts"],"sourcesContent":["import { reactPreservePlugin } from \"./preserver/plugin.js\";\nimport type {\n StreamPluginOptions,\n InlineCssOpt,\n PagePropOpt,\n} from \"../types.js\";\nimport { reactClientPlugin } from \"./react-client/plugin.js\";\nimport { envPlugin } from \"./env/plugin.js\";\n\nexport function vitePluginReactServer<\n T extends PagePropOpt = PagePropOpt,\n InlineCSS extends InlineCssOpt = InlineCssOpt\n>(options = {} as StreamPluginOptions<T, InlineCSS>): import(\"vite\").Plugin[] {\n return [\n envPlugin(),\n reactClientPlugin(options),\n reactPreservePlugin(options),\n ];\n}\n"],"names":[],"mappings":";;;;;;;;;AASO,SAAS,qBAAA,CAGd,OAAU,GAAA,EAAkE,EAAA;AAC5E,EAAO,OAAA;AAAA,IACL,SAAU,EAAA;AAAA,IACV,kBAAkB,OAAO,CAAA;AAAA,IACzB,oBAAoB,OAAO;AAAA,GAC7B;AACF;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"configureWorkerRequestHandler.d.ts","sourceRoot":"","sources":["../../../plugin/react-client/configureWorkerRequestHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,KAAK,EACV,mBAAmB,EACnB,YAAY,EACZ,WAAW,EACX,aAAa,EAEb,mBAAmB,EAEpB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,cAAc,EAAe,MAAM,qBAAqB,CAAC;AAWlE;;;;;GAKG;AACH,wBAAsB,6BAA6B,CACjD,CAAC,SAAS,WAAW,GAAG,WAAW,EACnC,SAAS,SAAS,YAAY,GAAG,YAAY,EAC7C,EACA,MAAM,EACN,mBAAmB,EACnB,WAAW,EAAE,YAAY,EACzB,UAAU,EACV,SAAS,GACV,EAAE;IACD,MAAM,EAAE,aAAa,CAAC;IACtB,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,WAAW,EAAE,mBAAmB,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IAC/C,UAAU,EAAE,cAAc,CAAC;IAC3B,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;CAC9C,iBAqLA"}
1
+ {"version":3,"file":"configureWorkerRequestHandler.d.ts","sourceRoot":"","sources":["../../../plugin/react-client/configureWorkerRequestHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,KAAK,EACV,mBAAmB,EACnB,YAAY,EACZ,WAAW,EACX,aAAa,EAEb,mBAAmB,EAEpB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,cAAc,EAAe,MAAM,qBAAqB,CAAC;AAYlE;;;;;GAKG;AACH,wBAAsB,6BAA6B,CACjD,CAAC,SAAS,WAAW,GAAG,WAAW,EACnC,SAAS,SAAS,YAAY,GAAG,YAAY,EAC7C,EACA,MAAM,EACN,mBAAmB,EACnB,WAAW,EAAE,YAAY,EACzB,UAAU,EACV,SAAS,GACV,EAAE;IACD,MAAM,EAAE,aAAa,CAAC;IACtB,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,WAAW,EAAE,mBAAmB,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IAC/C,UAAU,EAAE,cAAc,CAAC;IAC3B,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;CAC9C,iBAwRA"}
@@ -10,7 +10,7 @@ import { performance } from 'node:perf_hooks';
10
10
  import { restartWorker } from './restartWorker.js';
11
11
  import { handleWorkerRscStream } from './handleWorkerRscStream.js';
12
12
  import { getRouteFiles } from '../helpers/getRouteFiles.js';
13
- import { Readable } from 'node:stream';
13
+ import { PassThrough, Readable } from 'node:stream';
14
14
 
15
15
  async function configureWorkerRequestHandler({
16
16
  server,
@@ -55,6 +55,86 @@ async function configureWorkerRequestHandler({
55
55
  const handler = async (req, res, next) => {
56
56
  if (!req.url) return next();
57
57
  const info = requestInfo(req, handlerOptions, "", server.config.logger);
58
+ const serializedUserOptions = serializedOptions(
59
+ handlerOptions,
60
+ autoDiscoveredFiles
61
+ );
62
+ if (info.isServerActionRequest) {
63
+ try {
64
+ const chunks = [];
65
+ for await (const chunk of req) {
66
+ chunks.push(chunk);
67
+ }
68
+ const body = Buffer.concat(chunks).toString();
69
+ const parsed = JSON.parse(body);
70
+ let id;
71
+ let args;
72
+ if (Array.isArray(parsed)) {
73
+ args = parsed;
74
+ id = req.url?.split("?")[0] ?? "";
75
+ } else if (parsed && typeof parsed === "object" && "id" in parsed) {
76
+ id = parsed.id;
77
+ args = parsed.args ?? [];
78
+ } else {
79
+ throw new Error("Invalid server action request format");
80
+ }
81
+ res.setHeader("Content-Type", "text/x-component; charset=utf-8");
82
+ res.setHeader("Transfer-Encoding", "chunked");
83
+ res.setHeader("Connection", "keep-alive");
84
+ if (!currentWorker) {
85
+ currentWorker = await restartWorker({
86
+ server,
87
+ autoDiscoveredFiles,
88
+ userOptions: serializedUserOptions,
89
+ hmrChannel
90
+ });
91
+ }
92
+ currentWorker.postMessage({
93
+ type: "SERVER_ACTION",
94
+ id,
95
+ args
96
+ });
97
+ const passThrough = new PassThrough();
98
+ passThrough.pipe(res);
99
+ const messageHandler = (message) => {
100
+ if (message.type === "RSC_CHUNK") {
101
+ passThrough.write(message.chunk);
102
+ } else if (message.type === "RSC_END") {
103
+ passThrough.end();
104
+ currentWorker.removeListener("message", messageHandler);
105
+ } else if (message.type === "ERROR") {
106
+ passThrough.end();
107
+ currentWorker.removeListener("message", messageHandler);
108
+ server.config.logger.error(message.error.message + (message.error.stack ?? ""), {
109
+ error: message.error
110
+ });
111
+ }
112
+ };
113
+ currentWorker.on("message", messageHandler);
114
+ passThrough.on("error", (error) => {
115
+ server.config.logger.error(error.message + (error.stack ?? ""), {
116
+ error
117
+ });
118
+ res.end();
119
+ });
120
+ return;
121
+ } catch (error) {
122
+ if (error instanceof Error) {
123
+ server.config.logger.error(error.message + (error.stack ?? ""), {
124
+ error
125
+ });
126
+ }
127
+ res.statusCode = 500;
128
+ res.end(JSON.stringify({
129
+ type: "server-action-response",
130
+ returnValue: {
131
+ success: false,
132
+ error: error instanceof Error ? error.message : String(error)
133
+ }
134
+ }));
135
+ return;
136
+ }
137
+ }
58
138
  if (!info.isRscRequest) {
59
139
  return next();
60
140
  }
@@ -73,10 +153,6 @@ async function configureWorkerRequestHandler({
73
153
  res.setHeader("Content-Type", info.contentType);
74
154
  res.setHeader("Transfer-Encoding", "chunked");
75
155
  res.setHeader("Connection", "keep-alive");
76
- const serializedUserOptions = serializedOptions(
77
- handlerOptions,
78
- autoDiscoveredFiles
79
- );
80
156
  const userOnMetrics = typeof onMetrics === "function" ? (metrics) => {
81
157
  const elapsedTime = performance.now() - startTime;
82
158
  const formattedMetrics = {
@@ -1 +1 @@
1
- {"version":3,"file":"configureWorkerRequestHandler.js","sources":["../../../plugin/react-client/configureWorkerRequestHandler.ts"],"sourcesContent":["import type { ViteDevServer } from \"vite\";\nimport type {\n AutoDiscoveredFiles,\n InlineCssOpt,\n PagePropOpt,\n RenderMetrics,\n RequestHandler,\n ResolvedUserOptions,\n StreamMetrics,\n} from \"../types.js\";\nimport { MessageChannel, type Worker } from \"node:worker_threads\";\nimport { serializedOptions } from \"../helpers/serializeUserOptions.js\";\nimport { requestInfo } from \"../helpers/requestInfo.js\";\nimport { performance } from \"node:perf_hooks\";\nimport { restartWorker } from \"./restartWorker.js\";\nimport { handleWorkerRscStream } from \"./handleWorkerRscStream.js\";\nimport { getRouteFiles } from \"../helpers/getRouteFiles.js\";\nimport type { RscWorkerInputMessage } from \"../worker/types.js\";\nimport { Readable } from \"node:stream\";\nimport type { ReadableStream } from \"node:stream/web\";\n\n/**\n * Configures the worker request handler.\n * @param server - The Vite dev server\n * @param autoDiscoveredFiles - The auto discovered files\n * @param userOptions - The user options\n */\nexport async function configureWorkerRequestHandler<\n T extends PagePropOpt = PagePropOpt,\n InlineCSS extends InlineCssOpt = InlineCssOpt\n>({\n server,\n autoDiscoveredFiles,\n userOptions: _userOptions,\n hmrChannel,\n onMetrics,\n}: {\n server: ViteDevServer;\n autoDiscoveredFiles: AutoDiscoveredFiles;\n userOptions: ResolvedUserOptions<T, InlineCSS>;\n hmrChannel: MessageChannel;\n onMetrics?: (metrics: RenderMetrics) => void;\n}) {\n let {\n // remove these\n projectRoot: _projectRoot,\n moduleBaseURL: _moduleBaseURL,\n ...handlerUserOptions\n } = _userOptions;\n const handlerOptions = Object.assign({}, handlerUserOptions, {\n moduleBaseURL: server.config.base,\n moduleBasePath: server.config.base,\n projectRoot: server.config.root,\n });\n\n // Start the worker\n let currentWorker: Worker | null = null;\n const logger = server.config.logger;\n\n // Handle server restarts\n server.ws.on(\"restart\", async () => {\n logger.info(\"[react-client] Server restarting, shutting down worker...\");\n if (currentWorker) {\n currentWorker.postMessage({\n type: \"SHUTDOWN\",\n id: \"*\",\n } satisfies RscWorkerInputMessage);\n await new Promise((resolve, reject) => {\n currentWorker?.on(\"message\", (message) => {\n if (message.type === \"SHUTDOWN_COMPLETE\") {\n resolve(true);\n } else {\n reject(\"Did not receive SHUTDOWN_COMPLETE\");\n }\n });\n });\n currentWorker.removeAllListeners();\n currentWorker = null;\n }\n });\n\n // Create the request handler\n const handler: RequestHandler = async (req, res, next) => {\n if (!req.url) return next();\n\n const info = requestInfo(req, handlerOptions, \"\", server.config.logger);\n\n if (!info.isRscRequest) {\n return next();\n }\n\n const routeFiles = await getRouteFiles(\n info.route,\n autoDiscoveredFiles,\n handlerOptions\n );\n if (routeFiles.type === \"error\") {\n logger.error(routeFiles.error.message);\n return next();\n }\n const pagePath = routeFiles.page;\n const propsPath = routeFiles.props;\n try {\n // Set up response headers for streaming\n res.setHeader(\"Content-Type\", info.contentType);\n res.setHeader(\"Transfer-Encoding\", \"chunked\");\n res.setHeader(\"Connection\", \"keep-alive\");\n\n const serializedUserOptions = serializedOptions<T, InlineCSS>(\n handlerOptions,\n autoDiscoveredFiles\n );\n const userOnMetrics =\n typeof onMetrics === \"function\"\n ? (metrics: StreamMetrics) => {\n const elapsedTime = performance.now() - startTime;\n const formattedMetrics = {\n route: info.route,\n htmlSize: 0,\n rscSize: metrics.bytes,\n processingTime: elapsedTime,\n chunks: metrics.chunks,\n chunkRate: metrics.chunks / (elapsedTime / 1000),\n memoryUsage: process.memoryUsage(),\n streamMetrics: {\n ...metrics,\n duration: elapsedTime,\n },\n htmlSizes: new Map(),\n rscSizes: new Map([[info.route, metrics.bytes]]),\n } satisfies RenderMetrics;\n onMetrics(formattedMetrics);\n }\n : () => {};\n const startTime = performance.now();\n if (!currentWorker) {\n currentWorker = await restartWorker({\n server,\n autoDiscoveredFiles,\n userOptions: serializedUserOptions,\n hmrChannel,\n });\n }\n const stream = handleWorkerRscStream({\n worker: currentWorker!,\n message: {\n ...serializedUserOptions,\n id: info.route,\n type: \"RSC_RENDER\",\n // we make the worker stream aware of the route, pagePath, propsPath\n route: info.route,\n pagePath: pagePath,\n propsPath: propsPath,\n // override these at all times to ensure the settings will work for the dev server\n projectRoot: server.config.root,\n build: serializedUserOptions.build,\n manifest: autoDiscoveredFiles.staticManifest,\n cssFiles: new Map(),\n globalCss: new Map(),\n },\n logger,\n handlers: {\n onMetrics: (id, metrics) => {\n metrics.route = id;\n userOnMetrics(metrics);\n },\n onHmrAccept: () => {\n // TODO: implement\n // console.log(\"onHmrAccept\", routes);\n },\n onHmrUpdate: () => {\n // TODO: implement\n // console.log(\"onHmrUpdate\", routes);\n },\n },\n verbose: handlerOptions.verbose,\n });\n\n // Pipe the stream to the response\n if (res.writable) {\n Readable.fromWeb(stream as unknown as ReadableStream).pipe(res);\n }\n // wait for timeout\n } catch (error) {\n if (error instanceof Error) {\n server.config.logger.error(error.message + (error.stack ?? \"\"), {\n error,\n });\n }\n }\n let timeout: NodeJS.Timeout;\n try {\n await new Promise((reject) => {\n timeout = setTimeout(() => {\n clearTimeout(timeout);\n reject(new Error(\"RSC Render timeout\"));\n }, 5000);\n });\n } catch {\n if (currentWorker) {\n currentWorker.postMessage({\n type: \"SHUTDOWN\",\n id: \"*\",\n } satisfies RscWorkerInputMessage);\n await new Promise((resolve, reject) => {\n currentWorker?.on(\"message\", (message) => {\n if (message.type === \"SHUTDOWN_COMPLETE\") {\n resolve(true);\n } else {\n reject(\"Dit not receive SHUTDOWN_COMPLETE\");\n }\n });\n });\n currentWorker.removeAllListeners();\n }\n server.config.logger.error(\"RSC render timeout.\");\n clearTimeout(timeout!);\n res.end();\n }\n };\n // attach handler to the server\n server.middlewares.use(handler);\n // done\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"configureWorkerRequestHandler.js","sources":["../../../plugin/react-client/configureWorkerRequestHandler.ts"],"sourcesContent":["import type { ViteDevServer } from \"vite\";\nimport type {\n AutoDiscoveredFiles,\n InlineCssOpt,\n PagePropOpt,\n RenderMetrics,\n RequestHandler,\n ResolvedUserOptions,\n StreamMetrics,\n} from \"../types.js\";\nimport { MessageChannel, type Worker } from \"node:worker_threads\";\nimport { serializedOptions } from \"../helpers/serializeUserOptions.js\";\nimport { requestInfo } from \"../helpers/requestInfo.js\";\nimport { performance } from \"node:perf_hooks\";\nimport { restartWorker } from \"./restartWorker.js\";\nimport { handleWorkerRscStream } from \"./handleWorkerRscStream.js\";\nimport { getRouteFiles } from \"../helpers/getRouteFiles.js\";\nimport type { RscWorkerInputMessage } from \"../worker/types.js\";\nimport { Readable } from \"node:stream\";\nimport type { ReadableStream } from \"node:stream/web\";\nimport { PassThrough } from \"node:stream\";\n\n/**\n * Configures the worker request handler.\n * @param server - The Vite dev server\n * @param autoDiscoveredFiles - The auto discovered files\n * @param userOptions - The user options\n */\nexport async function configureWorkerRequestHandler<\n T extends PagePropOpt = PagePropOpt,\n InlineCSS extends InlineCssOpt = InlineCssOpt\n>({\n server,\n autoDiscoveredFiles,\n userOptions: _userOptions,\n hmrChannel,\n onMetrics,\n}: {\n server: ViteDevServer;\n autoDiscoveredFiles: AutoDiscoveredFiles;\n userOptions: ResolvedUserOptions<T, InlineCSS>;\n hmrChannel: MessageChannel;\n onMetrics?: (metrics: RenderMetrics) => void;\n}) {\n let {\n // remove these\n projectRoot: _projectRoot,\n moduleBaseURL: _moduleBaseURL,\n ...handlerUserOptions\n } = _userOptions;\n const handlerOptions = Object.assign({}, handlerUserOptions, {\n moduleBaseURL: server.config.base,\n moduleBasePath: server.config.base,\n projectRoot: server.config.root,\n });\n\n // Start the worker\n let currentWorker: Worker | null = null;\n const logger = server.config.logger;\n\n // Handle server restarts\n server.ws.on(\"restart\", async () => {\n logger.info(\"[react-client] Server restarting, shutting down worker...\");\n if (currentWorker) {\n currentWorker.postMessage({\n type: \"SHUTDOWN\",\n id: \"*\",\n } satisfies RscWorkerInputMessage);\n await new Promise((resolve, reject) => {\n currentWorker?.on(\"message\", (message) => {\n if (message.type === \"SHUTDOWN_COMPLETE\") {\n resolve(true);\n } else {\n reject(\"Did not receive SHUTDOWN_COMPLETE\");\n }\n });\n });\n currentWorker.removeAllListeners();\n currentWorker = null;\n }\n });\n\n // Create the request handler\n const handler: RequestHandler = async (req, res, next) => {\n if (!req.url) return next();\n\n const info = requestInfo(req, handlerOptions, \"\", server.config.logger);\n\n // Serialize user options for worker\n const serializedUserOptions = serializedOptions<T, InlineCSS>(\n handlerOptions,\n autoDiscoveredFiles\n );\n\n // Handle server action requests\n if (info.isServerActionRequest) {\n try {\n // Read request body\n const chunks: Buffer[] = [];\n for await (const chunk of req) {\n chunks.push(chunk);\n }\n const body = Buffer.concat(chunks).toString();\n const parsed = JSON.parse(body);\n \n // Get action ID and args from the request body\n let id: string;\n let args: unknown[];\n if (Array.isArray(parsed)) {\n // Format 1: Direct args array\n args = parsed;\n id = req.url?.split(\"?\")[0] ?? \"\";\n } else if (parsed && typeof parsed === \"object\" && \"id\" in parsed) {\n // Format 2: Object with id and args\n id = parsed.id;\n args = parsed.args ?? [];\n } else {\n throw new Error(\"Invalid server action request format\");\n }\n\n // Set up response headers for streaming\n res.setHeader(\"Content-Type\", \"text/x-component; charset=utf-8\");\n res.setHeader(\"Transfer-Encoding\", \"chunked\");\n res.setHeader(\"Connection\", \"keep-alive\");\n\n if (!currentWorker) {\n currentWorker = await restartWorker({\n server,\n autoDiscoveredFiles,\n userOptions: serializedUserOptions,\n hmrChannel,\n });\n }\n\n // Send server action request to worker\n currentWorker!.postMessage({\n type: \"SERVER_ACTION\",\n id,\n args,\n } satisfies RscWorkerInputMessage);\n\n // Create a pass-through stream for the response\n const passThrough = new PassThrough();\n passThrough.pipe(res);\n\n // Handle worker messages\n const messageHandler = (message: any) => {\n if (message.type === \"RSC_CHUNK\") {\n passThrough.write(message.chunk);\n } else if (message.type === \"RSC_END\") {\n passThrough.end();\n currentWorker!.removeListener(\"message\", messageHandler);\n } else if (message.type === \"ERROR\") {\n passThrough.end();\n currentWorker!.removeListener(\"message\", messageHandler);\n server.config.logger.error(message.error.message + (message.error.stack ?? \"\"), {\n error: message.error,\n });\n }\n };\n\n currentWorker!.on(\"message\", messageHandler);\n\n // Handle errors\n passThrough.on(\"error\", (error) => {\n server.config.logger.error(error.message + (error.stack ?? \"\"), {\n error,\n });\n res.end();\n });\n\n return;\n } catch (error) {\n if (error instanceof Error) {\n server.config.logger.error(error.message + (error.stack ?? \"\"), {\n error,\n });\n }\n res.statusCode = 500;\n res.end(JSON.stringify({\n type: \"server-action-response\",\n returnValue: {\n success: false,\n error: error instanceof Error ? error.message : String(error)\n }\n }));\n return;\n }\n }\n\n // Handle RSC requests\n if (!info.isRscRequest) {\n return next();\n }\n\n const routeFiles = await getRouteFiles(\n info.route,\n autoDiscoveredFiles,\n handlerOptions\n );\n if (routeFiles.type === \"error\") {\n logger.error(routeFiles.error.message);\n return next();\n }\n const pagePath = routeFiles.page;\n const propsPath = routeFiles.props;\n try {\n // Set up response headers for streaming\n res.setHeader(\"Content-Type\", info.contentType);\n res.setHeader(\"Transfer-Encoding\", \"chunked\");\n res.setHeader(\"Connection\", \"keep-alive\");\n\n const userOnMetrics =\n typeof onMetrics === \"function\"\n ? (metrics: StreamMetrics) => {\n const elapsedTime = performance.now() - startTime;\n const formattedMetrics = {\n route: info.route,\n htmlSize: 0,\n rscSize: metrics.bytes,\n processingTime: elapsedTime,\n chunks: metrics.chunks,\n chunkRate: metrics.chunks / (elapsedTime / 1000),\n memoryUsage: process.memoryUsage(),\n streamMetrics: {\n ...metrics,\n duration: elapsedTime,\n },\n htmlSizes: new Map(),\n rscSizes: new Map([[info.route, metrics.bytes]]),\n } satisfies RenderMetrics;\n onMetrics(formattedMetrics);\n }\n : () => {};\n const startTime = performance.now();\n if (!currentWorker) {\n currentWorker = await restartWorker({\n server,\n autoDiscoveredFiles,\n userOptions: serializedUserOptions,\n hmrChannel,\n });\n }\n const stream = handleWorkerRscStream({\n worker: currentWorker!,\n message: {\n ...serializedUserOptions,\n id: info.route,\n type: \"RSC_RENDER\",\n // we make the worker stream aware of the route, pagePath, propsPath\n route: info.route,\n pagePath: pagePath,\n propsPath: propsPath,\n // override these at all times to ensure the settings will work for the dev server\n projectRoot: server.config.root,\n build: serializedUserOptions.build,\n manifest: autoDiscoveredFiles.staticManifest,\n cssFiles: new Map(),\n globalCss: new Map(),\n },\n logger,\n handlers: {\n onMetrics: (id, metrics) => {\n metrics.route = id;\n userOnMetrics(metrics);\n },\n onHmrAccept: () => {\n // TODO: implement\n // console.log(\"onHmrAccept\", routes);\n },\n onHmrUpdate: () => {\n // TODO: implement\n // console.log(\"onHmrUpdate\", routes);\n },\n },\n verbose: handlerOptions.verbose,\n });\n\n // Pipe the stream to the response\n if (res.writable) {\n Readable.fromWeb(stream as unknown as ReadableStream).pipe(res);\n }\n // wait for timeout\n } catch (error) {\n if (error instanceof Error) {\n server.config.logger.error(error.message + (error.stack ?? \"\"), {\n error,\n });\n }\n }\n let timeout: NodeJS.Timeout;\n try {\n await new Promise((reject) => {\n timeout = setTimeout(() => {\n clearTimeout(timeout);\n reject(new Error(\"RSC Render timeout\"));\n }, 5000);\n });\n } catch {\n if (currentWorker) {\n currentWorker.postMessage({\n type: \"SHUTDOWN\",\n id: \"*\",\n } satisfies RscWorkerInputMessage);\n await new Promise((resolve, reject) => {\n currentWorker?.on(\"message\", (message) => {\n if (message.type === \"SHUTDOWN_COMPLETE\") {\n resolve(true);\n } else {\n reject(\"Dit not receive SHUTDOWN_COMPLETE\");\n }\n });\n });\n currentWorker.removeAllListeners();\n }\n server.config.logger.error(\"RSC render timeout.\");\n clearTimeout(timeout!);\n res.end();\n }\n };\n // attach handler to the server\n server.middlewares.use(handler);\n // done\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"createMessageHandlers.d.ts","sourceRoot":"","sources":["../../../plugin/react-client/createMessageHandlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,KAAK,qBAAqB,GAAG;IAC3B,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,EACnC,QAAQ,EACR,MAAM,EACN,OAAe,GAChB,EAAE,qBAAqB,aACL,sBAAsB,GAAG,SAAS,UAyCpD"}
1
+ {"version":3,"file":"createMessageHandlers.d.ts","sourceRoot":"","sources":["../../../plugin/react-client/createMessageHandlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,KAAK,qBAAqB,GAAG;IAC3B,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,EACnC,QAAQ,EACR,MAAM,EACN,OAAe,GAChB,EAAE,qBAAqB,aACL,sBAAsB,GAAG,SAAS,UA4CpD"}
@@ -44,6 +44,9 @@ function createMessageHandler({
44
44
  case "SERVER_MODULE":
45
45
  handlers.onServerModule?.(message.id, message.url, message.source);
46
46
  break;
47
+ case "CSS_FILE":
48
+ handlers.onCssFile?.(message.id, message.content);
49
+ break;
47
50
  default:
48
51
  logger.warn(`Unknown worker output message type: ${message.type}`);
49
52
  }