rwsdk 0.2.0-alpha.9 → 0.3.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 (93) hide show
  1. package/dist/lib/constants.d.mts +6 -1
  2. package/dist/lib/constants.mjs +6 -1
  3. package/dist/lib/smokeTests/browser.mjs +5 -21
  4. package/dist/lib/smokeTests/codeUpdates.d.mts +1 -1
  5. package/dist/lib/smokeTests/codeUpdates.mjs +41 -5
  6. package/dist/lib/smokeTests/development.d.mts +1 -1
  7. package/dist/lib/smokeTests/development.mjs +4 -10
  8. package/dist/lib/smokeTests/release.d.mts +1 -1
  9. package/dist/lib/smokeTests/release.mjs +4 -9
  10. package/dist/lib/smokeTests/runSmokeTests.mjs +2 -2
  11. package/dist/lib/smokeTests/templates/SmokeTest.template.js +3 -2
  12. package/dist/lib/testUtils/stubEnvVars.d.mts +2 -0
  13. package/dist/lib/testUtils/stubEnvVars.mjs +11 -0
  14. package/dist/runtime/client/client.d.ts +10 -0
  15. package/dist/runtime/{client.js → client/client.js} +13 -10
  16. package/dist/runtime/{clientNavigation.test.js → client/navigation.test.js} +1 -1
  17. package/dist/runtime/client/setWebpackRequire.d.ts +1 -0
  18. package/dist/runtime/client/setWebpackRequire.js +2 -0
  19. package/dist/runtime/{client.d.ts → client/types.d.ts} +4 -10
  20. package/dist/runtime/client/types.js +1 -0
  21. package/dist/runtime/entries/client.d.ts +2 -2
  22. package/dist/runtime/entries/client.js +2 -2
  23. package/dist/runtime/imports/client.d.ts +3 -3
  24. package/dist/runtime/imports/client.js +11 -15
  25. package/dist/runtime/imports/ssr.d.ts +3 -3
  26. package/dist/runtime/imports/ssr.js +3 -3
  27. package/dist/runtime/imports/worker.d.ts +3 -3
  28. package/dist/runtime/imports/worker.js +5 -4
  29. package/dist/runtime/lib/manifest.d.ts +11 -2
  30. package/dist/runtime/lib/manifest.js +1 -1
  31. package/dist/runtime/lib/memoizeOnId.d.ts +1 -0
  32. package/dist/runtime/lib/memoizeOnId.js +11 -0
  33. package/dist/runtime/lib/realtime/client.d.ts +1 -1
  34. package/dist/runtime/lib/realtime/client.js +1 -1
  35. package/dist/runtime/lib/router.d.ts +3 -3
  36. package/dist/runtime/lib/router.js +77 -33
  37. package/dist/runtime/register/ssr.d.ts +1 -1
  38. package/dist/runtime/register/ssr.js +4 -3
  39. package/dist/runtime/render/preloads.d.ts +6 -0
  40. package/dist/runtime/render/preloads.js +40 -0
  41. package/dist/runtime/render/renderRscThenableToHtmlStream.js +2 -1
  42. package/dist/runtime/render/stylesheets.js +1 -1
  43. package/dist/runtime/requestInfo/types.d.ts +3 -1
  44. package/dist/runtime/requestInfo/worker.js +9 -1
  45. package/dist/runtime/worker.d.ts +0 -3
  46. package/dist/runtime/worker.js +2 -11
  47. package/dist/scripts/debug-sync.mjs +142 -39
  48. package/dist/scripts/smoke-test.mjs +0 -10
  49. package/dist/scripts/worker-run.mjs +8 -3
  50. package/dist/vite/buildApp.d.mts +15 -0
  51. package/dist/vite/buildApp.mjs +53 -0
  52. package/dist/vite/configPlugin.d.mts +4 -2
  53. package/dist/vite/configPlugin.mjs +69 -62
  54. package/dist/vite/createDirectiveLookupPlugin.d.mts +0 -6
  55. package/dist/vite/createDirectiveLookupPlugin.mjs +61 -145
  56. package/dist/vite/directiveModulesDevPlugin.d.mts +8 -0
  57. package/dist/vite/directiveModulesDevPlugin.mjs +62 -0
  58. package/dist/vite/directivesFilteringPlugin.d.mts +6 -0
  59. package/dist/vite/directivesFilteringPlugin.mjs +31 -0
  60. package/dist/vite/directivesPlugin.mjs +28 -42
  61. package/dist/vite/getViteEsbuild.d.mts +1 -0
  62. package/dist/vite/getViteEsbuild.mjs +12 -0
  63. package/dist/vite/hasOwnReactVitePlugin.d.mts +3 -0
  64. package/dist/vite/hasOwnReactVitePlugin.mjs +14 -0
  65. package/dist/vite/injectVitePreamblePlugin.d.mts +3 -2
  66. package/dist/vite/injectVitePreamblePlugin.mjs +4 -2
  67. package/dist/vite/linkerPlugin.d.mts +4 -0
  68. package/dist/vite/linkerPlugin.mjs +41 -0
  69. package/dist/vite/manifestPlugin.d.mts +2 -2
  70. package/dist/vite/manifestPlugin.mjs +12 -37
  71. package/dist/vite/miniflareHMRPlugin.mjs +17 -2
  72. package/dist/vite/moveStaticAssetsPlugin.mjs +2 -1
  73. package/dist/vite/prismaPlugin.mjs +1 -1
  74. package/dist/vite/reactConditionsResolverPlugin.d.mts +3 -4
  75. package/dist/vite/reactConditionsResolverPlugin.mjs +74 -56
  76. package/dist/vite/redwoodPlugin.d.mts +1 -1
  77. package/dist/vite/redwoodPlugin.mjs +36 -12
  78. package/dist/vite/runDirectivesScan.d.mts +7 -0
  79. package/dist/vite/runDirectivesScan.mjs +152 -0
  80. package/dist/vite/ssrBridgePlugin.mjs +13 -14
  81. package/dist/vite/transformClientComponents.d.mts +0 -1
  82. package/dist/vite/transformClientComponents.mjs +1 -9
  83. package/dist/vite/transformJsxScriptTagsPlugin.d.mts +4 -3
  84. package/dist/vite/transformJsxScriptTagsPlugin.mjs +151 -158
  85. package/dist/vite/transformJsxScriptTagsPlugin.test.mjs +393 -136
  86. package/dist/vite/transformServerFunctions.d.mts +1 -1
  87. package/dist/vite/transformServerFunctions.mjs +11 -12
  88. package/package.json +28 -4
  89. /package/dist/runtime/{imports → client}/ClientOnly.d.ts +0 -0
  90. /package/dist/runtime/{imports → client}/ClientOnly.js +0 -0
  91. /package/dist/runtime/{clientNavigation.d.ts → client/navigation.d.ts} +0 -0
  92. /package/dist/runtime/{clientNavigation.js → client/navigation.js} +0 -0
  93. /package/dist/runtime/{clientNavigation.test.d.ts → client/navigation.test.d.ts} +0 -0
