vite-plugin-react-server 0.3.0 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/README.md +73 -40
  2. package/dist/assertServerCondition.d.ts +2 -0
  3. package/dist/assertServerCondition.d.ts.map +1 -0
  4. package/dist/bin/patch.js +51 -0
  5. package/dist/bin/patch.js.map +1 -0
  6. package/dist/build/createBuildConfig.d.ts +7 -6
  7. package/dist/build/createBuildConfig.d.ts.map +1 -1
  8. package/dist/build/mergeInputs.d.ts +5 -0
  9. package/dist/build/mergeInputs.d.ts.map +1 -0
  10. package/dist/helpers/inputNormalizer.d.ts +6 -0
  11. package/dist/helpers/inputNormalizer.d.ts.map +1 -0
  12. package/dist/helpers/normalizedRelativePath.d.ts +3 -1
  13. package/dist/helpers/normalizedRelativePath.d.ts.map +1 -1
  14. package/dist/helpers/tryManifest.d.ts +10 -3
  15. package/dist/helpers/tryManifest.d.ts.map +1 -1
  16. package/dist/html/createPageLoader.d.ts.map +1 -1
  17. package/dist/index.js +1 -1
  18. package/dist/options.d.ts +13 -8
  19. package/dist/options.d.ts.map +1 -1
  20. package/dist/plugin.d.ts +2 -7
  21. package/dist/plugin.d.ts.map +1 -1
  22. package/dist/react-client/plugin.js +1 -1
  23. package/dist/react-server/plugin.d.ts.map +1 -1
  24. package/dist/react-server/plugin.js +108 -61
  25. package/dist/react-server/plugin.js.map +1 -1
  26. package/dist/src/build/createBuildConfig.js +44 -0
  27. package/dist/src/build/createBuildConfig.js.map +1 -0
  28. package/dist/src/build/mergeInputs.js +16 -0
  29. package/dist/src/build/mergeInputs.js.map +1 -0
  30. package/dist/src/checkFilesExist.js.map +1 -0
  31. package/dist/src/collect-css-manifest.js.map +1 -0
  32. package/dist/src/components.js.map +1 -0
  33. package/dist/src/getEnv.js.map +1 -0
  34. package/dist/src/helpers/inputNormalizer.js +11 -0
  35. package/dist/src/helpers/inputNormalizer.js.map +1 -0
  36. package/dist/src/helpers/normalizedRelativePath.js +34 -0
  37. package/dist/src/helpers/normalizedRelativePath.js.map +1 -0
  38. package/dist/src/helpers/tryManifest.js +27 -0
  39. package/dist/src/helpers/tryManifest.js.map +1 -0
  40. package/dist/{html → src/html}/createPageLoader.js +3 -1
  41. package/dist/src/html/createPageLoader.js.map +1 -0
  42. package/dist/{options.js → src/options.js} +80 -24
  43. package/dist/src/options.js.map +1 -0
  44. package/dist/src/react-server/createHandler.js.map +1 -0
  45. package/dist/src/react-server/createRscStream.js.map +1 -0
  46. package/dist/src/resolvePage.js.map +1 -0
  47. package/dist/src/resolveProps.js.map +1 -0
  48. package/dist/src/worker/createHtmlStream.js +62 -0
  49. package/dist/src/worker/createHtmlStream.js.map +1 -0
  50. package/dist/{worker → src/worker}/createWorker.js +9 -8
  51. package/dist/src/worker/createWorker.js.map +1 -0
  52. package/dist/src/worker/renderPages.js.map +1 -0
  53. package/dist/types.d.ts +7 -2
  54. package/dist/types.d.ts.map +1 -1
  55. package/dist/worker/createWorker.d.ts +8 -1
  56. package/dist/worker/createWorker.d.ts.map +1 -1
  57. package/dist/worker/loader.js +7 -0
  58. package/dist/worker/loader.js.map +1 -0
  59. package/dist/worker/worker.js +112 -0
  60. package/dist/worker/worker.js.map +1 -0
  61. package/package.json +108 -111
  62. package/patches/react-server-dom-esm+0.0.1.patch +14519 -0
  63. package/src/assertServerCondition.ts +13 -0
  64. package/src/build/createBuildConfig.ts +27 -44
  65. package/src/build/mergeInputs.ts +42 -0
  66. package/src/helpers/inputNormalizer.ts +22 -0
  67. package/src/helpers/normalizedRelativePath.ts +25 -25
  68. package/src/helpers/tryManifest.ts +19 -5
  69. package/src/html/createPageLoader.ts +2 -0
  70. package/src/options.ts +119 -47
  71. package/src/plugin.ts +4 -30
  72. package/src/react-server/createSsrHandler.ts +1 -1
  73. package/src/react-server/plugin.ts +116 -56
  74. package/src/types.ts +19 -1
  75. package/src/worker/createWorker.ts +12 -7
  76. package/tsconfig.json +2 -0
  77. package/dist/build/createBuildConfig.js +0 -55
  78. package/dist/build/createBuildConfig.js.map +0 -1
  79. package/dist/checkFilesExist.js.map +0 -1
  80. package/dist/collect-css-manifest.js.map +0 -1
  81. package/dist/components.js.map +0 -1
  82. package/dist/getEnv.js.map +0 -1
  83. package/dist/helpers/normalizedRelativePath.js +0 -31
  84. package/dist/helpers/normalizedRelativePath.js.map +0 -1
  85. package/dist/html/createPageLoader.js.map +0 -1
  86. package/dist/options.js.map +0 -1
  87. package/dist/plugin.js +0 -31
  88. package/dist/plugin.js.map +0 -1
  89. package/dist/react-server/createHandler.js.map +0 -1
  90. package/dist/react-server/createRscStream.js.map +0 -1
  91. package/dist/resolvePage.js.map +0 -1
  92. package/dist/resolveProps.js.map +0 -1
  93. package/dist/transformer/index.js +0 -54
  94. package/dist/transformer/index.js.map +0 -1
  95. package/dist/transformer/preserveDirectives.js +0 -72
  96. package/dist/transformer/preserveDirectives.js.map +0 -1
  97. package/dist/transformer/transformer.js +0 -80
  98. package/dist/transformer/transformer.js.map +0 -1
  99. package/dist/worker/createWorker.js.map +0 -1
  100. package/dist/worker/renderPages.js.map +0 -1
  101. /package/dist/{checkFilesExist.js → src/checkFilesExist.js} +0 -0
  102. /package/dist/{collect-css-manifest.js → src/collect-css-manifest.js} +0 -0
  103. /package/dist/{components.js → src/components.js} +0 -0
  104. /package/dist/{getEnv.js → src/getEnv.js} +0 -0
  105. /package/dist/{react-server → src/react-server}/createHandler.js +0 -0
  106. /package/dist/{react-server → src/react-server}/createRscStream.js +0 -0
  107. /package/dist/{resolvePage.js → src/resolvePage.js} +0 -0
  108. /package/dist/{resolveProps.js → src/resolveProps.js} +0 -0
  109. /package/dist/{worker → src/worker}/renderPages.js +0 -0
