rwsdk 0.1.14 → 0.1.15-test.20250714213423

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.
@@ -5,7 +5,7 @@ export const loadModule = memoize(async (id) => {
5
5
  return await import(/* @vite-ignore */ id);
6
6
  }
7
7
  else {
8
- const { useClientLookup } = await import("virtual:use-client-lookup");
8
+ const { useClientLookup } = await import("virtual:use-client-lookup.js");
9
9
  const moduleFn = useClientLookup[id];
10
10
  if (!moduleFn) {
11
11
  throw new Error(`(client) No module found for '${id}' in module lookup for "use client" directive`);
@@ -1,6 +1,6 @@
1
1
  import memoize from "lodash/memoize";
2
2
  export const ssrLoadModule = memoize(async (id) => {
3
- const { useClientLookup } = await import("virtual:use-client-lookup");
3
+ const { useClientLookup } = await import("virtual:use-client-lookup.js");
4
4
  const moduleFn = useClientLookup[id];
5
5
  if (!moduleFn) {
6
6
  throw new Error(`(ssr) No module found for '${id}' in module lookup for "use client" directive`);
@@ -2,7 +2,7 @@ import memoize from "lodash/memoize";
2
2
  import { requestInfo } from "../requestInfo/worker";
3
3
  import { ssrWebpackRequire as baseSsrWebpackRequire } from "rwsdk/__ssr_bridge";
4
4
  export const loadServerModule = memoize(async (id) => {
5
- const { useServerLookup } = await import("virtual:use-server-lookup");
5
+ const { useServerLookup } = await import("virtual:use-server-lookup.js");
6
6
  const moduleFn = useServerLookup[id];
7
7
  if (!moduleFn) {
8
8
  throw new Error(`(worker) No module found for '${id}' in module lookup for "use server" directive`);
@@ -1,7 +1,7 @@
1
1
  import memoize from "lodash/memoize";
2
2
  import { createServerReference as baseCreateServerReference } from "react-server-dom-webpack/client.edge";
3
3
  export const loadServerModule = memoize(async (id) => {
4
- const { useServerLookup } = await import("virtual:use-server-lookup");
4
+ const { useServerLookup } = await import("virtual:use-server-lookup.js");
5
5
  const moduleFn = useServerLookup[id];
6
6
  if (!moduleFn) {
7
7
  throw new Error(`(worker) No module found for '${id}' in module lookup for "use server" directive`);
@@ -1,8 +1,7 @@
1
1
  import { Plugin } from "vite";
2
2
  export declare const cloudflareBuiltInModules: string[];
3
3
  export declare const externalModules: string[];
4
- export declare const configPlugin: ({ mode, silent, projectRootDir, clientEntryPathnames, workerEntryPathname, }: {
5
- mode: "development" | "production";
4
+ export declare const configPlugin: ({ silent, projectRootDir, clientEntryPathnames, workerEntryPathname, }: {
6
5
  silent: boolean;
7
6
  projectRootDir: string;
8
7
  clientEntryPathnames: string[];
@@ -1,7 +1,7 @@
1
1
  import path, { resolve } from "node:path";
2
+ import { builtinModules } from "node:module";
2
3
  import enhancedResolve from "enhanced-resolve";
3
4
  import { SSR_BRIDGE_PATH } from "../lib/constants.mjs";
4
- import { builtinModules } from "node:module";
5
5
  // port(justinvdm, 09 Jun 2025):
6
6
  // https://github.com/cloudflare/workers-sdk/blob/d533f5ee7da69c205d8d5e2a5f264d2370fc612b/packages/vite-plugin-cloudflare/src/cloudflare-environment.ts#L123-L128
7
7
  export const cloudflareBuiltInModules = [
@@ -15,9 +15,10 @@ export const externalModules = [
15
15
  ...builtinModules,
16
16
  ...builtinModules.map((m) => `node:${m}`),
17
17
  ];
18
- export const configPlugin = ({ mode, silent, projectRootDir, clientEntryPathnames, workerEntryPathname, }) => ({
18
+ export const configPlugin = ({ silent, projectRootDir, clientEntryPathnames, workerEntryPathname, }) => ({
19
19
  name: "rwsdk:config",
20
- config: (_, { command }) => {
20
+ config: async (_) => {
21
+ const mode = process.env.NODE_ENV;
21
22
  const baseConfig = {
22
23
  appType: "custom",
23
24
  mode,
@@ -78,6 +79,9 @@ export const configPlugin = ({ mode, silent, projectRootDir, clientEntryPathname
78
79
  jsx: "automatic",
79
80
  jsxImportSource: "react",
80
81
  plugins: [],
82
+ define: {
83
+ "process.env.NODE_ENV": JSON.stringify(mode),
84
+ },
81
85
  },
82
86
  },
83
87
  build: {
@@ -121,6 +125,9 @@ export const configPlugin = ({ mode, silent, projectRootDir, clientEntryPathname
121
125
  esbuildOptions: {
122
126
  jsx: "automatic",
123
127
  jsxImportSource: "react",
128
+ define: {
129
+ "process.env.NODE_ENV": JSON.stringify(mode),
130
+ },
124
131
  },
125
132
  },
126
133
  build: {
@@ -9,7 +9,6 @@ import { getSrcPaths } from "../lib/getSrcPaths.js";
9
9
  import { hasDirective } from "./hasDirective.mjs";
10
10
  export const findFilesContainingDirective = async ({ projectRootDir, files, directive, debugNamespace, }) => {
11
11
  const log = debug(debugNamespace);
12
- const verboseLog = debug(`verbose:${debugNamespace}`);
13
12
  log("Starting search for '%s' files in projectRootDir=%s", directive, projectRootDir);
14
13
  const filesToScan = await getSrcPaths(projectRootDir);
15
14
  log("Found %d files to scan for '%s' directive", filesToScan.length, directive);
@@ -17,10 +16,10 @@ export const findFilesContainingDirective = async ({ projectRootDir, files, dire
17
16
  try {
18
17
  const stats = await stat(file);
19
18
  if (!stats.isFile()) {
20
- verboseLog("Skipping %s (not a file)", file);
19
+ process.env.VERBOSE && log("Skipping %s (not a file)", file);
21
20
  continue;
22
21
  }
23
- verboseLog("Scanning file: %s", file);
22
+ process.env.VERBOSE && log("Scanning file: %s", file);
24
23
  const content = await readFile(file, "utf-8");
25
24
  if (hasDirective(content, directive)) {
26
25
  const normalizedPath = normalizeModulePath(projectRootDir, file);
@@ -33,11 +32,11 @@ export const findFilesContainingDirective = async ({ projectRootDir, files, dire
33
32
  }
34
33
  }
35
34
  log("Completed scan. Found %d %s files total", files.size, directive);
36
- verboseLog("Found files for %s: %j", directive, Array.from(files));
35
+ process.env.VERBOSE &&
36
+ log("Found files for %s: %j", directive, Array.from(files));
37
37
  };
38
38
  const resolveOptimizedDep = async (projectRootDir, id, environment, debugNamespace) => {
39
39
  const log = debug(debugNamespace);
40
- const verboseLog = debug(`verbose:${debugNamespace}`);
41
40
  try {
42
41
  const depsDir = environment === "client" ? "deps" : `deps_${environment}`;
43
42
  const nodeModulesDepsDirPath = path.join("node_modules", ".vite", depsDir);
@@ -57,25 +56,26 @@ const resolveOptimizedDep = async (projectRootDir, id, environment, debugNamespa
57
56
  log("Found optimized dependency: filePath=%s, optimizedPath=%s", id, optimizedPath);
58
57
  return optimizedPath;
59
58
  }
60
- verboseLog("File not found in optimized dependencies: id=%s", id);
59
+ process.env.VERBOSE &&
60
+ log("File not found in optimized dependencies: id=%s", id);
61
61
  return undefined;
62
62
  }
63
63
  catch (error) {
64
- verboseLog("Error resolving optimized dependency for id=%s: %s", id, error);
64
+ process.env.VERBOSE &&
65
+ log("Error resolving optimized dependency for id=%s: %s", id, error);
65
66
  return undefined;
66
67
  }
67
68
  };
68
69
  const addOptimizedDepsEntries = async ({ projectRootDir, directive, environment, debugNamespace, files, }) => {
69
70
  const log = debug(debugNamespace);
70
- const verboseLog = debug(`verbose:${debugNamespace}`);
71
71
  try {
72
72
  const depsDir = environment === "client" ? "deps" : `deps_${environment}`;
73
73
  const depsDirPath = path.join(projectRootDir, "node_modules", ".vite", depsDir);
74
74
  const manifestPath = path.join(depsDirPath, "_metadata.json");
75
- verboseLog("Checking for manifest at: %s", manifestPath);
75
+ process.env.VERBOSE && log("Checking for manifest at: %s", manifestPath);
76
76
  const manifestExists = await pathExists(manifestPath);
77
77
  if (!manifestExists) {
78
- verboseLog("Manifest not found at %s", manifestPath);
78
+ process.env.VERBOSE && log("Manifest not found at %s", manifestPath);
79
79
  return;
80
80
  }
81
81
  const manifestContent = await readFile(manifestPath, "utf-8");
@@ -89,7 +89,8 @@ const addOptimizedDepsEntries = async ({ projectRootDir, directive, environment,
89
89
  contents = await readFile(resolvedSrcPath, "utf-8");
90
90
  }
91
91
  catch (error) {
92
- verboseLog("Error reading file %s: %s", resolvedSrcPath, error);
92
+ process.env.VERBOSE &&
93
+ log("Error reading file %s: %s", resolvedSrcPath, error);
93
94
  continue;
94
95
  }
95
96
  if (hasDirective(contents, directive)) {
@@ -103,13 +104,13 @@ const addOptimizedDepsEntries = async ({ projectRootDir, directive, environment,
103
104
  }
104
105
  }
105
106
  catch (error) {
106
- verboseLog("Error adding optimized deps entries: %s", error);
107
+ process.env.VERBOSE &&
108
+ log("Error adding optimized deps entries: %s", error);
107
109
  }
108
110
  };
109
111
  export const createDirectiveLookupPlugin = async ({ projectRootDir, files, config, }) => {
110
112
  const debugNamespace = `rwsdk:vite:${config.pluginName}`;
111
113
  const log = debug(debugNamespace);
112
- const verboseLog = debug(`verbose:${debugNamespace}`);
113
114
  let isDev = false;
114
115
  log("Initializing %s plugin with projectRootDir=%s", config.pluginName, projectRootDir);
115
116
  await findFilesContainingDirective({
@@ -149,11 +150,12 @@ export const createDirectiveLookupPlugin = async ({ projectRootDir, files, confi
149
150
  const escapedVirtualModuleName = config.virtualModuleName.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&");
150
151
  const escapedPrefixedModuleName = `/@id/${config.virtualModuleName}`.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&");
151
152
  build.onResolve({
152
- filter: new RegExp(`^(${escapedVirtualModuleName}|${escapedPrefixedModuleName})$`),
153
+ filter: new RegExp(`^(${escapedVirtualModuleName}|${escapedPrefixedModuleName})\.js$`),
153
154
  }, () => {
154
- verboseLog("Esbuild onResolve: marking %s as external", config.virtualModuleName);
155
+ process.env.VERBOSE &&
156
+ log("Esbuild onResolve: marking %s as external", config.virtualModuleName);
155
157
  return {
156
- path: config.virtualModuleName,
158
+ path: `${config.virtualModuleName}.js`,
157
159
  external: true,
158
160
  };
159
161
  });
@@ -166,7 +168,8 @@ export const createDirectiveLookupPlugin = async ({ projectRootDir, files, confi
166
168
  viteConfig.optimizeDeps.include ??= [];
167
169
  for (const file of files) {
168
170
  const actualFilePath = path.join(projectRootDir, file);
169
- verboseLog("Adding to optimizeDeps.entries: %s", actualFilePath);
171
+ process.env.VERBOSE &&
172
+ log("Adding to optimizeDeps.entries: %s", actualFilePath);
170
173
  const entries = Array.isArray(viteConfig.optimizeDeps.entries)
171
174
  ? viteConfig.optimizeDeps.entries
172
175
  : [].concat(viteConfig.optimizeDeps.entries ?? []);
@@ -180,19 +183,17 @@ export const createDirectiveLookupPlugin = async ({ projectRootDir, files, confi
180
183
  }
181
184
  },
182
185
  resolveId(source) {
183
- verboseLog("Resolving id=%s", source);
184
- if (source === config.virtualModuleName ||
185
- source === `/@id/${config.virtualModuleName}` ||
186
- source === `/@id/${config.virtualModuleName}.js`) {
186
+ process.env.VERBOSE && log("Resolving id=%s", source);
187
+ if (source === `${config.virtualModuleName}.js`) {
187
188
  log("Resolving %s module", config.virtualModuleName);
188
189
  // context(justinvdm, 16 Jun 2025): Include .js extension
189
190
  // so it goes through vite processing chain
190
- return config.virtualModuleName + ".js";
191
+ return source;
191
192
  }
192
- verboseLog("No resolution for id=%s", source);
193
+ process.env.VERBOSE && log("No resolution for id=%s", source);
193
194
  },
194
195
  async load(id) {
195
- verboseLog("Loading id=%s", id);
196
+ process.env.VERBOSE && log("Loading id=%s", id);
196
197
  if (id === config.virtualModuleName + ".js") {
197
198
  log("Loading %s module with %d files", config.virtualModuleName, files.size);
198
199
  const environment = this.environment?.name || "client";
@@ -218,13 +219,13 @@ export const ${config.exportName} = {
218
219
  const code = s.toString();
219
220
  const map = s.generateMap();
220
221
  log("Generated virtual module code length: %d", code.length);
221
- verboseLog("Generated virtual module code: %s", code);
222
+ process.env.VERBOSE && log("Generated virtual module code: %s", code);
222
223
  return {
223
224
  code,
224
225
  map,
225
226
  };
226
227
  }
227
- verboseLog("No load handling for id=%s", id);
228
+ process.env.VERBOSE && log("No load handling for id=%s", id);
228
229
  },
229
230
  };
230
231
  };
@@ -5,7 +5,6 @@ import { transformClientComponents } from "./transformClientComponents.mjs";
5
5
  import { transformServerFunctions } from "./transformServerFunctions.mjs";
6
6
  import { normalizeModulePath } from "./normalizeModulePath.mjs";
7
7
  const log = debug("rwsdk:vite:rsc-directives-plugin");
8
- const verboseLog = debug("verbose:rwsdk:vite:rsc-directives-plugin");
9
8
  const getLoader = (filePath) => {
10
9
  const ext = path.extname(filePath).slice(1);
11
10
  switch (ext) {
@@ -76,7 +75,8 @@ export const directivesPlugin = ({ projectRootDir, clientFiles, serverFiles, })
76
75
  });
77
76
  },
78
77
  async transform(code, id) {
79
- verboseLog("Transform called for id=%s, environment=%s", id, this.environment.name);
78
+ process.env.VERBOSE &&
79
+ log("Transform called for id=%s, environment=%s", id, this.environment.name);
80
80
  const normalizedId = normalizeModulePath(projectRootDir, id);
81
81
  const clientResult = await transformClientComponents(code, normalizedId, {
82
82
  environmentName: this.environment.name,
@@ -98,7 +98,7 @@ export const directivesPlugin = ({ projectRootDir, clientFiles, serverFiles, })
98
98
  map: serverResult.map,
99
99
  };
100
100
  }
101
- verboseLog("No transformation applied for id=%s", id);
101
+ process.env.VERBOSE && log("No transformation applied for id=%s", id);
102
102
  },
103
103
  configEnvironment(env, config) {
104
104
  log("Configuring environment: env=%s", env);
@@ -110,7 +110,8 @@ export const directivesPlugin = ({ projectRootDir, clientFiles, serverFiles, })
110
110
  setup(build) {
111
111
  log("Setting up esbuild plugin for environment: %s", env);
112
112
  build.onLoad({ filter: /\.(js|ts|jsx|tsx|mts|mjs|cjs)$/ }, async (args) => {
113
- verboseLog("Esbuild onLoad called for environment=%s, path=%s", env, args.path);
113
+ process.env.VERBOSE &&
114
+ log("Esbuild onLoad called for environment=%s, path=%s", env, args.path);
114
115
  const normalizedPath = normalizeModulePath(projectRootDir, args.path);
115
116
  // context(justinvdm,2025-06-15): If we're in app code,
116
117
  // we will be doing the transform work in the vite plugin hooks,
@@ -161,7 +162,8 @@ export const directivesPlugin = ({ projectRootDir, clientFiles, serverFiles, })
161
162
  code = await fs.readFile(args.path, "utf-8");
162
163
  }
163
164
  catch {
164
- verboseLog("Failed to read file: %s, environment=%s", args.path, env);
165
+ process.env.VERBOSE &&
166
+ log("Failed to read file: %s, environment=%s", args.path, env);
165
167
  return undefined;
166
168
  }
167
169
  const clientResult = await transformClientComponents(code, normalizedPath, {
@@ -172,7 +174,8 @@ export const directivesPlugin = ({ projectRootDir, clientFiles, serverFiles, })
172
174
  });
173
175
  if (clientResult) {
174
176
  log("Esbuild client component transformation successful for environment=%s, path=%s", env, args.path);
175
- verboseLog("Esbuild client component transformation for environment=%s, path=%s, code: %j", env, args.path, clientResult.code);
177
+ process.env.VERBOSE &&
178
+ log("Esbuild client component transformation for environment=%s, path=%s, code: %j", env, args.path, clientResult.code);
176
179
  return {
177
180
  contents: clientResult.code,
178
181
  loader: getLoader(args.path),
@@ -186,7 +189,8 @@ export const directivesPlugin = ({ projectRootDir, clientFiles, serverFiles, })
186
189
  loader: getLoader(args.path),
187
190
  };
188
191
  }
189
- verboseLog("Esbuild no transformation applied for environment=%s, path=%s", env, args.path);
192
+ process.env.VERBOSE &&
193
+ log("Esbuild no transformation applied for environment=%s, path=%s", env, args.path);
190
194
  });
191
195
  },
192
196
  });
@@ -52,7 +52,7 @@ export const EXPORT_PATTERNS = [
52
52
  export function findImportSpecifiers(id, code, ignoredImportPatterns, log) {
53
53
  const ext = path.extname(id).toLowerCase();
54
54
  const lang = ext === ".tsx" || ext === ".jsx" ? Lang.Tsx : SgLang.TypeScript;
55
- const logger = log ?? (() => { });
55
+ const logger = process.env.VERBOSE ? (log ?? (() => { })) : () => { };
56
56
  const results = [];
57
57
  try {
58
58
  // sgParse and lang must be provided by the consumer
@@ -101,7 +101,7 @@ export function findImportSpecifiers(id, code, ignoredImportPatterns, log) {
101
101
  export function findExports(id, code, log) {
102
102
  const ext = path.extname(id).toLowerCase();
103
103
  const lang = ext === ".tsx" || ext === ".jsx" ? Lang.Tsx : SgLang.TypeScript;
104
- const logger = log ?? (() => { });
104
+ const logger = process.env.VERBOSE ? (log ?? (() => { })) : () => { };
105
105
  const results = [];
106
106
  const seen = new Set(); // Track seen exports to avoid duplicates
107
107
  try {
@@ -10,7 +10,7 @@ import path from "path";
10
10
  export function findSsrImportSpecifiers(id, code, log) {
11
11
  const ext = path.extname(id).toLowerCase();
12
12
  const lang = ext === ".tsx" || ext === ".jsx" ? Lang.Tsx : SgLang.TypeScript;
13
- const logger = log ?? (() => { });
13
+ const logger = process.env.VERBOSE ? (log ?? (() => { })) : () => { };
14
14
  const imports = [];
15
15
  const dynamicImports = [];
16
16
  try {
@@ -32,6 +32,22 @@ export function findSsrImportSpecifiers(id, code, log) {
32
32
  pattern: `__vite_ssr_dynamic_import__('$SPECIFIER')`,
33
33
  list: dynamicImports,
34
34
  },
35
+ {
36
+ pattern: `__vite_ssr_import__("$SPECIFIER", $$$REST)`,
37
+ list: imports,
38
+ },
39
+ {
40
+ pattern: `__vite_ssr_import__('$SPECIFIER', $$$REST)`,
41
+ list: imports,
42
+ },
43
+ {
44
+ pattern: `__vite_ssr_dynamic_import__("$SPECIFIER", $$$REST)`,
45
+ list: dynamicImports,
46
+ },
47
+ {
48
+ pattern: `__vite_ssr_dynamic_import__('$SPECIFIER', $$$REST)`,
49
+ list: dynamicImports,
50
+ },
35
51
  ];
36
52
  for (const { pattern, list } of patterns) {
37
53
  const matches = root.root().findAll(pattern);
@@ -1,5 +1,4 @@
1
1
  import { type Plugin } from "vite";
2
- export declare const injectVitePreamble: ({ clientEntryPathnames, mode, }: {
2
+ export declare const injectVitePreamble: ({ clientEntryPathnames, }: {
3
3
  clientEntryPathnames: string[];
4
- mode: "development" | "production";
5
4
  }) => Plugin;
@@ -1,5 +1,5 @@
1
1
  import MagicString from "magic-string";
2
- export const injectVitePreamble = ({ clientEntryPathnames, mode, }) => ({
2
+ export const injectVitePreamble = ({ clientEntryPathnames, }) => ({
3
3
  name: "rwsdk:inject-vite-preamble",
4
4
  apply: "serve",
5
5
  transform(code, id) {
@@ -10,7 +10,7 @@ export const injectVitePreamble = ({ clientEntryPathnames, mode, }) => ({
10
10
  return;
11
11
  }
12
12
  // Only inject preamble in development mode
13
- if (mode !== "development") {
13
+ if (process.env.NODE_ENV !== "development") {
14
14
  return;
15
15
  }
16
16
  const s = new MagicString(code);
@@ -8,7 +8,7 @@ import { hasDirective as sourceHasDirective } from "./hasDirective.mjs";
8
8
  import { isJsFile } from "./isJsFile.mjs";
9
9
  import { invalidateModule } from "./invalidateModule.mjs";
10
10
  import { getShortName } from "../lib/getShortName.mjs";
11
- const verboseLog = debug("verbose:rwsdk:vite:hmr-plugin");
11
+ const log = debug("rwsdk:vite:hmr-plugin");
12
12
  const hasDirective = async (filepath, directive) => {
13
13
  if (!isJsFile(filepath)) {
14
14
  return false;
@@ -37,7 +37,18 @@ export const miniflareHMRPlugin = (givenOptions) => [
37
37
  name: "rwsdk:miniflare-hmr",
38
38
  async hotUpdate(ctx) {
39
39
  const { clientFiles, serverFiles, viteEnvironment: { name: environment }, workerEntryPathname: entry, } = givenOptions;
40
- verboseLog("Hot update: (env=%s) %s\nModule graph:\n\n%s", this.environment.name, ctx.file, dumpFullModuleGraph(ctx.server, this.environment.name));
40
+ if (process.env.VERBOSE) {
41
+ log(`Hot update: (env=${this.environment.name}) ${ctx.file}\nModule graph:\n\n${dumpFullModuleGraph(ctx.server, this.environment.name)}`);
42
+ }
43
+ if (this.environment.name === "ssr") {
44
+ log("SSR update, invalidating recursively", ctx.file);
45
+ invalidateModule(ctx.server, "ssr", ctx.file, {
46
+ invalidateImportersRecursively: true,
47
+ });
48
+ invalidateModule(ctx.server, environment, VIRTUAL_SSR_PREFIX +
49
+ normalizeModulePath(givenOptions.rootDir, ctx.file), { invalidateImportersRecursively: true });
50
+ return [];
51
+ }
41
52
  if (!["client", environment].includes(this.environment.name)) {
42
53
  return [];
43
54
  }
@@ -77,31 +88,25 @@ export const miniflareHMRPlugin = (givenOptions) => [
77
88
  const modules = Array.from(ctx.server.environments[environment].moduleGraph.getModulesByFile(ctx.file) ?? []);
78
89
  const isWorkerUpdate = ctx.file === entry ||
79
90
  modules.some((module) => hasEntryAsAncestor(module, entry));
80
- // The worker doesnt need an update
81
- // => Short circuit HMR
82
- if (!isWorkerUpdate) {
83
- return [];
84
- }
85
91
  // The worker needs an update, but this is the client environment
86
92
  // => Notify for HMR update of any css files imported by in worker, that are also in the client module graph
87
93
  // Why: There may have been changes to css classes referenced, which might css modules to change
88
94
  if (this.environment.name === "client") {
89
- for (const [_, module] of ctx.server.environments[environment]
90
- .moduleGraph.idToModuleMap) {
91
- // todo(justinvdm, 13 Dec 2024): We check+update _all_ css files in worker module graph,
92
- // but it could just be a subset of css files that are actually affected, depending
93
- // on the importers and imports of the changed file. We should be smarter about this.
94
- if (module.file && module.file.endsWith(".css")) {
95
- const clientModules = ctx.server.environments.client.moduleGraph.getModulesByFile(module.file);
96
- for (const clientModule of clientModules ?? []) {
97
- invalidateModule(ctx.server, "client", clientModule);
95
+ if (isWorkerUpdate) {
96
+ for (const [_, module] of ctx.server.environments[environment]
97
+ .moduleGraph.idToModuleMap) {
98
+ // todo(justinvdm, 13 Dec 2024): We check+update _all_ css files in worker module graph,
99
+ // but it could just be a subset of css files that are actually affected, depending
100
+ // on the importers and imports of the changed file. We should be smarter about this.
101
+ if (module.file && module.file.endsWith(".css")) {
102
+ const clientModules = ctx.server.environments.client.moduleGraph.getModulesByFile(module.file);
103
+ for (const clientModule of clientModules ?? []) {
104
+ invalidateModule(ctx.server, "client", clientModule);
105
+ }
98
106
  }
99
107
  }
100
108
  }
101
- // context(justinvdm, 10 Jul 2025): If this isn't a file with a client
102
- // directive or a css file, we shouldn't invalidate anything else to
103
- // avoid full page reload
104
- return hasClientDirective || ctx.file.endsWith(".css") ? undefined : [];
109
+ return ctx.modules;
105
110
  }
106
111
  // The worker needs an update, and the hot check is for the worker environment
107
112
  // => Notify for custom RSC-based HMR update, then short circuit HMR
@@ -0,0 +1,5 @@
1
+ import { ConfigEnv } from "vite";
2
+ type Mode = "development" | "production";
3
+ export declare const resolveMode: (env: ConfigEnv) => Mode;
4
+ export declare const ensureMode: () => Mode;
5
+ export {};
@@ -0,0 +1,25 @@
1
+ import debug from "debug";
2
+ const log = debug("rwsdk:vite:mode");
3
+ const initialNodeEnv = process.env.NODE_ENV;
4
+ let mode;
5
+ export const resolveMode = (env) => {
6
+ if (mode) {
7
+ return mode;
8
+ }
9
+ if (initialNodeEnv) {
10
+ mode = initialNodeEnv === "development" ? "development" : "production";
11
+ log(`Resolved mode: %s (from initial NODE_ENV=%s)`, mode, initialNodeEnv);
12
+ }
13
+ else {
14
+ mode =
15
+ env.command === "serve" || env.isPreview ? "development" : "production";
16
+ log(`Resolved mode: %s (env.command=%s, env.isPreview=%s)`, mode, env.isPreview, env.command);
17
+ }
18
+ return mode;
19
+ };
20
+ export const ensureMode = () => {
21
+ if (mode === undefined) {
22
+ throw new Error("RedwoodSDK: mode is not resolved yet");
23
+ }
24
+ return mode;
25
+ };
@@ -0,0 +1,2 @@
1
+ import { Plugin } from "vite";
2
+ export declare function modePlugin(): Plugin;
@@ -0,0 +1,10 @@
1
+ import { resolveMode } from "./mode.mjs";
2
+ export function modePlugin() {
3
+ return {
4
+ name: "rwsdk:mode",
5
+ enforce: "pre",
6
+ config(_, env) {
7
+ resolveMode(env);
8
+ },
9
+ };
10
+ }
@@ -3,7 +3,6 @@ import { ROOT_DIR } from "../lib/constants.mjs";
3
3
  import enhancedResolve from "enhanced-resolve";
4
4
  import { ensureAliasArray } from "./ensureAliasArray.mjs";
5
5
  const log = debug("rwsdk:vite:react-conditions-resolver-plugin");
6
- const verboseLog = debug("verbose:rwsdk:vite:react-conditions-resolver-plugin");
7
6
  export const ENV_REACT_IMPORTS = {
8
7
  worker: [
9
8
  "react",
@@ -47,18 +46,22 @@ export const ENV_IMPORT_MAPPINGS = Object.fromEntries(Object.keys(ENV_RESOLVERS)
47
46
  resolveEnvImportMappings(env),
48
47
  ]));
49
48
  function resolveEnvImportMappings(env) {
50
- verboseLog("Resolving environment import mappings for env=%s", env);
49
+ process.env.VERBOSE &&
50
+ log("Resolving environment import mappings for env=%s", env);
51
51
  const mappings = new Map();
52
52
  const reactImports = ENV_REACT_IMPORTS[env];
53
53
  for (const importRequest of reactImports) {
54
- verboseLog("Resolving import request=%s for env=%s", importRequest, env);
54
+ process.env.VERBOSE &&
55
+ log("Resolving import request=%s for env=%s", importRequest, env);
55
56
  let resolved = false;
56
57
  try {
57
58
  resolved = ENV_RESOLVERS[env](ROOT_DIR, importRequest);
58
- verboseLog("Successfully resolved %s to %s for env=%s", importRequest, resolved, env);
59
+ process.env.VERBOSE &&
60
+ log("Successfully resolved %s to %s for env=%s", importRequest, resolved, env);
59
61
  }
60
62
  catch {
61
- verboseLog("Failed to resolve %s for env=%s", importRequest, env);
63
+ process.env.VERBOSE &&
64
+ log("Failed to resolve %s for env=%s", importRequest, env);
62
65
  }
63
66
  if (resolved) {
64
67
  mappings.set(importRequest, resolved);
@@ -77,10 +80,12 @@ function createEsbuildResolverPlugin(envName) {
77
80
  name: `rwsdk:react-conditions-resolver-esbuild-${envName}`,
78
81
  setup(build) {
79
82
  build.onResolve({ filter: /.*/ }, (args) => {
80
- verboseLog("ESBuild resolving %s for env=%s, args=%O", args.path, envName, args);
83
+ process.env.VERBOSE &&
84
+ log("ESBuild resolving %s for env=%s, args=%O", args.path, envName, args);
81
85
  const resolved = mappings.get(args.path);
82
86
  if (resolved && args.importer !== "") {
83
- verboseLog("ESBuild resolving %s -> %s for env=%s", args.path, resolved, envName);
87
+ process.env.VERBOSE &&
88
+ log("ESBuild resolving %s -> %s for env=%s", args.path, resolved, envName);
84
89
  if (args.path === "react-server-dom-webpack/client.edge") {
85
90
  return;
86
91
  }
@@ -89,7 +94,8 @@ function createEsbuildResolverPlugin(envName) {
89
94
  };
90
95
  }
91
96
  else {
92
- verboseLog("ESBuild no resolution found for %s for env=%s", args.path, envName);
97
+ process.env.VERBOSE &&
98
+ log("ESBuild no resolution found for %s for env=%s", args.path, envName);
93
99
  }
94
100
  });
95
101
  },
@@ -124,7 +130,7 @@ export const reactConditionsResolverPlugin = () => {
124
130
  envConfig.optimizeDeps ??= {};
125
131
  envConfig.optimizeDeps.esbuildOptions ??= {};
126
132
  envConfig.optimizeDeps.esbuildOptions.define ??= {};
127
- envConfig.optimizeDeps.esbuildOptions.define["process.env.NODE_ENV"] = JSON.stringify(process.env.NODE_ENV ?? "production");
133
+ envConfig.optimizeDeps.esbuildOptions.define["process.env.NODE_ENV"] = JSON.stringify(process.env.NODE_ENV);
128
134
  envConfig.optimizeDeps.esbuildOptions.plugins ??= [];
129
135
  envConfig.optimizeDeps.esbuildOptions.plugins.push(esbuildPlugin);
130
136
  envConfig.optimizeDeps.include ??= [];
@@ -152,10 +158,12 @@ export const reactConditionsResolverPlugin = () => {
152
158
  if (!envName) {
153
159
  return;
154
160
  }
155
- verboseLog("Resolving id=%s, environment=%s, importer=%s", id, envName, importer);
161
+ process.env.VERBOSE &&
162
+ log("Resolving id=%s, environment=%s, importer=%s", id, envName, importer);
156
163
  const mappings = ENV_IMPORT_MAPPINGS[envName];
157
164
  if (!mappings) {
158
- verboseLog("No mappings found for environment: %s", envName);
165
+ process.env.VERBOSE &&
166
+ log("No mappings found for environment: %s", envName);
159
167
  return;
160
168
  }
161
169
  const resolved = mappings.get(id);
@@ -163,7 +171,8 @@ export const reactConditionsResolverPlugin = () => {
163
171
  log("Resolved %s -> %s for env=%s", id, resolved, envName);
164
172
  return resolved;
165
173
  }
166
- verboseLog("No resolution found for id=%s in env=%s", id, envName);
174
+ process.env.VERBOSE &&
175
+ log("No resolution found for id=%s in env=%s", id, envName);
167
176
  },
168
177
  },
169
178
  ];
@@ -2,7 +2,6 @@ import { InlineConfig } from "vite";
2
2
  export type RedwoodPluginOptions = {
3
3
  silent?: boolean;
4
4
  rootDir?: string;
5
- mode?: "development" | "production";
6
5
  includeCloudflarePlugin?: boolean;
7
6
  configPath?: string;
8
7
  entry?: {
@@ -30,8 +30,6 @@ const determineWorkerEntryPathname = async (projectRootDir, workerConfigPath, op
30
30
  };
31
31
  export const redwoodPlugin = async (options = {}) => {
32
32
  const projectRootDir = process.cwd();
33
- const mode = options.mode ??
34
- (process.env.NODE_ENV === "development" ? "development" : "production");
35
33
  const workerConfigPath = options.configPath ?? (await findWranglerConfig(projectRootDir));
36
34
  const workerEntryPathname = await determineWorkerEntryPathname(projectRootDir, workerConfigPath, options);
37
35
  const clientEntryPathnames = (Array.isArray(options.entry?.client)
@@ -57,7 +55,6 @@ export const redwoodPlugin = async (options = {}) => {
57
55
  return [
58
56
  devServerTimingPlugin(),
59
57
  configPlugin({
60
- mode,
61
58
  silent: options.silent ?? false,
62
59
  projectRootDir,
63
60
  clientEntryPathnames,
@@ -90,7 +87,7 @@ export const redwoodPlugin = async (options = {}) => {
90
87
  serverFiles,
91
88
  }),
92
89
  vitePreamblePlugin(),
93
- injectVitePreamble({ clientEntryPathnames, mode }),
90
+ injectVitePreamble({ clientEntryPathnames }),
94
91
  useClientLookupPlugin({
95
92
  projectRootDir,
96
93
  clientFiles,
@@ -2,7 +2,6 @@ import debug from "debug";
2
2
  import { SSR_BRIDGE_PATH } from "../lib/constants.mjs";
3
3
  import { findSsrImportSpecifiers } from "./findSsrSpecifiers.mjs";
4
4
  const log = debug("rwsdk:vite:ssr-bridge-plugin");
5
- const verboseLog = debug("verbose:rwsdk:vite:ssr-bridge-plugin");
6
5
  export const VIRTUAL_SSR_PREFIX = "virtual:rwsdk:ssr:";
7
6
  export const ssrBridgePlugin = ({ clientFiles, serverFiles, }) => {
8
7
  log("Initializing SSR bridge plugin with SSR_BRIDGE_PATH=%s", SSR_BRIDGE_PATH);
@@ -33,7 +32,8 @@ export const ssrBridgePlugin = ({ clientFiles, serverFiles, }) => {
33
32
  setup(build) {
34
33
  log("Setting up esbuild plugin to mark rwsdk/__ssr paths as external for worker");
35
34
  build.onResolve({ filter: /.*$/ }, (args) => {
36
- verboseLog("Esbuild onResolve called for path=%s, args=%O", args.path, args);
35
+ process.env.VERBOSE &&
36
+ log("Esbuild onResolve called for path=%s, args=%O", args.path, args);
37
37
  if (args.path === "rwsdk/__ssr_bridge") {
38
38
  log("Marking as external: %s", args.path);
39
39
  return {
@@ -48,7 +48,8 @@ export const ssrBridgePlugin = ({ clientFiles, serverFiles, }) => {
48
48
  }
49
49
  },
50
50
  async resolveId(id) {
51
- verboseLog("Resolving id=%s, environment=%s, isDev=%s", id, this.environment?.name, isDev);
51
+ process.env.VERBOSE &&
52
+ log("Resolving id=%s, environment=%s, isDev=%s", id, this.environment?.name, isDev);
52
53
  if (isDev) {
53
54
  // context(justinvdm, 27 May 2025): In dev, we need to dynamically load
54
55
  // SSR modules, so we return the virtual id so that the dynamic loading
@@ -77,10 +78,11 @@ export const ssrBridgePlugin = ({ clientFiles, serverFiles, }) => {
77
78
  return SSR_BRIDGE_PATH;
78
79
  }
79
80
  }
80
- verboseLog("No resolution for id=%s", id);
81
+ process.env.VERBOSE && log("No resolution for id=%s", id);
81
82
  },
82
83
  async load(id) {
83
- verboseLog("Loading id=%s, isDev=%s, environment=%s", id, isDev, this.environment.name);
84
+ process.env.VERBOSE &&
85
+ log("Loading id=%s, isDev=%s, environment=%s", id, isDev, this.environment.name);
84
86
  if (id.startsWith(VIRTUAL_SSR_PREFIX) &&
85
87
  this.environment.name === "worker") {
86
88
  const realId = id.slice(VIRTUAL_SSR_PREFIX.length);
@@ -88,32 +90,42 @@ export const ssrBridgePlugin = ({ clientFiles, serverFiles, }) => {
88
90
  if (isDev) {
89
91
  log("Dev mode: fetching SSR module for realPath=%s", realId);
90
92
  const result = await devServer?.environments.ssr.fetchModule(realId);
91
- verboseLog("Fetch module result: id=%s, result=%O", realId, result);
93
+ process.env.VERBOSE &&
94
+ log("Fetch module result: id=%s, result=%O", realId, result);
92
95
  const code = "code" in result ? result.code : undefined;
93
96
  log("Fetched SSR module code length: %d", code?.length || 0);
94
- const { imports, dynamicImports } = findSsrImportSpecifiers(realId, code || "", verboseLog);
95
- const allSpecifiers = [...new Set([...imports, ...dynamicImports])];
97
+ const { imports, dynamicImports } = findSsrImportSpecifiers(realId, code || "", log);
98
+ const allSpecifiers = [
99
+ ...new Set([...imports, ...dynamicImports]),
100
+ ].map((id) => id.startsWith("/@id/") ? id.slice("/@id/".length) : id);
96
101
  const switchCases = allSpecifiers
97
- .map((specifier) => ` case "${specifier}": return import("${VIRTUAL_SSR_PREFIX}${specifier}");`)
102
+ .map((specifier) => ` case "${specifier}": import("${VIRTUAL_SSR_PREFIX}${specifier}");`)
98
103
  .join("\n");
99
104
  const transformedCode = `
100
105
  await (async function(__vite_ssr_import__, __vite_ssr_dynamic_import__) {${code}})(
101
- (id, ...args) => {ssrImport(id); return __vite_ssr_import__('/@id/${VIRTUAL_SSR_PREFIX}' + id, ...args);},
102
- (id, ...args) => {ssrImport(id); return __vite_ssr_dynamic_import__('/@id/${VIRTUAL_SSR_PREFIX}' + id, ...args);}
106
+ __ssrImport.bind(null, false),
107
+ __ssrImport.bind(null, true)
103
108
  );
104
109
 
105
- function ssrImport(id) {
110
+ function __ssrImport(isDynamic, id, ...args) {
111
+ id = id.startsWith('/@id/') ? id.slice('/@id/'.length) : id;
112
+
106
113
  switch (id) {
107
114
  ${switchCases}
108
115
  }
116
+
117
+ return isDynamic
118
+ ? __vite_ssr_dynamic_import__("/@id/${VIRTUAL_SSR_PREFIX}" + id, ...args)
119
+ : __vite_ssr_import__("/@id/${VIRTUAL_SSR_PREFIX}" + id, ...args);
109
120
  }
110
121
  `;
111
122
  log("Transformed SSR module code length: %d", transformedCode.length);
112
- verboseLog("Transformed SSR module code for realId=%s: %s", realId, transformedCode);
123
+ process.env.VERBOSE &&
124
+ log("Transformed SSR module code for realId=%s: %s", realId, transformedCode);
113
125
  return transformedCode;
114
126
  }
115
127
  }
116
- verboseLog("No load handling for id=%s", id);
128
+ process.env.VERBOSE && log("No load handling for id=%s", id);
117
129
  },
118
130
  };
119
131
  return ssrBridgePlugin;
@@ -4,21 +4,19 @@ import { hasDirective } from "./hasDirective.mjs";
4
4
  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
- const verboseLogVite = debug("verbose:rwsdk:vite:transform-client-components:vite");
8
- const verboseLogEsbuild = debug("verbose:rwsdk:vite:transform-client-components:esbuild");
9
7
  export async function transformClientComponents(code, normalizedId, ctx) {
10
8
  const log = ctx.isEsbuild ? logEsbuild : logVite;
11
- const verboseLog = ctx.isEsbuild ? verboseLogEsbuild : verboseLogVite;
12
9
  log("Called transformClientComponents for id: id=%s", normalizedId);
13
10
  if (!hasDirective(code, "use client")) {
14
11
  log("Skipping: no 'use client' directive in id=%s", normalizedId);
15
- verboseLog(":VERBOSE: Returning code unchanged for id=%s:\n%s", normalizedId, code);
12
+ process.env.VERBOSE &&
13
+ log(":VERBOSE: Returning code unchanged for id=%s:\n%s", normalizedId, code);
16
14
  return;
17
15
  }
18
16
  log("Processing 'use client' module: id=%s", normalizedId);
19
17
  ctx.addClientModule?.(ctx.environmentName, normalizedId);
20
18
  // Parse exports using the findExports helper
21
- const exportInfos = findExports(normalizedId, code, verboseLog);
19
+ const exportInfos = findExports(normalizedId, code, log);
22
20
  const processedExports = [];
23
21
  let defaultExportInfo;
24
22
  // Helper to get the computed local name (with alias suffix if present)
@@ -62,7 +60,8 @@ export async function transformClientComponents(code, normalizedId, ctx) {
62
60
  const start = match.index;
63
61
  const end = match.index + match[0].length;
64
62
  s.remove(start, end);
65
- verboseLog("Removed 'use client' directive from normalizedId=%s", normalizedId);
63
+ process.env.VERBOSE &&
64
+ log("Removed 'use client' directive from normalizedId=%s", normalizedId);
66
65
  break; // Only remove the first one
67
66
  }
68
67
  const sourceMap = s.generateMap({
@@ -70,7 +69,8 @@ export async function transformClientComponents(code, normalizedId, ctx) {
70
69
  includeContent: true,
71
70
  hires: true,
72
71
  });
73
- verboseLog(":VERBOSE: SSR transformed code for %s:\n%s", normalizedId, s.toString());
72
+ process.env.VERBOSE &&
73
+ log(":VERBOSE: SSR transformed code for %s:\n%s", normalizedId, s.toString());
74
74
  return {
75
75
  code: s.toString(),
76
76
  map: sourceMap,
@@ -107,7 +107,8 @@ export async function transformClientComponents(code, normalizedId, ctx) {
107
107
  hires: true,
108
108
  });
109
109
  const finalResult = s.toString();
110
- verboseLog(":VERBOSE: Transformed code (env=%s, normalizedId=%s):\n%s", normalizedId, ctx.environmentName, finalResult);
110
+ process.env.VERBOSE &&
111
+ log(":VERBOSE: Transformed code (env=%s, normalizedId=%s):\n%s", normalizedId, ctx.environmentName, finalResult);
111
112
  return {
112
113
  code: finalResult,
113
114
  map: sourceMap,
@@ -5,15 +5,14 @@ import { findExports } from "./findSpecifiers.mjs";
5
5
  import { parse as sgParse, Lang as SgLang, Lang } from "@ast-grep/napi";
6
6
  import path from "path";
7
7
  const log = debug("rwsdk:vite:transform-server-functions");
8
- const verboseLog = debug("verbose:rwsdk:vite:transform-server-functions");
9
8
  export const findExportedFunctions = (code, normalizedId) => {
10
9
  return findExportInfo(code, normalizedId).localFunctions;
11
10
  };
12
11
  export const findExportInfo = (code, normalizedId) => {
13
- verboseLog("Finding exported functions in source file");
12
+ process.env.VERBOSE && log("Finding exported functions in source file");
14
13
  const localFunctions = new Set();
15
14
  const reExports = [];
16
- const exportInfos = findExports(normalizedId || "file.ts", code, verboseLog);
15
+ const exportInfos = findExports(normalizedId || "file.ts", code, log);
17
16
  for (const exportInfo of exportInfos) {
18
17
  if (exportInfo.isReExport && exportInfo.moduleSpecifier) {
19
18
  // For re-exports, we need to determine the original name by parsing the code
@@ -29,11 +28,13 @@ export const findExportInfo = (code, normalizedId) => {
29
28
  originalName: originalName,
30
29
  moduleSpecifier: exportInfo.moduleSpecifier,
31
30
  });
32
- verboseLog("Found re-exported function: %s (original: %s) from %s", exportInfo.name, originalName, exportInfo.moduleSpecifier);
31
+ process.env.VERBOSE &&
32
+ log("Found re-exported function: %s (original: %s) from %s", exportInfo.name, originalName, exportInfo.moduleSpecifier);
33
33
  }
34
34
  else {
35
35
  localFunctions.add(exportInfo.name);
36
- verboseLog("Found exported function: %s", exportInfo.name);
36
+ process.env.VERBOSE &&
37
+ log("Found exported function: %s", exportInfo.name);
37
38
  }
38
39
  }
39
40
  log("Found %d local functions: %O", localFunctions.size, Array.from(localFunctions));
@@ -55,7 +56,7 @@ function findDefaultFunctionName(code, normalizedId) {
55
56
  }
56
57
  }
57
58
  catch (err) {
58
- verboseLog("Error finding default function name: %O", err);
59
+ process.env.VERBOSE && log("Error finding default function name: %O", err);
59
60
  }
60
61
  return null;
61
62
  }
@@ -79,15 +80,17 @@ function hasDefaultExport(code, normalizedId) {
79
80
  }
80
81
  }
81
82
  catch (err) {
82
- verboseLog("Error checking for default export: %O", err);
83
+ process.env.VERBOSE && log("Error checking for default export: %O", err);
83
84
  }
84
85
  return false;
85
86
  }
86
87
  export const transformServerFunctions = (code, normalizedId, environment, serverFiles, addServerModule) => {
87
- verboseLog("Transform server functions called for normalizedId=%s, environment=%s", normalizedId, environment);
88
+ process.env.VERBOSE &&
89
+ log("Transform server functions called for normalizedId=%s, environment=%s", normalizedId, environment);
88
90
  if (!hasDirective(code, "use server")) {
89
91
  log("Skipping: no 'use server' directive in id=%s", normalizedId);
90
- verboseLog(":VERBOSE: Returning code unchanged for id=%s:\n%s", normalizedId, code);
92
+ process.env.VERBOSE &&
93
+ log(":VERBOSE: Returning code unchanged for id=%s:\n%s", normalizedId, code);
91
94
  return;
92
95
  }
93
96
  log("Processing 'use server' module: normalizedId=%s, environment=%s", normalizedId, environment);
@@ -144,7 +147,8 @@ export const transformServerFunctions = (code, normalizedId, environment, server
144
147
  const start = match.index;
145
148
  const end = match.index + match[0].length;
146
149
  s.remove(start, end);
147
- verboseLog("Removed 'use server' directive from normalizedId=%s", normalizedId);
150
+ process.env.VERBOSE &&
151
+ log("Removed 'use server' directive from normalizedId=%s", normalizedId);
148
152
  break; // Only remove the first one
149
153
  }
150
154
  // Add imports at the very beginning
@@ -239,7 +243,8 @@ export const transformServerFunctions = (code, normalizedId, environment, server
239
243
  }
240
244
  }
241
245
  catch (err) {
242
- verboseLog("Error processing default function: %O", err);
246
+ process.env.VERBOSE &&
247
+ log("Error processing default function: %O", err);
243
248
  }
244
249
  }
245
250
  // Add registration calls at the end
@@ -286,5 +291,6 @@ export const transformServerFunctions = (code, normalizedId, environment, server
286
291
  }),
287
292
  };
288
293
  }
289
- verboseLog("No transformation applied for environment=%s, normalizedId=%s", environment, normalizedId);
294
+ process.env.VERBOSE &&
295
+ log("No transformation applied for environment=%s, normalizedId=%s", environment, normalizedId);
290
296
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rwsdk",
3
- "version": "0.1.14",
3
+ "version": "0.1.15-test.20250714213423",
4
4
  "description": "Build fast, server-driven webapps on Cloudflare with SSR, RSC, and realtime",
5
5
  "type": "module",
6
6
  "bin": {