rwsdk 1.0.0-beta.30 → 1.0.0-beta.30-test.20251120210809
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.
- package/dist/runtime/entries/no-react-server-ssr-bridge.d.ts +0 -0
- package/dist/runtime/entries/no-react-server-ssr-bridge.js +2 -0
- package/dist/runtime/requestInfo/worker.d.ts +0 -1
- package/dist/runtime/requestInfo/worker.js +1 -9
- package/dist/vite/cloudflarePreInitPlugin.d.mts +11 -0
- package/dist/vite/cloudflarePreInitPlugin.mjs +40 -0
- package/dist/vite/createDirectiveLookupPlugin.mjs +10 -7
- package/dist/vite/devServerTimingPlugin.mjs +4 -0
- package/dist/vite/directiveModulesDevPlugin.mjs +8 -0
- package/dist/vite/directivesPlugin.mjs +4 -4
- package/dist/vite/hmrStabilityPlugin.mjs +6 -1
- package/dist/vite/injectVitePreamblePlugin.mjs +0 -4
- package/dist/vite/knownDepsResolverPlugin.mjs +24 -5
- package/dist/vite/miniflareHMRPlugin.mjs +5 -0
- package/dist/vite/redwoodPlugin.mjs +2 -0
- package/dist/vite/runDirectivesScan.mjs +13 -4
- package/dist/vite/ssrBridgePlugin.mjs +14 -7
- package/dist/vite/staleDepRetryPlugin.mjs +6 -1
- package/dist/vite/transformJsxScriptTagsPlugin.mjs +0 -4
- package/dist/vite/virtualPlugin.mjs +6 -7
- package/package.json +1 -1
|
File without changes
|
|
@@ -2,7 +2,6 @@ import { DefaultAppContext, RequestInfo } from "./types";
|
|
|
2
2
|
type DefaultRequestInfo = RequestInfo<DefaultAppContext>;
|
|
3
3
|
export declare const requestInfo: DefaultRequestInfo;
|
|
4
4
|
export declare function getRequestInfo(): RequestInfo;
|
|
5
|
-
export declare function waitForRequestInfo(): Promise<DefaultRequestInfo>;
|
|
6
5
|
export declare function runWithRequestInfo<Result>(nextRequestInfo: DefaultRequestInfo, fn: () => Result): Result;
|
|
7
6
|
export declare function runWithRequestInfoOverrides<Result>(overrides: Partial<DefaultRequestInfo>, fn: () => Result): Result;
|
|
8
7
|
export {};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from "async_hooks";
|
|
2
2
|
import { defineRwState } from "rwsdk/__state";
|
|
3
|
-
const requestInfoDeferred = defineRwState("requestInfoDeferred", () => Promise.withResolvers());
|
|
4
3
|
const requestInfoStore = defineRwState("requestInfoStore", () => new AsyncLocalStorage());
|
|
5
4
|
const requestInfoBase = {};
|
|
6
5
|
const REQUEST_INFO_KEYS = ["request", "params", "ctx", "rw", "cf", "response"];
|
|
@@ -22,15 +21,8 @@ export function getRequestInfo() {
|
|
|
22
21
|
}
|
|
23
22
|
return store;
|
|
24
23
|
}
|
|
25
|
-
export function waitForRequestInfo() {
|
|
26
|
-
return requestInfoDeferred.promise;
|
|
27
|
-
}
|
|
28
24
|
export function runWithRequestInfo(nextRequestInfo, fn) {
|
|
29
|
-
|
|
30
|
-
requestInfoDeferred.resolve(nextRequestInfo);
|
|
31
|
-
return fn();
|
|
32
|
-
};
|
|
33
|
-
return requestInfoStore.run(nextRequestInfo, runWithRequestInfoFn);
|
|
25
|
+
return requestInfoStore.run(nextRequestInfo, fn);
|
|
34
26
|
}
|
|
35
27
|
export function runWithRequestInfoOverrides(overrides, fn) {
|
|
36
28
|
const requestInfo = requestInfoStore.getStore();
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Plugin } from "vite";
|
|
2
|
+
/**
|
|
3
|
+
* Plugin that performs initialization workarounds that must run before
|
|
4
|
+
* the Cloudflare plugin's `configureServer` hook executes.
|
|
5
|
+
*
|
|
6
|
+
* Cloudflare plugin v1.15.0 executes the worker entry file during
|
|
7
|
+
* `configureServer` to detect exports, which triggers SSR code evaluation
|
|
8
|
+
* before normal server initialization completes. This plugin ensures
|
|
9
|
+
* required systems are initialized beforehand.
|
|
10
|
+
*/
|
|
11
|
+
export declare const cloudflarePreInitPlugin: () => Plugin;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin that performs initialization workarounds that must run before
|
|
3
|
+
* the Cloudflare plugin's `configureServer` hook executes.
|
|
4
|
+
*
|
|
5
|
+
* Cloudflare plugin v1.15.0 executes the worker entry file during
|
|
6
|
+
* `configureServer` to detect exports, which triggers SSR code evaluation
|
|
7
|
+
* before normal server initialization completes. This plugin ensures
|
|
8
|
+
* required systems are initialized beforehand.
|
|
9
|
+
*/
|
|
10
|
+
export const cloudflarePreInitPlugin = () => {
|
|
11
|
+
return {
|
|
12
|
+
name: "rwsdk:cloudflare-pre-init",
|
|
13
|
+
// context(justinvdm, 20 Jan 2025): This plugin must run before the
|
|
14
|
+
// Cloudflare plugin's `configureServer` hook. The Cloudflare plugin
|
|
15
|
+
// executes the worker entry file during `configureServer` to detect
|
|
16
|
+
// exports, and blocks the rest of the configureServer plugins until the
|
|
17
|
+
// request is complete. We must initialize required systems (SSR dependency
|
|
18
|
+
// optimizer + our own plugins to them, as well as CSS plugin's moduleCache)
|
|
19
|
+
// before this happens to prevent errors.
|
|
20
|
+
enforce: "pre",
|
|
21
|
+
async configureServer(server) {
|
|
22
|
+
// context(justinvdm, 20 Jan 2025): Initialize SSR dependency optimizer before
|
|
23
|
+
// Cloudflare plugin triggers SSR code evaluation. This ensures dependencies
|
|
24
|
+
// in `optimizeDeps.include` (like `react-dom/server.edge`) are correctly
|
|
25
|
+
// registered before they are discovered lazily.
|
|
26
|
+
if (server.environments.ssr?.depsOptimizer) {
|
|
27
|
+
await server.environments.ssr.depsOptimizer.init();
|
|
28
|
+
}
|
|
29
|
+
// context(justinvdm, 20 Jan 2025): Initialize CSS plugin's shared moduleCache
|
|
30
|
+
// before CSS modules are processed. The Cloudflare plugin's export detection
|
|
31
|
+
// can trigger CSS module processing in the SSR environment during `configureServer`,
|
|
32
|
+
// which happens before `initServer` runs. Vite's CSS plugin uses a shared
|
|
33
|
+
// `moduleCache` that is initialized in the client environment's `buildStart` hook.
|
|
34
|
+
// By calling `buildStart` here (which is idempotent), we ensure the CSS plugin's
|
|
35
|
+
// cache is initialized before CSS modules are processed, preventing "Cannot read
|
|
36
|
+
// properties of undefined (reading 'set')" errors.
|
|
37
|
+
await server.environments.client.pluginContainer.buildStart();
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
};
|
|
@@ -42,6 +42,10 @@ export const createDirectiveLookupPlugin = async ({ projectRootDir, files, confi
|
|
|
42
42
|
log("Development mode: %s", isDev);
|
|
43
43
|
},
|
|
44
44
|
configureServer(server) {
|
|
45
|
+
// context(justinvdm, 19 Nov 2025): This hook simply saves a reference
|
|
46
|
+
// to the dev server instance for use in other hooks. Unlike plugins that
|
|
47
|
+
// must run before the Cloudflare plugin to prevent startup deadlocks,
|
|
48
|
+
// its execution order is not critical, so `enforce: 'pre'` is not needed.
|
|
45
49
|
devServer = server;
|
|
46
50
|
},
|
|
47
51
|
configEnvironment(env, viteConfig) {
|
|
@@ -97,9 +101,12 @@ export const createDirectiveLookupPlugin = async ({ projectRootDir, files, confi
|
|
|
97
101
|
log("Skipping optimizeDeps and aliasing for environment: %s", env);
|
|
98
102
|
}
|
|
99
103
|
},
|
|
100
|
-
resolveId(source) {
|
|
101
|
-
// Skip during directive scanning to avoid performance issues
|
|
102
|
-
|
|
104
|
+
resolveId(source, _importer, options) {
|
|
105
|
+
// Skip during our directive scanning to avoid performance issues
|
|
106
|
+
// context(justinvdm, 20 Jan 2025): We check options.custom?.rwsdk?.directiveScan to distinguish
|
|
107
|
+
// between our directive scan (which should skip) and external calls like Cloudflare's early
|
|
108
|
+
// dispatch (which should be handled normally).
|
|
109
|
+
if (options?.custom?.rwsdk?.directiveScan === true) {
|
|
103
110
|
return;
|
|
104
111
|
}
|
|
105
112
|
if (source !== `${config.virtualModuleName}.js`) {
|
|
@@ -140,10 +147,6 @@ export const createDirectiveLookupPlugin = async ({ projectRootDir, files, confi
|
|
|
140
147
|
return source;
|
|
141
148
|
},
|
|
142
149
|
async load(id) {
|
|
143
|
-
// Skip during directive scanning to avoid performance issues
|
|
144
|
-
if (process.env.RWSDK_DIRECTIVE_SCAN_ACTIVE) {
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
150
|
if (id === config.virtualModuleName + ".js") {
|
|
148
151
|
log("Loading %s module with %d files", config.virtualModuleName, files.size);
|
|
149
152
|
const environment = this.environment?.name || "client";
|
|
@@ -6,6 +6,10 @@ export const devServerTimingPlugin = () => {
|
|
|
6
6
|
return {
|
|
7
7
|
name: "rwsdk:dev-server-timing",
|
|
8
8
|
configureServer(server) {
|
|
9
|
+
// context(justinvdm, 19 Nov 2025): This hook adds a middleware for
|
|
10
|
+
// logging the time to first response. Unlike other plugins that must
|
|
11
|
+
// run before the Cloudflare plugin to prevent startup deadlocks, its
|
|
12
|
+
// execution order is not critical, so `enforce: 'pre'` is not needed.
|
|
9
13
|
server.middlewares.use((_req, res, next) => {
|
|
10
14
|
if (!hasLoggedFirstResponse) {
|
|
11
15
|
res.on("finish", () => {
|
|
@@ -37,7 +37,15 @@ export const directiveModulesDevPlugin = ({ clientFiles, serverFiles, projectRoo
|
|
|
37
37
|
const APP_SERVER_BARREL_PATH = path.join(tempDir, "app-server-barrel.js");
|
|
38
38
|
return {
|
|
39
39
|
name: "rwsdk:directive-modules-dev",
|
|
40
|
+
enforce: "pre",
|
|
40
41
|
configureServer(server) {
|
|
42
|
+
// context(justinvdm, 19 Nov 2025): We must run this hook before the
|
|
43
|
+
// Cloudflare plugin's `configureServer` hook. The Cloudflare plugin makes
|
|
44
|
+
// a request back to the dev server to determine worker exports, which
|
|
45
|
+
// triggers Vite's dependency optimizer. Our esbuild plugin for the
|
|
46
|
+
// optimizer blocks on `scanPromise`. By running this first with `enforce: 'pre'`,
|
|
47
|
+
// we ensure our scan is kicked off before the Cloudflare plugin can trigger
|
|
48
|
+
// the optimizer, preventing a deadlock.
|
|
41
49
|
if (!process.env.VITE_IS_DEV_SERVER) {
|
|
42
50
|
resolveScanPromise();
|
|
43
51
|
return;
|
|
@@ -35,6 +35,10 @@ export const directivesPlugin = ({ projectRootDir, clientFiles, serverFiles, })
|
|
|
35
35
|
isBuild = config.command === "build";
|
|
36
36
|
},
|
|
37
37
|
configureServer(server) {
|
|
38
|
+
// context(justinvdm, 19 Nov 2025): This hook adds a middleware to track
|
|
39
|
+
// when the first server response has finished. Unlike plugins that must
|
|
40
|
+
// run before the Cloudflare plugin to prevent startup deadlocks, its
|
|
41
|
+
// execution order is not critical, so `enforce: 'pre'` is not needed.
|
|
38
42
|
devServer = server;
|
|
39
43
|
devServer.middlewares.use((_req, res, next) => {
|
|
40
44
|
// context(justinvdm, 15 Jun 2025): We want to watch for new client and server modules
|
|
@@ -52,10 +56,6 @@ export const directivesPlugin = ({ projectRootDir, clientFiles, serverFiles, })
|
|
|
52
56
|
});
|
|
53
57
|
},
|
|
54
58
|
async transform(code, id) {
|
|
55
|
-
// Skip during directive scanning to avoid performance issues
|
|
56
|
-
if (process.env.RWSDK_DIRECTIVE_SCAN_ACTIVE) {
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
59
|
if (isBuild &&
|
|
60
60
|
this.environment?.name === "worker" &&
|
|
61
61
|
process.env.RWSDK_BUILD_PASS !== "worker") {
|
|
@@ -41,7 +41,12 @@ export function hmrStabilityPlugin() {
|
|
|
41
41
|
return null;
|
|
42
42
|
},
|
|
43
43
|
configureServer(server) {
|
|
44
|
-
//
|
|
44
|
+
// context(justinvdm, 19 Nov 2025): This hook adds an error handling
|
|
45
|
+
// middleware for stale dependency errors. It runs in a returned function,
|
|
46
|
+
// which intentionally places it late in the middleware stack. Unlike
|
|
47
|
+
// other plugins that must run before the Cloudflare plugin to prevent
|
|
48
|
+
// startup deadlocks, its timing is not critical, so `enforce: 'pre'`
|
|
49
|
+
// is not needed.
|
|
45
50
|
return () => {
|
|
46
51
|
server.middlewares.use(async function rwsdkStaleBundleErrorHandler(err, req, res, next) {
|
|
47
52
|
if (err &&
|
|
@@ -4,10 +4,6 @@ export const injectVitePreamble = ({ clientEntryPoints, projectRootDir, }) => ({
|
|
|
4
4
|
name: "rwsdk:inject-vite-preamble",
|
|
5
5
|
apply: "serve",
|
|
6
6
|
transform(code, id) {
|
|
7
|
-
// Skip during directive scanning to avoid performance issues
|
|
8
|
-
if (process.env.RWSDK_DIRECTIVE_SCAN_ACTIVE) {
|
|
9
|
-
return;
|
|
10
|
-
}
|
|
11
7
|
if (this.environment.name !== "client") {
|
|
12
8
|
return;
|
|
13
9
|
}
|
|
@@ -95,15 +95,32 @@ export const knownDepsResolverPlugin = ({ projectRootDir, }) => {
|
|
|
95
95
|
if (!mappings) {
|
|
96
96
|
return null;
|
|
97
97
|
}
|
|
98
|
+
// Create reverse mapping from slugified names to original imports
|
|
99
|
+
// Vite converts "react-dom/server.edge" -> "react-dom_server__edge"
|
|
100
|
+
// Pattern: / becomes _, . becomes __
|
|
101
|
+
const slugifiedToOriginal = new Map();
|
|
102
|
+
for (const [original, resolved] of mappings) {
|
|
103
|
+
const slugified = original.replace(/\//g, "_").replace(/\./g, "__");
|
|
104
|
+
slugifiedToOriginal.set(slugified, original);
|
|
105
|
+
}
|
|
98
106
|
return {
|
|
99
107
|
name: `rwsdk:known-dependencies-resolver-esbuild-${envName}`,
|
|
100
108
|
setup(build) {
|
|
101
109
|
build.onResolve({ filter: /.*/ }, (args) => {
|
|
102
110
|
let resolved = mappings.get(args.path);
|
|
111
|
+
// If not found, check if it's a slugified version
|
|
112
|
+
if (!resolved) {
|
|
113
|
+
const originalImport = slugifiedToOriginal.get(args.path);
|
|
114
|
+
if (originalImport) {
|
|
115
|
+
resolved = mappings.get(originalImport);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
103
118
|
if (!resolved) {
|
|
104
119
|
resolved = resolveKnownImport(args.path, envName, projectRootDir);
|
|
105
120
|
}
|
|
106
|
-
|
|
121
|
+
// Resolve for both entry points (importer === '') and regular imports
|
|
122
|
+
// Entry points come from optimizeDeps.include and are critical to intercept
|
|
123
|
+
if (resolved) {
|
|
107
124
|
if (args.path === "react-server-dom-webpack/client.edge") {
|
|
108
125
|
return;
|
|
109
126
|
}
|
|
@@ -118,7 +135,6 @@ export const knownDepsResolverPlugin = ({ projectRootDir, }) => {
|
|
|
118
135
|
return [
|
|
119
136
|
{
|
|
120
137
|
name: "rwsdk:known-dependencies-resolver:config",
|
|
121
|
-
enforce: "post",
|
|
122
138
|
config(config, { command }) {
|
|
123
139
|
isBuild = command === "build";
|
|
124
140
|
log("Configuring plugin for command=%s", command);
|
|
@@ -162,9 +178,12 @@ export const knownDepsResolverPlugin = ({ projectRootDir, }) => {
|
|
|
162
178
|
{
|
|
163
179
|
name: "rwsdk:known-dependencies-resolver:resolveId",
|
|
164
180
|
enforce: "pre",
|
|
165
|
-
async resolveId(id, importer) {
|
|
166
|
-
// Skip during directive scanning to avoid performance issues
|
|
167
|
-
|
|
181
|
+
async resolveId(id, importer, options) {
|
|
182
|
+
// Skip during our directive scanning to avoid performance issues
|
|
183
|
+
// context(justinvdm, 20 Jan 2025): We check options.custom?.rwsdk?.directiveScan to distinguish
|
|
184
|
+
// between our directive scan (which should skip) and external calls like Cloudflare's early
|
|
185
|
+
// dispatch (which should be handled normally).
|
|
186
|
+
if (options?.custom?.rwsdk?.directiveScan === true) {
|
|
168
187
|
return;
|
|
169
188
|
}
|
|
170
189
|
if (!isBuild) {
|
|
@@ -37,6 +37,11 @@ export const miniflareHMRPlugin = (givenOptions) => [
|
|
|
37
37
|
{
|
|
38
38
|
name: "rwsdk:miniflare-hmr",
|
|
39
39
|
configureServer(server) {
|
|
40
|
+
// context(justinvdm, 19 Nov 2025): This hook sets up an error handler
|
|
41
|
+
// middleware. It runs in a returned function, which intentionally
|
|
42
|
+
// places it late in the middleware stack. Unlike plugins that must
|
|
43
|
+
// run before the Cloudflare plugin to prevent startup deadlocks, its
|
|
44
|
+
// timing is not critical, so `enforce: 'pre'` is not needed.
|
|
40
45
|
return () => {
|
|
41
46
|
server.middlewares.use(function rwsdkDevServerErrorHandler(err, _req, _res, next) {
|
|
42
47
|
if (err) {
|
|
@@ -10,6 +10,7 @@ import { pathExists } from "fs-extra";
|
|
|
10
10
|
import { $ } from "../lib/$.mjs";
|
|
11
11
|
import { findWranglerConfig } from "../lib/findWranglerConfig.mjs";
|
|
12
12
|
import { hasPkgScript } from "../lib/hasPkgScript.mjs";
|
|
13
|
+
import { cloudflarePreInitPlugin } from "./cloudflarePreInitPlugin.mjs";
|
|
13
14
|
import { configPlugin } from "./configPlugin.mjs";
|
|
14
15
|
import { devServerTimingPlugin } from "./devServerTimingPlugin.mjs";
|
|
15
16
|
import { directiveModulesDevPlugin } from "./directiveModulesDevPlugin.mjs";
|
|
@@ -106,6 +107,7 @@ export const redwoodPlugin = async (options = {}) => {
|
|
|
106
107
|
projectRootDir,
|
|
107
108
|
}),
|
|
108
109
|
knownDepsResolverPlugin({ projectRootDir }),
|
|
110
|
+
cloudflarePreInitPlugin(),
|
|
109
111
|
tsconfigPaths({ root: projectRootDir }),
|
|
110
112
|
shouldIncludeCloudflarePlugin
|
|
111
113
|
? cloudflare({
|
|
@@ -87,8 +87,6 @@ export function classifyModule({ contents, inheritedEnv, }) {
|
|
|
87
87
|
}
|
|
88
88
|
export const runDirectivesScan = async ({ rootConfig, environments, clientFiles, serverFiles, entries: initialEntries, }) => {
|
|
89
89
|
deferredLog("\n… (rwsdk) Scanning for 'use client' and 'use server' directives...");
|
|
90
|
-
// Set environment variable to indicate scanning is in progress
|
|
91
|
-
process.env.RWSDK_DIRECTIVE_SCAN_ACTIVE = "true";
|
|
92
90
|
try {
|
|
93
91
|
const fileContentCache = new Map();
|
|
94
92
|
const directiveCheckCache = new Map();
|
|
@@ -197,6 +195,19 @@ export const runDirectivesScan = async ({ rootConfig, environments, clientFiles,
|
|
|
197
195
|
log("Resolution result:", resolved);
|
|
198
196
|
const resolvedPath = resolved?.id;
|
|
199
197
|
if (resolvedPath && path.isAbsolute(resolvedPath)) {
|
|
198
|
+
try {
|
|
199
|
+
const stats = await fsp.stat(resolvedPath);
|
|
200
|
+
if (stats.isDirectory()) {
|
|
201
|
+
log("Resolved path is a directory, marking as external to avoid scan error:", resolvedPath);
|
|
202
|
+
return { external: true };
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
catch (e) {
|
|
206
|
+
// This can happen for virtual modules or special paths that don't
|
|
207
|
+
// exist on the filesystem. We can safely externalize them.
|
|
208
|
+
log("Could not stat resolved path, marking as external:", resolvedPath);
|
|
209
|
+
return { external: true };
|
|
210
|
+
}
|
|
200
211
|
// Normalize the path for esbuild compatibility
|
|
201
212
|
const normalizedPath = normalizeModulePath(resolvedPath, rootConfig.root, { absolute: true });
|
|
202
213
|
log("Normalized path:", normalizedPath);
|
|
@@ -290,8 +301,6 @@ export const runDirectivesScan = async ({ rootConfig, environments, clientFiles,
|
|
|
290
301
|
throw new Error(`RWSDK directive scan failed:\n${e.stack}`);
|
|
291
302
|
}
|
|
292
303
|
finally {
|
|
293
|
-
// Always clear the scanning flag when done
|
|
294
|
-
delete process.env.RWSDK_DIRECTIVE_SCAN_ACTIVE;
|
|
295
304
|
deferredLog("✔ (rwsdk) Done scanning for 'use client' and 'use server' directives.");
|
|
296
305
|
process.env.VERBOSE &&
|
|
297
306
|
log("Client/server files after scanning: client=%O, server=%O", Array.from(clientFiles), Array.from(serverFiles));
|
|
@@ -12,6 +12,10 @@ export const ssrBridgePlugin = ({ clientFiles, serverFiles, }) => {
|
|
|
12
12
|
name: "rwsdk:ssr-bridge",
|
|
13
13
|
enforce: "pre",
|
|
14
14
|
configureServer(server) {
|
|
15
|
+
// context(justinvdm, 19 Nov 2025): This plugin patches the dev server's
|
|
16
|
+
// HMR and optimizer behavior to coordinate the `ssr` and `worker`
|
|
17
|
+
// environments. It runs with `enforce: 'pre'` to ensure these patches
|
|
18
|
+
// are in place before other plugins start interacting with the server.
|
|
15
19
|
devServer = server;
|
|
16
20
|
const ssrHot = server.environments.ssr.hot;
|
|
17
21
|
const originalSsrHotSend = ssrHot.send;
|
|
@@ -54,12 +58,14 @@ export const ssrBridgePlugin = ({ clientFiles, serverFiles, }) => {
|
|
|
54
58
|
config.optimizeDeps.esbuildOptions.plugins.push({
|
|
55
59
|
name: "rwsdk-ssr-external",
|
|
56
60
|
setup(build) {
|
|
61
|
+
console.log("[TIMING] rwsdk-ssr-external.setup: START - Plugin setup function called");
|
|
57
62
|
log("Setting up esbuild plugin to mark rwsdk/__ssr paths as external for worker");
|
|
58
63
|
build.onResolve({ filter: /.*$/ }, (args) => {
|
|
59
64
|
process.env.VERBOSE &&
|
|
60
65
|
log("Esbuild onResolve called for path=%s, args=%O", args.path, args);
|
|
61
66
|
if (args.path === "rwsdk/__ssr_bridge" ||
|
|
62
67
|
args.path.startsWith(VIRTUAL_SSR_PREFIX)) {
|
|
68
|
+
console.log(`[TIMING] rwsdk-ssr-external.onResolve: Intercepted ${args.path}`);
|
|
63
69
|
log("Marking as external: %s", args.path);
|
|
64
70
|
return {
|
|
65
71
|
path: args.path,
|
|
@@ -67,14 +73,19 @@ export const ssrBridgePlugin = ({ clientFiles, serverFiles, }) => {
|
|
|
67
73
|
};
|
|
68
74
|
}
|
|
69
75
|
});
|
|
76
|
+
console.log("[TIMING] rwsdk-ssr-external.setup: COMPLETE - onResolve hook registered");
|
|
70
77
|
},
|
|
71
78
|
});
|
|
72
79
|
log("Worker environment esbuild configuration complete");
|
|
73
80
|
}
|
|
74
81
|
},
|
|
75
|
-
async resolveId(id, importer) {
|
|
76
|
-
// Skip during directive scanning to avoid performance issues
|
|
77
|
-
|
|
82
|
+
async resolveId(id, importer, options) {
|
|
83
|
+
// Skip during our directive scanning to avoid performance issues
|
|
84
|
+
// context(justinvdm, 20 Jan 2025): We check options.custom?.rwsdk?.directiveScan to distinguish
|
|
85
|
+
// between our directive scan (which should skip) and external calls like Cloudflare's early
|
|
86
|
+
// dispatch (which should be handled normally). This prevents race conditions where external
|
|
87
|
+
// calls happen during directive scanning.
|
|
88
|
+
if (options?.custom?.rwsdk?.directiveScan === true) {
|
|
78
89
|
return;
|
|
79
90
|
}
|
|
80
91
|
// context(justinvdm, 19 Nov 2025):
|
|
@@ -133,10 +144,6 @@ export const ssrBridgePlugin = ({ clientFiles, serverFiles, }) => {
|
|
|
133
144
|
}
|
|
134
145
|
},
|
|
135
146
|
async load(id) {
|
|
136
|
-
// Skip during directive scanning to avoid performance issues
|
|
137
|
-
if (process.env.RWSDK_DIRECTIVE_SCAN_ACTIVE) {
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
147
|
if (id.startsWith(VIRTUAL_SSR_PREFIX) &&
|
|
141
148
|
this.environment.name === "worker") {
|
|
142
149
|
const realId = id.slice(VIRTUAL_SSR_PREFIX.length);
|
|
@@ -43,7 +43,12 @@ export function staleDepRetryPlugin() {
|
|
|
43
43
|
return null;
|
|
44
44
|
},
|
|
45
45
|
configureServer(server) {
|
|
46
|
-
//
|
|
46
|
+
// context(justinvdm, 19 Nov 2025): This hook adds an error handling
|
|
47
|
+
// middleware for stale dependency errors. It runs in a returned function,
|
|
48
|
+
// which intentionally places it late in the middleware stack. Unlike
|
|
49
|
+
// other plugins that must run before the Cloudflare plugin to prevent
|
|
50
|
+
// startup deadlocks, its timing is not critical, so `enforce: 'pre'`
|
|
51
|
+
// is not needed.
|
|
47
52
|
return () => {
|
|
48
53
|
server.middlewares.use(async function rwsdkStaleBundleErrorHandler(err, req, res, next) {
|
|
49
54
|
if (err &&
|
|
@@ -319,10 +319,6 @@ export const transformJsxScriptTagsPlugin = ({ clientEntryPoints, projectRootDir
|
|
|
319
319
|
isBuild = config.command === "build";
|
|
320
320
|
},
|
|
321
321
|
async transform(code, id) {
|
|
322
|
-
// Skip during directive scanning to avoid performance issues
|
|
323
|
-
if (process.env.RWSDK_DIRECTIVE_SCAN_ACTIVE) {
|
|
324
|
-
return;
|
|
325
|
-
}
|
|
326
322
|
if (isBuild &&
|
|
327
323
|
this.environment?.name === "worker" &&
|
|
328
324
|
process.env.RWSDK_BUILD_PASS !== "worker") {
|
|
@@ -3,9 +3,12 @@ export const virtualPlugin = (name, load) => {
|
|
|
3
3
|
name = "virtual:" + name;
|
|
4
4
|
return {
|
|
5
5
|
name: `rwsdk:virtual-${name}`,
|
|
6
|
-
resolveId(source, _importer,
|
|
7
|
-
// Skip during directive scanning to avoid performance issues
|
|
8
|
-
|
|
6
|
+
resolveId(source, _importer, options) {
|
|
7
|
+
// Skip during our directive scanning to avoid performance issues
|
|
8
|
+
// context(justinvdm, 20 Jan 2025): We check options.custom?.rwsdk?.directiveScan to distinguish
|
|
9
|
+
// between our directive scan (which should skip) and external calls like Cloudflare's early
|
|
10
|
+
// dispatch (which should be handled normally).
|
|
11
|
+
if (options?.custom?.rwsdk?.directiveScan === true) {
|
|
9
12
|
return;
|
|
10
13
|
}
|
|
11
14
|
if (source === name || source.startsWith(`${name}?`)) {
|
|
@@ -14,10 +17,6 @@ export const virtualPlugin = (name, load) => {
|
|
|
14
17
|
return;
|
|
15
18
|
},
|
|
16
19
|
load(id, options) {
|
|
17
|
-
// Skip during directive scanning to avoid performance issues
|
|
18
|
-
if (process.env.RWSDK_DIRECTIVE_SCAN_ACTIVE) {
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
20
|
if (id === `\0${name}` || id.startsWith(`\0${name}?`)) {
|
|
22
21
|
return load.apply(this, [id, options]);
|
|
23
22
|
}
|