@vitejs/plugin-rsc 0.4.28 → 0.4.30

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 (66) hide show
  1. package/README.md +2 -50
  2. package/dist/{browser-QU10IP0-.js → browser--ZREVnM9.js} +1 -1
  3. package/dist/{browser-BhJd-Orx.js → browser-7NhxQxuk.js} +1 -1
  4. package/dist/{browser-mbRygLxB.d.ts → browser-CQv7Z3J4.d.ts} +1 -1
  5. package/dist/browser.d.ts +3 -3
  6. package/dist/browser.js +3 -3
  7. package/dist/cjs-WQBk0zA_.js +104 -0
  8. package/dist/core/browser.d.ts +1 -1
  9. package/dist/core/browser.js +2 -2
  10. package/dist/core/rsc.d.ts +2 -2
  11. package/dist/core/rsc.js +2 -2
  12. package/dist/core/ssr.d.ts +2 -2
  13. package/dist/core/ssr.js +2 -2
  14. package/dist/{encryption-runtime-CJUalqt3.js → encryption-runtime-CugTJCLM.js} +2 -3
  15. package/dist/extra/browser.d.ts +1 -1
  16. package/dist/extra/browser.js +5 -6
  17. package/dist/extra/rsc.d.ts +1 -1
  18. package/dist/extra/rsc.js +11 -17
  19. package/dist/extra/ssr.js +8 -10
  20. package/dist/index-DWN3vCIQ.d.ts +89 -0
  21. package/dist/index.d.ts +3 -24
  22. package/dist/index.js +6 -4
  23. package/dist/{plugin-iKgvucKS.js → plugin-Bzocj-4a.js} +70 -496
  24. package/dist/{plugin-BFcMxUSS.d.ts → plugin-Cfy_9VpM.d.ts} +1 -9
  25. package/dist/plugin.d.ts +2 -1
  26. package/dist/plugin.js +5 -3
  27. package/dist/plugins/cjs.d.ts +6 -0
  28. package/dist/plugins/cjs.js +5 -0
  29. package/dist/react/browser.d.ts +3 -3
  30. package/dist/react/browser.js +2 -2
  31. package/dist/react/rsc.d.ts +3 -3
  32. package/dist/react/rsc.js +3 -3
  33. package/dist/react/ssr.d.ts +3 -3
  34. package/dist/react/ssr.js +3 -3
  35. package/dist/{rpc-tGuLT8PD.js → rpc-CUvSZurk.js} +2 -3
  36. package/dist/{rsc-CxDPDiLz.d.ts → rsc-3bkzqdsJ.d.ts} +1 -1
  37. package/dist/{rsc-VjVw_i-M.js → rsc-BdCB3621.js} +1 -1
  38. package/dist/{rsc-BwEwbLG4.js → rsc-CiAoLCx8.js} +1 -1
  39. package/dist/{rsc-BfBPoIV8.js → rsc-GFzFWyhT.js} +2 -3
  40. package/dist/rsc-html-stream/browser.js +1 -1
  41. package/dist/rsc-html-stream/ssr.js +1 -1
  42. package/dist/rsc.d.ts +4 -4
  43. package/dist/rsc.js +5 -5
  44. package/dist/{shared-CEyKoKAb.js → shared-CXg_u-4h.js} +1 -2
  45. package/dist/{ssr-CWjOQSe3.js → ssr-8BA2nj0-.js} +2 -2
  46. package/dist/{ssr-BoNKka-5.d.ts → ssr-CMjeQ9AS.d.ts} +1 -1
  47. package/dist/{ssr-BEKKb_cw.js → ssr-Cd4SbAaO.js} +1 -1
  48. package/dist/{ssr--rFiBtws.js → ssr-Cm2FP2zD.js} +1 -1
  49. package/dist/ssr.d.ts +3 -3
  50. package/dist/ssr.js +5 -5
  51. package/dist/transforms/index.d.ts +2 -0
  52. package/dist/transforms/index.js +4 -0
  53. package/dist/transforms-D1-2JfCh.js +330 -0
  54. package/dist/utils/encryption-runtime.d.ts +1 -1
  55. package/dist/utils/encryption-runtime.js +4 -4
  56. package/dist/utils/rpc.js +1 -1
  57. package/package.json +3 -2
  58. /package/dist/{browser-CuwQIlVY.d.ts → browser-DwWQeoll.d.ts} +0 -0
  59. /package/dist/{client-C1J4FCf5.js → client-C7Eok9hc.js} +0 -0
  60. /package/dist/{encryption-runtime-SgJRa9yj.d.ts → encryption-runtime-B8xcnJoN.d.ts} +0 -0
  61. /package/dist/{index-QWzVHuya.d.ts → index-CPkExgij.d.ts} +0 -0
  62. /package/dist/{rsc-CFtzqEG8.d.ts → rsc-JJjz3Z0i.d.ts} +0 -0
  63. /package/dist/{rsc-Cv3XEZqB.d.ts → rsc-c22DF1A7.d.ts} +0 -0
  64. /package/dist/{server-D0-DavPP.js → server-BTo03tXh.js} +0 -0
  65. /package/dist/{shared-BWHxNw3Q.js → shared-AvKUASD5.js} +0 -0
  66. /package/dist/{ssr-D6GTzOzx.d.ts → ssr-BrSGyrxe.d.ts} +0 -0
@@ -1,8 +1,10 @@
1
- import { createDebug, tinyassert } from "./dist-DiJnRA1C.js";
1
+ import { createDebug } from "./dist-DiJnRA1C.js";
2
2
  import { vitePluginRscCore } from "./plugin-CZbI4rhS.js";
3
+ import { hasDirective, transformDirectiveProxyExport, transformServerActionServer, transformWrapExport } from "./transforms-D1-2JfCh.js";
3
4
  import { generateEncryptionKey, toBase64 } from "./encryption-utils-BDwwcMVT.js";
4
- import { createRpcServer } from "./rpc-tGuLT8PD.js";
5
- import { parseCssVirtual, parseIdQuery, toCssVirtual } from "./shared-BWHxNw3Q.js";
5
+ import { createRpcServer } from "./rpc-CUvSZurk.js";
6
+ import { cjsModuleRunnerPlugin } from "./cjs-WQBk0zA_.js";
7
+ import { parseCssVirtual, parseIdQuery, toCssVirtual } from "./shared-AvKUASD5.js";
6
8
  import { createRequire } from "node:module";
