vike-react-rsc-rudder 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +73 -0
  3. package/dist/cache-BCYpxG4P.js +164 -0
  4. package/dist/client-BpZo3JRu.js +86 -0
  5. package/dist/client.d.ts +1 -0
  6. package/dist/client.js +53 -0
  7. package/dist/config.d.ts +4 -0
  8. package/dist/config.js +875 -0
  9. package/dist/constants.d.ts +1 -0
  10. package/dist/getGlobalObject-CzWO6NfD.js +10 -0
  11. package/dist/hooks/pageContext/pageContext-client.d.ts +11 -0
  12. package/dist/hooks/pageContext/pageContext-client.js +4 -0
  13. package/dist/hooks/pageContext/pageContext-server.d.ts +7 -0
  14. package/dist/hooks/pageContext/pageContext-server.js +4 -0
  15. package/dist/integration/client.d.ts +1 -0
  16. package/dist/integration/client.js +16 -0
  17. package/dist/integration/getPageElement/getPageElement-server.d.ts +14 -0
  18. package/dist/integration/onBeforeRender.d.ts +2 -0
  19. package/dist/integration/onBeforeRender.js +17 -0
  20. package/dist/integration/onPageTransitionStart.d.ts +2 -0
  21. package/dist/integration/onPageTransitionStart.js +11 -0
  22. package/dist/integration/onRenderClient.d.ts +2 -0
  23. package/dist/integration/onRenderClient.js +63 -0
  24. package/dist/integration/onRenderHtml.d.ts +2 -0
  25. package/dist/integration/onRenderHtml.js +10 -0
  26. package/dist/integration/rscMiddleware.d.ts +3 -0
  27. package/dist/integration/rscMiddleware.js +35 -0
  28. package/dist/pageContext-client-CmvZ4bmk.js +27 -0
  29. package/dist/pageContext-server-B1QwrAws.js +22 -0
  30. package/dist/plugin/index.d.ts +20 -0
  31. package/dist/plugin/plugins/clientDepTrackerPlugin.d.ts +7 -0
  32. package/dist/plugin/plugins/config.d.ts +8 -0
  33. package/dist/plugin/plugins/cssTrackerPlugin.d.ts +6 -0
  34. package/dist/plugin/plugins/dev.d.ts +2 -0
  35. package/dist/plugin/plugins/hmrPlugin.d.ts +2 -0
  36. package/dist/plugin/plugins/injectManifestBuild.d.ts +6 -0
  37. package/dist/plugin/plugins/serverComponentExclusionPlugin.d.ts +6 -0
  38. package/dist/plugin/plugins/useClientPlugin.d.ts +2 -0
  39. package/dist/plugin/plugins/useServerPlugin.d.ts +2 -0
  40. package/dist/plugin/plugins/virtuals.d.ts +2 -0
  41. package/dist/plugin/utils.d.ts +6 -0
  42. package/dist/register/browser.d.ts +1 -0
  43. package/dist/register/browser.js +3 -0
  44. package/dist/register/server.d.ts +1 -0
  45. package/dist/register/server.js +3 -0
  46. package/dist/register/ssr.d.ts +1 -0
  47. package/dist/register/ssr.js +3 -0
  48. package/dist/runtime/cache.d.ts +50 -0
  49. package/dist/runtime/client/globalState.d.ts +22 -0
  50. package/dist/runtime/client.d.ts +5 -0
  51. package/dist/runtime/rscBridge.d.ts +7 -0
  52. package/dist/runtime/server.d.ts +7 -0
  53. package/dist/runtime/server.js +110 -0
  54. package/dist/runtime/serverActionContext.d.ts +23 -0
  55. package/dist/runtime/ssr.d.ts +2 -0
  56. package/dist/runtime/ssr.js +107 -0
  57. package/dist/server.d.ts +1 -0
  58. package/dist/server.js +4 -0
  59. package/dist/serverActionContext-7Jnbh0-W.js +38 -0
  60. package/dist/types/Config.d.ts +59 -0
  61. package/dist/types.d.ts +22 -0
  62. package/dist/utils/getGlobalObject.d.ts +1 -0
  63. package/dist/utils/isReactElement.d.ts +5 -0
  64. package/package.json +81 -0
