rwsdk 1.0.6 → 1.0.8

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.
@@ -4,4 +4,5 @@ interface ImportMeta {
4
4
  interface ImportMetaEnv {
5
5
  readonly DEV: boolean;
6
6
  readonly VITE_IS_DEV_SERVER: string;
7
+ readonly BASE_URL: string;
7
8
  }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Ensures asset hrefs from the Vite manifest are absolute paths.
3
+ *
4
+ * Vite's manifest stores file paths without a leading slash (e.g. "assets/foo.js").
5
+ * When used as href attributes, these resolve relative to the current page URL,
6
+ * breaking on nested routes (e.g. /dashboard/editor resolves "assets/foo.js"
7
+ * as "/dashboard/assets/foo.js" instead of "/assets/foo.js").
8
+ *
9
+ * Prepends import.meta.env.BASE_URL (defaults to "/") to make paths absolute.
10
+ */
11
+ export declare const toAbsoluteHref: (href: string) => string;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Ensures asset hrefs from the Vite manifest are absolute paths.
3
+ *
4
+ * Vite's manifest stores file paths without a leading slash (e.g. "assets/foo.js").
5
+ * When used as href attributes, these resolve relative to the current page URL,
6
+ * breaking on nested routes (e.g. /dashboard/editor resolves "assets/foo.js"
7
+ * as "/dashboard/assets/foo.js" instead of "/assets/foo.js").
8
+ *
9
+ * Prepends import.meta.env.BASE_URL (defaults to "/") to make paths absolute.
10
+ */
11
+ export const toAbsoluteHref = (href) => href.startsWith("/") ? href : import.meta.env.BASE_URL + href;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,23 @@
1
+ import { describe, expect, it, vi, afterEach } from "vitest";
2
+ import { toAbsoluteHref } from "./assetPaths";
3
+ describe("toAbsoluteHref", () => {
4
+ afterEach(() => {
5
+ vi.unstubAllEnvs();
6
+ });
7
+ it("prepends / to relative paths when BASE_URL is /", () => {
8
+ vi.stubEnv("BASE_URL", "/");
9
+ expect(toAbsoluteHref("assets/client-abc123.js")).toBe("/assets/client-abc123.js");
10
+ });
11
+ it("prepends custom base to relative paths", () => {
12
+ vi.stubEnv("BASE_URL", "/app/");
13
+ expect(toAbsoluteHref("assets/client-abc123.js")).toBe("/app/assets/client-abc123.js");
14
+ });
15
+ it("does not double-prefix already absolute paths", () => {
16
+ vi.stubEnv("BASE_URL", "/");
17
+ expect(toAbsoluteHref("/assets/client-abc123.js")).toBe("/assets/client-abc123.js");
18
+ });
19
+ it("handles CSS paths", () => {
20
+ vi.stubEnv("BASE_URL", "/");
21
+ expect(toAbsoluteHref("assets/styles-def456.css")).toBe("/assets/styles-def456.css");
22
+ });
23
+ });
@@ -29,13 +29,14 @@ export function findScriptForModule(id, manifest) {
29
29
  }
30
30
  return find(id);
31
31
  }