7
9
  import assert from "node:assert";
8
10
  import fs from "node:fs";
@@ -13,300 +15,11 @@ import * as esModuleLexer from "es-module-lexer";
13
15
  import MagicString from "magic-string";
14
16
  import * as vite from "vite";
15
17
  import { defaultServerConditions, isCSSRequest, normalizePath, parseAstAsync } from "vite";
16
- import { crawlFrameworkPkgs, findClosestPkgJsonPath } from "vitefu";
18
+ import { crawlFrameworkPkgs } from "vitefu";
17
19
  import { walk } from "estree-walker";
18
- import { analyze, extract_names } from "periscopic";
19
20
  import { stripVTControlCharacters } from "node:util";
20
21
  import { createHash } from "node:crypto";
21
22
 
22
- //#region src/transforms/hoist.ts
23
- function transformHoistInlineDirective(input, ast, { runtime, rejectNonAsyncFunction,...options }) {
24
- const output = new MagicString(input);
25
- const directive = typeof options.directive === "string" ? exactRegex(options.directive) : options.directive;
26
- walk(ast, { enter(node) {
27
- if (node.type === "ExportAllDeclaration") this.remove();
28
- if (node.type === "ExportNamedDeclaration" && !node.declaration) this.remove();
29
- } });
30
- const analyzed = analyze(ast);
31
- const names = [];
32
- walk(ast, { enter(node, parent) {
33
- if ((node.type === "FunctionExpression" || node.type === "FunctionDeclaration" || node.type === "ArrowFunctionExpression") && node.body.type === "BlockStatement") {
34
- const match = matchDirective(node.body.body, directive);
35
- if (!match) return;
36
- if (!node.async && rejectNonAsyncFunction) throw Object.assign(/* @__PURE__ */ new Error(`"${directive}" doesn't allow non async function`), { pos: node.start });
37
- const scope = analyzed.map.get(node);
38
- tinyassert(scope);
39
- const declName = node.type === "FunctionDeclaration" && node.id.name;
40
- const originalName = declName || parent?.type === "VariableDeclarator" && parent.id.type === "Identifier" && parent.id.name || "anonymous_server_function";
41
- const bindVars = [...scope.references].filter((ref) => {
42
- if (ref === declName) return false;
43
- const owner = scope.find_owner(ref);
44
- return owner && owner !== scope && owner !== analyzed.scope;
45
- });
46
- let newParams = [...bindVars, ...node.params.map((n) => input.slice(n.start, n.end))].join(", ");
47
- if (bindVars.length > 0 && options.decode) {
48
- newParams = ["$$hoist_encoded", ...node.params.map((n) => input.slice(n.start, n.end))].join(", ");
49
- output.appendLeft(node.body.body[0].start, `const [${bindVars.join(",")}] = ${options.decode("$$hoist_encoded")};\n`);
50
- }
51
- const newName = `$$hoist_${names.length}` + (originalName ? `_${originalName}` : "");
52
- names.push(newName);
53
- output.update(node.start, node.body.start, `\n;${options.noExport ? "" : "export "}${node.async ? "async " : ""}function ${newName}(${newParams}) `);
54
- output.appendLeft(node.end, `;\n/* #__PURE__ */ Object.defineProperty(${newName}, "name", { value: ${JSON.stringify(originalName)} });\n`);
55
- output.move(node.start, node.end, input.length);
56
- let newCode = `/* #__PURE__ */ ${runtime(newName, newName, { directiveMatch: match })}`;
57
- if (bindVars.length > 0) {
58
- const bindArgs = options.encode ? options.encode("[" + bindVars.join(", ") + "]") : bindVars.join(", ");
59
- newCode = `${newCode}.bind(null, ${bindArgs})`;
60
- }
61
- if (declName) {
62
- newCode = `const ${declName} = ${newCode};`;
63
- if (parent?.type === "ExportDefaultDeclaration") {
64
- output.remove(parent.start, node.start);
65
- newCode = `${newCode}\nexport default ${declName};`;
66
- }
67
- }
68
- output.appendLeft(node.start, newCode);
69
- }
70
- } });
71
- return {
72
- output,
73
- names
74
- };
75
- }
76
- const exactRegex = (s) => /* @__PURE__ */ new RegExp("^" + s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&") + "$");
77
- function matchDirective(body, directive) {
78
- for (const stable of body) if (stable.type === "ExpressionStatement" && stable.expression.type === "Literal" && typeof stable.expression.value === "string") {
79
- const match = stable.expression.value.match(directive);
80
- if (match) return match;
81
- }
82
- }
83
-
84
- //#endregion
85
- //#region src/transforms/wrap-export.ts
86
- function transformWrapExport(input, ast, options) {
87
- const output = new MagicString(input);
88
- const exportNames = [];
89
- const toAppend = [];
90
- const filter = options.filter ?? (() => true);
91
- function wrapSimple(start, end, exports) {
92
- exportNames.push(...exports.map((e) => e.name));
93
- const newCode = exports.map((e) => [filter(e.name, e.meta) && `${e.name} = /* #__PURE__ */ ${options.runtime(e.name, e.name, e.meta)};\n`, `export { ${e.name} };\n`]).flat().filter(Boolean).join("");
94
- output.update(start, end, newCode);
95
- output.move(start, end, input.length);
96
- }
97
- function wrapExport(name, exportName, meta = {}) {
98
- exportNames.push(exportName);
99
- if (!filter(exportName, meta)) {
100
- toAppend.push(`export { ${name} as ${exportName} }`);
101
- return;
102
- }
103
- toAppend.push(`const $$wrap_${name} = /* #__PURE__ */ ${options.runtime(name, exportName, meta)}`, `export { $$wrap_${name} as ${exportName} }`);
104
- }
105
- function validateNonAsyncFunction(node) {
106
- if (!options.rejectNonAsyncFunction) return;
107
- if (node.type === "ClassDeclaration" || (node.type === "FunctionDeclaration" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression") && !node.async) throw Object.assign(/* @__PURE__ */ new Error(`unsupported non async function`), { pos: node.start });
108
- }
109
- for (const node of ast.body) {
110
- if (node.type === "ExportNamedDeclaration") if (node.declaration) if (node.declaration.type === "FunctionDeclaration" || node.declaration.type === "ClassDeclaration") {
111
- /**
112
- * export function foo() {}
113
- */
114
- validateNonAsyncFunction(node.declaration);
115
- const name = node.declaration.id.name;
116
- wrapSimple(node.start, node.declaration.start, [{
117
- name,
118
- meta: {
119
- isFunction: true,
120
- declName: name
121
- }
122
- }]);
123
- } else if (node.declaration.type === "VariableDeclaration") {
124
- /**
125
- * export const foo = 1, bar = 2
126
- */
127
- for (const decl of node.declaration.declarations) if (decl.init) validateNonAsyncFunction(decl.init);
128
- if (node.declaration.kind === "const") output.update(node.declaration.start, node.declaration.start + 5, "let");
129
- const names = node.declaration.declarations.flatMap((decl) => extract_names(decl.id));
130
- let isFunction = false;
131
- if (node.declaration.declarations.length === 1) {
132
- const decl = node.declaration.declarations[0];
133
- isFunction = decl.id.type === "Identifier" && (decl.init?.type === "ArrowFunctionExpression" || decl.init?.type === "FunctionExpression");
134
- }
135
- wrapSimple(node.start, node.declaration.start, names.map((name) => ({
136
- name,
137
- meta: {
138
- isFunction,
139
- declName: name
140
- }
141
- })));
142
- } else node.declaration;
143
- else if (node.source) {
144
- /**
145
- * export { foo, bar as car } from './foo'
146
- */
147
- output.remove(node.start, node.end);
148
- for (const spec of node.specifiers) {
149
- tinyassert(spec.local.type === "Identifier");
150
- tinyassert(spec.exported.type === "Identifier");
151
- const name = spec.local.name;
152
- toAppend.push(`import { ${name} as $$import_${name} } from ${node.source.raw}`);
153
- wrapExport(`$$import_${name}`, spec.exported.name);
154
- }
155
- } else {
156
- /**
157
- * export { foo, bar as car }
158
- */
159
- output.remove(node.start, node.end);
160
- for (const spec of node.specifiers) {
161
- tinyassert(spec.local.type === "Identifier");
162
- tinyassert(spec.exported.type === "Identifier");
163
- wrapExport(spec.local.name, spec.exported.name);
164
- }
165
- }
166
- /**
167
- * export * from './foo'
168
- */
169
- if (!options.ignoreExportAllDeclaration && node.type === "ExportAllDeclaration") throw Object.assign(/* @__PURE__ */ new Error("unsupported ExportAllDeclaration"), { pos: node.start });
170
- /**
171
- * export default function foo() {}
172
- * export default class Foo {}
173
- * export default () => {}
174
- */
175
- if (node.type === "ExportDefaultDeclaration") {
176
- validateNonAsyncFunction(node.declaration);
177
- let localName;
178
- let isFunction = false;
179
- let declName;
180
- let defaultExportIdentifierName;
181
- if ((node.declaration.type === "FunctionDeclaration" || node.declaration.type === "ClassDeclaration") && node.declaration.id) {
182
- localName = node.declaration.id.name;
183
- output.remove(node.start, node.declaration.start);
184
- isFunction = node.declaration.type === "FunctionDeclaration";
185
- declName = node.declaration.id.name;
186
- } else {
187
- localName = "$$default";
188
- output.update(node.start, node.declaration.start, "const $$default = ");
189
- if (node.declaration.type === "Identifier") defaultExportIdentifierName = node.declaration.name;
190
- }
191
- wrapExport(localName, "default", {
192
- isFunction,
193
- declName,
194
- defaultExportIdentifierName
195
- });
196
- }
197
- }
198
- if (toAppend.length > 0) output.append([
199
- "",
200
- ...toAppend,
201
- ""
202
- ].join(";\n"));
203
- return {
204
- exportNames,
205
- output
206
- };
207
- }
208
-
209
- //#endregion
210
- //#region src/transforms/utils.ts
211
- function hasDirective(body, directive) {
212
- return !!body.find((stmt) => stmt.type === "ExpressionStatement" && stmt.expression.type === "Literal" && typeof stmt.expression.value === "string" && stmt.expression.value === directive);
213
- }
214
-
215
- //#endregion
216
- //#region src/transforms/proxy-export.ts
217
- function transformDirectiveProxyExport(ast, options) {
218
- if (!hasDirective(ast.body, options.directive)) return;
219
- return transformProxyExport(ast, options);
220
- }
221
- function transformProxyExport(ast, options) {
222
- if (options.keep && typeof options.code !== "string") throw new Error("`keep` option requires `code`");
223
- const output = new MagicString(options.code ?? " ".repeat(ast.end));
224
- const exportNames = [];
225
- function createExport(node, names) {
226
- exportNames.push(...names);
227
- const newCode = names.map((name) => (name === "default" ? `export default` : `export const ${name} =`) + ` /* #__PURE__ */ ${options.runtime(name)};\n`).join("");
228
- output.update(node.start, node.end, newCode);
229
- }
230
- function validateNonAsyncFunction(node, ok) {
231
- if (options.rejectNonAsyncFunction && !ok) throw Object.assign(/* @__PURE__ */ new Error(`unsupported non async function`), { pos: node.start });
232
- }
233
- for (const node of ast.body) {
234
- if (node.type === "ExportNamedDeclaration") {
235
- if (node.declaration) if (node.declaration.type === "FunctionDeclaration" || node.declaration.type === "ClassDeclaration") {
236
- /**
237
- * export function foo() {}
238
- */
239
- validateNonAsyncFunction(node, node.declaration.type === "FunctionDeclaration" && node.declaration.async);
240
- createExport(node, [node.declaration.id.name]);
241
- } else if (node.declaration.type === "VariableDeclaration") {
242
- /**
243
- * export const foo = 1, bar = 2
244
- */
245
- validateNonAsyncFunction(node, node.declaration.declarations.every((decl) => decl.init?.type === "ArrowFunctionExpression" && decl.init.async));
246
- if (options.keep && options.code) {
247
- if (node.declaration.declarations.length === 1) {
248
- const decl = node.declaration.declarations[0];
249
- if (decl.id.type === "Identifier" && decl.init) {
250
- const name = decl.id.name;
251
- const value = options.code.slice(decl.init.start, decl.init.end);
252
- const newCode = `export const ${name} = /* #__PURE__ */ ${options.runtime(name, { value })};`;
253
- output.update(node.start, node.end, newCode);
254
- exportNames.push(name);
255
- continue;
256
- }
257
- }
258
- }
259
- const names = node.declaration.declarations.flatMap((decl) => extract_names(decl.id));
260
- createExport(node, names);
261
- } else node.declaration;
262
- else {
263
- /**
264
- * export { foo, bar as car } from './foo'
265
- * export { foo, bar as car }
266
- */
267
- const names = [];
268
- for (const spec of node.specifiers) {
269
- tinyassert(spec.exported.type === "Identifier");
270
- names.push(spec.exported.name);
271
- }
272
- createExport(node, names);
273
- }
274
- continue;
275
- }
276
- /**
277
- * export * from './foo'
278
- */
279
- if (!options.ignoreExportAllDeclaration && node.type === "ExportAllDeclaration") throw new Error("unsupported ExportAllDeclaration");
280
- /**
281
- * export default function foo() {}
282
- * export default class Foo {}
283
- * export default () => {}
284
- */
285
- if (node.type === "ExportDefaultDeclaration") {
286
- validateNonAsyncFunction(node, node.declaration.type === "Identifier" || node.declaration.type === "FunctionDeclaration" && node.declaration.async);
287
- createExport(node, ["default"]);
288
- continue;
289
- }
290
- if (options.keep) continue;
291
- output.remove(node.start, node.end);
292
- }
293
- return {
294
- exportNames,
295
- output
296
- };
297
- }
298
-
299
- //#endregion
300
- //#region src/transforms/server-action.ts
301
- function transformServerActionServer(input, ast, options) {
302
- if (hasDirective(ast.body, "use server")) return transformWrapExport(input, ast, options);
303
- return transformHoistInlineDirective(input, ast, {
304
- ...options,
305
- directive: "use server"
306
- });
307
- }
308
-
309
- //#endregion
310
23
  //#region src/plugins/vite-utils.ts
311
24
  const VALID_ID_PREFIX = `/@id/`;
312
25
  const NULL_BYTE_PLACEHOLDER = `__x00__`;
@@ -336,8 +49,7 @@ function slash(p) {
336
49
  const isWindows = typeof process !== "undefined" && process.platform === "win32";
337
50
  function injectQuery(url, queryToInject) {
338
51
  const { file, postfix } = splitFileAndPostfix(url);
339
- const normalizedFile = isWindows ? slash(file) : file;
340
- return `${normalizedFile}?${queryToInject}${postfix[0] === "?" ? `&${postfix.slice(1)}` : postfix}`;
52
+ return `${isWindows ? slash(file) : file}?${queryToInject}${postfix[0] === "?" ? `&${postfix.slice(1)}` : postfix}`;
341
53
  }
342
54
  function normalizeResolvedIdToUrl(environment, url, resolved) {
343
55
  const root = environment.config.root;
@@ -371,106 +83,12 @@ function cleanStack(stack) {
371
83
  return stack.split(/\n/).filter((l) => /^\s*at/.test(l)).join("\n");
372
84
  }
373
85
  function evalValue(rawValue) {
374
- const fn = new Function(`
86
+ return new Function(`
375
87
  var console, exports, global, module, process, require
376
88
  return (\n${rawValue}\n)
377
- `);
378
- return fn();
379
- }
380
-
381
- //#endregion
382
- //#region src/transforms/cjs.ts
383
- function transformCjsToEsm(code, ast) {
384
- const output = new MagicString(code);
385
- const analyzed = analyze(ast);
386
- const parentNodes = [];
387
- const hoistedCodes = [];
388
- let hoistIndex = 0;
389
- walk(ast, {
390
- enter(node) {
391
- parentNodes.push(node);
392
- if (node.type === "CallExpression" && node.callee.type === "Identifier" && node.callee.name === "require" && node.arguments.length === 1) {
393
- let isTopLevel = true;
394
- for (const parent of parentNodes) {
395
- if (parent.type === "FunctionExpression" || parent.type === "FunctionDeclaration" || parent.type === "ArrowFunctionExpression") isTopLevel = false;
396
- const scope = analyzed.map.get(parent);
397
- if (scope && scope.declarations.has("require")) return;
398
- }
399
- if (isTopLevel) {
400
- output.update(node.start, node.callee.end, "(await import");
401
- output.appendRight(node.end, ")");
402
- } else {
403
- const hoisted = `__cjs_to_esm_hoist_${hoistIndex}`;
404
- const importee = code.slice(node.arguments[0].start, node.arguments[0].end);
405
- hoistedCodes.push(`const ${hoisted} = await import(${importee});\n`);
406
- output.update(node.start, node.end, hoisted);
407
- hoistIndex++;
408
- }
409
- }
410
- },
411
- leave() {
412
- parentNodes.pop();
413
- }
414
- });
415
- for (const hoisted of hoistedCodes.reverse()) output.prepend(hoisted);
416
- output.prepend(`const exports = {}; const module = { exports };\n`);
417
- return { output };
418
- }
419
-
420
- //#endregion
421
- //#region src/plugins/cjs.ts
422
- const debug = createDebug("vite-rsc:cjs");
423
- function cjsModuleRunnerPlugin() {
424
- const warnedPackages = /* @__PURE__ */ new Set();
425
- return [{
426
- name: "cjs-module-runner-transform",
427
- apply: "serve",
428
- applyToEnvironment: (env) => env.config.dev.moduleRunnerTransform,
429
- async transform(code, id) {
430
- if (id.includes("/node_modules/") && !id.startsWith(this.environment.config.cacheDir) && /\b(require|exports)\b/.test(code)) {
431
- id = parseIdQuery(id).filename;
432
- if (!/\.[cm]?js$/.test(id)) return;
433
- if (id.endsWith(".mjs")) return;
434
- if (id.endsWith(".js")) {
435
- const pkgJsonPath = await findClosestPkgJsonPath(path.dirname(id));
436
- if (pkgJsonPath) {
437
- const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, "utf-8"));
438
- if (pkgJson.type === "module") return;
439
- }
440
- }
441
- const [, , , hasModuleSyntax] = esModuleLexer.parse(code);
442
- if (hasModuleSyntax) return;
443
- const packageKey = extractPackageKey(id);
444
- if (!warnedPackages.has(packageKey)) {
445
- debug(`non-optimized CJS dependency in '${this.environment.name}' environment: ${id}`);
446
- warnedPackages.add(packageKey);
447
- }
448
- const ast = await parseAstAsync(code);
449
- const result = transformCjsToEsm(code, ast);
450
- const output = result.output;
451
- output.append(`
452
- ;__vite_ssr_exportAll__(module.exports);
453
- export default module.exports;
454
- `);
455
- return {
456
- code: output.toString(),
457
- map: output.generateMap({ hires: "boundary" })
458
- };
459
- }
460
- }
461
- }];
462
- }
463
- function extractPackageKey(id) {
464
- const yarnMatch = id.match(/\/.yarn\/cache\/([^/]+)/);
465
- if (yarnMatch) return yarnMatch[1];
466
- if (id.includes("/node_modules")) {
467
- id = id.split("/node_modules/").at(-1);
468
- let [x, y] = id.split("/");
469
- if (x.startsWith("@")) return `${x}/${y}`;
470
- return x;
471
- }
472
- return id;
89
+ `)();
473
90
  }
91
+ const directRequestRE = /(\?|&)direct=?(?:&|$)/;
474
92
 
475
93
  //#endregion
476
94
  //#region src/plugins/utils.ts
@@ -516,6 +134,14 @@ function getEntrySource(config, name = "index") {
516
134
  function hashString(v) {
517
135
  return createHash("sha256").update(v).digest().toString("hex").slice(0, 12);
518
136
  }
137
+ function getFetchHandlerExport(exports) {
138
+ if ("default" in exports) {
139
+ const default_ = exports.default;
140
+ if (default_ && typeof default_ === "object" && "fetch" in default_ && typeof default_.fetch === "function") return default_.fetch;
141
+ if (typeof default_ === "function") return default_;
142
+ }
143
+ throw new Error("Invalid server handler entry");
144
+ }
519
145
 
520
146
  //#endregion
521
147
  //#region src/plugins/scan.ts
@@ -526,9 +152,8 @@ function scanBuildStripPlugin({ manager }) {
526
152
  enforce: "post",
527
153
  async transform(code, _id, _options) {
528
154
  if (!manager.isScanBuild) return;
529
- const output = await transformScanBuildStrip(code);
530
155
  return {
531
- code: output,
156
+ code: await transformScanBuildStrip(code),
532
157
  map: { mappings: "" }
533
158
  };
534
159
  }
@@ -676,8 +301,7 @@ var RscPluginManager = class {
676
301
  };
677
302
  /** @experimental */
678
303
  function getPluginApi(config) {
679
- const plugin = config.plugins.find((p) => p.name === "rsc:minimal");
680
- return plugin?.api;
304
+ return config.plugins.find((p) => p.name === "rsc:minimal")?.api;
681
305
  }
682
306
  /** @experimental */
683
307
  function vitePluginRscMinimal(rscPluginOptions = {}, manager = new RscPluginManager()) {
@@ -791,6 +415,7 @@ function vitePluginRsc(rscPluginOptions = {}) {
791
415
  ssr: {
792
416
  build: {
793
417
  outDir: config.environments?.ssr?.build?.outDir ?? "dist/ssr",
418
+ copyPublicDir: false,
794
419
  rollupOptions: { input: rscPluginOptions.entries?.ssr && { index: rscPluginOptions.entries.ssr } }
795
420
  },
796
421
  resolve: { noExternal },
@@ -810,6 +435,7 @@ function vitePluginRsc(rscPluginOptions = {}) {
810
435
  rsc: {
811
436
  build: {
812
437
  outDir: config.environments?.rsc?.build?.outDir ?? "dist/rsc",
438
+ copyPublicDir: false,
813
439
  emitAssets: true,
814
440
  rollupOptions: { input: rscPluginOptions.entries?.rsc && { index: rscPluginOptions.entries.rsc } }
815
441
  },
@@ -875,8 +501,9 @@ function vitePluginRsc(rscPluginOptions = {}) {
875
501
  const resolved = await environment.pluginContainer.resolveId(source);
876
502
  assert(resolved, `[vite-rsc] failed to resolve server handler '${source}'`);
877
503
  const mod = await environment.runner.import(resolved.id);
504
+ const fetchHandler = getFetchHandlerExport(mod);
878
505
  req.url = req.originalUrl ?? req.url;
879
- await createRequestListener(mod.default)(req, res);
506
+ await createRequestListener(fetchHandler)(req, res);
880
507
  } catch (e) {
881
508
  next(e);
882
509
  }
@@ -891,12 +518,9 @@ function vitePluginRsc(rscPluginOptions = {}) {
891
518
  entryName: "index"
892
519
  };
893
520
  const entryFile = path.join(manager.config.environments[options.environmentName].build.outDir, `${options.entryName}.js`);
894
- const entry = pathToFileURL(entryFile).href;
895
- const mod = await import(
896
- /* @vite-ignore */
897
- entry
898
- );
899
- const handler = createRequestListener(mod.default);
521
+ const mod = await import(pathToFileURL(entryFile).href);
522
+ const fetchHandler = getFetchHandlerExport(mod);
523
+ const handler = createRequestListener(fetchHandler);
900
524
  server.middlewares.use((req, _res, next) => {
901
525
  delete req.headers["accept-encoding"];
902
526
  next();
@@ -914,10 +538,9 @@ function vitePluginRsc(rscPluginOptions = {}) {
914
538
  },
915
539
  async hotUpdate(ctx) {
916
540
  if (isCSSRequest(ctx.file)) {
917
- if (this.environment.name === "client") return ctx.modules.filter((m) => !(m.id?.includes("?direct") && !m.isSelfAccepting));
541
+ if (this.environment.name === "client") return;
918
542
  }
919
- const ids = ctx.modules.map((mod) => mod.id).filter((v) => v !== null);
920
- if (ids.length === 0) return;
543
+ if (ctx.modules.map((mod) => mod.id).filter((v) => v !== null).length === 0) return;
921
544
  if (this.environment.name === "rsc") {
922
545
  for (const mod of ctx.modules) if (mod.type === "js" && mod.id && mod.id in manager.clientReferenceMetaMap) try {
923
546
  await this.environment.transformRequest(mod.url);
@@ -957,9 +580,7 @@ function vitePluginRsc(rscPluginOptions = {}) {
957
580
  });
958
581
  }
959
582
  if (this.environment.name === "client") {
960
- const env = ctx.server.environments.rsc;
961
- const mod = env.moduleGraph.getModuleById(ctx.file);
962
- if (mod) {
583
+ if (ctx.server.environments.rsc.moduleGraph.getModuleById(ctx.file)) {
963
584
  for (const clientMod of ctx.modules) for (const importer of clientMod.importers) if (importer.id && isCSSRequest(importer.id)) await this.environment.reloadModule(importer);
964
585
  return [];
965
586
  }
@@ -1039,8 +660,7 @@ function vitePluginRsc(rscPluginOptions = {}) {
1039
660
  const runnerProxy = new Proxy({}, { get(_target, p, _receiver) {
1040
661
  if (typeof p !== "string" || p === "then") return;
1041
662
  return async (...args) => {
1042
- const mod = await environment.runner.import(resolvedEntry.id);
1043
- return mod[p](...args);
663
+ return (await environment.runner.import(resolvedEntry.id))[p](...args);
1044
664
  };
1045
665
  } });
1046
666
  return createRpcServer(runnerProxy);
@@ -1167,8 +787,7 @@ export default assetsManifest.bootstrapScriptContent;
1167
787
  createVirtualPlugin(VIRTUAL_ENTRIES.browser.slice(8), async function() {
1168
788
  assert(this.environment.mode === "dev");
1169
789
  let code = "";
1170
- const resolved = await this.resolve("/@react-refresh");
1171
- if (resolved) code += `
790
+ if (await this.resolve("/@react-refresh")) code += `
1172
791
  import RefreshRuntime from "/@react-refresh";
1173
792
  RefreshRuntime.injectIntoGlobalHook(window);
1174
793
  window.$RefreshReg$ = () => {};
@@ -1183,7 +802,7 @@ window.__vite_plugin_react_preamble_installed__ = true;
1183
802
  const ssrCss = document.querySelectorAll("link[rel='stylesheet']");
1184
803
  import.meta.hot.on("vite:beforeUpdate", () => {
1185
804
  ssrCss.forEach(node => {
1186
- if (node.dataset.precedence?.startsWith("vite-rsc/")) {
805
+ if (node.dataset.precedence?.startsWith("vite-rsc/client-references")) {
1187
806
  node.remove();
1188
807
  }
1189
808
  });
@@ -1226,7 +845,7 @@ function vitePluginUseClient(useClientPluginOptions, manager) {
1226
845
  id = normalizePath(path.relative(process.cwd(), id));
1227
846
  if (optimizerMetadata?.ids.includes(id)) ctx.warn("client component dependency is inconsistently optimized. It's recommended to add the dependency to 'optimizeDeps.exclude'.");
1228
847
  }
1229
- const debug$1 = createDebug("vite-rsc:use-client");
848
+ const debug = createDebug("vite-rsc:use-client");
1230
849
  return [
1231
850
  {
1232
851
  name: "rsc:use-client",
@@ -1245,7 +864,7 @@ function vitePluginUseClient(useClientPluginOptions, manager) {
1245
864
  let referenceKey;
1246
865
  const packageSource = packageSources.get(id);
1247
866
  if (!packageSource && this.environment.mode === "dev" && id.includes("/node_modules/")) {
1248
- debug$1(`internal client reference created through a package imported in '${this.environment.name}' environment: ${id}`);
867
+ debug(`internal client reference created through a package imported in '${this.environment.name}' environment: ${id}`);
1249
868
  id = cleanUrl(id);
1250
869
  warnInoncistentClientOptimization(this, id);
1251
870
  importId = `/@id/__x00__virtual:vite-rsc/client-in-server-package-proxy/${encodeURIComponent(id)}`;
@@ -1264,8 +883,7 @@ function vitePluginUseClient(useClientPluginOptions, manager) {
1264
883
  importId = id;
1265
884
  referenceKey = hashString(manager.toRelativeId(id));
1266
885
  }
1267
- const transformDirectiveProxyExport_ = withRollupError(this, transformDirectiveProxyExport);
1268
- const result = transformDirectiveProxyExport_(ast, {
886
+ const result = withRollupError(this, transformDirectiveProxyExport)(ast, {
1269
887
  directive: "use client",
1270
888
  code,
1271
889
  keep: !!useClientPluginOptions.keepUseCientProxy,
@@ -1314,17 +932,17 @@ function vitePluginUseClient(useClientPluginOptions, manager) {
1314
932
  let code = "";
1315
933
  manager.clientReferenceGroups = {};
1316
934
  for (const meta of Object.values(manager.clientReferenceMetaMap)) {
935
+ if (!meta.serverChunk) continue;
1317
936
  let name = useClientPluginOptions.clientChunks?.({
1318
937
  id: meta.importId,
1319
938
  normalizedId: manager.toRelativeId(meta.importId),
1320
939
  serverChunk: meta.serverChunk
1321
940
  }) ?? meta.serverChunk;
1322
941
  name = cleanUrl(name.replaceAll("..", "__"));
1323
- const group = manager.clientReferenceGroups[name] ??= [];
1324
- group.push(meta);
942
+ (manager.clientReferenceGroups[name] ??= []).push(meta);
1325
943
  meta.groupChunkId = `\0virtual:vite-rsc/client-references/group/${name}`;
1326
944
  }
1327
- debug$1("client-reference-groups", manager.clientReferenceGroups);
945
+ debug("client-reference-groups", manager.clientReferenceGroups);
1328
946
  for (const [name, metas] of Object.entries(manager.clientReferenceGroups)) {
1329
947
  const groupVirtual = `virtual:vite-rsc/client-references/group/${name}`;
1330
948
  for (const meta of metas) code += `\
@@ -1392,12 +1010,11 @@ function vitePluginUseClient(useClientPluginOptions, manager) {
1392
1010
  if (id.startsWith("\0virtual:vite-rsc/client-package-proxy/")) {
1393
1011
  assert(this.environment.mode === "dev");
1394
1012
  const source = id.slice(39);
1395
- const meta = Object.values(manager.clientReferenceMetaMap).find((v) => v.packageSource === source);
1396
- const exportNames = meta.exportNames;
1397
- return `export {${exportNames.join(",")}} from ${JSON.stringify(source)};\n`;
1013
+ return `export {${Object.values(manager.clientReferenceMetaMap).find((v) => v.packageSource === source).exportNames.join(",")}} from ${JSON.stringify(source)};\n`;
1398
1014
  }
1399
1015
  },
1400
1016
  generateBundle(_options, bundle) {
1017
+ if (manager.isScanBuild) return;
1401
1018
  if (this.environment.name !== serverEnvironmentName) return;
1402
1019
  for (const chunk of Object.values(bundle)) if (chunk.type === "chunk") {
1403
1020
  const metas = [];
@@ -1432,8 +1049,7 @@ function customOptimizerMetadataPlugin({ setMetadata }) {
1432
1049
  setup(build) {
1433
1050
  build.onEnd((result) => {
1434
1051
  if (!result.metafile?.inputs || !build.initialOptions.outdir) return;
1435
- const ids = Object.keys(result.metafile.inputs);
1436
- const metadata = { ids };
1052
+ const metadata = { ids: Object.keys(result.metafile.inputs) };
1437
1053
  setMetadata(metadata);
1438
1054
  fs.writeFileSync(path.join(build.initialOptions.outdir, MEATADATA_FILE), JSON.stringify(metadata, null, 2));
1439
1055
  });
@@ -1445,8 +1061,7 @@ function customOptimizerMetadataPlugin({ setMetadata }) {
1445
1061
  name: "vite-rsc-metafile",
1446
1062
  writeBundle(options) {
1447
1063
  assert(options.dir);
1448
- const ids = [...this.getModuleIds()].map((id) => path.relative(process.cwd(), id));
1449
- const metadata = { ids };
1064
+ const metadata = { ids: [...this.getModuleIds()].map((id) => path.relative(process.cwd(), id)) };
1450
1065
  setMetadata(metadata);
1451
1066
  fs.writeFileSync(path.join(options.dir, MEATADATA_FILE), JSON.stringify(metadata, null, 2));
1452
1067
  }
@@ -1510,7 +1125,7 @@ function vitePluginDefineEncryptionKey(useServerPluginOptions) {
1510
1125
  function vitePluginUseServer(useServerPluginOptions, manager) {
1511
1126
  const serverEnvironmentName = useServerPluginOptions.environment?.rsc ?? "rsc";
1512
1127
  const browserEnvironmentName = useServerPluginOptions.environment?.browser ?? "client";
1513
- const debug$1 = createDebug("vite-rsc:use-server");
1128
+ const debug = createDebug("vite-rsc:use-server");
1514
1129
  return [{
1515
1130
  name: "rsc:use-server",
1516
1131
  async transform(code, id) {
@@ -1523,7 +1138,7 @@ function vitePluginUseServer(useServerPluginOptions, manager) {
1523
1138
  const getNormalizedId = () => {
1524
1139
  if (!normalizedId_) {
1525
1140
  if (this.environment.mode === "dev" && id.includes("/node_modules/")) {
1526
- debug$1(`internal server reference created through a package imported in ${this.environment.name} environment: ${id}`);
1141
+ debug(`internal server reference created through a package imported in ${this.environment.name} environment: ${id}`);
1527
1142
  id = cleanUrl(id);
1528
1143
  }
1529
1144
  if (manager.config.command === "build") normalizedId_ = hashString(manager.toRelativeId(id));
@@ -1565,8 +1180,7 @@ function vitePluginUseServer(useServerPluginOptions, manager) {
1565
1180
  delete manager.serverReferenceMetaMap[id];
1566
1181
  return;
1567
1182
  }
1568
- const transformDirectiveProxyExport_ = withRollupError(this, transformDirectiveProxyExport);
1569
- const result = transformDirectiveProxyExport_(ast, {
1183
+ const result = withRollupError(this, transformDirectiveProxyExport)(ast, {
1570
1184
  code,
1571
1185
  runtime: (name$1) => `$$ReactClient.createServerReference(${JSON.stringify(getNormalizedId() + "#" + name$1)},$$ReactClient.callServer, undefined, ` + (this.environment.mode === "dev" ? `$$ReactClient.findSourceMapURL,` : "undefined,") + `${JSON.stringify(name$1)})`,
1572
1186
  directive: "use server",
@@ -1735,8 +1349,7 @@ function vitePluginRscCss(rscCssOptions = {}, manager) {
1735
1349
  if (options === false) return false;
1736
1350
  if (options?.filter && !options.filter(filename)) return false;
1737
1351
  if (!/\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)\b/.test(code) || !/\.[tj]sx?$/.test(filename)) return false;
1738
- const result = esModuleLexer.parse(code);
1739
- if (!result[0].some((i) => i.t === 1 && i.n && isCSSRequest(i.n))) return false;
1352
+ if (!esModuleLexer.parse(code)[0].some((i) => i.t === 1 && i.n && isCSSRequest(i.n))) return false;
1740
1353
  return (_name, meta) => !!(meta.isFunction && meta.declName && /^[A-Z]/.test(meta.declName) || meta.defaultExportIdentifierName && /^[A-Z]/.test(meta.defaultExportIdentifierName));
1741
1354
  }
1742
1355
  return [
@@ -1761,6 +1374,19 @@ function vitePluginRscCss(rscCssOptions = {}, manager) {
1761
1374
  };
1762
1375
  }
1763
1376
  },
1377
+ {
1378
+ name: "rsc:rsc-css-self-accept",
1379
+ apply: "serve",
1380
+ transform: {
1381
+ order: "post",
1382
+ handler(_code, id, _options) {
1383
+ if (this.environment.name === "client" && this.environment.mode === "dev" && isCSSRequest(id) && directRequestRE.test(id)) {
1384
+ const mod = this.environment.moduleGraph.getModuleById(id);
1385
+ if (mod && !mod.isSelfAccepting) mod.isSelfAccepting = true;
1386
+ }
1387
+ }
1388
+ }
1389
+ },
1764
1390
  {
1765
1391
  name: "rsc:css-virtual",
1766
1392
  resolveId(source) {
@@ -1836,14 +1462,11 @@ function vitePluginRscCss(rscCssOptions = {}, manager) {
1836
1462
  const importer = parsed.id;
1837
1463
  if (this.environment.mode === "dev") {
1838
1464
  const result = collectCss(server.environments.rsc, importer);
1465
+ for (const file of [importer, ...result.visitedFiles]) this.addWatchFile(file);
1839
1466
  const cssHrefs = result.hrefs.map((href) => href.slice(1));
1840
- const jsHrefs = [`@id/__x00__${toCssVirtual({
1841
- id: importer,
1842
- type: "rsc-browser"
1843
- })}`];
1844
1467
  const deps = assetsURLOfDeps({
1845
1468
  css: cssHrefs,
1846
- js: jsHrefs
1469
+ js: []
1847
1470
  }, manager);
1848
1471
  return generateResourcesCode(serializeValueWithRuntime(deps), manager);
1849
1472
  } else {
@@ -1855,38 +1478,13 @@ function vitePluginRscCss(rscCssOptions = {}, manager) {
1855
1478
  `;
1856
1479
  }
1857
1480
  }
1858
- if (parsed?.type === "rsc-browser") {
1859
- assert(this.environment.name === "client");
1860
- assert(this.environment.mode === "dev");
1861
- const importer = parsed.id;
1862
- const result = collectCss(server.environments.rsc, importer);
1863
- let code = result.ids.map((id$1) => id$1.replace(/^\0/, "")).map((id$1) => `import ${JSON.stringify(id$1)};\n`).join("");
1864
- code += `if (import.meta.hot) { import.meta.hot.accept() }\n`;
1865
- return code;
1866
- }
1867
- },
1868
- hotUpdate(ctx) {
1869
- if (this.environment.name === "rsc") {
1870
- const { server } = manager;
1871
- const mods = collectModuleDependents(ctx.modules);
1872
- for (const mod of mods) if (mod.id) {
1873
- invalidteModuleById(server.environments.rsc, `\0` + toCssVirtual({
1874
- id: mod.id,
1875
- type: "rsc"
1876
- }));
1877
- invalidteModuleById(server.environments.client, `\0` + toCssVirtual({
1878
- id: mod.id,
1879
- type: "rsc-browser"
1880
- }));
1881
- }
1882
- }
1883
1481
  }
1884
1482
  },
1885
1483
  createVirtualPlugin("vite-rsc/remove-duplicate-server-css", async function() {
1886
1484
  assert.equal(this.environment.mode, "dev");
1887
1485
  function removeFn() {
1888
1486
  document.querySelectorAll("link[rel='stylesheet']").forEach((node) => {
1889
- if (node instanceof HTMLElement && node.dataset.precedence?.startsWith("vite-rsc/")) node.remove();
1487
+ if (node instanceof HTMLElement && node.dataset.precedence?.startsWith("vite-rsc/client-reference")) node.remove();
1890
1488
  });
1891
1489
  }
1892
1490
  return `\
@@ -1902,39 +1500,15 @@ export default function RemoveDuplicateServerCss() {
1902
1500
  })
1903
1501
  ];
1904
1502
  }
1905
- function invalidteModuleById(environment, id) {
1906
- const mod = environment.moduleGraph.getModuleById(id);
1907
- if (mod) environment.moduleGraph.invalidateModule(mod);
1908
- return mod;
1909
- }
1910
- function collectModuleDependents(mods) {
1911
- const visited = /* @__PURE__ */ new Set();
1912
- function recurse(mod) {
1913
- if (visited.has(mod)) return;
1914
- visited.add(mod);
1915
- for (const importer of mod.importers) recurse(importer);
1916
- }
1917
- for (const mod of mods) recurse(mod);
1918
- return [...visited];
1919
- }
1920
1503
  function generateResourcesCode(depsCode, manager) {
1921
1504
  const ResourcesFn = (React, deps, RemoveDuplicateServerCss) => {
1922
1505
  return function Resources() {
1923
- return React.createElement(React.Fragment, null, [
1924
- ...deps.css.map((href) => React.createElement("link", {
1925
- key: "css:" + href,
1926
- rel: "stylesheet",
1927
- precedence: "vite-rsc/importer-resources",
1928
- href
1929
- })),
1930
- ...deps.js.map((href) => React.createElement("script", {
1931
- key: "js:" + href,
1932
- type: "module",
1933
- async: true,
1934
- src: href
1935
- })),
1936
- RemoveDuplicateServerCss && React.createElement(RemoveDuplicateServerCss, { key: "remove-duplicate-css" })
1937
- ]);
1506
+ return React.createElement(React.Fragment, null, [...deps.css.map((href) => React.createElement("link", {
1507
+ key: "css:" + href,
1508
+ rel: "stylesheet",
1509
+ precedence: "vite-rsc/importer-resources",
1510
+ href
1511
+ })), RemoveDuplicateServerCss && React.createElement(RemoveDuplicateServerCss, { key: "remove-duplicate-css" })]);
1938
1512
  };
1939
1513
  };
1940
1514
  return `
@@ -1979,4 +1553,4 @@ function __vite_rsc_wrap_css__(value, name) {
1979
1553
  }
1980
1554
 
1981
1555
  //#endregion
1982
- export { getPluginApi, transformHoistInlineDirective, transformRscCssExport, vitePluginRsc, vitePluginRscMinimal };
1556
+ export { getPluginApi, transformRscCssExport, vitePluginRsc, vitePluginRscMinimal };