@@ -1,54 +0,0 @@
1
- import { normalizePath } from "vite";
2
- import { DEFAULT_CONFIG } from "../options.js";
3
- import { createRscTransformer } from "./transformer.js";
4
- function viteReactClientTransformPlugin(options) {
5
- if (process.env["NODE_OPTIONS"]?.match(/--conditions=react-server/)) {
6
- console.log("react-server");
7
- } else {
8
- throw new Error('react-server condition not found, set NODE_OPTIONS="--conditions react-server"');
9
- }
10
- const projectRoot = process.cwd();
11
- const include = DEFAULT_CONFIG.FILE_REGEX;
12
- const exclude = options?.exclude;
13
- let transform;
14
- return {
15
- name: "vite:react-stream-transformer",
16
- enforce: "pre",
17
- configResolved(config) {
18
- transform = createRscTransformer({
19
- moduleId: moduleIdDefault({
20
- projectRoot,
21
- output: {
22
- dir: config.build?.outDir ?? DEFAULT_CONFIG.BUILD.server
23
- },
24
- isProduction: config.isProduction
25
- })
26
- }).transform;
27
- },
28
- transform(code, id, opts) {
29
- if (!matchPattern(id, include) || exclude) {
30
- return null;
31
- }
32
- const directiveMatch = code.startsWith('"use client"') || code.startsWith("'use client'");
33
- if (!directiveMatch) return null;
34
- return transform(code, id, opts);
35
- }
36
- };
37
- }
38
- const moduleIdDefault = ({
39
- projectRoot,
40
- output: _,
41
- isProduction
42
- }) => (moduleId) => {
43
- const normalized = normalizePath(moduleId);
44
- const noRoot = normalized.startsWith(projectRoot) ? normalized.slice(projectRoot.length) : normalized;
45
- if (!isProduction) {
46
- return noRoot;
47
- }
48
- return noRoot.replace(DEFAULT_CONFIG.FILE_REGEX, ".js");
49
- };
50
- const matchPattern = (file, pattern) => Array.isArray(pattern) ? pattern.some((p) => file.match(p)) : file.match(pattern);
51
- export {
52
- viteReactClientTransformPlugin
53
- };
54
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sources":["../../src/transformer/index.ts"],"sourcesContent":["import type { Plugin } from \"vite\";\nimport { normalizePath } from \"vite\";\nimport { DEFAULT_CONFIG } from \"../options.js\";\nimport { createRscTransformer } from \"./transformer.js\";\nimport type { ViteReactClientTransformOptions } from \"./types.js\";\n\n\n/**\n * Plugin for transforming React Client Components.\n *\n * Core responsibilities:\n * 1. Detects \"use client\" directives\n * 2. Transforms client components for RSC boundaries\n * 3. Adds client reference metadata for RSC\n *\n * When a component is marked with \"use client\", it:\n * - Gets transformed into a client reference\n * - Maintains module ID for RSC boundaries\n * - Preserves class/function behavior\n *\n * @example\n * ```ts\n * export default defineConfig({\n * plugins: [\n * viteReactClientTransformPlugin({\n * projectRoot: process.cwd(),\n * })\n * ]\n * });\n * ```\n */\n\nexport function viteReactClientTransformPlugin(\n options?: ViteReactClientTransformOptions\n): Plugin {\n if(process.env['NODE_OPTIONS']?.match(/--conditions=react-server/)) {\n console.log('react-server')\n } else {\n throw new Error('react-server condition not found, set NODE_OPTIONS=\"--conditions react-server\"')\n }\n const projectRoot = options?.projectRoot || process.cwd();\n const include = options?.include || DEFAULT_CONFIG.FILE_REGEX;\n const exclude = options?.exclude;\n let transform: any;\n // get the file we are imported from (parent)\n\n return {\n name: \"vite:react-stream-transformer\",\n enforce: \"pre\",\n\n configResolved(config) {\n transform = createRscTransformer({\n moduleId:\n options?.moduleId ||\n moduleIdDefault({\n projectRoot: projectRoot,\n output: {\n dir: config.build?.outDir ?? DEFAULT_CONFIG.BUILD.server,\n },\n isProduction: config.isProduction,\n }),\n }).transform;\n },\n\n transform(code: string, id: string, opts) {\n // Skip if file doesn't match patterns\n if (\n !matchPattern(id, include) ||\n (exclude && matchPattern(id, exclude))\n ) {\n return null;\n }\n\n // Look for use client directive at start of file (no exceptions)\n const directiveMatch =\n code.startsWith('\"use client\"') || code.startsWith(\"'use client'\");\n if (!directiveMatch) return null;\n\n // Transform client components\n return transform(code, id, opts);\n },\n };\n}\n\nconst moduleIdDefault =\n ({\n projectRoot,\n output: _,\n isProduction,\n }: {\n isProduction: boolean;\n projectRoot: string;\n output: { dir: string };\n }) =>\n (moduleId: string) => {\n const normalized = normalizePath(moduleId);\n const noRoot = normalized.startsWith(projectRoot)\n ? normalized.slice(projectRoot.length)\n : normalized;\n if (!isProduction) {\n return noRoot;\n }\n return noRoot.replace(DEFAULT_CONFIG.FILE_REGEX, \".js\");\n };\n\nconst matchPattern = (\n file: string,\n pattern: string | RegExp | (string | RegExp)[]\n) =>\n Array.isArray(pattern)\n ? pattern.some((p) => file.match(p as RegExp))\n : file.match(pattern as RegExp);\n"],"names":[],"mappings":";;;AAgCO,SAAS,+BACd,SACQ;AACR,MAAG,QAAQ,IAAI,cAAc,GAAG,MAAM,2BAA2B,GAAG;AAClE,YAAQ,IAAI,cAAc;AAAA,EAAA,OACrB;AACC,UAAA,IAAI,MAAM,gFAAgF;AAAA,EAAA;AAElG,QAAM,cAAsC,QAAQ,IAAI;AAClD,QAAA,UAA8B,eAAe;AACnD,QAAM,UAAU,SAAS;AACrB,MAAA;AAGG,SAAA;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IAET,eAAe,QAAQ;AACrB,kBAAY,qBAAqB;AAAA,QAC/B,UAEE,gBAAgB;AAAA,UACd;AAAA,UACA,QAAQ;AAAA,YACN,KAAK,OAAO,OAAO,UAAU,eAAe,MAAM;AAAA,UACpD;AAAA,UACA,cAAc,OAAO;AAAA,QACtB,CAAA;AAAA,MACJ,CAAA,EAAE;AAAA,IACL;AAAA,IAEA,UAAU,MAAc,IAAY,MAAM;AAGtC,UAAA,CAAC,aAAa,IAAI,OAAO,KACxB,SACD;AACO,eAAA;AAAA,MAAA;AAIT,YAAM,iBACJ,KAAK,WAAW,cAAc,KAAK,KAAK,WAAW,cAAc;AAC/D,UAAA,CAAC,eAAuB,QAAA;AAGrB,aAAA,UAAU,MAAM,IAAI,IAAI;AAAA,IAAA;AAAA,EAEnC;AACF;AAEA,MAAM,kBACJ,CAAC;AAAA,EACC;AAAA,EACA,QAAQ;AAAA,EACR;AACF,MAKA,CAAC,aAAqB;AACd,QAAA,aAAa,cAAc,QAAQ;AACnC,QAAA,SAAS,WAAW,WAAW,WAAW,IAC5C,WAAW,MAAM,YAAY,MAAM,IACnC;AACJ,MAAI,CAAC,cAAc;AACV,WAAA;AAAA,EAAA;AAET,SAAO,OAAO,QAAQ,eAAe,YAAY,KAAK;AACxD;AAEF,MAAM,eAAe,CACnB,MACA,YAEA,MAAM,QAAQ,OAAO,IACjB,QAAQ,KAAK,CAAC,MAAM,KAAK,MAAM,CAAW,CAAC,IAC3C,KAAK,MAAM,OAAiB;"}
@@ -1,72 +0,0 @@
1
- import { SourceMapGenerator } from "source-map";
2
- import { DEFAULT_CONFIG } from "../options.js";
3
- const REACT_DIRECTIVES = /* @__PURE__ */ new Set(["use client", "use server", "use no-memo"]);
4
- function preserveDirectives(options) {
5
- const meta = {
6
- directives: {}
7
- };
8
- const fileRegex = DEFAULT_CONFIG.FILE_REGEX;
9
- return {
10
- name: "react-preserve-directives",
11
- transform: {
12
- order: "post",
13
- handler(code, id) {
14
- if (!fileRegex.test(id)) {
15
- return null;
16
- }
17
- const ast = this.parse(code);
18
- if (ast.type !== "Program") {
19
- return null;
20
- }
21
- let hasDirectives = false;
22
- const directives = /* @__PURE__ */ new Set();
23
- for (const node of ast.body) {
24
- if (node.type !== "ExpressionStatement") {
25
- break;
26
- }
27
- if (node.expression.type === "Literal" && typeof node.expression.value === "string" && REACT_DIRECTIVES.has(node.expression.value)) {
28
- directives.add(node.expression.value);
29
- hasDirectives = true;
30
- }
31
- }
32
- if (!hasDirectives) return null;
33
- meta.directives[id] = directives;
34
- const map = new SourceMapGenerator({
35
- file: id,
36
- sourceRoot: ""
37
- });
38
- map.setSourceContent(id, code);
39
- return {
40
- code,
41
- map: map.toString(),
42
- meta: { directives: Array.from(directives) }
43
- };
44
- }
45
- },
46
- renderChunk(code, chunk) {
47
- const moduleIds = chunk.moduleIds;
48
- const chunkDirectives = moduleIds.map((id) => meta.directives[id]).filter((dirs) => !!dirs).reduce((acc, dirs) => {
49
- dirs.forEach((d) => acc.add(d));
50
- return acc;
51
- }, /* @__PURE__ */ new Set());
52
- if (chunkDirectives.size) {
53
- const directiveCode = Array.from(chunkDirectives).map((d) => `"${d}";`).join("\n");
54
- return {
55
- code: `${directiveCode}
56
- ${code}`
57
- };
58
- }
59
- return null;
60
- },
61
- onLog(level, log) {
62
- if (log.code === "MODULE_LEVEL_DIRECTIVE" && level === "warn") {
63
- return false;
64
- }
65
- return this.warn(log);
66
- }
67
- };
68
- }
69
- export {
70
- preserveDirectives
71
- };
72
- //# sourceMappingURL=preserveDirectives.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"preserveDirectives.js","sources":["../../src/transformer/preserveDirectives.ts"],"sourcesContent":["import type { Node } from \"estree\";\nimport type { Plugin } from \"rollup\";\nimport { SourceMapGenerator } from \"source-map\";\nimport { DEFAULT_CONFIG } from \"../options.js\";\nimport type { Options } from \"../types.js\";\n\nconst REACT_DIRECTIVES = new Set([\"use client\", \"use server\", \"use no-memo\"]);\n\ninterface PreserveDirectiveMeta {\n directives: Record<string, Set<string>>;\n}\n\nexport function preserveDirectives(options?: Pick<Options, \"include\">): Plugin {\n const meta: PreserveDirectiveMeta = {\n directives: {},\n };\n const fileRegex = options?.include ?? DEFAULT_CONFIG.FILE_REGEX;\n\n return {\n name: \"react-preserve-directives\",\n transform: {\n order: \"post\",\n handler(code, id) {\n if (!fileRegex.test(id)) {\n return null;\n }\n\n const ast = this.parse(code) as Node;\n if (ast.type !== \"Program\") {\n return null;\n }\n\n let hasDirectives = false;\n const directives = new Set<string>();\n\n // Look for directives at start of file\n for (const node of ast.body) {\n if (node.type !== \"ExpressionStatement\") {\n break;\n }\n\n if (\n node.expression.type === \"Literal\" &&\n typeof node.expression.value === \"string\" &&\n REACT_DIRECTIVES.has(node.expression.value)\n ) {\n directives.add(node.expression.value);\n hasDirectives = true;\n }\n }\n\n if (!hasDirectives) return null;\n\n meta.directives[id] = directives;\n\n // Generate source map\n const map = new SourceMapGenerator({\n file: id,\n sourceRoot: \"\",\n });\n map.setSourceContent(id, code);\n\n return {\n code,\n map: map.toString(),\n meta: { directives: Array.from(directives) },\n };\n },\n },\n\n renderChunk(code, chunk) {\n const moduleIds = chunk.moduleIds;\n const chunkDirectives = moduleIds\n .map((id) => meta.directives[id])\n .filter((dirs): dirs is Set<string> => !!dirs)\n .reduce((acc, dirs) => {\n dirs.forEach((d) => acc.add(d));\n return acc;\n }, new Set<string>());\n\n if (chunkDirectives.size) {\n const directiveCode = Array.from(chunkDirectives)\n .map((d) => `\"${d}\";`)\n .join(\"\\n\");\n return {\n code: `${directiveCode}\\n${code}`,\n };\n }\n\n return null;\n },\n\n onLog(level, log) {\n if (log.code === \"MODULE_LEVEL_DIRECTIVE\" && level === \"warn\") {\n return false;\n }\n return this.warn(log);\n },\n };\n}\n"],"names":[],"mappings":";;AAMA,MAAM,mBAAuB,oBAAA,IAAI,CAAC,cAAc,cAAc,aAAa,CAAC;AAMrE,SAAS,mBAAmB,SAA4C;AAC7E,QAAM,OAA8B;AAAA,IAClC,YAAY,CAAA;AAAA,EACd;AACM,QAAA,YAAgC,eAAe;AAE9C,SAAA;AAAA,IACL,MAAM;AAAA,IACN,WAAW;AAAA,MACT,OAAO;AAAA,MACP,QAAQ,MAAM,IAAI;AAChB,YAAI,CAAC,UAAU,KAAK,EAAE,GAAG;AAChB,iBAAA;AAAA,QAAA;AAGH,cAAA,MAAM,KAAK,MAAM,IAAI;AACvB,YAAA,IAAI,SAAS,WAAW;AACnB,iBAAA;AAAA,QAAA;AAGT,YAAI,gBAAgB;AACd,cAAA,iCAAiB,IAAY;AAGxB,mBAAA,QAAQ,IAAI,MAAM;AACvB,cAAA,KAAK,SAAS,uBAAuB;AACvC;AAAA,UAAA;AAGF,cACE,KAAK,WAAW,SAAS,aACzB,OAAO,KAAK,WAAW,UAAU,YACjC,iBAAiB,IAAI,KAAK,WAAW,KAAK,GAC1C;AACW,uBAAA,IAAI,KAAK,WAAW,KAAK;AACpB,4BAAA;AAAA,UAAA;AAAA,QAClB;AAGE,YAAA,CAAC,cAAsB,QAAA;AAEtB,aAAA,WAAW,EAAE,IAAI;AAGhB,cAAA,MAAM,IAAI,mBAAmB;AAAA,UACjC,MAAM;AAAA,UACN,YAAY;AAAA,QAAA,CACb;AACG,YAAA,iBAAiB,IAAI,IAAI;AAEtB,eAAA;AAAA,UACL;AAAA,UACA,KAAK,IAAI,SAAS;AAAA,UAClB,MAAM,EAAE,YAAY,MAAM,KAAK,UAAU,EAAE;AAAA,QAC7C;AAAA,MAAA;AAAA,IAEJ;AAAA,IAEA,YAAY,MAAM,OAAO;AACvB,YAAM,YAAY,MAAM;AAClB,YAAA,kBAAkB,UACrB,IAAI,CAAC,OAAO,KAAK,WAAW,EAAE,CAAC,EAC/B,OAAO,CAAC,SAA8B,CAAC,CAAC,IAAI,EAC5C,OAAO,CAAC,KAAK,SAAS;AACrB,aAAK,QAAQ,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC;AACvB,eAAA;AAAA,MAAA,GACF,oBAAA,IAAA,CAAa;AAEtB,UAAI,gBAAgB,MAAM;AACxB,cAAM,gBAAgB,MAAM,KAAK,eAAe,EAC7C,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,EACpB,KAAK,IAAI;AACL,eAAA;AAAA,UACL,MAAM,GAAG,aAAa;AAAA,EAAK,IAAI;AAAA,QACjC;AAAA,MAAA;AAGK,aAAA;AAAA,IACT;AAAA,IAEA,MAAM,OAAO,KAAK;AAChB,UAAI,IAAI,SAAS,4BAA4B,UAAU,QAAQ;AACtD,eAAA;AAAA,MAAA;AAEF,aAAA,KAAK,KAAK,GAAG;AAAA,IAAA;AAAA,EAExB;AACF;"}
@@ -1,80 +0,0 @@
1
- import { SourceMapGenerator } from "source-map";
2
- function createRscTransformer(options) {
3
- return {
4
- name: "vite:react-stream-transformer",
5
- enforce: "post",
6
- async transform(code, path, { ssr }) {
7
- try {
8
- let transformedCode = code;
9
- const directiveMatch = code.match(/^["']use client["'];?/);
10
- const moduleId = options.moduleId(path, ssr);
11
- console.log("[RSC Transform] Module path transformation:", {
12
- original: path,
13
- transformed: moduleId
14
- });
15
- const exportMatches = Array.from(
16
- code.matchAll(/export\s+(?:const|let|var|function|class)\s+(\w+)/g)
17
- );
18
- if (!exportMatches.length) {
19
- console.warn(`[RSC] No exports found in client component: ${path}`);
20
- return null;
21
- }
22
- for (const [fullMatch, exportName] of exportMatches) {
23
- if (!exportName) {
24
- console.warn(`[RSC] Invalid export in client component: ${path}`);
25
- continue;
26
- }
27
- const isClass = fullMatch.includes("class");
28
- transformedCode = transformedCode.replace(
29
- fullMatch,
30
- fullMatch.replace("export ", "")
31
- );
32
- if (!directiveMatch || directiveMatch.index !== 0) {
33
- transformedCode += `
34
- const ${exportName}Ref = Object.defineProperties(
35
- ${isClass ? `class extends ${exportName} {
36
- constructor(...args) { super(...args); }
37
- }` : `function(...args) { return ${exportName}.apply(null, args); }`},
38
- {
39
- $$typeof: { value: Symbol.for("react.server.reference") },
40
- $$id: { value: ${JSON.stringify(moduleId + "#" + exportName)} },
41
- $$filepath: { value: ${JSON.stringify(path)} },
42
- $$async: { value: true }
43
- }
44
- );
45
- export { ${exportName}Ref as ${exportName} };
46
- `;
47
- } else {
48
- transformedCode += `
49
- const ${exportName}Ref = Object.defineProperties(
50
- ${isClass ? `class extends ${exportName} {
51
- constructor(...args) { super(...args); }
52
- }` : `function(...args) { return ${exportName}.apply(null, args); }`},
53
- {
54
- $$typeof: { value: Symbol.for("react.client.reference") },
55
- $$id: { value: ${JSON.stringify(moduleId + "#" + exportName)} },
56
- $$filepath: { value: ${JSON.stringify(path)} }
57
- }
58
- );
59
- export { ${exportName}Ref as ${exportName} };
60
- `;
61
- }
62
- }
63
- return {
64
- code: transformedCode,
65
- map: new SourceMapGenerator({ file: path }).toString()
66
- };
67
- } catch (error) {
68
- console.error(
69
- `[RSC] Error transforming client component: ${path}`,
70
- error
71
- );
72
- throw error;
73
- }
74
- }
75
- };
76
- }
77
- export {
78
- createRscTransformer
79
- };
80
- //# sourceMappingURL=transformer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"transformer.js","sources":["../../src/transformer/transformer.ts"],"sourcesContent":["import { SourceMapGenerator } from \"source-map\";\nimport type { TransformerOptions } from \"./types.js\";\n\nexport function createRscTransformer(options: TransformerOptions) {\n return {\n name: \"vite:react-stream-transformer\",\n enforce: \"post\" as const,\n\n async transform(\n code: string,\n path: string,\n { ssr }: { inMap: null | string; ssr: boolean }\n ) {\n try {\n let transformedCode = code;\n const directiveMatch = code.match(/^[\"']use client[\"'];?/);\n const moduleId = options.moduleId(path, ssr);\n\n // Log the path transformation\n console.log(\"[RSC Transform] Module path transformation:\", {\n original: path,\n transformed: moduleId,\n });\n\n // Find all named exports\n const exportMatches = Array.from(\n code.matchAll(/export\\s+(?:const|let|var|function|class)\\s+(\\w+)/g)\n );\n\n if (!exportMatches.length) {\n console.warn(`[RSC] No exports found in client component: ${path}`);\n return null;\n }\n\n // Transform each export\n for (const [fullMatch, exportName] of exportMatches) {\n if (!exportName) {\n console.warn(`[RSC] Invalid export in client component: ${path}`);\n continue;\n }\n\n const isClass = fullMatch.includes(\"class\");\n\n // Remove export keyword\n transformedCode = transformedCode.replace(\n fullMatch,\n fullMatch.replace(\"export \", \"\")\n );\n\n if (!directiveMatch || directiveMatch.index !== 0) {\n // Server component\n transformedCode += `\nconst ${exportName}Ref = Object.defineProperties(\n ${\n isClass\n ? `class extends ${exportName} {\n constructor(...args) { super(...args); }\n }`\n : `function(...args) { return ${exportName}.apply(null, args); }`\n },\n {\n $$typeof: { value: Symbol.for(\"react.server.reference\") },\n $$id: { value: ${JSON.stringify(moduleId + \"#\" + exportName)} },\n $$filepath: { value: ${JSON.stringify(path)} },\n $$async: { value: true }\n }\n);\nexport { ${exportName}Ref as ${exportName} };\n`;\n } else {\n // Client component\n transformedCode += `\nconst ${exportName}Ref = Object.defineProperties(\n ${\n isClass\n ? `class extends ${exportName} {\n constructor(...args) { super(...args); }\n }`\n : `function(...args) { return ${exportName}.apply(null, args); }`\n },\n {\n $$typeof: { value: Symbol.for(\"react.client.reference\") },\n $$id: { value: ${JSON.stringify(moduleId + \"#\" + exportName)} },\n $$filepath: { value: ${JSON.stringify(path)} }\n }\n);\nexport { ${exportName}Ref as ${exportName} };\n`;\n }\n }\n\n return {\n code: transformedCode,\n map: new SourceMapGenerator({ file: path }).toString(),\n };\n } catch (error) {\n console.error(\n `[RSC] Error transforming client component: ${path}`,\n error\n );\n throw error;\n }\n },\n };\n}\n\n/**\n * transformedCode += `\nconst ${exportName}Ref = Object.defineProperties(\n ${\n isClass\n ? `class extends ${exportName} {\n constructor(...args) { super(...args); }\n }`\n : `function(...args) { return ${exportName}.apply(null, args); }`\n },\n {\n $$typeof: { value: Symbol.for(\"react.client.reference\") },\n $$id: { value: ${JSON.stringify(moduleId + \"#\" + exportName)} }\n }\n);\nexport { ${exportName}Ref as ${exportName} };`;\n */\n"],"names":[],"mappings":";AAGO,SAAS,qBAAqB,SAA6B;AACzD,SAAA;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IAET,MAAM,UACJ,MACA,MACA,EAAE,OACF;AACI,UAAA;AACF,YAAI,kBAAkB;AAChB,cAAA,iBAAiB,KAAK,MAAM,uBAAuB;AACzD,cAAM,WAAW,QAAQ,SAAS,MAAM,GAAG;AAG3C,gBAAQ,IAAI,+CAA+C;AAAA,UACzD,UAAU;AAAA,UACV,aAAa;AAAA,QAAA,CACd;AAGD,cAAM,gBAAgB,MAAM;AAAA,UAC1B,KAAK,SAAS,oDAAoD;AAAA,QACpE;AAEI,YAAA,CAAC,cAAc,QAAQ;AACjB,kBAAA,KAAK,+CAA+C,IAAI,EAAE;AAC3D,iBAAA;AAAA,QAAA;AAIT,mBAAW,CAAC,WAAW,UAAU,KAAK,eAAe;AACnD,cAAI,CAAC,YAAY;AACP,oBAAA,KAAK,6CAA6C,IAAI,EAAE;AAChE;AAAA,UAAA;AAGI,gBAAA,UAAU,UAAU,SAAS,OAAO;AAG1C,4BAAkB,gBAAgB;AAAA,YAChC;AAAA,YACA,UAAU,QAAQ,WAAW,EAAE;AAAA,UACjC;AAEA,cAAI,CAAC,kBAAkB,eAAe,UAAU,GAAG;AAE9B,+BAAA;AAAA,QACvB,UAAU;AAAA,IAEd,UACI,iBAAiB,UAAU;AAAA;AAAA,aAG3B,8BAA8B,UAAU,uBAC9C;AAAA;AAAA;AAAA,qBAGmB,KAAK,UAAU,WAAW,MAAM,UAAU,CAAC;AAAA,2BACrC,KAAK,UAAU,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA,WAIpC,UAAU,UAAU,UAAU;AAAA;AAAA,UAAA,OAExB;AAEc,+BAAA;AAAA,QACvB,UAAU;AAAA,IAEd,UACI,iBAAiB,UAAU;AAAA;AAAA,aAG3B,8BAA8B,UAAU,uBAC9C;AAAA;AAAA;AAAA,qBAGmB,KAAK,UAAU,WAAW,MAAM,UAAU,CAAC;AAAA,2BACrC,KAAK,UAAU,IAAI,CAAC;AAAA;AAAA;AAAA,WAGpC,UAAU,UAAU,UAAU;AAAA;AAAA,UAAA;AAAA,QAE/B;AAGK,eAAA;AAAA,UACL,MAAM;AAAA,UACN,KAAK,IAAI,mBAAmB,EAAE,MAAM,KAAK,CAAC,EAAE,SAAS;AAAA,QACvD;AAAA,eACO,OAAO;AACN,gBAAA;AAAA,UACN,8CAA8C,IAAI;AAAA,UAClD;AAAA,QACF;AACM,cAAA;AAAA,MAAA;AAAA,IACR;AAAA,EAEJ;AACF;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"createWorker.js","sources":["../../src/worker/createWorker.ts"],"sourcesContent":["import { resolve } from \"node:path\";\nimport { Worker } from \"node:worker_threads\";\n\nexport async function createWorker(\n projectRoot: string,\n outDir: string,\n fileName: string,\n mode: \"production\" | \"development\"\n) {\n console.log(\"[Worker] Creating worker...\");\n const workerPath = resolve(projectRoot, outDir, fileName);\n console.log(\"[Worker] Worker path:\", workerPath);\n\n try {\n const worker = new Worker(workerPath, {\n env: {\n NODE_OPTIONS: \"\",\n NODE_PATH: resolve(projectRoot, \"node_modules\"),\n NODE_ENV: mode,\n },\n });\n worker.setMaxListeners(1000);\n\n // Wait for worker to be ready\n await new Promise<void>((resolve, reject) => {\n worker.once(\"message\", (message) => {\n if (message.type === \"READY\") {\n resolve();\n }\n });\n worker.once(\"error\", reject);\n });\n\n return worker;\n } catch (error) {\n console.error(\"[Worker] Startup error:\", error);\n throw error;\n }\n}\n"],"names":["resolve"],"mappings":";;AAGA,eAAsB,aACpB,aACA,QACA,UACA,MACA;AACA,UAAQ,IAAI,6BAA6B;AACzC,QAAM,aAAa,QAAQ,aAAa,QAAQ,QAAQ;AAChD,UAAA,IAAI,yBAAyB,UAAU;AAE3C,MAAA;AACI,UAAA,SAAS,IAAI,OAAO,YAAY;AAAA,MACpC,KAAK;AAAA,QACH,cAAc;AAAA,QACd,WAAW,QAAQ,aAAa,cAAc;AAAA,QAC9C,UAAU;AAAA,MAAA;AAAA,IACZ,CACD;AACD,WAAO,gBAAgB,GAAI;AAG3B,UAAM,IAAI,QAAc,CAACA,UAAS,WAAW;AACpC,aAAA,KAAK,WAAW,CAAC,YAAY;AAC9B,YAAA,QAAQ,SAAS,SAAS;AAC5BA,mBAAQ;AAAA,QAAA;AAAA,MACV,CACD;AACM,aAAA,KAAK,SAAS,MAAM;AAAA,IAAA,CAC5B;AAEM,WAAA;AAAA,WACA,OAAO;AACN,YAAA,MAAM,2BAA2B,KAAK;AACxC,UAAA;AAAA,EAAA;AAEV;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"renderPages.js","sources":["../../src/worker/renderPages.ts"],"sourcesContent":["import { join, resolve as resolvePath } from \"node:path\";\nimport { Transform } from \"node:stream\";\nimport type { Worker } from \"node:worker_threads\";\nimport type { PipeableStreamOptions } from \"react-dom/server.node\";\nimport { createHandler } from \"../react-server/createHandler.js\";\nimport type { StreamPluginOptions } from \"../types.js\";\nimport type {\n WorkerRscChunkMessage,\n WorkerRscEndMessage,\n} from \"./types.js\";\n\ntype RenderPagesOptions = {\n pluginOptions: Required<\n Pick<\n StreamPluginOptions,\n \"moduleBase\" | \"moduleBasePath\" | \"moduleBaseURL\" | \"projectRoot\"\n >\n > &\n Pick<\n StreamPluginOptions,\n \"Page\" | \"props\" | \"build\" | \"Html\" | \"pageExportName\" | \"propsExportName\"\n >;\n outDir: string;\n manifest: Record<string, { file: string }>;\n worker: Worker;\n pipableStreamOptions?: PipeableStreamOptions;\n loader: (id: string) => Promise<Record<string, any>>;\n onCssFile?: (path: string) => void;\n clientCss?: string[];\n};\n\nexport async function renderPages(\n routes: string[],\n options: RenderPagesOptions\n) {\n const destinationRoot = resolvePath(\n options.pluginOptions.projectRoot,\n options.outDir\n );\n const failedRoutes = new Map<string, Error>();\n const moduleBasePath = join(\n destinationRoot,\n options.pluginOptions.moduleBasePath\n );\n const moduleBaseURL = options.pluginOptions.moduleBaseURL;\n\n const htmlRoot = resolvePath(\n options.pluginOptions.projectRoot,\n options.pluginOptions.build?.client ?? options.outDir\n );\n const filesOutputted: string[] = [];\n\n options.worker.on(\"message\", (msg) => {\n switch (msg.type) {\n case \"ERROR\":\n console.error(\"[RenderPages] Worker error:\", msg.error);\n break;\n case \"HTML\":\n filesOutputted.push(msg.outputPath);\n if (filesOutputted.length === routes.length) {\n renderPromises.push(\n new Promise<void>((resolve) => {\n options.worker.removeAllListeners();\n options.worker.terminate();\n resolve();\n })\n );\n }\n break;\n default:\n break;\n }\n });\n const pipableStreamOptions = options.pipableStreamOptions ?? {};\n\n // Create promises for each route in the batch\n const renderPromises = routes.map(async (route) => {\n try {\n // Wait for handler creation\n const result = await createHandler(route, options.pluginOptions, {\n loader: options.loader,\n manifest: options.manifest,\n });\n\n if (result.type !== \"success\") {\n return;\n }\n const htmlOutputPath = join(htmlRoot, route, \"index.html\");\n\n // Create a promise that resolves when the worker completes\n await new Promise<void>((resolve, reject) => {\n // Pipe RSC stream to worker\n const transform = new Transform({\n transform(chunk, _encoding, callback) {\n // Send raw chunk\n options.worker.postMessage({\n type: \"RSC_CHUNK\",\n id: route,\n chunk: chunk,\n moduleBasePath,\n moduleBaseURL,\n htmlOutputPath: htmlOutputPath,\n outDir: options.outDir,\n pipableStreamOptions,\n } satisfies WorkerRscChunkMessage);\n callback();\n },\n flush(callback) {\n options.worker.postMessage({\n type: \"RSC_END\",\n id: route,\n } satisfies WorkerRscEndMessage);\n callback();\n },\n });\n\n // Listen for worker response for this route\n const messageHandler = (msg: any) => {\n if (msg.route === route) {\n if (msg.type === \"ERROR\") {\n options.worker.removeListener(\"message\", messageHandler);\n reject(new Error(msg.error));\n } else if (msg.type === \"HTML\") {\n options.worker.removeListener(\"message\", messageHandler);\n resolve();\n }\n }\n };\n\n options.worker.on(\"message\", messageHandler);\n result.stream?.pipe(transform);\n });\n } catch (error) {\n failedRoutes.set(route, error as Error);\n }\n });\n\n // Wait for all routes to complete\n await Promise.all(renderPromises);\n\n if (failedRoutes.size > 0) {\n console.error(\"[vite-react-stream] Failed routes:\", failedRoutes);\n }\n}\n"],"names":["resolvePath","resolve"],"mappings":";;;AA+BsB,eAAA,YACpB,QACA,SACA;AACA,QAAM,kBAAkBA;AAAAA,IACtB,QAAQ,cAAc;AAAA,IACtB,QAAQ;AAAA,EACV;AACM,QAAA,mCAAmB,IAAmB;AAC5C,QAAM,iBAAiB;AAAA,IACrB;AAAA,IACA,QAAQ,cAAc;AAAA,EACxB;AACM,QAAA,gBAAgB,QAAQ,cAAc;AAE5C,QAAM,WAAWA;AAAAA,IACf,QAAQ,cAAc;AAAA,IACtB,QAAQ,cAAc,OAAO,UAAU,QAAQ;AAAA,EACjD;AACA,QAAM,iBAA2B,CAAC;AAElC,UAAQ,OAAO,GAAG,WAAW,CAAC,QAAQ;AACpC,YAAQ,IAAI,MAAM;AAAA,MAChB,KAAK;AACK,gBAAA,MAAM,+BAA+B,IAAI,KAAK;AACtD;AAAA,MACF,KAAK;AACY,uBAAA,KAAK,IAAI,UAAU;AAC9B,YAAA,eAAe,WAAW,OAAO,QAAQ;AAC5B,yBAAA;AAAA,YACb,IAAI,QAAc,CAACC,aAAY;AAC7B,sBAAQ,OAAO,mBAAmB;AAClC,sBAAQ,OAAO,UAAU;AACjB,cAAAA,SAAA;AAAA,YACT,CAAA;AAAA,UACH;AAAA,QAAA;AAEF;AAAA,IAEA;AAAA,EACJ,CACD;AACK,QAAA,uBAAuB,QAAQ,wBAAwB,CAAC;AAG9D,QAAM,iBAAiB,OAAO,IAAI,OAAO,UAAU;AAC7C,QAAA;AAEF,YAAM,SAAS,MAAM,cAAc,OAAO,QAAQ,eAAe;AAAA,QAC/D,QAAQ,QAAQ;AAAA,QAChB,UAAU,QAAQ;AAAA,MAAA,CACnB;AAEG,UAAA,OAAO,SAAS,WAAW;AAC7B;AAAA,MAAA;AAEF,YAAM,iBAAiB,KAAK,UAAU,OAAO,YAAY;AAGzD,YAAM,IAAI,QAAc,CAACA,UAAS,WAAW;AAErC,cAAA,YAAY,IAAI,UAAU;AAAA,UAC9B,UAAU,OAAO,WAAW,UAAU;AAEpC,oBAAQ,OAAO,YAAY;AAAA,cACzB,MAAM;AAAA,cACN,IAAI;AAAA,cACJ;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA,QAAQ,QAAQ;AAAA,cAChB;AAAA,YAAA,CAC+B;AACxB,qBAAA;AAAA,UACX;AAAA,UACA,MAAM,UAAU;AACd,oBAAQ,OAAO,YAAY;AAAA,cACzB,MAAM;AAAA,cACN,IAAI;AAAA,YAAA,CACyB;AACtB,qBAAA;AAAA,UAAA;AAAA,QACX,CACD;AAGK,cAAA,iBAAiB,CAAC,QAAa;AAC/B,cAAA,IAAI,UAAU,OAAO;AACnB,gBAAA,IAAI,SAAS,SAAS;AAChB,sBAAA,OAAO,eAAe,WAAW,cAAc;AACvD,qBAAO,IAAI,MAAM,IAAI,KAAK,CAAC;AAAA,YAAA,WAClB,IAAI,SAAS,QAAQ;AACtB,sBAAA,OAAO,eAAe,WAAW,cAAc;AAC/C,cAAAA,SAAA;AAAA,YAAA;AAAA,UACV;AAAA,QAEJ;AAEQ,gBAAA,OAAO,GAAG,WAAW,cAAc;AACpC,eAAA,QAAQ,KAAK,SAAS;AAAA,MAAA,CAC9B;AAAA,aACM,OAAO;AACD,mBAAA,IAAI,OAAO,KAAc;AAAA,IAAA;AAAA,EACxC,CACD;AAGK,QAAA,QAAQ,IAAI,cAAc;AAE5B,MAAA,aAAa,OAAO,GAAG;AACjB,YAAA,MAAM,sCAAsC,YAAY;AAAA,EAAA;AAEpE;"}
File without changes
File without changes
File without changes
File without changes
File without changes