@@ -3,6 +3,7 @@ import { unstable_readConfig } from "wrangler";
3
3
  import { cloudflare } from "@cloudflare/vite-plugin";
4
4
  import { devServerConstantPlugin } from "./devServerConstant.mjs";
5
5
  import { hasOwnCloudflareVitePlugin } from "./hasOwnCloudflareVitePlugin.mjs";
6
+ import { hasOwnReactVitePlugin } from "./hasOwnReactVitePlugin.mjs";
6
7
  import reactPlugin from "@vitejs/plugin-react";
7
8
  import tsconfigPaths from "vite-tsconfig-paths";
8
9
  import { transformJsxScriptTagsPlugin } from "./transformJsxScriptTagsPlugin.mjs";
@@ -23,6 +24,9 @@ import { ssrBridgePlugin } from "./ssrBridgePlugin.mjs";
23
24
  import { hasPkgScript } from "../lib/hasPkgScript.mjs";
24
25
  import { devServerTimingPlugin } from "./devServerTimingPlugin.mjs";
25
26
  import { manifestPlugin } from "./manifestPlugin.mjs";
27
+ import { linkerPlugin } from "./linkerPlugin.mjs";
28
+ import { directiveModulesDevPlugin } from "./directiveModulesDevPlugin.mjs";
29
+ import { directivesFilteringPlugin } from "./directivesFilteringPlugin.mjs";
26
30
  const determineWorkerEntryPathname = async (projectRootDir, workerConfigPath, options) => {
27
31
  if (options.entry?.worker) {
28
32
  return resolve(projectRootDir, options.entry.worker);
@@ -30,17 +34,20 @@ const determineWorkerEntryPathname = async (projectRootDir, workerConfigPath, op
30
34
  const workerConfig = unstable_readConfig({ config: workerConfigPath });
31
35
  return resolve(projectRootDir, workerConfig.main ?? "src/worker.tsx");
32
36
  };
37
+ const clientFiles = new Set();
38
+ const serverFiles = new Set();
39
+ const clientEntryPoints = new Set();
33
40
  export const redwoodPlugin = async (options = {}) => {
34
41
  const projectRootDir = process.cwd();
35
- const workerConfigPath = options.configPath ?? (await findWranglerConfig(projectRootDir));
42
+ const workerConfigPath = options.configPath ??
43
+ (process.env.RWSDK_WRANGLER_CONFIG
44
+ ? resolve(projectRootDir, process.env.RWSDK_WRANGLER_CONFIG)
45
+ : await findWranglerConfig(projectRootDir));
36
46
  const workerEntryPathname = await determineWorkerEntryPathname(projectRootDir, workerConfigPath, options);
37
- const clientEntryPathnames = (Array.isArray(options.entry?.client)
38
- ? options.entry.client
39
- : [options.entry?.client ?? "src/client.tsx"]).map((entry) => resolve(projectRootDir, entry));
40
- const clientFiles = new Set();
41
- const serverFiles = new Set();
42
47
  const shouldIncludeCloudflarePlugin = options.includeCloudflarePlugin ??
43
48
  !(await hasOwnCloudflareVitePlugin({ rootProjectDir: projectRootDir }));
49
+ const shouldIncludeReactPlugin = options.includeReactPlugin ??
50
+ !(await hasOwnReactVitePlugin({ rootProjectDir: projectRootDir }));
44
51
  // context(justinvdm, 31 Mar 2025): We assume that if there is no .wrangler directory,
45
52
  // then this is fresh install, and we run `npm run dev:init` here.
46
53
  if (process.env.RWSDK_WORKER_RUN !== "1" &&
@@ -56,19 +63,26 @@ export const redwoodPlugin = async (options = {}) => {
56
63
  }
57
64
  return [
58
65
  devServerTimingPlugin(),
66
+ directiveModulesDevPlugin({
67
+ clientFiles,
68
+ serverFiles,
69
+ projectRootDir,
70
+ }),
59
71
  devServerConstantPlugin(),
60
72
  configPlugin({
61
73
  silent: options.silent ?? false,
62
74
  projectRootDir,
63
- clientEntryPathnames,
64
75
  workerEntryPathname,
76
+ clientFiles,
77
+ serverFiles,
78
+ clientEntryPoints,
65
79
  }),
66
80
  ssrBridgePlugin({
67
81
  clientFiles,
68
82
  serverFiles,
69
83
  projectRootDir,
70
84
  }),
71
- reactConditionsResolverPlugin(),
85
+ reactConditionsResolverPlugin({ projectRootDir }),
72
86
  tsconfigPaths({ root: projectRootDir }),
73
87
  shouldIncludeCloudflarePlugin
74
88
  ? cloudflare({
@@ -83,14 +97,17 @@ export const redwoodPlugin = async (options = {}) => {
83
97
  viteEnvironment: { name: "worker" },
84
98
  workerEntryPathname,
85
99
  }),
86
- reactPlugin(),
100
+ shouldIncludeReactPlugin ? reactPlugin() : [],
87
101
  directivesPlugin({
88
102
  projectRootDir,
89
103
  clientFiles,
90
104
  serverFiles,
91
105
  }),
92
106
  vitePreamblePlugin(),
93
- injectVitePreamble({ clientEntryPathnames }),
107
+ injectVitePreamble({
108
+ clientEntryPoints,
109
+ projectRootDir,
110
+ }),
94
111
  useClientLookupPlugin({
95
112
  projectRootDir,
96
113
  clientFiles,
@@ -100,12 +117,19 @@ export const redwoodPlugin = async (options = {}) => {
100
117
  serverFiles,
101
118
  }),
102
119
  transformJsxScriptTagsPlugin({
103
- manifestPath: resolve(projectRootDir, "dist", "client", ".vite", "manifest.json"),
120
+ clientEntryPoints,
121
+ projectRootDir,
104
122
  }),
105
123
  manifestPlugin({
106
- manifestPath: resolve(projectRootDir, "dist", "client", ".vite", "manifest.json"),
124
+ projectRootDir,
107
125
  }),
108
126
  moveStaticAssetsPlugin({ rootDir: projectRootDir }),
109
127
  prismaPlugin({ projectRootDir }),
128
+ linkerPlugin({ projectRootDir }),
129
+ directivesFilteringPlugin({
130
+ clientFiles,
131
+ serverFiles,
132
+ projectRootDir,
133
+ }),
110
134
  ];
111
135
  };
@@ -0,0 +1,7 @@
1
+ import { ResolvedConfig } from "vite";
2
+ export declare function runDirectivesScan({ rootConfig, envName, clientFiles, serverFiles, }: {
3
+ rootConfig: ResolvedConfig;
4
+ envName: string;
5
+ clientFiles: Set<string>;
6
+ serverFiles: Set<string>;
7
+ }): Promise<any>;
@@ -0,0 +1,152 @@
1
+ import fsp from "node:fs/promises";
2
+ import { hasDirective } from "./hasDirective.mjs";
3
+ import path from "node:path";
4
+ import debug from "debug";
5
+ import { ensureAliasArray } from "./ensureAliasArray.mjs";
6
+ import { getViteEsbuild } from "./getViteEsbuild.mjs";
7
+ import { normalizeModulePath } from "../lib/normalizeModulePath.mjs";
8
+ const log = debug("rwsdk:vite:run-directives-scan");
9
+ // Copied from Vite's source code.
10
+ // https://github.com/vitejs/vite/blob/main/packages/vite/src/shared/utils.ts
11
+ const isObject = (value) => Object.prototype.toString.call(value) === "[object Object]";
12
+ // Copied from Vite's source code.
13
+ // https://github.com/vitejs/vite/blob/main/packages/vite/src/node/utils.ts
14
+ const externalRE = /^(https?:)?\/\//;
15
+ const isExternalUrl = (url) => externalRE.test(url);
16
+ function createEsbuildScanPlugin({ clientFiles, serverFiles, aliases, projectRootDir, }) {
17
+ return {
18
+ name: "rwsdk:esbuild-scan-plugin",
19
+ setup(build) {
20
+ // Match Vite's behavior by externalizing assets and special queries.
21
+ // This prevents esbuild from trying to bundle them, which would fail.
22
+ const scriptFilter = /\.(c|m)?[jt]sx?$/;
23
+ const specialQueryFilter = /[?&](?:url|raw|worker|sharedworker|inline)\b/;
24
+ // This regex is used to identify if a path has any file extension.
25
+ const hasExtensionRegex = /\.[^/]+$/;
26
+ build.onResolve({ filter: specialQueryFilter }, (args) => {
27
+ log("Externalizing special query:", args.path);
28
+ return { external: true };
29
+ });
30
+ build.onResolve({ filter: /.*/, namespace: "file" }, (args) => {
31
+ // Externalize if the path has an extension AND that extension is not a
32
+ // script extension. Extensionless paths are assumed to be scripts and
33
+ // are allowed to pass through for resolution.
34
+ if (hasExtensionRegex.test(args.path) &&
35
+ !scriptFilter.test(args.path)) {
36
+ log("Externalizing non-script import:", args.path);
37
+ return { external: true };
38
+ }
39
+ });
40
+ build.onResolve({ filter: /.*/ }, async (args) => {
41
+ // Prevent infinite recursion.
42
+ if (args.pluginData?.rwsdkScanResolver) {
43
+ return null;
44
+ }
45
+ // 1. First, try to resolve aliases.
46
+ for (const { find, replacement } of aliases) {
47
+ const findPattern = find instanceof RegExp ? find : new RegExp(`^${find}(\\/.*)?$`);
48
+ if (findPattern.test(args.path)) {
49
+ const newPath = args.path.replace(findPattern, (_match, rest) => {
50
+ // `rest` is the captured group `(\\/.*)?` from the regex.
51
+ return replacement + (rest || "");
52
+ });
53
+ const resolved = await build.resolve(newPath, {
54
+ importer: args.importer,
55
+ resolveDir: args.resolveDir,
56
+ kind: args.kind,
57
+ pluginData: { rwsdkScanResolver: true },
58
+ });
59
+ if (resolved.errors.length === 0) {
60
+ return resolved;
61
+ }
62
+ log("Could not resolve aliased path '%s' (from '%s'). Marking as external. Errors: %s", newPath, args.path, resolved.errors.map((e) => e.text).join(", "));
63
+ return { external: true };
64
+ }
65
+ }
66
+ // 2. If no alias matches, try esbuild's default resolver.
67
+ const resolved = await build.resolve(args.path, {
68
+ importer: args.importer,
69
+ resolveDir: args.resolveDir,
70
+ kind: args.kind,
71
+ pluginData: { rwsdkScanResolver: true },
72
+ });
73
+ // If it fails, mark as external but don't crash.
74
+ if (resolved.errors.length > 0) {
75
+ log("Could not resolve '%s'. Marking as external. Errors: %s", args.path, resolved.errors.map((e) => e.text).join(", "));
76
+ return { external: true };
77
+ }
78
+ return resolved;
79
+ });
80
+ build.onLoad({ filter: /\.(m|c)?[jt]sx?$/ }, async (args) => {
81
+ if (!args.path.startsWith("/") ||
82
+ args.path.includes("virtual:") ||
83
+ isExternalUrl(args.path)) {
84
+ return null;
85
+ }
86
+ try {
87
+ const contents = await fsp.readFile(args.path, "utf-8");
88
+ if (hasDirective(contents, "use client")) {
89
+ log("Discovered 'use client' in:", args.path);
90
+ clientFiles.add(normalizeModulePath(args.path, projectRootDir));
91
+ }
92
+ if (hasDirective(contents, "use server")) {
93
+ log("Discovered 'use server' in:", args.path);
94
+ serverFiles.add(normalizeModulePath(args.path, projectRootDir));
95
+ }
96
+ return { contents, loader: "default" };
97
+ }
98
+ catch (e) {
99
+ log("Could not read file during scan, skipping:", args.path, e);
100
+ return null;
101
+ }
102
+ });
103
+ },
104
+ };
105
+ }
106
+ export async function runDirectivesScan({ rootConfig, envName, clientFiles, serverFiles, }) {
107
+ const esbuild = await getViteEsbuild(rootConfig.root);
108
+ const env = rootConfig.environments[envName];
109
+ const input = env.build.rollupOptions?.input;
110
+ let entries;
111
+ if (Array.isArray(input)) {
112
+ entries = input;
113
+ }
114
+ else if (typeof input === "string") {
115
+ entries = [input];
116
+ }
117
+ else if (isObject(input)) {
118
+ entries = Object.values(input);
119
+ }
120
+ else {
121
+ entries = [];
122
+ }
123
+ if (entries.length === 0) {
124
+ log("No entries found for directives scan in environment '%s', skipping.", envName);
125
+ return;
126
+ }
127
+ const absoluteEntries = entries.map((entry) => path.resolve(rootConfig.root, entry));
128
+ log("Starting directives scan for environment '%s' with entries:", envName, absoluteEntries);
129
+ try {
130
+ const result = await esbuild.build({
131
+ entryPoints: absoluteEntries,
132
+ bundle: true,
133
+ write: false,
134
+ platform: "node",
135
+ format: "esm",
136
+ logLevel: "silent",
137
+ metafile: true,
138
+ plugins: [
139
+ createEsbuildScanPlugin({
140
+ clientFiles,
141
+ serverFiles,
142
+ aliases: ensureAliasArray(env),
143
+ projectRootDir: rootConfig.root,
144
+ }),
145
+ ],
146
+ });
147
+ return result.metafile;
148
+ }
149
+ catch (e) {
150
+ throw new Error(`RWSDK directive scan failed:\n${e.message}`);
151
+ }
152
+ }
@@ -1,11 +1,10 @@
1
1
  import debug from "debug";
2
- import { SSR_BRIDGE_PATH } from "../lib/constants.mjs";
3
2
  import { findSsrImportCallSites } from "./findSsrSpecifiers.mjs";
3
+ import { INTERMEDIATE_SSR_BRIDGE_PATH } from "../lib/constants.mjs";
4
4
  import MagicString from "magic-string";
5
5
  const log = debug("rwsdk:vite:ssr-bridge-plugin");
6
6
  export const VIRTUAL_SSR_PREFIX = "virtual:rwsdk:ssr:";
7
7
  export const ssrBridgePlugin = ({ clientFiles, serverFiles, }) => {
8
- log("Initializing SSR bridge plugin with SSR_BRIDGE_PATH=%s", SSR_BRIDGE_PATH);
9
8
  let devServer;
10
9
  let isDev = false;
11
10
  const ssrBridgePlugin = {
@@ -49,8 +48,6 @@ export const ssrBridgePlugin = ({ clientFiles, serverFiles, }) => {
49
48
  }
50
49
  },
51
50
  async resolveId(id) {
52
- process.env.VERBOSE &&
53
- log("Resolving id=%s, environment=%s, isDev=%s", id, this.environment?.name, isDev);
54
51
  if (isDev) {
55
52
  // context(justinvdm, 27 May 2025): In dev, we need to dynamically load
56
53
  // SSR modules, so we return the virtual id so that the dynamic loading
@@ -75,20 +72,23 @@ export const ssrBridgePlugin = ({ clientFiles, serverFiles, }) => {
75
72
  }
76
73
  }
77
74
  else {
78
- // context(justinvdm, 27 May 2025): In builds, since all SSR import chains
79
- // originate at SSR bridge module, we return the path to the already built
80
- // SSR bridge bundle - SSR env builds it, worker build tries to resolve it
81
- // here and uses it
75
+ // In build mode, the behavior depends on the build pass
82
76
  if (id === "rwsdk/__ssr_bridge" && this.environment.name === "worker") {
83
- log("Bridge module case (build): id=%s matches rwsdk/__ssr_bridge in worker environment, returning SSR_BRIDGE_PATH=%s", id, SSR_BRIDGE_PATH);
84
- return SSR_BRIDGE_PATH;
77
+ if (process.env.RWSDK_BUILD_PASS === "worker") {
78
+ // First pass: resolve to a temporary, external path
79
+ log("Bridge module case (build-worker pass): resolving to external path");
80
+ return { id: INTERMEDIATE_SSR_BRIDGE_PATH, external: true };
81
+ }
82
+ else if (process.env.RWSDK_BUILD_PASS === "linker") {
83
+ // Second pass (linker): resolve to the real intermediate build
84
+ // artifact so it can be bundled in.
85
+ log("Bridge module case (build-linker pass): resolving to bundleable path");
86
+ return { id: INTERMEDIATE_SSR_BRIDGE_PATH, external: false };
87
+ }
85
88
  }
86
89
  }
87
- process.env.VERBOSE && log("No resolution for id=%s", id);
88
90
  },
89
91
  async load(id) {
90
- process.env.VERBOSE &&
91
- log("Loading id=%s, isDev=%s, environment=%s", id, isDev, this.environment.name);
92
92
  if (id.startsWith(VIRTUAL_SSR_PREFIX) &&
93
93
  this.environment.name === "worker") {
94
94
  const realId = id.slice(VIRTUAL_SSR_PREFIX.length);
@@ -132,7 +132,6 @@ export const ssrBridgePlugin = ({ clientFiles, serverFiles, }) => {
132
132
  return out;
133
133
  }
134
134
  }
135
- process.env.VERBOSE && log("No load handling for id=%s", id);
136
135
  },
137
136
  };
138
137
  return ssrBridgePlugin;
@@ -2,7 +2,6 @@ interface TransformContext {
2
2
  environmentName: string;
3
3
  clientFiles?: Set<string>;
4
4
  isEsbuild?: boolean;
5
- addClientModule?: (environment: string, id: string) => void;
6
5
  }
7
6
  interface TransformResult {
8
7
  code: string;
@@ -5,16 +5,10 @@ import { findExports } from "./findSpecifiers.mjs";
5
5
  const logVite = debug("rwsdk:vite:transform-client-components:vite");
6
6
  const logEsbuild = debug("rwsdk:vite:transform-client-components:esbuild");
7
7
  export async function transformClientComponents(code, normalizedId, ctx) {
8
- const log = ctx.isEsbuild ? logEsbuild : logVite;
9
- log("Called transformClientComponents for id: id=%s", normalizedId);
10
8
  if (!hasDirective(code, "use client")) {
11
- log("Skipping: no 'use client' directive in id=%s", normalizedId);
12
- process.env.VERBOSE &&
13
- log(":VERBOSE: Returning code unchanged for id=%s:\n%s", normalizedId, code);
14
9
  return;
15
10
  }
16
- log("Processing 'use client' module: id=%s", normalizedId);
17
- ctx.addClientModule?.(ctx.environmentName, normalizedId);
11
+ const log = ctx.isEsbuild ? logEsbuild : logVite;
18
12
  // Parse exports using the findExports helper
19
13
  const exportInfos = findExports(normalizedId, code, log);
20
14
  const processedExports = [];
@@ -85,7 +79,6 @@ export async function transformClientComponents(code, normalizedId, ctx) {
85
79
  const computedLocalNames = new Map(processedExports.map((info) => [getComputedLocalName(info), info]));
86
80
  // Add registerClientReference assignments for unique names
87
81
  for (const [computedLocalName, correspondingInfo] of computedLocalNames) {
88
- log(":isEsbuild=%s: Registering client reference for named export: %s as %s", !!ctx.isEsbuild, correspondingInfo.local, correspondingInfo.exported);
89
82
  s.append(`const ${computedLocalName} = registerClientReference("${normalizedId}", "${correspondingInfo.exported}");\n`);
90
83
  }
91
84
  // Add grouped export statement for named exports (preserving order and alias)
@@ -93,7 +86,6 @@ export async function transformClientComponents(code, normalizedId, ctx) {
93
86
  const exportNames = Array.from(computedLocalNames.entries()).map(([computedLocalName, correspondingInfo]) => correspondingInfo.local === correspondingInfo.exported
94
87
  ? computedLocalName
95
88
  : `${computedLocalName} as ${correspondingInfo.exported}`);
96
- log(":isEsbuild=%s: Exporting named exports: %O", !!ctx.isEsbuild, exportNames);
97
89
  s.append(`export { ${exportNames.join(", ")} };\n`);
98
90
  }
99
91
  // Add default export if present
@@ -1,8 +1,9 @@
1
1
  import { type Plugin } from "vite";
2
- export declare function transformJsxScriptTagsCode(code: string, manifest?: Record<string, any>): Promise<{
2
+ export declare function transformJsxScriptTagsCode(code: string, clientEntryPoints: Set<string>, manifest: Record<string, any> | undefined, projectRootDir: string): Promise<{
3
3
  code: string;
4
4
  map: null;
5
5
  } | undefined>;
6
- export declare const transformJsxScriptTagsPlugin: ({ manifestPath, }: {
7
- manifestPath: string;
6
+ export declare const transformJsxScriptTagsPlugin: ({ clientEntryPoints, projectRootDir, }: {
7
+ clientEntryPoints: Set<string>;
8
+ projectRootDir: string;
8
9
  }) => Plugin;