32
+ import { toAbsoluteHref } from "./assetPaths.js";
32
33
  export const Preloads = async ({ requestInfo, }) => {
33
34
  const manifest = await getManifest();
34
35
  const allScripts = new Set();
35
36
  for (const scriptId of requestInfo.rw.scriptsToBeLoaded) {
36
37
  const script = findScriptForModule(scriptId, manifest);
37
38
  if (script) {
38
- allScripts.add(script.file);
39
+ allScripts.add(toAbsoluteHref(script.file));
39
40
  }
40
41
  }
41
42
  return (_jsx(_Fragment, { children: Array.from(allScripts).map((href) => (_jsx("link", { rel: "modulepreload", href: href }, href))) }));
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,69 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { findScriptForModule } from "./preloads";
3
+ describe("findScriptForModule", () => {
4
+ it("finds a direct entry module", () => {
5
+ const manifest = {
6
+ "src/client.tsx": {
7
+ file: "assets/client-abc123.js",
8
+ isEntry: true,
9
+ },
10
+ };
11
+ const result = findScriptForModule("/src/client.tsx", manifest);
12
+ expect(result?.file).toBe("assets/client-abc123.js");
13
+ });
14
+ it("finds a dynamic entry module", () => {
15
+ const manifest = {
16
+ "src/pages/editor.tsx": {
17
+ file: "assets/editor-def456.js",
18
+ isDynamicEntry: true,
19
+ },
20
+ };
21
+ const result = findScriptForModule("/src/pages/editor.tsx", manifest);
22
+ expect(result?.file).toBe("assets/editor-def456.js");
23
+ });
24
+ it("follows imports to find the entry", () => {
25
+ const manifest = {
26
+ "src/components/Button.tsx": {
27
+ file: "assets/button-abc.js",
28
+ imports: ["src/lib/utils.ts"],
29
+ },
30
+ "src/lib/utils.ts": {
31
+ file: "assets/utils-def.js",
32
+ isEntry: true,
33
+ },
34
+ };
35
+ const result = findScriptForModule("/src/components/Button.tsx", manifest);
36
+ expect(result?.file).toBe("assets/utils-def.js");
37
+ });
38
+ it("returns undefined for missing modules", () => {
39
+ const manifest = {};
40
+ const result = findScriptForModule("/src/missing.tsx", manifest);
41
+ expect(result).toBeUndefined();
42
+ });
43
+ it("handles circular imports without infinite loop", () => {
44
+ const manifest = {
45
+ "src/a.ts": {
46
+ file: "assets/a.js",
47
+ imports: ["src/b.ts"],
48
+ },
49
+ "src/b.ts": {
50
+ file: "assets/b.js",
51
+ imports: ["src/a.ts"],
52
+ },
53
+ };
54
+ const result = findScriptForModule("/src/a.ts", manifest);
55
+ expect(result).toBeUndefined();
56
+ });
57
+ it("strips leading slash from id to match manifest keys", () => {
58
+ const manifest = {
59
+ "src/client.tsx": {
60
+ file: "assets/client.js",
61
+ isEntry: true,
62
+ },
63
+ };
64
+ // Module IDs from scriptsToBeLoaded have leading slashes
65
+ expect(findScriptForModule("/src/client.tsx", manifest)?.file).toBe("assets/client.js");
66
+ // Should also work without leading slash
67
+ expect(findScriptForModule("src/client.tsx", manifest)?.file).toBe("assets/client.js");
68
+ });
69
+ });
@@ -27,13 +27,14 @@ const findCssForModule = (scriptId, manifest) => {
27
27
  inner(scriptId);
28
28
  return Array.from(css);
29
29
  };
30
+ import { toAbsoluteHref } from "./assetPaths.js";
30
31
  export const Stylesheets = async ({ requestInfo, }) => {
31
32
  const manifest = await getManifest();
32
33
  const allStylesheets = new Set();
33
34
  for (const scriptId of requestInfo.rw.scriptsToBeLoaded) {
34
35
  const css = findCssForModule(scriptId, manifest);
35
36
  for (const entry of css) {
36
- allStylesheets.add(entry);
37
+ allStylesheets.add(toAbsoluteHref(entry));
37
38
  }
38
39
  }
39
40
  return (_jsx(_Fragment, { children: Array.from(allStylesheets).map((href) => (_jsx("link", { rel: "stylesheet", href: href, precedence: "first" }, href))) }));
@@ -19,7 +19,8 @@ export const directivesFilteringPlugin = ({ clientFiles, serverFiles, projectRoo
19
19
  absolute: true,
20
20
  });
21
21
  const info = this.getModuleInfo(absoluteId);
22
- if (!info?.isIncluded) {
22
+ if (!info ||
23
+ (typeof info.isIncluded !== "undefined" && !info.isIncluded)) {
23
24
  files.delete(id);
24
25
  }
25
26
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rwsdk",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "Build fast, server-driven webapps on Cloudflare with SSR, RSC, and realtime",
5
5
  "type": "module",
6
6
  "bin": {
@@ -153,8 +153,8 @@
153
153
  "author": "RedwoodSDK <peter@redwoodjs.com>",
154
154
  "license": "MIT",
155
155
  "dependencies": {
156
- "@ast-grep/napi": "~0.41.0",
157
- "@cloudflare/workers-types": "~4.20260331.1",
156
+ "@ast-grep/napi": "~0.42.1",
157
+ "@cloudflare/workers-types": "~4.20260405.1",
158
158
  "@mdx-js/mdx": "~3.1.1",
159
159
  "@puppeteer/browsers": "~2.13.0",
160
160
  "@types/decompress": "~4.2.7",
@@ -167,7 +167,7 @@
167
167
  "chokidar": "~5.0.0",
168
168
  "debug": "~4.4.3",
169
169
  "decompress": "~4.2.1",
170
- "enhanced-resolve": "~5.20.0",
170
+ "enhanced-resolve": "~5.20.1",
171
171
  "eventsource-parser": "~3.0.6",
172
172
  "execa": "~9.6.1",
173
173
  "find-up": "~8.0.0",
@@ -203,8 +203,8 @@
203
203
  },
204
204
  "packageManager": "pnpm@10.31.0",
205
205
  "devDependencies": {
206
- "@cloudflare/vite-plugin": "1.30.1",
207
- "wrangler": "^4.77.0",
206
+ "@cloudflare/vite-plugin": "1.31.0",
207
+ "wrangler": "^4.80.0",
208
208
  "capnweb": "~0.5.0",
209
209
  "@types/debug": "~4.1.13",
210
210
  "@types/js-beautify": "~1.14.3",
@@ -215,7 +215,7 @@
215
215
  "semver": "~7.7.4",
216
216
  "tsx": "~4.21.0",
217
217
  "typescript": "~6.0.2",
218
- "vite": "~7.3.1",
218
+ "vite": "~7.3.2",
219
219
  "vitest": "~4.1.2"
220
220
  }
221
221
  }