@catmint/vite 0.0.0-prealpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/LICENSE +339 -0
  2. package/dist/boundary.d.ts +15 -0
  3. package/dist/boundary.d.ts.map +1 -0
  4. package/dist/boundary.js +193 -0
  5. package/dist/boundary.js.map +1 -0
  6. package/dist/build-entries.d.ts +81 -0
  7. package/dist/build-entries.d.ts.map +1 -0
  8. package/dist/build-entries.js +1139 -0
  9. package/dist/build-entries.js.map +1 -0
  10. package/dist/cors-utils.d.ts +22 -0
  11. package/dist/cors-utils.d.ts.map +1 -0
  12. package/dist/cors-utils.js +36 -0
  13. package/dist/cors-utils.js.map +1 -0
  14. package/dist/dev-server.d.ts +34 -0
  15. package/dist/dev-server.d.ts.map +1 -0
  16. package/dist/dev-server.js +1683 -0
  17. package/dist/dev-server.js.map +1 -0
  18. package/dist/env-transform.d.ts +16 -0
  19. package/dist/env-transform.d.ts.map +1 -0
  20. package/dist/env-transform.js +125 -0
  21. package/dist/env-transform.js.map +1 -0
  22. package/dist/error-page.d.ts +19 -0
  23. package/dist/error-page.d.ts.map +1 -0
  24. package/dist/error-page.js +152 -0
  25. package/dist/error-page.js.map +1 -0
  26. package/dist/index.d.ts +92 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +100 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/mdx-transform.d.ts +33 -0
  31. package/dist/mdx-transform.d.ts.map +1 -0
  32. package/dist/mdx-transform.js +86 -0
  33. package/dist/mdx-transform.js.map +1 -0
  34. package/dist/middleware.d.ts +13 -0
  35. package/dist/middleware.d.ts.map +1 -0
  36. package/dist/middleware.js +155 -0
  37. package/dist/middleware.js.map +1 -0
  38. package/dist/resolve-utils.d.ts +17 -0
  39. package/dist/resolve-utils.d.ts.map +1 -0
  40. package/dist/resolve-utils.js +51 -0
  41. package/dist/resolve-utils.js.map +1 -0
  42. package/dist/route-gen.d.ts +12 -0
  43. package/dist/route-gen.d.ts.map +1 -0
  44. package/dist/route-gen.js +221 -0
  45. package/dist/route-gen.js.map +1 -0
  46. package/dist/server-fn-transform.d.ts +12 -0
  47. package/dist/server-fn-transform.d.ts.map +1 -0
  48. package/dist/server-fn-transform.js +394 -0
  49. package/dist/server-fn-transform.js.map +1 -0
  50. package/dist/utils.d.ts +56 -0
  51. package/dist/utils.d.ts.map +1 -0
  52. package/dist/utils.js +198 -0
  53. package/dist/utils.js.map +1 -0
  54. package/package.json +37 -0