package/dist/config.js ADDED
@@ -0,0 +1,875 @@
1
+ import { tinyassert } from "@hiogawa/utils";
2
+ import { defaultServerConditions, normalizePath, parseAstAsync } from "vite";
3
+ import { serverEntryVirtualId } from "@brillout/vite-plugin-server-entry/plugin";
4
+ import path from "path";
5
+ import { hasDirective, transformDirectiveProxyExport, transformServerActionServer } from "@hiogawa/transforms";
6
+ import { createHash } from "node:crypto";
7
+ import path$1 from "node:path";
8
+ import assert from "node:assert";
9
+ import rscCore from "@vitejs/plugin-rsc/core/plugin";
10
+
11
+ //#region src/plugin/plugins/clientDepTrackerPlugin.ts
12
+ const jsFileRE$1 = /\.(jsx?|tsx?|m?js|cjs)$/;
13
+ /**
14
+ * Creates a client dependency tracker for handling client component dependencies
15
+ * Works in both development and build modes with on-demand dependency tracking
16
+ */
17
+ function clientDepTrackerPlugin() {
18
+ const jsImportMapBuild = {};
19
+ let staticGraph = null;
20
+ function buildGraph() {
21
+ const clientDependencies = new Set();
22
+ const collectClientDependencies = (moduleId, visited = new Set()) => {
23
+ if (visited.has(moduleId)) return;
24
+ visited.add(moduleId);
25
+ clientDependencies.add(moduleId);
26
+ for (const jsImport of jsImportMapBuild[moduleId] || []) collectClientDependencies(jsImport, new Set(visited));
27
+ };
28
+ for (const clientRefPath of Object.values(global.vikeReactRscGlobalState.clientReferences || {})) collectClientDependencies(clientRefPath, new Set());
29
+ console.log(`[Client Dependency Tracker] Found ${clientDependencies.size} client reference dependencies`);
30
+ return clientDependencies;
31
+ }
32
+ const plugin = {
33
+ name: "vike-rsc:client-dependency-tracker",
34
+ enforce: "pre",
35
+ resolveId: {
36
+ order: "pre",
37
+ async handler(source, importer, options) {
38
+ if (!importer || source.includes("\0") || source.includes("node_modules")) return;
39
+ try {
40
+ const resolved = await this.resolve(source, importer, {
41
+ skipSelf: true,
42
+ ...options
43
+ });
44
+ if (!resolved) return;
45
+ const resolvedId = resolved.id;
46
+ if (!jsImportMapBuild[importer]) jsImportMapBuild[importer] = [];
47
+ if (jsFileRE$1?.test(resolvedId)) {
48
+ if (!jsImportMapBuild[importer].includes(resolvedId)) jsImportMapBuild[importer].push(resolvedId);
49
+ }
50
+ } catch (error) {}
51
+ }
52
+ },
53
+ buildEnd() {
54
+ if (this.environment.name === "rsc" && !global.vikeReactRscGlobalState.disableUseClientPlugin) staticGraph = buildGraph();
55
+ }
56
+ };
57
+ global.vikeReactRscGlobalState.isClientDependency = (id) => {
58
+ const dependencies = staticGraph || buildGraph();
59
+ if (Object.values(global.vikeReactRscGlobalState.clientReferences || {}).includes(id)) {
60
+ console.log(`[Client Dependency Tracker] ${id} is a client reference`);
61
+ return true;
62
+ }
63
+ const isClientDep = dependencies.has(id);
64
+ if (isClientDep && true) console.log(`[Client Dependency Tracker] ${id} is a client dependency`);
65
+ return isClientDep;
66
+ };
67
+ return plugin;
68
+ }
69
+
70
+ //#endregion
71
+ //#region src/constants.ts
72
+ const PKG_NAME = "vike-react-rsc-rudder";
73
+
74
+ //#endregion
75
+ //#region src/plugin/plugins/config.ts
76
+ const distRsc = "dist/rsc";
77
+ const configs = [
78
+ {
79
+ name: "vike-rsc:config:pre",
80
+ enforce: "pre",
81
+ config() {
82
+ const noExternal = [
83
+ "react",
84
+ "react-dom",
85
+ PKG_NAME,
86
+ "@vitejs/plugin-rsc",
87
+ "react-streaming"
88
+ ];
89
+ return { environments: {
90
+ client: { optimizeDeps: {
91
+ include: ["react-dom/client", "@vitejs/plugin-rsc/vendor/react-server-dom/client.browser"],
92
+ exclude: [
93
+ PKG_NAME,
94
+ "@vitejs/plugin-rsc",
95
+ "virtual:enviroment-name"
96
+ ]
97
+ } },
98
+ ssr: {
99
+ optimizeDeps: {
100
+ include: [
101
+ "react",
102
+ "react-dom",
103
+ "react/jsx-runtime",
104
+ "react/jsx-dev-runtime",
105
+ "react-dom/server.edge",
106
+ "react-dom/static.edge",
107
+ "react-streaming/server.web",
108
+ "@vitejs/plugin-rsc/vendor/react-server-dom/client.edge"
109
+ ],
110
+ exclude: [
111
+ PKG_NAME,
112
+ "@vitejs/plugin-rsc",
113
+ "virtual:enviroment-name"
114
+ ]
115
+ },
116
+ resolve: { noExternal },
117
+ build: { rollupOptions: { input: {
118
+ ssr: "virtual:build-ssr-entry",
119
+ entry: serverEntryVirtualId
120
+ } } }
121
+ },
122
+ rsc: {
123
+ resolve: {
124
+ conditions: ["react-server", ...defaultServerConditions],
125
+ noExternal
126
+ },
127
+ optimizeDeps: {
128
+ include: [
129
+ "react",
130
+ "react-dom",
131
+ "react/jsx-runtime",
132
+ "react/jsx-dev-runtime",
133
+ "@vitejs/plugin-rsc/vendor/react-server-dom/server.edge",
134
+ "@vitejs/plugin-rsc/vendor/react-server-dom/client.edge"
135
+ ],
136
+ exclude: [
137
+ PKG_NAME,
138
+ "@vitejs/plugin-rsc",
139
+ "virtual:enviroment-name"
140
+ ]
141
+ },
142
+ build: {
143
+ outDir: distRsc,
144
+ ssr: true,
145
+ rollupOptions: { input: { index: "virtual:build-rsc-entry" } }
146
+ }
147
+ }
148
+ } };
149
+ },
150
+ sharedDuringBuild: false
151
+ },
152
+ {
153
+ name: "vike-rsc:config-rsc",
154
+ applyToEnvironment(env) {
155
+ return env.name === "rsc";
156
+ },
157
+ config() {
158
+ return { vitePluginServerEntry: { disableServerEntryEmit: true } };
159
+ }
160
+ },
161
+ {
162
+ name: "vike-rsc:config:post",
163
+ config() {
164
+ return { builder: { async buildApp(builder) {
165
+ global.vikeReactRscGlobalState.disableUseClientPlugin = true;
166
+ await builder.build(builder.environments.rsc);
167
+ global.vikeReactRscGlobalState.disableUseClientPlugin = false;
168
+ await builder.build(builder.environments.rsc);
169
+ await builder.build(builder.environments.client);
170
+ await builder.build(builder.environments.ssr);
171
+ } } };
172
+ }
173
+ }
174
+ ];
175
+
176
+ //#endregion
177
+ //#region src/plugin/plugins/cssTrackerPlugin.ts
178
+ const styleFileRE$2 = /\.(css|less|sass|scss|styl|stylus|pcss|postcss)($|\?)/;
179
+ const jsFileRE = /\.(jsx?|tsx?|m?js|cjs)$/;
180
+ /**
181
+ * Creates a CSS dependency tracker for proxying CSS imports from rsc to client
182
+ */
183
+ function cssTrackerPlugin() {
184
+ const cssImportMapBuild = {};
185
+ const jsImportMapBuild = {};
186
+ const originalSourceMap = {};
187
+ let root;
188
+ const plugin = {
189
+ name: "vike-rsc:collect-css-dependencies",
190
+ applyToEnvironment(environment) {
191
+ return environment.name === "rsc";
192
+ },
193
+ configResolved(config$1) {
194
+ root = config$1.root;
195
+ },
196
+ resolveId: {
197
+ order: "pre",
198
+ async handler(source, importer, options) {
199
+ if (!importer || source.includes("\0") || source.includes("node_modules")) return;
200
+ try {
201
+ const resolved = await this.resolve(source, importer, {
202
+ skipSelf: true,
203
+ ...options
204
+ });
205
+ if (!resolved) return;
206
+ const resolvedId = resolved.id;
207
+ originalSourceMap[resolvedId] = source;
208
+ if (!cssImportMapBuild[importer]) cssImportMapBuild[importer] = [];
209
+ if (!jsImportMapBuild[importer]) jsImportMapBuild[importer] = [];
210
+ if (styleFileRE$2?.test(resolvedId)) {
211
+ if (!cssImportMapBuild[importer].includes(resolvedId)) cssImportMapBuild[importer].push(resolvedId);
212
+ } else if (jsFileRE?.test(resolvedId)) {
213
+ if (!jsImportMapBuild[importer].includes(resolvedId)) jsImportMapBuild[importer].push(resolvedId);
214
+ }
215
+ } catch (error) {}
216
+ }
217
+ },
218
+ buildEnd() {
219
+ if (!global.vikeReactRscGlobalState.disableUseClientPlugin) staticGraph = buildGraph();
220
+ }
221
+ };
222
+ let staticGraph = null;
223
+ function buildGraph() {
224
+ const graph = {};
225
+ const processedModules = new Set();
226
+ const collectCssDependencies = (moduleId, visited = new Set()) => {
227
+ if (visited.has(moduleId) || processedModules.has(moduleId)) return;
228
+ visited.add(moduleId);
229
+ processedModules.add(moduleId);
230
+ graph[moduleId] = graph[moduleId] || new Set();
231
+ for (const cssImport of cssImportMapBuild[moduleId] || []) graph[moduleId].add({
232
+ importee: cssImport,
233
+ importer: moduleId
234
+ });
235
+ for (const jsImport of jsImportMapBuild[moduleId] || []) {
236
+ collectCssDependencies(jsImport, new Set(visited));
237
+ for (const cssImportInfo of graph[jsImport] || []) graph[moduleId].add(cssImportInfo);
238
+ }
239
+ };
240
+ const allModuleIds = [...new Set([...Object.keys(cssImportMapBuild), ...Object.keys(jsImportMapBuild)])];
241
+ for (const moduleId of allModuleIds) collectCssDependencies(moduleId);
242
+ {
243
+ const totalCssImports = Object.values(graph).reduce((sum, set) => sum + set.size, 0);
244
+ console.log(`[CSS Dependency Tracker] Built graph with ${Object.keys(graph).length} modules and ${totalCssImports} CSS imports`);
245
+ }
246
+ return graph;
247
+ }
248
+ global.vikeReactRscGlobalState.pruneCssRegistry = (id) => {
249
+ const removedModuleIds = new Set();
250
+ function removeModuleAndDependencies(moduleId) {
251
+ if (removedModuleIds.has(moduleId)) return;
252
+ removedModuleIds.add(moduleId);
253
+ const jsDependencies = [...jsImportMapBuild[moduleId] || []];
254
+ delete cssImportMapBuild[moduleId];
255
+ delete jsImportMapBuild[moduleId];
256
+ for (const jsDepId of jsDependencies) removeModuleAndDependencies(jsDepId);
257
+ }
258
+ removeModuleAndDependencies(id);
259
+ for (const [moduleId, jsDeps] of Object.entries(jsImportMapBuild)) jsImportMapBuild[moduleId] = jsDeps.filter((depId) => !removedModuleIds.has(depId));
260
+ staticGraph = null;
261
+ console.log(`[CSS Dependency Tracker] Removed module ${id} and ${removedModuleIds.size - 1} dependencies from the graph`);
262
+ };
263
+ global.vikeReactRscGlobalState.getCssDependencies = async (id) => {
264
+ if (!staticGraph) await traverse(global.vikeReactRscGlobalState.devServer.environments.rsc, id);
265
+ const graph = staticGraph || buildGraph();
266
+ const cssImportInfos = Array.from(graph[id] || new Set());
267
+ const cssIds = new Set();
268
+ const jsIds = new Set();
269
+ for (const { importee, importer } of cssImportInfos) {
270
+ cssIds.add(importee);
271
+ jsIds.add(importer);
272
+ }
273
+ const uniqueCssIds = Array.from(cssIds);
274
+ if (uniqueCssIds.length > 0) console.log(`[CSS Dependency Tracker] Found ${uniqueCssIds.length} CSS dependencies for ${id} from ${jsIds.size} JS modules`);
275
+ const normalizedCss = await Promise.all(uniqueCssIds.map((cssId) => normalizeId({
276
+ id: cssId,
277
+ server: global.vikeReactRscGlobalState.devServer?.environments.rsc,
278
+ root
279
+ })));
280
+ const normalizedJs = await Promise.all(Array.from(jsIds).map((jsId) => normalizeId({
281
+ id: jsId,
282
+ server: global.vikeReactRscGlobalState.devServer?.environments.rsc,
283
+ root
284
+ })));
285
+ return {
286
+ cssIds: normalizedCss,
287
+ jsIds: normalizedJs
288
+ };
289
+ };
290
+ return plugin;
291
+ }
292
+ async function traverse(server, entry) {
293
+ try {
294
+ const mod = await server.transformRequest(entry);
295
+ const deps = new Set(mod?.deps ?? []);
296
+ for (const dep of deps) try {
297
+ const mod$1 = await server.transformRequest(dep);
298
+ for (const element of mod$1?.deps ?? []) deps.add(element);
299
+ } catch (error) {}
300
+ } catch (e) {}
301
+ }
302
+ async function normalizeId({ id, server, root }) {
303
+ root ??= server?.config.root;
304
+ tinyassert(root);
305
+ if (id.startsWith(root)) id = id.slice(root.length);
306
+ return id.replace("\0", "");
307
+ }
308
+
309
+ //#endregion
310
+ //#region src/plugin/plugins/dev.ts
311
+ const exposeDevServer = {
312
+ name: "rsc-dev",
313
+ configureServer(server) {
314
+ global.vikeReactRscGlobalState.devServer = server;
315
+ try {
316
+ if (server.environments.rsc) server.environments.rsc.runner;
317
+ if (server.environments.ssr) server.environments.ssr.runner;
318
+ console.log("[RSC Plugin] Dev server runners initialized");
319
+ } catch (e) {
320
+ console.error("[RSC Plugin] Failed to initialize runners:", e);
321
+ }
322
+ }
323
+ };
324
+
325
+ //#endregion
326
+ //#region src/plugin/plugins/injectManifestBuild.ts
327
+ /**
328
+ * Vite plugin that generates a manifest for React Server Components during build.
329
+ * Creates a mapping of page IDs to their corresponding config loaders.
330
+ */
331
+ function vikeRscManifestPluginBuild() {
332
+ const PLACEHOLDER = "__VIKE_RSC_PAGES_MANIFEST__";
333
+ return {
334
+ name: "vike-rsc-manifest-build",
335
+ apply: "build",
336
+ applyToEnvironment(environment) {
337
+ return environment.name === "rsc";
338
+ },
339
+ generateBundle(_outputOptions, bundle) {
340
+ const placeholderChunks = [];
341
+ const pageEntries = {};
342
+ for (const [fileName, output] of Object.entries(bundle)) {
343
+ if (output.type !== "chunk") continue;
344
+ const chunk = output;
345
+ if (chunk.isEntry && chunk.facadeModuleId) {
346
+ const pageId = chunk.facadeModuleId.split("virtual:vike:page-entry:server:")[1];
347
+ if (pageId) pageEntries[chunk.name] = {
348
+ chunkName: chunk.name,
349
+ fileName,
350
+ pageId
351
+ };
352
+ }
353
+ if (chunk.code && chunk.code.includes(PLACEHOLDER)) placeholderChunks.push(chunk);
354
+ }
355
+ for (const chunk of placeholderChunks) {
356
+ const manifestContent = generateManifestCode(pageEntries, chunk.fileName);
357
+ chunk.code = chunk.code.replace(new RegExp(PLACEHOLDER, "g"), manifestContent);
358
+ }
359
+ }
360
+ };
361
+ }
362
+ /**
363
+ * Generates the manifest code with an IIFE containing a helper function
364
+ * and the page entries map.
365
+ *
366
+ * @param pageEntries - Record of page entries with their metadata
367
+ * @param chunkFileName - The file name of the current chunk
368
+ * @returns The generated manifest code as a string
369
+ */
370
+ function generateManifestCode(pageEntries, chunkFileName) {
371
+ let code = `(function() {
372
+ /**
373
+ * Helper function that extracts config values from the imported module
374
+ * @param {Object} module - The imported module containing configValuesSerialized
375
+ * @returns {Object} - The extracted configuration object
376
+ */
377
+ function extractConfig(module) {
378
+ return Object.fromEntries(
379
+ Object.entries(module.configValuesSerialized).map(([key, value]) => [
380
+ key,
381
+ [Array.isArray(value.valueSerialized)
382
+ ? value.valueSerialized.map(v => v.exportValues?.default || v.exportValues?.[key])
383
+ : value.valueSerialized.exportValues?.default || value.valueSerialized.exportValues?.[key]].flat(1)
384
+ ])
385
+ );
386
+ }
387
+
388
+ return {`;
389
+ let isFirst = true;
390
+ const chunkDir = path.dirname(chunkFileName);
391
+ for (const entry of Object.values(pageEntries)) {
392
+ if (!isFirst) code += ",";
393
+ isFirst = false;
394
+ const entryPath = path.relative(chunkDir, entry.fileName);
395
+ const normalizedPath = normalizePath(entryPath);
396
+ const importPath = normalizedPath.startsWith(".") ? normalizedPath : `./${normalizedPath}`;
397
+ code += `
398
+ "${entry.pageId}": {
399
+ getConfig: () => import("${importPath}").then(extractConfig)
400
+ }`;
401
+ }
402
+ code += `
403
+ };
404
+ })()`;
405
+ return code;
406
+ }
407
+
408
+ //#endregion
409
+ //#region src/plugin/plugins/serverComponentExclusionPlugin.ts
410
+ const styleFileRE$1 = /\.(css|less|sass|scss|styl|stylus|pcss|postcss)($|\?)/;
411
+ /**
412
+ * Plugin to exclude server components from client and SSR bundles
413
+ * while preserving CSS imports for proper styling.
414
+ */
415
+ const serverComponentExclusionPlugin = () => {
416
+ const debug = true;
417
+ let devServer;
418
+ return [{
419
+ name: "vike-rsc:server-component-exclusion",
420
+ applyToEnvironment(environment) {
421
+ return environment.name === "client";
422
+ },
423
+ configureServer(server) {
424
+ devServer = server;
425
+ },
426
+ async transform(code, id) {
427
+ if (this.environment?.name !== "client") return null;
428
+ if (!code) return null;
429
+ if (id.includes("\0") || id.includes("node_modules") || styleFileRE$1.test(id) || !/\.(jsx?|tsx?|mjs|cjs)($|\?)/.test(id)) return null;
430
+ try {
431
+ const relPath = path.relative(this.environment.config.root, id);
432
+ if (relPath.startsWith("..") || path.isAbsolute(relPath)) return null;
433
+ const boundaries = [...Object.values(global.vikeReactRscGlobalState.clientReferences), ...Object.values(global.vikeReactRscGlobalState.serverReferences)];
434
+ if (boundaries.includes(id)) return null;
435
+ if (global.vikeReactRscGlobalState.isClientDependency(id)) {
436
+ if (debug) console.log(`[RSC Plugin] Preserving client dependency in client bundle: ${relPath}`);
437
+ return null;
438
+ }
439
+ const ast = await parseAstAsync(code);
440
+ if (hasDirective(ast.body, "use client") || hasDirective(ast.body, "use server")) {
441
+ if (debug) console.log(`[RSC Plugin] ${relPath} has use client/server directive, preserving in client bundle`);
442
+ return null;
443
+ }
444
+ const proxyCode = `
445
+ // Server component asset proxy (original code excluded from client bundle)
446
+ // Original file: ${id}
447
+ export default {};
448
+ export {};
449
+ ${devServer ? "import \"virtual:css-proxy.css?id=" + encodeURIComponent(id) + "\"" : "import \"virtual:css-proxy?id=" + encodeURIComponent(id) + "\""}
450
+ if (import.meta.hot) {
451
+ import.meta.hot.accept();
452
+ }
453
+ `;
454
+ return {
455
+ code: proxyCode,
456
+ map: { mappings: "" }
457
+ };
458
+ } catch (error) {
459
+ console.error(`[RSC Plugin] Error in server component exclusion for ${id}:`, error);
460
+ }
461
+ return null;
462
+ }
463
+ }, {
464
+ name: "vike-rsc:css-proxy",
465
+ resolveId(source) {
466
+ if (source.startsWith("virtual:css-proxy")) return "\0" + source;
467
+ },
468
+ async load(id) {
469
+ if (!id.includes("virtual:css-proxy")) return;
470
+ const parsedUrl = new URL(id);
471
+ const externalId = parsedUrl.searchParams.get("id");
472
+ const res = await global.vikeReactRscGlobalState.getCssDependencies(externalId);
473
+ console.log(res);
474
+ const cssIds = res.cssIds;
475
+ if (debug && cssIds.length > 0) console.log(`[RSC Plugin] Found ${cssIds.length} CSS dependencies for ${externalId}`);
476
+ if (!devServer) return cssIds.map((cssPath) => `import "${cssPath}";`).join("\n") + "\n";
477
+ global.vikeReactRscGlobalState.excludedModuleMap[externalId] = res.jsIds;
478
+ const cssStrings = await Promise.all(cssIds.map((url) => devServer.environments.client.transformRequest(url + "?direct").then((res$1) => res$1?.code))).then((res$1) => res$1.filter(Boolean));
479
+ return cssStrings.join("\n");
480
+ }
481
+ }];
482
+ };
483
+
484
+ //#endregion
485
+ //#region src/plugin/utils.ts
486
+ function hashString(value) {
487
+ return createHash("sha256").update(value).digest("hex").slice(0, 12);
488
+ }
489
+ async function normalizeReferenceId(id, name, server, config$1) {
490
+ if (!server) return hashString(path$1.relative(config$1.root, id));
491
+ const environment = server.environments[name];
492
+ const transformed = await environment.transformRequest("virtual:normalize-reference-id/" + encodeURIComponent(id));
493
+ assert(transformed);
494
+ const m = transformed.code.match(/(?:__vite_ssr_dynamic_import__|import)\("(.*)"\)/);
495
+ const newId = m?.[1];
496
+ if (!newId) {
497
+ console.error("[normalizeReferenceId]", {
498
+ name,
499
+ id,
500
+ code: transformed.code
501
+ });
502
+ throw new Error("normalizeReferenceId");
503
+ }
504
+ return newId;
505
+ }
506
+ function createVirtualPlugin(name, load) {
507
+ name = "virtual:" + name;
508
+ return {
509
+ name: `virtual-${name}`,
510
+ resolveId(source) {
511
+ return source === name ? "\0" + name : void 0;
512
+ },
513
+ load(id) {
514
+ if (id === "\0" + name) return load.apply(this);
515
+ }
516
+ };
517
+ }
518
+ function virtualNormalizeReferenceIdPlugin() {
519
+ const prefix = "virtual:normalize-reference-id/";
520
+ return {
521
+ name: "virtual-normalize-reference-id",
522
+ apply: "serve",
523
+ resolveId(source) {
524
+ if (source.startsWith(prefix)) return "\0" + source;
525
+ },
526
+ load(id) {
527
+ if (id.startsWith("\0" + prefix)) {
528
+ const decodedId = decodeURIComponent(id.slice(prefix.length + 1));
529
+ return `export default () => import("${decodedId}")`;
530
+ }
531
+ }
532
+ };
533
+ }
534
+
535
+ //#endregion
536
+ //#region src/plugin/plugins/useClientPlugin.ts
537
+ const useClientPlugin = () => {
538
+ let resolvedConfig;
539
+ let devServer;
540
+ return [{
541
+ name: "vike-rsc:transform-client-directive",
542
+ configResolved(config$1) {
543
+ resolvedConfig = config$1;
544
+ },
545
+ configureServer(server) {
546
+ devServer = server;
547
+ },
548
+ async transform(code, id) {
549
+ if (this.environment?.name !== "rsc") return;
550
+ if (!code.includes("use client")) return;
551
+ if (global.vikeReactRscGlobalState.disableUseClientPlugin) return;
552
+ try {
553
+ const ast = await parseAstAsync(code);
554
+ const normalizedId = await normalizeReferenceId(id, "client", devServer, resolvedConfig);
555
+ const output = await transformDirectiveProxyExport(ast, {
556
+ directive: "use client",
557
+ id: normalizedId,
558
+ runtime: "$$register"
559
+ });
560
+ if (!output) return;
561
+ global.vikeReactRscGlobalState.clientReferences[normalizedId] = id;
562
+ output.prepend(`
563
+ import { registerClientReference } from "${PKG_NAME}/__internal/register/server";
564
+ const $$register = (id, name) => registerClientReference({}, id, name);
565
+ `);
566
+ return {
567
+ code: output.toString(),
568
+ map: { mappings: "" }
569
+ };
570
+ } catch (error) {
571
+ console.error(`[RSC Plugin] Error transforming client directive in ${id}:`, error);
572
+ return;
573
+ }
574
+ }
575
+ }, createVirtualPlugin("client-references", function() {
576
+ if (this.environment.name === "rsc" && this.environment?.mode !== "build") return "export default {};";
577
+ return [
578
+ `export default {`,
579
+ ...Object.entries(global.vikeReactRscGlobalState.clientReferences).map(([normalizedId, id]) => `${JSON.stringify(normalizedId)}: () => import(${JSON.stringify(id)}),\n`),
580
+ `}`
581
+ ].join("\n");
582
+ })];
583
+ };
584
+
585
+ //#endregion
586
+ //#region src/plugin/plugins/useServerPlugin.ts
587
+ const useServerPlugin = () => {
588
+ let resolvedConfig;
589
+ let devServer;
590
+ return [{
591
+ name: "vike-rsc:transform-server-directive",
592
+ configResolved(config$1) {
593
+ resolvedConfig = config$1;
594
+ },
595
+ configureServer(server) {
596
+ devServer = server;
597
+ },
598
+ async transform(code, id) {
599
+ if (id.includes("/.vite/")) return;
600
+ if (!code.includes("use server")) return;
601
+ try {
602
+ const ast = await parseAstAsync(code);
603
+ const normalizedId = await normalizeReferenceId(id, "rsc", devServer, resolvedConfig);
604
+ if (this.environment.name === "rsc") {
605
+ const { output } = await transformServerActionServer(code, ast, {
606
+ id: normalizedId,
607
+ runtime: "$$register"
608
+ });
609
+ if (!output.hasChanged()) return;
610
+ global.vikeReactRscGlobalState.serverReferences[normalizedId] = id;
611
+ output.prepend(`
612
+ import { registerServerReference } from "${PKG_NAME}/__internal/register/server";
613
+ const $$register = (value, id, name) => {
614
+ if (typeof value !== 'function') return value;
615
+ return registerServerReference(value, id, name);
616
+ }
617
+ `);
618
+ return {
619
+ code: output.toString(),
620
+ map: output.generateMap({ hires: "boundary" })
621
+ };
622
+ } else {
623
+ const output = await transformDirectiveProxyExport(ast, {
624
+ id: normalizedId,
625
+ runtime: "$$proxy",
626
+ directive: "use server"
627
+ });
628
+ if (!output) return;
629
+ global.vikeReactRscGlobalState.serverReferences[normalizedId] = id;
630
+ const res = await global.vikeReactRscGlobalState.getCssDependencies(id);
631
+ console.log(res);
632
+ for (const cssId of res.cssIds) output.prepend(`import "${cssId}";`);
633
+ const name = this.environment.name === "client" ? "browser" : "ssr";
634
+ output.prepend(`
635
+ import { createServerReference, callServer } from "${PKG_NAME}/__internal/register/${name}";
636
+ const $$proxy = (id, name) => {
637
+ const r = createServerReference(${JSON.stringify(normalizedId)} + "#" + name, (...args) =>{ "${normalizedId}"; return callServer(...args)})
638
+ Object.defineProperty(r, "name", { value: ${JSON.stringify(normalizedId)}});
639
+ return r;
640
+ }
641
+ `);
642
+ return {
643
+ code: output.toString(),
644
+ map: { mappings: "" }
645
+ };
646
+ }
647
+ } catch (error) {
648
+ console.error(`[RSC Plugin] Error transforming server directive in ${id}:`, error);
649
+ return;
650
+ }
651
+ }
652
+ }, createVirtualPlugin("server-references", function() {
653
+ if (this.environment.name !== "rsc" || this.environment?.mode !== "build") return "export default {};";
654
+ return [
655
+ `export default {`,
656
+ ...Object.entries(global.vikeReactRscGlobalState.serverReferences).map(([normalizedId, id]) => `${JSON.stringify(normalizedId)}: () => import(${JSON.stringify(id)}),\n`),
657
+ `}`
658
+ ].join("\n");
659
+ })];
660
+ };
661
+
662
+ //#endregion
663
+ //#region src/plugin/plugins/virtuals.ts
664
+ const importRsc = `
665
+ import * as serverModule from "${PKG_NAME}/__internal/runtime/server";
666
+ export * from "${PKG_NAME}/__internal/runtime/server";
667
+ export default serverModule;
668
+ `;
669
+ const importSsr = `
670
+ import * as ssrModule from "${PKG_NAME}/__internal/runtime/ssr";
671
+ export * from "${PKG_NAME}/__internal/runtime/ssr";
672
+ export default ssrModule;
673
+ `;
674
+ const virtuals = [
675
+ createVirtualPlugin("enviroment-name", function() {
676
+ return `export default "${this.environment.name}"`;
677
+ }),
678
+ createVirtualPlugin("build-rsc-entry", () => importRsc),
679
+ createVirtualPlugin("build-ssr-entry", () => importSsr),
680
+ createVirtualPlugin("runtime/ssr", function() {
681
+ if (this.environment.name === "ssr") return importSsr;
682
+ if (this.environment.mode === "dev") return `
683
+ const devServer = global.vikeReactRscGlobalState.devServer;
684
+ const ssrRunner = devServer?.environments.ssr?.runner;
685
+ const ssrModule = await ssrRunner?.import("${PKG_NAME}/__internal/runtime/ssr");
686
+ const moduleProxy = new Proxy({}, {
687
+ get(target, prop) {
688
+ return ssrModule[prop];
689
+ }
690
+ });
691
+ export default moduleProxy;
692
+ `;
693
+ return `
694
+ import * as ssrModule from "virtual:dist-importer?server";
695
+ export * from "virtual:dist-importer?server";
696
+ export default ssrModule;
697
+ `;
698
+ }),
699
+ createVirtualPlugin("runtime/server", function() {
700
+ if (this.environment.name === "rsc") return importRsc;
701
+ if (this.environment.mode === "dev") return `
702
+ const devServer = global.vikeReactRscGlobalState.devServer;
703
+ const serverRunner = devServer?.environments.rsc?.runner;
704
+ const serverModule = await serverRunner?.import("${PKG_NAME}/__internal/runtime/server");
705
+ const moduleProxy = new Proxy({}, {
706
+ get(target, prop) {
707
+ return serverModule[prop];
708
+ }
709
+ });
710
+ export default moduleProxy;
711
+ `;
712
+ return `
713
+ import * as serverModule from "virtual:dist-importer?rsc";
714
+ export * from "virtual:dist-importer?rsc";
715
+ export default serverModule;
716
+ `;
717
+ }),
718
+ {
719
+ name: "virtual:dist-importer",
720
+ resolveId(source) {
721
+ if (source.includes("virtual:dist-importer")) return {
722
+ id: `__VIRTUAL_BUILD_ENTRY__?${source.split("?")[1]}`,
723
+ external: true
724
+ };
725
+ return;
726
+ },
727
+ renderChunk(code, chunk) {
728
+ if (code.includes("__VIRTUAL_BUILD_ENTRY__")) {
729
+ const importerPath = path.join(this.environment.config.build.outDir, chunk.fileName);
730
+ code = code.replaceAll("__VIRTUAL_BUILD_ENTRY__?server", path.relative(path.dirname(importerPath), "dist/server/ssr.mjs")).replaceAll("__VIRTUAL_BUILD_ENTRY__?rsc", path.relative(path.dirname(importerPath), "dist/rsc/index.mjs"));
731
+ return { code };
732
+ }
733
+ return;
734
+ }
735
+ }
736
+ ];
737
+
738
+ //#endregion
739
+ //#region src/plugin/plugins/hmrPlugin.ts
740
+ const styleFileRE = /\.(css|less|sass|scss|styl|stylus|pcss|postcss)($|\?)/;
741
+ const hmrPlugin = () => {
742
+ return {
743
+ name: "vike-rsc:hmr",
744
+ hotUpdate: {
745
+ order: "pre",
746
+ handler(ctx) {
747
+ const clientEnv = ctx.server.environments.client;
748
+ const cliendIds = new Set(Object.values(global.vikeReactRscGlobalState.clientReferences));
749
+ if (this.environment.name === "ssr") {
750
+ const withoutRscMods = ctx.modules.filter(({ id }) => {
751
+ return id && (cliendIds.has(id) || !global.vikeReactRscGlobalState.devServer?.environments.rsc.moduleGraph.getModuleById(id));
752
+ });
753
+ return withoutRscMods;
754
+ }
755
+ if (this.environment.name === "client") {
756
+ const withoutRscMods = ctx.modules.filter(({ id }) => {
757
+ return id && (cliendIds.has(id) || global.vikeReactRscGlobalState.isClientDependency(id) || styleFileRE.test(id) || !global.vikeReactRscGlobalState.devServer?.environments.rsc.moduleGraph.getModuleById(id));
758
+ });
759
+ return withoutRscMods;
760
+ }
761
+ if (this.environment.name === "rsc") {
762
+ const ids = ctx.modules.map((mod) => mod.id).filter((v) => v !== null);
763
+ const flattenedImporters = new Set(ctx.modules);
764
+ for (const mod of flattenedImporters) {
765
+ if (mod.id && cliendIds.has(mod.id)) break;
766
+ console.log(global.vikeReactRscGlobalState.excludedModuleMap, mod.url);
767
+ const excludedModule = Object.entries(global.vikeReactRscGlobalState.excludedModuleMap).find(([root, jsIds]) => jsIds.some((id) => id.split("?t=")[0] === mod.url))?.[0];
768
+ if (excludedModule) {
769
+ global.vikeReactRscGlobalState.pruneCssRegistry(excludedModule);
770
+ this.environment.moduleGraph.invalidateModule(mod);
771
+ const clientMod = clientEnv.moduleGraph.getModuleById(excludedModule);
772
+ const cssProxyModClient = clientEnv.moduleGraph.getModuleById(`\0virtual:css-proxy.css?id=${encodeURIComponent(excludedModule)}`);
773
+ clientEnv.moduleGraph.invalidateModule(clientMod);
774
+ clientEnv.moduleGraph.invalidateModule(cssProxyModClient);
775
+ clientEnv.reloadModule(cssProxyModClient);
776
+ break;
777
+ }
778
+ for (const importer of mod.importers) flattenedImporters.add(importer);
779
+ }
780
+ if (ids.length > 0) if (ids.some((id) => cliendIds.has(id))) return;
781
+ else ctx.server.environments.client.hot.send({
782
+ type: "custom",
783
+ event: "rsc:update",
784
+ data: { file: ctx.file }
785
+ });
786
+ }
787
+ }
788
+ }
789
+ };
790
+ };
791
+
792
+ //#endregion
793
+ //#region src/plugin/index.ts
794
+ global.vikeReactRscGlobalState ||= {
795
+ clientReferences: {},
796
+ serverReferences: {},
797
+ devServer: void 0,
798
+ disableUseClientPlugin: false,
799
+ getCssDependencies: async () => ({
800
+ cssIds: [],
801
+ jsIds: []
802
+ }),
803
+ pruneCssRegistry: () => {},
804
+ isClientDependency: () => false,
805
+ excludedModuleMap: {}
806
+ };
807
+ function vikeRscPlugin() {
808
+ return [
809
+ ...configs,
810
+ ...virtuals,
811
+ exposeDevServer,
812
+ vikeRscManifestPluginBuild(),
813
+ cssTrackerPlugin(),
814
+ clientDepTrackerPlugin(),
815
+ ...useClientPlugin(),
816
+ ...useServerPlugin(),
817
+ virtualNormalizeReferenceIdPlugin(),
818
+ ...serverComponentExclusionPlugin(),
819
+ hmrPlugin(),
820
+ rscCore()
821
+ ];
822
+ }
823
+
824
+ //#endregion
825
+ //#region src/config.ts
826
+ const config = {
827
+ name: "vike-react-rsc-rudder",
828
+ require: { vike: ">=0.4.182" },
829
+ onRenderHtml: "import:vike-react-rsc-rudder/__internal/integration/onRenderHtml:onRenderHtml",
830
+ onRenderClient: "import:vike-react-rsc-rudder/__internal/integration/onRenderClient:onRenderClient",
831
+ onBeforeRender: "import:vike-react-rsc-rudder/__internal/integration/onBeforeRender:onBeforeRender",
832
+ onPageTransitionStart: "import:vike-react-rsc-rudder/__internal/integration/onPageTransitionStart:onPageTransitionStart",
833
+ client: "import:vike-react-rsc-rudder/__internal/integration/client:default",
834
+ middleware: "import:vike-react-rsc-rudder/__internal/integration/rscMiddleware:default",
835
+ passToClient: ["rscPayloadString"],
836
+ clientRouting: true,
837
+ hydrationCanBeAborted: true,
838
+ meta: {
839
+ rsc: { env: {
840
+ server: true,
841
+ client: false
842
+ } },
843
+ onBeforeRender: { env: {
844
+ server: true,
845
+ client: false
846
+ } },
847
+ Head: {
848
+ env: { server: true },
849
+ cumulative: true
850
+ },
851
+ Wrapper: {
852
+ env: {
853
+ client: true,
854
+ server: true
855
+ },
856
+ cumulative: true
857
+ },
858
+ Layout: {
859
+ env: {
860
+ server: true,
861
+ client: true
862
+ },
863
+ cumulative: true
864
+ },
865
+ Loading: { env: {
866
+ server: true,
867
+ client: true
868
+ } }
869
+ },
870
+ vite6BuilderApp: true,
871
+ vite: { plugins: [vikeRscPlugin()] }
872
+ };
873
+
874
+ //#endregion
875
+ export { config as default };