rwsdk 1.0.0-alpha.1-test.20250911154541 → 1.0.0-alpha.11
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/lib/e2e/browser.d.mts +10 -0
- package/dist/lib/e2e/browser.mjs +124 -0
- package/dist/lib/e2e/dev.d.mts +8 -0
- package/dist/lib/e2e/dev.mjs +242 -0
- package/dist/lib/e2e/environment.d.mts +14 -0
- package/dist/lib/e2e/environment.mjs +266 -0
- package/dist/lib/e2e/index.d.mts +8 -0
- package/dist/lib/e2e/index.mjs +8 -0
- package/dist/lib/e2e/poll.d.mts +8 -0
- package/dist/lib/e2e/poll.mjs +31 -0
- package/dist/lib/e2e/release.d.mts +56 -0
- package/dist/lib/e2e/release.mjs +559 -0
- package/dist/lib/e2e/retry.d.mts +4 -0
- package/dist/lib/e2e/retry.mjs +16 -0
- package/dist/lib/e2e/setup.d.mts +2 -0
- package/dist/lib/e2e/setup.mjs +1 -0
- package/dist/lib/e2e/tarball.d.mts +14 -0
- package/dist/lib/e2e/tarball.mjs +99 -0
- package/dist/lib/e2e/testHarness.d.mts +126 -0
- package/dist/lib/e2e/testHarness.mjs +418 -0
- package/dist/lib/e2e/types.d.mts +32 -0
- package/dist/lib/getShortName.mjs +6 -1
- package/dist/lib/getShortName.test.d.mts +1 -0
- package/dist/lib/getShortName.test.mjs +25 -0
- package/dist/lib/hasPkgScript.d.mts +4 -1
- package/dist/lib/hasPkgScript.mjs +9 -6
- package/dist/lib/hasPkgScript.test.d.mts +1 -0
- package/dist/lib/hasPkgScript.test.mjs +33 -0
- package/dist/lib/jsonUtils.mjs +3 -0
- package/dist/lib/jsonUtils.test.d.mts +1 -0
- package/dist/lib/jsonUtils.test.mjs +90 -0
- package/dist/lib/normalizeModulePath.d.mts +5 -0
- package/dist/lib/normalizeModulePath.mjs +1 -1
- package/dist/lib/normalizeModulePath.test.d.mts +1 -0
- package/dist/lib/{normalizeModulePath.test.js → normalizeModulePath.test.mjs} +20 -1
- package/dist/lib/smokeTests/browser.mjs +3 -94
- package/dist/lib/smokeTests/development.mjs +2 -223
- package/dist/lib/smokeTests/environment.d.mts +4 -11
- package/dist/lib/smokeTests/environment.mjs +10 -158
- package/dist/lib/smokeTests/release.d.mts +2 -49
- package/dist/lib/smokeTests/release.mjs +3 -503
- package/dist/runtime/lib/injectHtmlAtMarker.d.ts +11 -0
- package/dist/runtime/lib/injectHtmlAtMarker.js +90 -0
- package/dist/runtime/lib/memoizeOnId.test.d.ts +1 -0
- package/dist/runtime/lib/memoizeOnId.test.js +49 -0
- package/dist/runtime/lib/realtime/protocol.test.d.ts +1 -0
- package/dist/runtime/lib/realtime/protocol.test.js +107 -0
- package/dist/runtime/lib/realtime/shared.test.d.ts +1 -0
- package/dist/runtime/lib/realtime/shared.test.js +18 -0
- package/dist/runtime/lib/realtime/validateUpgradeRequest.test.d.ts +1 -0
- package/dist/runtime/lib/realtime/validateUpgradeRequest.test.js +66 -0
- package/dist/runtime/lib/realtime/worker.d.ts +1 -1
- package/dist/runtime/lib/router.js +40 -22
- package/dist/runtime/lib/router.test.js +591 -2
- package/dist/runtime/lib/rwContext.d.ts +22 -0
- package/dist/runtime/lib/rwContext.js +1 -0
- package/dist/runtime/lib/turnstile/verifyTurnstileToken.d.ts +2 -1
- package/dist/runtime/lib/turnstile/verifyTurnstileToken.js +6 -6
- package/dist/runtime/lib/turnstile/verifyTurnstileToken.test.d.ts +1 -0
- package/dist/runtime/lib/turnstile/verifyTurnstileToken.test.js +49 -0
- package/dist/runtime/register/worker.d.ts +1 -1
- package/dist/runtime/register/worker.js +26 -21
- package/dist/runtime/render/assembleDocument.d.ts +6 -0
- package/dist/runtime/render/assembleDocument.js +22 -0
- package/dist/runtime/render/createThenableFromReadableStream.d.ts +1 -0
- package/dist/runtime/render/createThenableFromReadableStream.js +9 -0
- package/dist/runtime/render/normalizeActionResult.d.ts +1 -0
- package/dist/runtime/render/normalizeActionResult.js +43 -0
- package/dist/runtime/render/preloads.d.ts +2 -2
- package/dist/runtime/render/preloads.js +2 -3
- package/dist/runtime/render/{renderRscThenableToHtmlStream.d.ts → renderDocumentHtmlStream.d.ts} +3 -3
- package/dist/runtime/render/renderDocumentHtmlStream.js +39 -0
- package/dist/runtime/render/renderHtmlStream.d.ts +7 -0
- package/dist/runtime/render/renderHtmlStream.js +31 -0
- package/dist/runtime/render/renderToRscStream.d.ts +2 -3
- package/dist/runtime/render/renderToRscStream.js +2 -41
- package/dist/runtime/render/renderToStream.d.ts +2 -1
- package/dist/runtime/render/renderToStream.js +15 -8
- package/dist/runtime/render/stylesheets.d.ts +2 -2
- package/dist/runtime/render/stylesheets.js +2 -3
- package/dist/runtime/ssrBridge.d.ts +2 -1
- package/dist/runtime/ssrBridge.js +2 -1
- package/dist/runtime/worker.d.ts +1 -0
- package/dist/runtime/worker.js +11 -6
- package/dist/scripts/debug-sync.mjs +102 -133
- package/dist/vite/buildApp.d.mts +2 -1
- package/dist/vite/buildApp.mjs +9 -5
- package/dist/vite/checkIsUsingPrisma.d.mts +4 -0
- package/dist/vite/checkIsUsingPrisma.mjs +2 -2
- package/dist/vite/checkIsUsingPrisma.test.d.mts +1 -0
- package/dist/vite/checkIsUsingPrisma.test.mjs +30 -0
- package/dist/vite/configPlugin.mjs +35 -14
- package/dist/vite/createDirectiveLookupPlugin.d.mts +9 -0
- package/dist/vite/createDirectiveLookupPlugin.mjs +33 -29
- package/dist/vite/createDirectiveLookupPlugin.test.d.mts +1 -0
- package/dist/vite/createDirectiveLookupPlugin.test.mjs +40 -0
- package/dist/vite/directiveModulesDevPlugin.d.mts +4 -1
- package/dist/vite/directiveModulesDevPlugin.mjs +5 -4
- package/dist/vite/directiveModulesDevPlugin.test.d.mts +1 -0
- package/dist/vite/directiveModulesDevPlugin.test.mjs +59 -0
- package/dist/vite/directivesPlugin.d.mts +1 -0
- package/dist/vite/directivesPlugin.mjs +1 -1
- package/dist/vite/directivesPlugin.test.d.mts +1 -0
- package/dist/vite/directivesPlugin.test.mjs +24 -0
- package/dist/vite/ensureAliasArray.test.d.mts +1 -0
- package/dist/vite/ensureAliasArray.test.mjs +71 -0
- package/dist/vite/findSpecifiers.mjs +2 -1
- package/dist/vite/findSpecifiers.test.d.mts +1 -0
- package/dist/vite/findSpecifiers.test.mjs +202 -0
- package/dist/vite/findSsrSpecifiers.test.d.mts +1 -0
- package/dist/vite/findSsrSpecifiers.test.mjs +99 -0
- package/dist/vite/hasDirective.d.mts +6 -3
- package/dist/vite/hasDirective.mjs +43 -27
- package/dist/vite/hasDirective.test.d.mts +1 -0
- package/dist/vite/hasDirective.test.mjs +107 -0
- package/dist/vite/isJsFile.test.d.mts +1 -0
- package/dist/vite/isJsFile.test.mjs +38 -0
- package/dist/vite/{reactConditionsResolverPlugin.d.mts → knownDepsResolverPlugin.d.mts} +2 -2
- package/dist/vite/{reactConditionsResolverPlugin.mjs → knownDepsResolverPlugin.mjs} +28 -23
- package/dist/vite/linkerPlugin.d.mts +8 -0
- package/dist/vite/linkerPlugin.mjs +30 -22
- package/dist/vite/linkerPlugin.test.d.mts +1 -0
- package/dist/vite/linkerPlugin.test.mjs +41 -0
- package/dist/vite/miniflareHMRPlugin.d.mts +5 -0
- package/dist/vite/miniflareHMRPlugin.mjs +2 -2
- package/dist/vite/miniflareHMRPlugin.test.d.mts +1 -0
- package/dist/vite/miniflareHMRPlugin.test.mjs +42 -0
- package/dist/vite/redwoodPlugin.d.mts +9 -0
- package/dist/vite/redwoodPlugin.mjs +29 -5
- package/dist/vite/redwoodPlugin.test.d.mts +1 -0
- package/dist/vite/redwoodPlugin.test.mjs +34 -0
- package/dist/vite/resolveForcedPaths.d.mts +4 -0
- package/dist/vite/resolveForcedPaths.mjs +9 -0
- package/dist/vite/runDirectivesScan.d.mts +21 -1
- package/dist/vite/runDirectivesScan.mjs +67 -52
- package/dist/vite/runDirectivesScan.test.d.mts +1 -0
- package/dist/vite/runDirectivesScan.test.mjs +73 -0
- package/dist/vite/ssrBridgePlugin.mjs +8 -1
- package/dist/vite/transformClientComponents.mjs +6 -4
- package/dist/vite/transformClientComponents.test.mjs +116 -58
- package/dist/vite/transformServerFunctions.d.mts +1 -1
- package/dist/vite/transformServerFunctions.mjs +1 -1
- package/dist/vite/transformServerFunctions.test.mjs +3 -3
- package/package.json +12 -4
- package/dist/runtime/render/renderRscThenableToHtmlStream.js +0 -54
- package/dist/runtime/render/transformRscToHtmlStream.d.ts +0 -8
- package/dist/runtime/render/transformRscToHtmlStream.js +0 -19
- /package/dist/lib/{normalizeModulePath.test.d.ts → e2e/types.mjs} +0 -0
|
@@ -1,7 +1,27 @@
|
|
|
1
1
|
import { Environment, ResolvedConfig } from "vite";
|
|
2
|
-
|
|
2
|
+
type Resolver = (context: {}, path: string, request: string, resolveContext: {}, callback: (err: Error | null, result?: string | false) => void) => void;
|
|
3
|
+
export declare function resolveModuleWithEnvironment({ path, importer, importerEnv, clientResolver, workerResolver, }: {
|
|
4
|
+
path: string;
|
|
5
|
+
importer?: string;
|
|
6
|
+
importerEnv: "client" | "worker";
|
|
7
|
+
clientResolver: Resolver;
|
|
8
|
+
workerResolver: Resolver;
|
|
9
|
+
}): Promise<{
|
|
10
|
+
id: string;
|
|
11
|
+
} | null>;
|
|
12
|
+
export declare function classifyModule({ contents, inheritedEnv, }: {
|
|
13
|
+
contents: string;
|
|
14
|
+
inheritedEnv: "client" | "worker";
|
|
15
|
+
}): {
|
|
16
|
+
moduleEnv: "client" | "worker";
|
|
17
|
+
isClient: boolean;
|
|
18
|
+
isServer: boolean;
|
|
19
|
+
};
|
|
20
|
+
export declare const runDirectivesScan: ({ rootConfig, environments, clientFiles, serverFiles, entries: initialEntries, }: {
|
|
3
21
|
rootConfig: ResolvedConfig;
|
|
4
22
|
environments: Record<string, Environment>;
|
|
5
23
|
clientFiles: Set<string>;
|
|
6
24
|
serverFiles: Set<string>;
|
|
25
|
+
entries: string[];
|
|
7
26
|
}) => Promise<void>;
|
|
27
|
+
export {};
|
|
@@ -4,8 +4,9 @@ import path from "node:path";
|
|
|
4
4
|
import debug from "debug";
|
|
5
5
|
import { getViteEsbuild } from "./getViteEsbuild.mjs";
|
|
6
6
|
import { normalizeModulePath } from "../lib/normalizeModulePath.mjs";
|
|
7
|
+
import { INTERMEDIATES_OUTPUT_DIR } from "../lib/constants.mjs";
|
|
7
8
|
import { externalModules } from "./constants.mjs";
|
|
8
|
-
import { createViteAwareResolver
|
|
9
|
+
import { createViteAwareResolver } from "./createViteAwareResolver.mjs";
|
|
9
10
|
const log = debug("rwsdk:vite:run-directives-scan");
|
|
10
11
|
// Copied from Vite's source code.
|
|
11
12
|
// https://github.com/vitejs/vite/blob/main/packages/vite/src/shared/utils.ts
|
|
@@ -14,13 +15,47 @@ const isObject = (value) => Object.prototype.toString.call(value) === "[object O
|
|
|
14
15
|
// https://github.com/vitejs/vite/blob/main/packages/vite/src/node/utils.ts
|
|
15
16
|
const externalRE = /^(https?:)?\/\//;
|
|
16
17
|
const isExternalUrl = (url) => externalRE.test(url);
|
|
17
|
-
export
|
|
18
|
+
export async function resolveModuleWithEnvironment({ path, importer, importerEnv, clientResolver, workerResolver, }) {
|
|
19
|
+
const resolver = importerEnv === "client" ? clientResolver : workerResolver;
|
|
20
|
+
return new Promise((resolvePromise) => {
|
|
21
|
+
resolver({}, importer || "", path, {}, (err, result) => {
|
|
22
|
+
if (!err && result) {
|
|
23
|
+
resolvePromise({ id: result });
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
if (err) {
|
|
27
|
+
const errorMessage = err.message || String(err);
|
|
28
|
+
if (errorMessage.includes("Package path . is not exported")) {
|
|
29
|
+
log("Package exports error for %s, marking as external", path);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
log("Resolution failed for %s: %s", path, errorMessage);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
resolvePromise(null);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
export function classifyModule({ contents, inheritedEnv, }) {
|
|
41
|
+
let moduleEnv = inheritedEnv;
|
|
42
|
+
const isClient = hasDirective(contents, "use client");
|
|
43
|
+
const isServer = hasDirective(contents, "use server");
|
|
44
|
+
if (isClient) {
|
|
45
|
+
moduleEnv = "client";
|
|
46
|
+
}
|
|
47
|
+
else if (isServer) {
|
|
48
|
+
moduleEnv = "worker";
|
|
49
|
+
}
|
|
50
|
+
return { moduleEnv, isClient, isServer };
|
|
51
|
+
}
|
|
52
|
+
export const runDirectivesScan = async ({ rootConfig, environments, clientFiles, serverFiles, entries: initialEntries, }) => {
|
|
18
53
|
console.log("\n🔍 Scanning for 'use client' and 'use server' directives...");
|
|
19
54
|
// Set environment variable to indicate scanning is in progress
|
|
20
55
|
process.env.RWSDK_DIRECTIVE_SCAN_ACTIVE = "true";
|
|
21
56
|
try {
|
|
22
57
|
const esbuild = await getViteEsbuild(rootConfig.root);
|
|
23
|
-
const input = environments.worker.config.build.rollupOptions?.input;
|
|
58
|
+
const input = initialEntries ?? environments.worker.config.build.rollupOptions?.input;
|
|
24
59
|
let entries;
|
|
25
60
|
if (Array.isArray(input)) {
|
|
26
61
|
entries = input;
|
|
@@ -38,7 +73,9 @@ export const runDirectivesScan = async ({ rootConfig, environments, clientFiles,
|
|
|
38
73
|
log("No entries found for directives scan in worker environment, skipping.");
|
|
39
74
|
return;
|
|
40
75
|
}
|
|
41
|
-
|
|
76
|
+
// Filter out virtual modules since they can't be scanned by esbuild
|
|
77
|
+
const realEntries = entries.filter((entry) => !entry.includes("virtual:"));
|
|
78
|
+
const absoluteEntries = realEntries.map((entry) => path.resolve(rootConfig.root, entry));
|
|
42
79
|
log("Starting directives scan for worker environment with entries:", absoluteEntries);
|
|
43
80
|
const workerResolver = createViteAwareResolver(rootConfig, environments.worker);
|
|
44
81
|
const clientResolver = createViteAwareResolver(rootConfig, environments.client);
|
|
@@ -87,17 +124,12 @@ export const runDirectivesScan = async ({ rootConfig, environments, clientFiles,
|
|
|
87
124
|
/\.(m|c)?[jt]sx?$/.test(args.importer)) {
|
|
88
125
|
try {
|
|
89
126
|
const importerContents = await readFileWithCache(args.importer);
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
log("Pre-detected importer 'use server' in:", args.importer);
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
importerEnv = "worker"; // Default for entry points
|
|
100
|
-
}
|
|
127
|
+
const classification = classifyModule({
|
|
128
|
+
contents: importerContents,
|
|
129
|
+
inheritedEnv: "worker", // Default for entry points
|
|
130
|
+
});
|
|
131
|
+
importerEnv = classification.moduleEnv;
|
|
132
|
+
log("Pre-detected importer environment in:", args.importer, "as", importerEnv);
|
|
101
133
|
moduleEnvironments.set(args.importer, importerEnv);
|
|
102
134
|
}
|
|
103
135
|
catch (e) {
|
|
@@ -109,25 +141,12 @@ export const runDirectivesScan = async ({ rootConfig, environments, clientFiles,
|
|
|
109
141
|
importerEnv = "worker"; // Default for entry points or non-script files
|
|
110
142
|
}
|
|
111
143
|
log("Importer:", args.importer, "environment:", importerEnv);
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
else {
|
|
119
|
-
if (err) {
|
|
120
|
-
const errorMessage = err.message || String(err);
|
|
121
|
-
if (errorMessage.includes("Package path . is not exported")) {
|
|
122
|
-
log("Package exports error for %s, marking as external", args.path);
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
log("Resolution failed for %s: %s", args.path, errorMessage);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
resolve(null);
|
|
129
|
-
}
|
|
130
|
-
});
|
|
144
|
+
const resolved = await resolveModuleWithEnvironment({
|
|
145
|
+
path: args.path,
|
|
146
|
+
importer: args.importer,
|
|
147
|
+
importerEnv,
|
|
148
|
+
clientResolver,
|
|
149
|
+
workerResolver,
|
|
131
150
|
});
|
|
132
151
|
log("Resolution result:", resolved);
|
|
133
152
|
const resolvedPath = resolved?.id;
|
|
@@ -158,29 +177,22 @@ export const runDirectivesScan = async ({ rootConfig, environments, clientFiles,
|
|
|
158
177
|
try {
|
|
159
178
|
const contents = await readFileWithCache(args.path);
|
|
160
179
|
const inheritedEnv = args.pluginData?.inheritedEnv || "worker";
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if (isClient) {
|
|
166
|
-
currentEnv = "client";
|
|
167
|
-
}
|
|
168
|
-
else if (isServer) {
|
|
169
|
-
// `else if` handles cases where a file might have both directives.
|
|
170
|
-
// "use client" takes precedence.
|
|
171
|
-
currentEnv = "worker";
|
|
172
|
-
}
|
|
180
|
+
const { moduleEnv, isClient, isServer } = classifyModule({
|
|
181
|
+
contents,
|
|
182
|
+
inheritedEnv,
|
|
183
|
+
});
|
|
173
184
|
// Store the definitive environment for this module, so it can be used when it becomes an importer.
|
|
174
|
-
|
|
175
|
-
|
|
185
|
+
const realPath = await fsp.realpath(args.path);
|
|
186
|
+
moduleEnvironments.set(realPath, moduleEnv);
|
|
187
|
+
log("Set environment for", realPath, "to", moduleEnv);
|
|
176
188
|
// Finally, populate the output sets if the file has a directive.
|
|
177
189
|
if (isClient) {
|
|
178
|
-
log("Discovered 'use client' in:",
|
|
179
|
-
clientFiles.add(normalizeModulePath(
|
|
190
|
+
log("Discovered 'use client' in:", realPath);
|
|
191
|
+
clientFiles.add(normalizeModulePath(realPath, rootConfig.root));
|
|
180
192
|
}
|
|
181
193
|
if (isServer) {
|
|
182
|
-
log("Discovered 'use server' in:",
|
|
183
|
-
serverFiles.add(normalizeModulePath(
|
|
194
|
+
log("Discovered 'use server' in:", realPath);
|
|
195
|
+
serverFiles.add(normalizeModulePath(realPath, rootConfig.root));
|
|
184
196
|
}
|
|
185
197
|
return { contents, loader: "default" };
|
|
186
198
|
}
|
|
@@ -195,6 +207,7 @@ export const runDirectivesScan = async ({ rootConfig, environments, clientFiles,
|
|
|
195
207
|
entryPoints: absoluteEntries,
|
|
196
208
|
bundle: true,
|
|
197
209
|
write: false,
|
|
210
|
+
outdir: path.join(INTERMEDIATES_OUTPUT_DIR, "directive-scan"),
|
|
198
211
|
platform: "node",
|
|
199
212
|
format: "esm",
|
|
200
213
|
logLevel: "silent",
|
|
@@ -208,5 +221,7 @@ export const runDirectivesScan = async ({ rootConfig, environments, clientFiles,
|
|
|
208
221
|
// Always clear the scanning flag when done
|
|
209
222
|
delete process.env.RWSDK_DIRECTIVE_SCAN_ACTIVE;
|
|
210
223
|
console.log("✅ Scan complete.");
|
|
224
|
+
process.env.VERBOSE &&
|
|
225
|
+
log("Client/server files after scanning: client=%O, server=%O", Array.from(clientFiles), Array.from(serverFiles));
|
|
211
226
|
}
|
|
212
227
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from "vitest";
|
|
2
|
+
import { resolveModuleWithEnvironment, classifyModule, } from "./runDirectivesScan.mjs";
|
|
3
|
+
describe("runDirectivesScan helpers", () => {
|
|
4
|
+
describe("resolveModuleWithEnvironment", () => {
|
|
5
|
+
it("should use the client resolver when importerEnv is 'client'", async () => {
|
|
6
|
+
const clientResolver = vi.fn((_a, _b, _c, _d, cb) => cb(null, "/resolved/client"));
|
|
7
|
+
const workerResolver = vi.fn();
|
|
8
|
+
const result = await resolveModuleWithEnvironment({
|
|
9
|
+
path: "test-path",
|
|
10
|
+
importerEnv: "client",
|
|
11
|
+
clientResolver,
|
|
12
|
+
workerResolver,
|
|
13
|
+
});
|
|
14
|
+
expect(clientResolver).toHaveBeenCalled();
|
|
15
|
+
expect(workerResolver).not.toHaveBeenCalled();
|
|
16
|
+
expect(result).toEqual({ id: "/resolved/client" });
|
|
17
|
+
});
|
|
18
|
+
it("should use the worker resolver when importerEnv is 'worker'", async () => {
|
|
19
|
+
const clientResolver = vi.fn();
|
|
20
|
+
const workerResolver = vi.fn((_a, _b, _c, _d, cb) => cb(null, "/resolved/worker"));
|
|
21
|
+
const result = await resolveModuleWithEnvironment({
|
|
22
|
+
path: "test-path",
|
|
23
|
+
importerEnv: "worker",
|
|
24
|
+
clientResolver,
|
|
25
|
+
workerResolver,
|
|
26
|
+
});
|
|
27
|
+
expect(workerResolver).toHaveBeenCalled();
|
|
28
|
+
expect(clientResolver).not.toHaveBeenCalled();
|
|
29
|
+
expect(result).toEqual({ id: "/resolved/worker" });
|
|
30
|
+
});
|
|
31
|
+
it("should return null on resolution error", async () => {
|
|
32
|
+
const clientResolver = vi.fn((_a, _b, _c, _d, cb) => cb(new Error("Resolution failed")));
|
|
33
|
+
const workerResolver = vi.fn();
|
|
34
|
+
const result = await resolveModuleWithEnvironment({
|
|
35
|
+
path: "test-path",
|
|
36
|
+
importerEnv: "client",
|
|
37
|
+
clientResolver,
|
|
38
|
+
workerResolver,
|
|
39
|
+
});
|
|
40
|
+
expect(result).toBeNull();
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
describe("classifyModule", () => {
|
|
44
|
+
it("should return 'client' if 'use client' directive is present", () => {
|
|
45
|
+
const contents = `'use client';\nconsole.log('hello');`;
|
|
46
|
+
const result = classifyModule({ contents, inheritedEnv: "worker" });
|
|
47
|
+
expect(result.moduleEnv).toBe("client");
|
|
48
|
+
expect(result.isClient).toBe(true);
|
|
49
|
+
expect(result.isServer).toBe(false);
|
|
50
|
+
});
|
|
51
|
+
it("should return 'worker' if 'use server' directive is present", () => {
|
|
52
|
+
const contents = `"use server";\nexport default () => {};`;
|
|
53
|
+
const result = classifyModule({ contents, inheritedEnv: "client" });
|
|
54
|
+
expect(result.moduleEnv).toBe("worker");
|
|
55
|
+
expect(result.isClient).toBe(false);
|
|
56
|
+
expect(result.isServer).toBe(true);
|
|
57
|
+
});
|
|
58
|
+
it("should prioritize 'use client' over 'use server'", () => {
|
|
59
|
+
const contents = `'use client';\n'use server';\nconsole.log('hello');`;
|
|
60
|
+
const result = classifyModule({ contents, inheritedEnv: "worker" });
|
|
61
|
+
expect(result.moduleEnv).toBe("client");
|
|
62
|
+
expect(result.isClient).toBe(true);
|
|
63
|
+
expect(result.isServer).toBe(false);
|
|
64
|
+
});
|
|
65
|
+
it("should return the inherited environment if no directive is present", () => {
|
|
66
|
+
const contents = `console.log('no directive');`;
|
|
67
|
+
const result = classifyModule({ contents, inheritedEnv: "worker" });
|
|
68
|
+
expect(result.moduleEnv).toBe("worker");
|
|
69
|
+
expect(result.isClient).toBe(false);
|
|
70
|
+
expect(result.isServer).toBe(false);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
});
|
|
@@ -34,7 +34,8 @@ export const ssrBridgePlugin = ({ clientFiles, serverFiles, }) => {
|
|
|
34
34
|
build.onResolve({ filter: /.*$/ }, (args) => {
|
|
35
35
|
process.env.VERBOSE &&
|
|
36
36
|
log("Esbuild onResolve called for path=%s, args=%O", args.path, args);
|
|
37
|
-
if (args.path === "rwsdk/__ssr_bridge"
|
|
37
|
+
if (args.path === "rwsdk/__ssr_bridge" ||
|
|
38
|
+
args.path.startsWith(VIRTUAL_SSR_PREFIX)) {
|
|
38
39
|
log("Marking as external: %s", args.path);
|
|
39
40
|
return {
|
|
40
41
|
path: args.path,
|
|
@@ -77,6 +78,12 @@ export const ssrBridgePlugin = ({ clientFiles, serverFiles, }) => {
|
|
|
77
78
|
}
|
|
78
79
|
else {
|
|
79
80
|
// In build mode, the behavior depends on the build pass
|
|
81
|
+
if (id.startsWith(VIRTUAL_SSR_PREFIX)) {
|
|
82
|
+
if (this.environment.name === "worker") {
|
|
83
|
+
log("Virtual SSR module case (build-worker pass): resolving to external");
|
|
84
|
+
return { id, external: true };
|
|
85
|
+
}
|
|
86
|
+
}
|
|
80
87
|
if (id === "rwsdk/__ssr_bridge" && this.environment.name === "worker") {
|
|
81
88
|
if (process.env.RWSDK_BUILD_PASS === "worker") {
|
|
82
89
|
// First pass: resolve to a temporary, external path
|
|
@@ -5,7 +5,8 @@ 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
|
-
if (!
|
|
8
|
+
if (!ctx.clientFiles?.has(normalizedId) &&
|
|
9
|
+
!hasDirective(code, "use client")) {
|
|
9
10
|
return;
|
|
10
11
|
}
|
|
11
12
|
const log = ctx.isEsbuild ? logEsbuild : logVite;
|
|
@@ -76,13 +77,14 @@ export async function transformClientComponents(code, normalizedId, ctx) {
|
|
|
76
77
|
// 4. Non-SSR files: replace all implementation with registerClientReference logic
|
|
77
78
|
// Generate completely new code for worker/client environments
|
|
78
79
|
const s = new MagicString("");
|
|
79
|
-
|
|
80
|
+
s.append('import { ssrLoadModule } from "rwsdk/__ssr_bridge";\n');
|
|
80
81
|
s.append('import { registerClientReference } from "rwsdk/worker";\n');
|
|
82
|
+
s.append(`const SSRModule = await ssrLoadModule("${normalizedId}");\n`);
|
|
81
83
|
// Compute unique computed local names first
|
|
82
84
|
const computedLocalNames = new Map(processedExports.map((info) => [getComputedLocalName(info), info]));
|
|
83
85
|
// Add registerClientReference assignments for unique names
|
|
84
86
|
for (const [computedLocalName, correspondingInfo] of computedLocalNames) {
|
|
85
|
-
s.append(`const ${computedLocalName} = registerClientReference("${normalizedId}", "${correspondingInfo.exported}");\n`);
|
|
87
|
+
s.append(`const ${computedLocalName} = registerClientReference(SSRModule, "${normalizedId}", "${correspondingInfo.exported}");\n`);
|
|
86
88
|
}
|
|
87
89
|
// Add grouped export statement for named exports (preserving order and alias)
|
|
88
90
|
if (processedExports.length > 0) {
|
|
@@ -94,7 +96,7 @@ export async function transformClientComponents(code, normalizedId, ctx) {
|
|
|
94
96
|
// Add default export if present
|
|
95
97
|
if (defaultExportInfo) {
|
|
96
98
|
log(":isEsbuild=%s: Registering client reference for default export: %s", !!ctx.isEsbuild, defaultExportInfo.exported);
|
|
97
|
-
s.append(`export default registerClientReference("${normalizedId}", "${defaultExportInfo.exported}");\n`);
|
|
99
|
+
s.append(`export default registerClientReference(SSRModule, "${normalizedId}", "${defaultExportInfo.exported}");\n`);
|
|
98
100
|
}
|
|
99
101
|
const sourceMap = s.generateMap({
|
|
100
102
|
source: normalizedId,
|
|
@@ -13,8 +13,10 @@ describe("transformClientComponents", () => {
|
|
|
13
13
|
export const Component = () => {
|
|
14
14
|
return jsx('div', { children: 'Hello' });
|
|
15
15
|
}
|
|
16
|
-
`)) ?? "").toEqual(`import {
|
|
17
|
-
|
|
16
|
+
`)) ?? "").toEqual(`import { ssrLoadModule } from "rwsdk/__ssr_bridge";
|
|
17
|
+
import { registerClientReference } from "rwsdk/worker";
|
|
18
|
+
const SSRModule = await ssrLoadModule("/test/file.tsx");
|
|
19
|
+
const Component = registerClientReference(SSRModule, "/test/file.tsx", "Component");
|
|
18
20
|
export { Component };
|
|
19
21
|
`);
|
|
20
22
|
});
|
|
@@ -24,8 +26,10 @@ export { Component };
|
|
|
24
26
|
export const Component = async () => {
|
|
25
27
|
return jsx('div', { children: 'Hello' });
|
|
26
28
|
}
|
|
27
|
-
`)) ?? "").toEqual(`import {
|
|
28
|
-
|
|
29
|
+
`)) ?? "").toEqual(`import { ssrLoadModule } from "rwsdk/__ssr_bridge";
|
|
30
|
+
import { registerClientReference } from "rwsdk/worker";
|
|
31
|
+
const SSRModule = await ssrLoadModule("/test/file.tsx");
|
|
32
|
+
const Component = registerClientReference(SSRModule, "/test/file.tsx", "Component");
|
|
29
33
|
export { Component };
|
|
30
34
|
`);
|
|
31
35
|
});
|
|
@@ -34,8 +38,10 @@ export { Component };
|
|
|
34
38
|
|
|
35
39
|
export function Component() {
|
|
36
40
|
return jsx('div', { children: 'Hello' });
|
|
37
|
-
}`)) ?? "").toEqual(`import {
|
|
38
|
-
|
|
41
|
+
}`)) ?? "").toEqual(`import { ssrLoadModule } from "rwsdk/__ssr_bridge";
|
|
42
|
+
import { registerClientReference } from "rwsdk/worker";
|
|
43
|
+
const SSRModule = await ssrLoadModule("/test/file.tsx");
|
|
44
|
+
const Component = registerClientReference(SSRModule, "/test/file.tsx", "Component");
|
|
39
45
|
export { Component };
|
|
40
46
|
`);
|
|
41
47
|
});
|
|
@@ -44,8 +50,10 @@ export { Component };
|
|
|
44
50
|
|
|
45
51
|
export default () => {
|
|
46
52
|
return jsx('div', { children: 'Hello' });
|
|
47
|
-
}`)) ?? "").toEqual(`import {
|
|
48
|
-
|
|
53
|
+
}`)) ?? "").toEqual(`import { ssrLoadModule } from "rwsdk/__ssr_bridge";
|
|
54
|
+
import { registerClientReference } from "rwsdk/worker";
|
|
55
|
+
const SSRModule = await ssrLoadModule("/test/file.tsx");
|
|
56
|
+
export default registerClientReference(SSRModule, "/test/file.tsx", "default");
|
|
49
57
|
`);
|
|
50
58
|
});
|
|
51
59
|
it("transforms default export function declaration component", async () => {
|
|
@@ -53,8 +61,10 @@ export default registerClientReference("/test/file.tsx", "default");
|
|
|
53
61
|
|
|
54
62
|
export default function Component({ prop1, prop2 }) {
|
|
55
63
|
return jsx('div', { children: 'Hello' });
|
|
56
|
-
}`)) ?? "").toEqual(`import {
|
|
57
|
-
|
|
64
|
+
}`)) ?? "").toEqual(`import { ssrLoadModule } from "rwsdk/__ssr_bridge";
|
|
65
|
+
import { registerClientReference } from "rwsdk/worker";
|
|
66
|
+
const SSRModule = await ssrLoadModule("/test/file.tsx");
|
|
67
|
+
export default registerClientReference(SSRModule, "/test/file.tsx", "default");
|
|
58
68
|
`);
|
|
59
69
|
});
|
|
60
70
|
it("transforms mixed export styles (inline, grouped, and default)", async () => {
|
|
@@ -81,13 +91,15 @@ export default function Main() {
|
|
|
81
91
|
}
|
|
82
92
|
|
|
83
93
|
export { Second, Third }
|
|
84
|
-
export { Fourth as AnotherName }`)) ?? "").toEqual(`import {
|
|
85
|
-
|
|
86
|
-
const
|
|
87
|
-
const
|
|
88
|
-
const
|
|
94
|
+
export { Fourth as AnotherName }`)) ?? "").toEqual(`import { ssrLoadModule } from "rwsdk/__ssr_bridge";
|
|
95
|
+
import { registerClientReference } from "rwsdk/worker";
|
|
96
|
+
const SSRModule = await ssrLoadModule("/test/file.tsx");
|
|
97
|
+
const First = registerClientReference(SSRModule, "/test/file.tsx", "First");
|
|
98
|
+
const Second = registerClientReference(SSRModule, "/test/file.tsx", "Second");
|
|
99
|
+
const Third = registerClientReference(SSRModule, "/test/file.tsx", "Third");
|
|
100
|
+
const Fourth_AnotherName = registerClientReference(SSRModule, "/test/file.tsx", "AnotherName");
|
|
89
101
|
export { First, Second, Third, Fourth_AnotherName as AnotherName };
|
|
90
|
-
export default registerClientReference("/test/file.tsx", "default");
|
|
102
|
+
export default registerClientReference(SSRModule, "/test/file.tsx", "default");
|
|
91
103
|
`);
|
|
92
104
|
});
|
|
93
105
|
it("transforms function declaration that is exported default separately", async () => {
|
|
@@ -98,8 +110,10 @@ function Component({ prop1, prop2 }) {
|
|
|
98
110
|
return jsx('div', { children: 'Hello' });
|
|
99
111
|
}
|
|
100
112
|
|
|
101
|
-
export default Component;`)) ?? "").toEqual(`import {
|
|
102
|
-
|
|
113
|
+
export default Component;`)) ?? "").toEqual(`import { ssrLoadModule } from "rwsdk/__ssr_bridge";
|
|
114
|
+
import { registerClientReference } from "rwsdk/worker";
|
|
115
|
+
const SSRModule = await ssrLoadModule("/test/file.tsx");
|
|
116
|
+
export default registerClientReference(SSRModule, "/test/file.tsx", "default");
|
|
103
117
|
`);
|
|
104
118
|
});
|
|
105
119
|
it("Works in dev", async () => {
|
|
@@ -183,8 +197,10 @@ export function Chat() {
|
|
|
183
197
|
columnNumber: 5
|
|
184
198
|
}, this);
|
|
185
199
|
}
|
|
186
|
-
`)) ?? "").toEqual(`import {
|
|
187
|
-
|
|
200
|
+
`)) ?? "").toEqual(`import { ssrLoadModule } from "rwsdk/__ssr_bridge";
|
|
201
|
+
import { registerClientReference } from "rwsdk/worker";
|
|
202
|
+
const SSRModule = await ssrLoadModule("/test/file.tsx");
|
|
203
|
+
const Chat = registerClientReference(SSRModule, "/test/file.tsx", "Chat");
|
|
188
204
|
export { Chat };
|
|
189
205
|
`);
|
|
190
206
|
});
|
|
@@ -198,8 +214,10 @@ const MyComponent = () => {
|
|
|
198
214
|
return jsx('div', { children: 'Hello' });
|
|
199
215
|
}
|
|
200
216
|
|
|
201
|
-
export { MyComponent as CustomName }`)) ?? "").toEqual(`import {
|
|
202
|
-
|
|
217
|
+
export { MyComponent as CustomName }`)) ?? "").toEqual(`import { ssrLoadModule } from "rwsdk/__ssr_bridge";
|
|
218
|
+
import { registerClientReference } from "rwsdk/worker";
|
|
219
|
+
const SSRModule = await ssrLoadModule("/test/file.tsx");
|
|
220
|
+
const MyComponent_CustomName = registerClientReference(SSRModule, "/test/file.tsx", "CustomName");
|
|
203
221
|
export { MyComponent_CustomName as CustomName };
|
|
204
222
|
`);
|
|
205
223
|
});
|
|
@@ -210,10 +228,12 @@ const First = () => jsx('div', { children: 'First' });
|
|
|
210
228
|
const Second = () => jsx('div', { children: 'Second' });
|
|
211
229
|
const Third = () => jsx('div', { children: 'Third' });
|
|
212
230
|
|
|
213
|
-
export { First, Second, Third }`)) ?? "").toEqual(`import {
|
|
214
|
-
|
|
215
|
-
const
|
|
216
|
-
const
|
|
231
|
+
export { First, Second, Third }`)) ?? "").toEqual(`import { ssrLoadModule } from "rwsdk/__ssr_bridge";
|
|
232
|
+
import { registerClientReference } from "rwsdk/worker";
|
|
233
|
+
const SSRModule = await ssrLoadModule("/test/file.tsx");
|
|
234
|
+
const First = registerClientReference(SSRModule, "/test/file.tsx", "First");
|
|
235
|
+
const Second = registerClientReference(SSRModule, "/test/file.tsx", "Second");
|
|
236
|
+
const Third = registerClientReference(SSRModule, "/test/file.tsx", "Third");
|
|
217
237
|
export { First, Second, Third };
|
|
218
238
|
`);
|
|
219
239
|
});
|
|
@@ -224,10 +244,12 @@ const Component = () => jsx('div', {});
|
|
|
224
244
|
const data = { value: 42 };
|
|
225
245
|
const helper = () => console.log('helper');
|
|
226
246
|
|
|
227
|
-
export { Component, data, helper }`)) ?? "").toEqual(`import {
|
|
228
|
-
|
|
229
|
-
const
|
|
230
|
-
const
|
|
247
|
+
export { Component, data, helper }`)) ?? "").toEqual(`import { ssrLoadModule } from "rwsdk/__ssr_bridge";
|
|
248
|
+
import { registerClientReference } from "rwsdk/worker";
|
|
249
|
+
const SSRModule = await ssrLoadModule("/test/file.tsx");
|
|
250
|
+
const Component = registerClientReference(SSRModule, "/test/file.tsx", "Component");
|
|
251
|
+
const data = registerClientReference(SSRModule, "/test/file.tsx", "data");
|
|
252
|
+
const helper = registerClientReference(SSRModule, "/test/file.tsx", "helper");
|
|
231
253
|
export { Component, data, helper };
|
|
232
254
|
`);
|
|
233
255
|
});
|
|
@@ -239,9 +261,11 @@ export const Slot = () => {
|
|
|
239
261
|
}
|
|
240
262
|
|
|
241
263
|
export { Slot, Slot as Root }
|
|
242
|
-
`)) ?? "").toEqual(`import {
|
|
243
|
-
|
|
244
|
-
const
|
|
264
|
+
`)) ?? "").toEqual(`import { ssrLoadModule } from "rwsdk/__ssr_bridge";
|
|
265
|
+
import { registerClientReference } from "rwsdk/worker";
|
|
266
|
+
const SSRModule = await ssrLoadModule("/test/file.tsx");
|
|
267
|
+
const Slot = registerClientReference(SSRModule, "/test/file.tsx", "Slot");
|
|
268
|
+
const Slot_Root = registerClientReference(SSRModule, "/test/file.tsx", "Root");
|
|
245
269
|
export { Slot, Slot_Root as Root };
|
|
246
270
|
`);
|
|
247
271
|
});
|
|
@@ -274,31 +298,33 @@ function SidebarMenuSub() { return jsx("div", {}); }
|
|
|
274
298
|
function SidebarMenuSubItem() { return jsx("div", {}); }
|
|
275
299
|
function SidebarMenuSubButton() { return jsx("div", {}); }
|
|
276
300
|
export { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, useSidebar, };`;
|
|
277
|
-
expect((await transform(code)) ?? "").toEqual(`import {
|
|
278
|
-
|
|
279
|
-
const
|
|
280
|
-
const
|
|
281
|
-
const
|
|
282
|
-
const
|
|
283
|
-
const
|
|
284
|
-
const
|
|
285
|
-
const
|
|
286
|
-
const
|
|
287
|
-
const
|
|
288
|
-
const
|
|
289
|
-
const
|
|
290
|
-
const
|
|
291
|
-
const
|
|
292
|
-
const
|
|
293
|
-
const
|
|
294
|
-
const
|
|
295
|
-
const
|
|
296
|
-
const
|
|
297
|
-
const
|
|
298
|
-
const
|
|
299
|
-
const
|
|
300
|
-
const
|
|
301
|
-
const
|
|
301
|
+
expect((await transform(code)) ?? "").toEqual(`import { ssrLoadModule } from "rwsdk/__ssr_bridge";
|
|
302
|
+
import { registerClientReference } from "rwsdk/worker";
|
|
303
|
+
const SSRModule = await ssrLoadModule("/test/file.tsx");
|
|
304
|
+
const Sidebar = registerClientReference(SSRModule, "/test/file.tsx", "Sidebar");
|
|
305
|
+
const SidebarContent = registerClientReference(SSRModule, "/test/file.tsx", "SidebarContent");
|
|
306
|
+
const SidebarFooter = registerClientReference(SSRModule, "/test/file.tsx", "SidebarFooter");
|
|
307
|
+
const SidebarGroup = registerClientReference(SSRModule, "/test/file.tsx", "SidebarGroup");
|
|
308
|
+
const SidebarGroupAction = registerClientReference(SSRModule, "/test/file.tsx", "SidebarGroupAction");
|
|
309
|
+
const SidebarGroupContent = registerClientReference(SSRModule, "/test/file.tsx", "SidebarGroupContent");
|
|
310
|
+
const SidebarGroupLabel = registerClientReference(SSRModule, "/test/file.tsx", "SidebarGroupLabel");
|
|
311
|
+
const SidebarHeader = registerClientReference(SSRModule, "/test/file.tsx", "SidebarHeader");
|
|
312
|
+
const SidebarInput = registerClientReference(SSRModule, "/test/file.tsx", "SidebarInput");
|
|
313
|
+
const SidebarInset = registerClientReference(SSRModule, "/test/file.tsx", "SidebarInset");
|
|
314
|
+
const SidebarMenu = registerClientReference(SSRModule, "/test/file.tsx", "SidebarMenu");
|
|
315
|
+
const SidebarMenuAction = registerClientReference(SSRModule, "/test/file.tsx", "SidebarMenuAction");
|
|
316
|
+
const SidebarMenuBadge = registerClientReference(SSRModule, "/test/file.tsx", "SidebarMenuBadge");
|
|
317
|
+
const SidebarMenuButton = registerClientReference(SSRModule, "/test/file.tsx", "SidebarMenuButton");
|
|
318
|
+
const SidebarMenuItem = registerClientReference(SSRModule, "/test/file.tsx", "SidebarMenuItem");
|
|
319
|
+
const SidebarMenuSkeleton = registerClientReference(SSRModule, "/test/file.tsx", "SidebarMenuSkeleton");
|
|
320
|
+
const SidebarMenuSub = registerClientReference(SSRModule, "/test/file.tsx", "SidebarMenuSub");
|
|
321
|
+
const SidebarMenuSubButton = registerClientReference(SSRModule, "/test/file.tsx", "SidebarMenuSubButton");
|
|
322
|
+
const SidebarMenuSubItem = registerClientReference(SSRModule, "/test/file.tsx", "SidebarMenuSubItem");
|
|
323
|
+
const SidebarProvider = registerClientReference(SSRModule, "/test/file.tsx", "SidebarProvider");
|
|
324
|
+
const SidebarRail = registerClientReference(SSRModule, "/test/file.tsx", "SidebarRail");
|
|
325
|
+
const SidebarSeparator = registerClientReference(SSRModule, "/test/file.tsx", "SidebarSeparator");
|
|
326
|
+
const SidebarTrigger = registerClientReference(SSRModule, "/test/file.tsx", "SidebarTrigger");
|
|
327
|
+
const useSidebar = registerClientReference(SSRModule, "/test/file.tsx", "useSidebar");
|
|
302
328
|
export { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, useSidebar };
|
|
303
329
|
`);
|
|
304
330
|
});
|
|
@@ -319,3 +345,35 @@ describe("transformClientComponents logic branches (from transformClientComponen
|
|
|
319
345
|
expect(result?.code).toEqual("export const foo = 1;");
|
|
320
346
|
});
|
|
321
347
|
});
|
|
348
|
+
describe("transformClientComponents (dev server node_modules)", () => {
|
|
349
|
+
async function transformDev(code, id) {
|
|
350
|
+
process.env.VITE_IS_DEV_SERVER = "1";
|
|
351
|
+
const result = await transformClientComponents(code, id, {
|
|
352
|
+
environmentName: "worker",
|
|
353
|
+
});
|
|
354
|
+
delete process.env.VITE_IS_DEV_SERVER;
|
|
355
|
+
return result?.code;
|
|
356
|
+
}
|
|
357
|
+
it("uses barrel file import for node_modules files in dev", async () => {
|
|
358
|
+
const id = "/test/node_modules/my-lib/component.js";
|
|
359
|
+
const code = `"use client";
|
|
360
|
+
export const MyComponent = () => {};`;
|
|
361
|
+
expect((await transformDev(code, id)) ?? "").toEqual(`import { ssrLoadModule } from "rwsdk/__ssr_bridge";
|
|
362
|
+
import { registerClientReference } from "rwsdk/worker";
|
|
363
|
+
const SSRModule = await ssrLoadModule("/test/node_modules/my-lib/component.js");
|
|
364
|
+
const MyComponent = registerClientReference(SSRModule, "/test/node_modules/my-lib/component.js", "MyComponent");
|
|
365
|
+
export { MyComponent };
|
|
366
|
+
`);
|
|
367
|
+
});
|
|
368
|
+
it("uses virtual module import for app source files in dev", async () => {
|
|
369
|
+
const id = "/test/app/component.tsx";
|
|
370
|
+
const code = `"use client";
|
|
371
|
+
export const MyComponent = () => {};`;
|
|
372
|
+
expect((await transformDev(code, id)) ?? "").toEqual(`import { ssrLoadModule } from "rwsdk/__ssr_bridge";
|
|
373
|
+
import { registerClientReference } from "rwsdk/worker";
|
|
374
|
+
const SSRModule = await ssrLoadModule("/test/app/component.tsx");
|
|
375
|
+
const MyComponent = registerClientReference(SSRModule, "/test/app/component.tsx", "MyComponent");
|
|
376
|
+
export { MyComponent };
|
|
377
|
+
`);
|
|
378
|
+
});
|
|
379
|
+
});
|
|
@@ -12,5 +12,5 @@ type ExportInfoCompat = {
|
|
|
12
12
|
};
|
|
13
13
|
export declare const findExportedFunctions: (code: string, normalizedId?: string) => Set<string>;
|
|
14
14
|
export declare const findExportInfo: (code: string, normalizedId?: string) => ExportInfoCompat;
|
|
15
|
-
export declare const transformServerFunctions: (code: string, normalizedId: string, environment: "client" | "worker" | "ssr", serverFiles
|
|
15
|
+
export declare const transformServerFunctions: (code: string, normalizedId: string, environment: "client" | "worker" | "ssr", serverFiles: Set<string>) => TransformResult | undefined;
|
|
16
16
|
export type { TransformResult };
|