package/dist/utils.js ADDED
@@ -0,0 +1,198 @@
1
+ // @catmint/vite/utils — Shared utilities for the Vite plugin
2
+ import { createHash } from "node:crypto";
3
+ import { posix } from "node:path";
4
+ /**
5
+ * Produce a short deterministic hash from a string input.
6
+ * Used to generate stable, opaque endpoint identifiers for server functions.
7
+ */
8
+ export function deterministicHash(input) {
9
+ return createHash("sha256").update(input).digest("hex").slice(0, 8);
10
+ }
11
+ /**
12
+ * Check if a file is a server-only module based on its extension pattern.
13
+ * Matches `*.server.ts` and `*.server.tsx`.
14
+ *
15
+ * NOTE: `*.fn.ts` files are NOT server-only — they are importable from client
16
+ * code. The `catmint:server-fn-transform` plugin rewrites them into fetch stubs
17
+ * in client bundles, so the boundary plugin must allow them through.
18
+ */
19
+ export function isServerOnlyFile(id) {
20
+ return /\.server\.(ts|tsx)$/.test(id);
21
+ }
22
+ /**
23
+ * Check if a file is a client component based on its extension pattern.
24
+ * Matches `*.client.tsx`.
25
+ */
26
+ export function isClientComponentFile(id) {
27
+ return /\.client\.tsx$/.test(id);
28
+ }
29
+ /**
30
+ * Check if a file is an error boundary file (`error.tsx`).
31
+ */
32
+ export function isErrorFile(id) {
33
+ return /\/error\.tsx$/.test(id) || id === "error.tsx";
34
+ }
35
+ /**
36
+ * Check if a file is a page file (`page.tsx` or `page.mdx`).
37
+ */
38
+ export function isPageFile(id) {
39
+ return (/\/page\.(tsx|mdx)$/.test(id) || id === "page.tsx" || id === "page.mdx");
40
+ }
41
+ /**
42
+ * Check if a file is a layout file (`layout.tsx`).
43
+ */
44
+ export function isLayoutFile(id) {
45
+ return /\/layout\.tsx$/.test(id) || id === "layout.tsx";
46
+ }
47
+ /**
48
+ * Check if a file is a server function module (`*.fn.ts`).
49
+ */
50
+ export function isServerFnFile(id) {
51
+ return /\.fn\.(ts|tsx?)$/.test(id);
52
+ }
53
+ /**
54
+ * Normalize a file path to a forward-slash posix path.
55
+ */
56
+ export function toPosixPath(filePath) {
57
+ return filePath.split(/[\\/]/).join(posix.sep);
58
+ }
59
+ /**
60
+ * Derive the RPC endpoint path for a server function.
61
+ * Uses the relative file path (from project root) and the function name
62
+ * to produce a stable `/__catmint/fn/<basename>/<hash>` path.
63
+ */
64
+ export function serverFnEndpoint(relativeFilePath, fnName) {
65
+ const posixPath = toPosixPath(relativeFilePath);
66
+ // Strip the extension for the URL base
67
+ const base = posixPath.replace(/\.(fn\.ts|fn\.tsx?)$/, "");
68
+ const hash = deterministicHash(`${posixPath}:${fnName}`);
69
+ return `/__catmint/fn/${base}/${hash}`;
70
+ }
71
+ // --------------------------------------------------------------------------
72
+ // Client-side navigation runtime (inlined into client entry modules)
73
+ // --------------------------------------------------------------------------
74
+ /**
75
+ * JavaScript code inlined into client entry modules to enable client-side
76
+ * (soft) navigation. When a user clicks a relative link, this code intercepts
77
+ * the click, fetches the RSC flight stream for the target URL, deserializes
78
+ * it, and tells React to render the new tree — no full page reload needed.
79
+ *
80
+ * This runtime is shared between the dev server (virtual:catmint/client-hydrate)
81
+ * and the production build (virtual:catmint/client-rsc-entry).
82
+ */
83
+ export const CLIENT_NAVIGATION_RUNTIME = `
84
+ function setupClientNavigation(reactRoot) {
85
+ if (!reactRoot) return;
86
+
87
+ function isRelativeUrl(href) {
88
+ if (href.startsWith("http://") || href.startsWith("https://") || href.startsWith("//")) return false;
89
+ if (/^[a-zA-Z][a-zA-Z0-9+\\-.]*:/.test(href)) return false;
90
+ if (href.startsWith("#")) return false;
91
+ return true;
92
+ }
93
+
94
+ function shouldIntercept(event, anchor) {
95
+ if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return false;
96
+ if (event.button !== 0) return false;
97
+ if (event.defaultPrevented) return false;
98
+ var target = anchor.getAttribute("target");
99
+ if (target && target !== "_self") return false;
100
+ if (anchor.hasAttribute("download")) return false;
101
+ if (anchor.hasAttribute("data-catmint-reload")) return false;
102
+ var href = anchor.getAttribute("href");
103
+ if (!href) return false;
104
+ return isRelativeUrl(href);
105
+ }
106
+
107
+ function findAnchor(target) {
108
+ if (!target || !(target instanceof Element)) return null;
109
+ return target.closest("a");
110
+ }
111
+
112
+ var navigating = false;
113
+
114
+ async function performNavigation(url, opts) {
115
+ if (navigating) return;
116
+ navigating = true;
117
+
118
+ try {
119
+ var rscUrl = "/__catmint/rsc?path=" + encodeURIComponent(url.split("#")[0]);
120
+ var response = await fetch(rscUrl);
121
+
122
+ if (!response.ok) {
123
+ // RSC fetch failed — fall back to full page reload
124
+ window.location.href = url;
125
+ return;
126
+ }
127
+
128
+ // Dynamically import createFromReadableStream for RSC deserialization
129
+ var rscBrowser = await import("@vitejs/plugin-rsc/browser");
130
+ var newRoot = await rscBrowser.createFromReadableStream(response.body);
131
+
132
+ // Update the URL
133
+ if (opts && opts.replace) {
134
+ window.history.replaceState(null, "", url);
135
+ } else {
136
+ window.history.pushState(null, "", url);
137
+ }
138
+
139
+ // Tell React to render the new tree
140
+ reactRoot.render(newRoot);
141
+
142
+ // Scroll to top unless explicitly disabled
143
+ if (!opts || opts.scroll !== false) {
144
+ // Handle hash navigation
145
+ var hashIdx = url.indexOf("#");
146
+ if (hashIdx !== -1) {
147
+ var hash = url.slice(hashIdx + 1);
148
+ var el = document.getElementById(hash);
149
+ if (el) {
150
+ el.scrollIntoView();
151
+ } else {
152
+ window.scrollTo(0, 0);
153
+ }
154
+ } else {
155
+ window.scrollTo(0, 0);
156
+ }
157
+ }
158
+ } catch (err) {
159
+ console.error("[catmint] Client navigation error:", err);
160
+ // Fall back to full page reload on error
161
+ window.location.href = url;
162
+ } finally {
163
+ navigating = false;
164
+ }
165
+ }
166
+
167
+ // Intercept clicks on <a> tags with relative hrefs
168
+ document.addEventListener("click", function(event) {
169
+ var anchor = findAnchor(event.target);
170
+ if (!anchor) return;
171
+ if (!shouldIntercept(event, anchor)) return;
172
+
173
+ var href = anchor.getAttribute("href");
174
+ var resolved = new URL(href, window.location.href);
175
+
176
+ // Only intercept same-origin
177
+ if (resolved.origin !== window.location.origin) return;
178
+
179
+ var targetPath = resolved.pathname + resolved.search;
180
+ var currentPath = window.location.pathname + window.location.search;
181
+ if (targetPath === currentPath && resolved.hash) return;
182
+
183
+ event.preventDefault();
184
+ var replace = anchor.hasAttribute("data-catmint-replace");
185
+ performNavigation(
186
+ resolved.pathname + resolved.search + resolved.hash,
187
+ { replace: replace, scroll: true }
188
+ );
189
+ });
190
+
191
+ // Handle browser back/forward
192
+ window.addEventListener("popstate", function() {
193
+ var url = window.location.pathname + window.location.search + window.location.hash;
194
+ performNavigation(url, { replace: true, scroll: false });
195
+ });
196
+ }
197
+ `;
198
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAE7D,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAElC;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACtE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAAU;IACzC,OAAO,qBAAqB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACxC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,EAAU;IAC9C,OAAO,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,EAAU;IACpC,OAAO,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,WAAW,CAAC;AACxD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,EAAU;IACnC,OAAO,CACL,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,UAAU,IAAI,EAAE,KAAK,UAAU,CACxE,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,EAAU;IACrC,OAAO,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,YAAY,CAAC;AAC1D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,EAAU;IACvC,OAAO,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACrC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,QAAgB;IAC1C,OAAO,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AACjD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAC9B,gBAAwB,EACxB,MAAc;IAEd,MAAM,SAAS,GAAG,WAAW,CAAC,gBAAgB,CAAC,CAAC;IAChD,uCAAuC;IACvC,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC,CAAC;IAC3D,MAAM,IAAI,GAAG,iBAAiB,CAAC,GAAG,SAAS,IAAI,MAAM,EAAE,CAAC,CAAC;IACzD,OAAO,iBAAiB,IAAI,IAAI,IAAI,EAAE,CAAC;AACzC,CAAC;AAED,6EAA6E;AAC7E,qEAAqE;AACrE,6EAA6E;AAE7E;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkHxC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@catmint/vite",
3
+ "version": "0.0.0-prealpha.1",
4
+ "type": "module",
5
+ "private": false,
6
+ "license": "MIT",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "main": "dist/index.js",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js"
15
+ }
16
+ },
17
+ "dependencies": {
18
+ "@mdx-js/mdx": "^3.1.1",
19
+ "@swc/core": "^1.15.11",
20
+ "@vitejs/plugin-rsc": "^0.5.20",
21
+ "estree-walker": "^3.0.3",
22
+ "magic-string": "^0.30.21",
23
+ "rsc-html-stream": "^0.0.7"
24
+ },
25
+ "peerDependencies": {
26
+ "vite": "^6.0.0"
27
+ },
28
+ "devDependencies": {
29
+ "@types/estree": "^1.0.8",
30
+ "typescript": "^5.7.0",
31
+ "vite": "^6.0.0"
32
+ },
33
+ "scripts": {
34
+ "build": "tsc",
35
+ "test": "vitest run"
36
+ }
37
+ }