@cmj/juice 0.3.1 → 0.4.0

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/README.md CHANGED
@@ -63,6 +63,34 @@ const handler = createRouter(manifest);
63
63
  // handler: (Request) => Promise<Response>
64
64
  ```
65
65
 
66
+ ### Server Actions (Two-Argument Pattern)
67
+
68
+ Simple form actions receive `FormData` as the first argument — React 19 native. When you need more power, use `ActionContext` as the opt-in second argument:
69
+
70
+ ```ts
71
+ 'use server';
72
+ import type { ActionContext } from '@cmj/juice/runtime';
73
+
74
+ // Simple: FormData-only (React 19 native)
75
+ export async function addToCart(formData: FormData) {
76
+ const id = formData.get('productId');
77
+ }
78
+
79
+ // Power: headers, cookies, params via second arg
80
+ export async function processWebhook(body: unknown, ctx: ActionContext) {
81
+ ctx.request.headers.get('x-signature');
82
+ ctx.cookies.get('session_id');
83
+ ctx.params.id;
84
+ }
85
+ ```
86
+
87
+ Test your actions with the public `createActionContext` factory:
88
+
89
+ ```ts
90
+ import { createActionContext } from '@cmj/juice/runtime';
91
+ const ctx = createActionContext(new Request('https://example.com'));
92
+ ```
93
+
66
94
  ## How It Works
67
95
 
68
96
  ```
@@ -76,12 +104,13 @@ Source (.tsx) → Vite Plugin → flight-manifest.json → Runtime → Response
76
104
  ## Features
77
105
 
78
106
  - **React 19 RSC** — Server Components, Suspense, streaming SSR
79
- - **Server Actions** — `'use server'` with FormData support
107
+ - **Server Actions** — `'use server'` with FormData + opt-in `ActionContext` for headers, cookies, params
80
108
  - **Zero config** — One plugin call, no magic files
81
109
  - **One dependency** — Only `urlpattern-polyfill` for cross-platform routing
82
110
  - **Multi-platform** — Bun, Node.js, Cloudflare Workers, Deno
83
111
  - **Empathic errors** — "What-Why-How" error messages for fast debugging
84
112
  - **HMR** — Full hot module replacement in development
113
+ - **Testable actions** — Public `createActionContext` factory for unit testing
85
114
 
86
115
  ## License
87
116
 
@@ -0,0 +1,57 @@
1
+ import { type ReactNode } from 'react';
2
+ /**
3
+ * Callback to update the React root with a new RSC payload.
4
+ * Set by `initNavigation()`.
5
+ */
6
+ type PageSetter = (node: ReactNode) => void;
7
+ /**
8
+ * Options for `initNavigation`.
9
+ */
10
+ export interface NavigationOptions {
11
+ /**
12
+ * Whether to use View Transitions API for page transitions.
13
+ * Falls back to instant swap if the API is not available.
14
+ * @default true
15
+ */
16
+ viewTransitions?: boolean;
17
+ /**
18
+ * Enable prefetching of RSC payloads on hover/focus of `<a>` tags.
19
+ * @default false
20
+ */
21
+ prefetch?: boolean;
22
+ /**
23
+ * Custom function to call server actions via RSC protocol.
24
+ * Used by `createFromFetch` for `'use server'` invocations.
25
+ */
26
+ callServer?: (id: string, args: unknown[]) => Promise<unknown>;
27
+ }
28
+ /**
29
+ * Initialize client-side SPA navigation using the Navigation API.
30
+ *
31
+ * Call this once after hydrating your React root. Subsequent navigations
32
+ * (clicking `<a>` tags, browser back/forward) will fetch RSC payloads
33
+ * from the server and update the React tree without full page reloads.
34
+ *
35
+ * @param setPage - Callback to update the React root with new content.
36
+ * Typically wraps a `useState` setter.
37
+ * @param options - Configuration options.
38
+ *
39
+ * @returns A cleanup function that removes the navigation listener.
40
+ *
41
+ * @example
42
+ * ```tsx
43
+ * import { hydrateRoot } from 'react-dom/client';
44
+ * import { initNavigation } from '@cmj/juice/client';
45
+ *
46
+ * function App() {
47
+ * const [page, setPage] = useState<ReactNode>(initialServerContent);
48
+ * useEffect(() => initNavigation(setPage), []);
49
+ * return <>{page}</>;
50
+ * }
51
+ *
52
+ * hydrateRoot(document, <App />);
53
+ * ```
54
+ */
55
+ export declare function initNavigation(setPage: PageSetter, options?: NavigationOptions): () => void;
56
+ export {};
57
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"AASA,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AASxD;;;GAGG;AACH,KAAK,UAAU,GAAG,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;AAE5C;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAChE;AAoGD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,UAAU,EACnB,OAAO,GAAE,iBAAsB,GAC9B,MAAM,IAAI,CAmFZ"}
@@ -0,0 +1,197 @@
1
+ // ── juice/client — Navigation API bridge ──────────────────────────
2
+ // Intercepts browser navigations via the Navigation API and fetches
3
+ // RSC payloads from the server for seamless SPA transitions.
4
+ //
5
+ // ~2KB minified. Zero dependencies beyond React 19.
6
+ // Progressive enhancement: falls back to MPA if Navigation API
7
+ // is not available or JavaScript is disabled.
8
+ // ────────────────────────────────────────────────────────────────────
9
+ import { startTransition } from 'react';
10
+ import { createFromFetch } from 'react-server-dom-webpack/client.browser';
11
+ /**
12
+ * The RSC content type used for payload negotiation.
13
+ * Must match the server's `RSC_CONTENT_TYPE` in `rsc.ts`.
14
+ */
15
+ const RSC_CONTENT_TYPE = 'text/x-component';
16
+ // ── Prefetch cache ────────────────────────────────────────────────
17
+ const prefetchCache = new Map();
18
+ function prefetchRSC(url) {
19
+ if (prefetchCache.has(url))
20
+ return;
21
+ const promise = fetch(url, {
22
+ headers: { 'Accept': RSC_CONTENT_TYPE },
23
+ priority: 'low',
24
+ });
25
+ prefetchCache.set(url, promise);
26
+ // Expire after 30 seconds to avoid stale data
27
+ setTimeout(() => prefetchCache.delete(url), 30_000);
28
+ }
29
+ // ── Prefetch observer ─────────────────────────────────────────────
30
+ function setupPrefetching() {
31
+ // Prefetch on hover (desktop) and focus (keyboard nav)
32
+ document.addEventListener('pointerenter', (e) => {
33
+ const anchor = e.target.closest('a[href]');
34
+ if (!anchor)
35
+ return;
36
+ const href = anchor.getAttribute('href');
37
+ if (href && isSameOrigin(href)) {
38
+ prefetchRSC(new URL(href, location.href).href);
39
+ }
40
+ }, { capture: true, passive: true });
41
+ document.addEventListener('focusin', (e) => {
42
+ const anchor = e.target.closest('a[href]');
43
+ if (!anchor)
44
+ return;
45
+ const href = anchor.getAttribute('href');
46
+ if (href && isSameOrigin(href)) {
47
+ prefetchRSC(new URL(href, location.href).href);
48
+ }
49
+ }, { capture: true, passive: true });
50
+ // IntersectionObserver for data-prefetch links
51
+ if ('IntersectionObserver' in globalThis) {
52
+ const observer = new IntersectionObserver((entries) => {
53
+ for (const entry of entries) {
54
+ if (entry.isIntersecting) {
55
+ const href = entry.target.href;
56
+ if (href)
57
+ prefetchRSC(href);
58
+ observer.unobserve(entry.target);
59
+ }
60
+ }
61
+ }, { rootMargin: '200px' });
62
+ // Observe current and future [data-prefetch] links
63
+ for (const el of document.querySelectorAll('a[data-prefetch]')) {
64
+ observer.observe(el);
65
+ }
66
+ // MutationObserver to catch dynamically added links
67
+ new MutationObserver((mutations) => {
68
+ for (const mutation of mutations) {
69
+ for (const node of mutation.addedNodes) {
70
+ if (node instanceof HTMLAnchorElement && node.hasAttribute('data-prefetch')) {
71
+ observer.observe(node);
72
+ }
73
+ if (node instanceof HTMLElement) {
74
+ for (const el of node.querySelectorAll('a[data-prefetch]')) {
75
+ observer.observe(el);
76
+ }
77
+ }
78
+ }
79
+ }
80
+ }).observe(document.body, { childList: true, subtree: true });
81
+ }
82
+ }
83
+ // ── Helpers ───────────────────────────────────────────────────────
84
+ function isSameOrigin(href) {
85
+ try {
86
+ const url = new URL(href, location.href);
87
+ return url.origin === location.origin;
88
+ }
89
+ catch {
90
+ return false;
91
+ }
92
+ }
93
+ // ── View Transitions wrapper ──────────────────────────────────────
94
+ function withViewTransition(enabled, fn) {
95
+ if (enabled && 'startViewTransition' in document) {
96
+ document.startViewTransition(fn);
97
+ }
98
+ else {
99
+ fn();
100
+ }
101
+ }
102
+ // ── Main: initNavigation ──────────────────────────────────────────
103
+ /**
104
+ * Initialize client-side SPA navigation using the Navigation API.
105
+ *
106
+ * Call this once after hydrating your React root. Subsequent navigations
107
+ * (clicking `<a>` tags, browser back/forward) will fetch RSC payloads
108
+ * from the server and update the React tree without full page reloads.
109
+ *
110
+ * @param setPage - Callback to update the React root with new content.
111
+ * Typically wraps a `useState` setter.
112
+ * @param options - Configuration options.
113
+ *
114
+ * @returns A cleanup function that removes the navigation listener.
115
+ *
116
+ * @example
117
+ * ```tsx
118
+ * import { hydrateRoot } from 'react-dom/client';
119
+ * import { initNavigation } from '@cmj/juice/client';
120
+ *
121
+ * function App() {
122
+ * const [page, setPage] = useState<ReactNode>(initialServerContent);
123
+ * useEffect(() => initNavigation(setPage), []);
124
+ * return <>{page}</>;
125
+ * }
126
+ *
127
+ * hydrateRoot(document, <App />);
128
+ * ```
129
+ */
130
+ export function initNavigation(setPage, options = {}) {
131
+ const { viewTransitions = true, prefetch = false, callServer, } = options;
132
+ // Check for Navigation API support
133
+ if (!('navigation' in globalThis)) {
134
+ if (process.env.NODE_ENV === 'development') {
135
+ console.warn('[juice/client] Navigation API not available. ' +
136
+ 'Client-side navigation disabled (MPA mode).');
137
+ }
138
+ return () => { };
139
+ }
140
+ const nav = globalThis.navigation;
141
+ // Set up prefetching if enabled
142
+ if (prefetch) {
143
+ setupPrefetching();
144
+ }
145
+ // ── Navigation interceptor ────────────────────────────────────
146
+ const handler = (event) => {
147
+ // Only intercept navigations we can handle
148
+ if (!event.canIntercept)
149
+ return;
150
+ // Skip hash-only navigations
151
+ if (event.hashChange)
152
+ return;
153
+ // Skip downloads
154
+ if (event.downloadRequest)
155
+ return;
156
+ // Skip form submissions (handled by server actions)
157
+ if (event.formData)
158
+ return;
159
+ // Only handle same-origin navigations
160
+ const destinationUrl = new URL(event.destination.url);
161
+ if (destinationUrl.origin !== location.origin)
162
+ return;
163
+ // Intercept the navigation
164
+ event.intercept({
165
+ // Enable automatic scroll restoration
166
+ scroll: 'after-transition',
167
+ async handler() {
168
+ const url = event.destination.url;
169
+ // Use prefetched response if available
170
+ const fetchPromise = prefetchCache.has(url)
171
+ ? prefetchCache.get(url)
172
+ : fetch(url, {
173
+ headers: { 'Accept': RSC_CONTENT_TYPE },
174
+ signal: event.signal,
175
+ });
176
+ // Clear the prefetch cache entry
177
+ prefetchCache.delete(url);
178
+ // Decode the RSC payload
179
+ const rscPayload = createFromFetch(fetchPromise, {
180
+ callServer,
181
+ });
182
+ // Update the React tree with View Transitions
183
+ withViewTransition(viewTransitions, () => {
184
+ startTransition(() => {
185
+ setPage(rscPayload);
186
+ });
187
+ });
188
+ },
189
+ });
190
+ };
191
+ nav.addEventListener('navigate', handler);
192
+ // Return cleanup function
193
+ return () => {
194
+ nav.removeEventListener('navigate', handler);
195
+ };
196
+ }
197
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { initNavigation, type NavigationOptions } from './client.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,3 @@
1
+ // ── juice/client barrel export ────────────────────────────────────
2
+ export { initNavigation } from './client.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,OAAO,EAAE,cAAc,EAA0B,MAAM,aAAa,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { FlightManifest, RouterOptions } from './types.js';
1
+ import type { FlightManifest, RouterOptions, ParsedBody, ActionContext } from './types.js';
2
2
  /**
3
3
  * Extracts the server action ID from the request.
4
4
  *
@@ -12,15 +12,67 @@ import type { FlightManifest, RouterOptions } from './types.js';
12
12
  * @internal
13
13
  */
14
14
  export declare function _extractActionId(req: Request): Promise<string | null>;
15
+ /**
16
+ * Parses the request body based on Content-Type and returns a
17
+ * discriminated `ParsedBody` union.
18
+ *
19
+ * - `multipart/form-data` → `{ kind: 'form', data: FormData }`
20
+ * - `application/x-www-form-urlencoded` → `{ kind: 'form', data: FormData }`
21
+ * - `application/json` → `{ kind: 'json', data: unknown }`
22
+ * - Everything else → `{ kind: 'text', data: string }`
23
+ *
24
+ * The `kind` field enables runtime narrowing without casts:
25
+ * ```ts
26
+ * if (parsed.kind === 'form') parsed.data.get('name'); // FormData ✅
27
+ * if (parsed.kind === 'json') parsed.data; // unknown ✅
28
+ * if (parsed.kind === 'text') parsed.data.length; // string ✅
29
+ * ```
30
+ *
31
+ * @param req - The incoming POST `Request`.
32
+ * @returns The parsed body with discriminator.
33
+ *
34
+ * @internal
35
+ */
36
+ export declare function _parseBody(req: Request): Promise<ParsedBody>;
37
+ /**
38
+ * Parses cookies from the `Cookie` header into a `ReadonlyMap`.
39
+ *
40
+ * Zero dependencies. Handles edge cases:
41
+ * - Empty header → empty map
42
+ * - Malformed pairs (no `=`) → skipped
43
+ * - Values containing `=` → preserved
44
+ * - Leading/trailing whitespace → trimmed
45
+ *
46
+ * @param req - The incoming `Request`.
47
+ * @returns A readonly map of cookie name → value.
48
+ *
49
+ * @internal
50
+ */
51
+ export declare function _parseCookies(req: Request): ReadonlyMap<string, string>;
52
+ /**
53
+ * Constructs an `ActionContext` from the raw request.
54
+ *
55
+ * This is a **public API** — use it in tests to create mock contexts:
56
+ * ```ts
57
+ * import { createActionContext } from '@cmj/juice/runtime';
58
+ * const ctx = createActionContext(new Request('https://example.com'));
59
+ * ```
60
+ *
61
+ * The `cookies` property is lazy — only parsed on first access via
62
+ * a getter. This keeps the fast path (no cookie access) allocation-free.
63
+ */
64
+ export declare function createActionContext(req: Request, params?: Readonly<Record<string, string>>): ActionContext;
15
65
  /**
16
66
  * The POST server action pipeline.
17
67
  *
18
68
  * 1. Extracts the action ID from the request.
19
69
  * 2. Looks up the action in the manifest.
20
70
  * 3. Dynamically imports the action module.
21
- * 4. Parses the request body.
22
- * 5. Executes the action function.
23
- * 6. Returns the result as a JSON response, or passes through
71
+ * 4. Parses the request body into a `ParsedBody`.
72
+ * 5. Constructs an `ActionContext` (request, cookies, params).
73
+ * 6. Calls the action with **two arguments**: `(body, ctx)`
74
+ * preserving React 19 `<form>` compatibility.
75
+ * 7. Returns the result as a JSON response, or passes through
24
76
  * a thrown `Response` directly.
25
77
  *
26
78
  * @param req - The incoming POST `Request`.
@@ -1 +1 @@
1
- {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../src/runtime/actions.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIhE;;;;;;;;;;;GAWG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAoBxB;AAgCD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,OAAO,EACZ,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC,GAAG,aAAa,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACvG,OAAO,CAAC,QAAQ,CAAC,CAoHnB"}
1
+ {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../src/runtime/actions.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAI3F;;;;;;;;;;;GAWG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAoBxB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAelE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAavE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,OAAO,EACZ,MAAM,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM,GAC5C,aAAa,CAkBf;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,OAAO,EACZ,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC,GAAG,aAAa,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACvG,OAAO,CAAC,QAAQ,CAAC,CA4HnB"}
@@ -36,28 +36,96 @@ export async function _extractActionId(req) {
36
36
  return null;
37
37
  }
38
38
  /**
39
- * Parses the request body based on Content-Type.
39
+ * Parses the request body based on Content-Type and returns a
40
+ * discriminated `ParsedBody` union.
40
41
  *
41
- * - `multipart/form-data` → `FormData`
42
- * - `application/x-www-form-urlencoded` → `FormData`
43
- * - `application/json` → parsed JSON object
44
- * - Everything else → raw text
42
+ * - `multipart/form-data` → `{ kind: 'form', data: FormData }`
43
+ * - `application/x-www-form-urlencoded` → `{ kind: 'form', data: FormData }`
44
+ * - `application/json` → `{ kind: 'json', data: unknown }`
45
+ * - Everything else → `{ kind: 'text', data: string }`
46
+ *
47
+ * The `kind` field enables runtime narrowing without casts:
48
+ * ```ts
49
+ * if (parsed.kind === 'form') parsed.data.get('name'); // FormData ✅
50
+ * if (parsed.kind === 'json') parsed.data; // unknown ✅
51
+ * if (parsed.kind === 'text') parsed.data.length; // string ✅
52
+ * ```
45
53
  *
46
54
  * @param req - The incoming POST `Request`.
47
- * @returns The parsed body.
55
+ * @returns The parsed body with discriminator.
48
56
  *
49
57
  * @internal
50
58
  */
51
- async function _parseBody(req) {
59
+ export async function _parseBody(req) {
52
60
  const contentType = req.headers.get('content-type') ?? '';
53
61
  if (contentType.includes('multipart/form-data') ||
54
62
  contentType.includes('application/x-www-form-urlencoded')) {
55
- return req.formData();
63
+ return { kind: 'form', data: await req.formData() };
56
64
  }
57
65
  if (contentType.includes('application/json')) {
58
- return req.json();
66
+ return { kind: 'json', data: await req.json() };
67
+ }
68
+ return { kind: 'text', data: await req.text() };
69
+ }
70
+ /**
71
+ * Parses cookies from the `Cookie` header into a `ReadonlyMap`.
72
+ *
73
+ * Zero dependencies. Handles edge cases:
74
+ * - Empty header → empty map
75
+ * - Malformed pairs (no `=`) → skipped
76
+ * - Values containing `=` → preserved
77
+ * - Leading/trailing whitespace → trimmed
78
+ *
79
+ * @param req - The incoming `Request`.
80
+ * @returns A readonly map of cookie name → value.
81
+ *
82
+ * @internal
83
+ */
84
+ export function _parseCookies(req) {
85
+ const header = req.headers.get('cookie') ?? '';
86
+ if (!header)
87
+ return new Map();
88
+ const entries = [];
89
+ for (const pair of header.split(';')) {
90
+ const eqIndex = pair.indexOf('=');
91
+ if (eqIndex === -1)
92
+ continue;
93
+ const key = pair.slice(0, eqIndex).trim();
94
+ const value = pair.slice(eqIndex + 1).trim();
95
+ if (key)
96
+ entries.push([key, value]);
59
97
  }
60
- return req.text();
98
+ return new Map(entries);
99
+ }
100
+ /**
101
+ * Constructs an `ActionContext` from the raw request.
102
+ *
103
+ * This is a **public API** — use it in tests to create mock contexts:
104
+ * ```ts
105
+ * import { createActionContext } from '@cmj/juice/runtime';
106
+ * const ctx = createActionContext(new Request('https://example.com'));
107
+ * ```
108
+ *
109
+ * The `cookies` property is lazy — only parsed on first access via
110
+ * a getter. This keeps the fast path (no cookie access) allocation-free.
111
+ */
112
+ export function createActionContext(req, params = {}) {
113
+ const url = new URL(req.url);
114
+ // Lazy cookie parsing via getter
115
+ let _cookies;
116
+ return Object.create(null, {
117
+ request: { value: req, enumerable: true },
118
+ url: { value: url, enumerable: true },
119
+ params: { value: params, enumerable: true },
120
+ cookies: {
121
+ get() {
122
+ if (!_cookies)
123
+ _cookies = _parseCookies(req);
124
+ return _cookies;
125
+ },
126
+ enumerable: true,
127
+ },
128
+ });
61
129
  }
62
130
  /**
63
131
  * The POST server action pipeline.
@@ -65,9 +133,11 @@ async function _parseBody(req) {
65
133
  * 1. Extracts the action ID from the request.
66
134
  * 2. Looks up the action in the manifest.
67
135
  * 3. Dynamically imports the action module.
68
- * 4. Parses the request body.
69
- * 5. Executes the action function.
70
- * 6. Returns the result as a JSON response, or passes through
136
+ * 4. Parses the request body into a `ParsedBody`.
137
+ * 5. Constructs an `ActionContext` (request, cookies, params).
138
+ * 6. Calls the action with **two arguments**: `(body, ctx)`
139
+ * preserving React 19 `<form>` compatibility.
140
+ * 7. Returns the result as a JSON response, or passes through
71
141
  * a thrown `Response` directly.
72
142
  *
73
143
  * @param req - The incoming POST `Request`.
@@ -127,11 +197,17 @@ export async function _serverActionPipeline(req, manifest, options) {
127
197
  `"${actionRef.moduleId}" but export "${actionRef.exportName}" ` +
128
198
  `is not a function. Check your 'use server' exports.`);
129
199
  }
130
- // ── 4. Parse body ──────────────────────────────────────────
131
- const body = await _parseBody(req);
132
- // ── 5. Execute ─────────────────────────────────────────────
133
- const result = await actionFn(body);
134
- // ── 6. Return ──────────────────────────────────────────────
200
+ // ── 4. Parse body into discriminated union ─────────────────
201
+ const parsed = await _parseBody(req);
202
+ // ── 5. Construct ActionContext (no body — body is arg 1) ───
203
+ const ctx = createActionContext(req);
204
+ // ── 6. Execute with two arguments: (body, ctx) ────────────
205
+ // First arg: the parsed body (FormData, JSON, or text)
206
+ // → React 19 <form action={fn}> compatibility preserved
207
+ // Second arg: ActionContext (request, cookies, params)
208
+ // → opt-in power when the developer needs it
209
+ const result = await actionFn(parsed.data, ctx);
210
+ // ── 7. Return ──────────────────────────────────────────────
135
211
  // If the action returns a Response directly, pass it through.
136
212
  if (result instanceof Response) {
137
213
  return result;
@@ -1 +1 @@
1
- {"version":3,"file":"actions.js","sourceRoot":"","sources":["../../src/runtime/actions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"actions.js","sourceRoot":"","sources":["../../src/runtime/actions.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,5 @@
1
1
  export { createRouter } from './router.js';
2
- export type { FlightManifest, RouterOptions } from './types.js';
2
+ export { createActionContext } from './actions.js';
3
+ export { _isRSCRequest, _buildModuleMap, RSC_CONTENT_TYPE } from './rsc.js';
4
+ export type { FlightManifest, RouterOptions, ActionContext, ParsedBody } from './types.js';
3
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5E,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
@@ -1,5 +1,7 @@
1
1
  // ── juice/runtime ──────────────────────────────────────────────────
2
- // Public API barrel. Three exports. One function, two types.
2
+ // Public API barrel. Two functions, three types.
3
3
  // ────────────────────────────────────────────────────────────────────
4
4
  export { createRouter } from './router.js';
5
+ export { createActionContext } from './actions.js';
6
+ export { _isRSCRequest, _buildModuleMap, RSC_CONTENT_TYPE } from './rsc.js';
5
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,6DAA6D;AAC7D,uEAAuE;AAEvE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,iDAAiD;AACjD,uEAAuE;AAEvE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/runtime/router.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EAEd,MAAM,YAAY,CAAC;AAwNpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsEG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,cAAc,EACxB,OAAO,CAAC,EAAE,aAAa,GACtB,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAiErC"}
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/runtime/router.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EAEd,MAAM,YAAY,CAAC;AAwNpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsEG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,cAAc,EACxB,OAAO,CAAC,EAAE,aAAa,GACtB,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAmErC"}
@@ -7,6 +7,7 @@
7
7
  import { ManifestValidationError, HookExecutionError } from './errors.js';
8
8
  import { _compileRoutes, _matchRoute } from './matcher.js';
9
9
  import { _renderPipeline } from './render.js';
10
+ import { _renderRSCPipeline, _isRSCRequest } from './rsc.js';
10
11
  import { _serverActionPipeline } from './actions.js';
11
12
  import { _generateDevErrorOverlay } from './dev.js';
12
13
  // ── Manifest Normalization ────────────────────────────────────────
@@ -259,6 +260,7 @@ export function createRouter(manifest, options) {
259
260
  const hmrUrl = options?.hmrUrl ?? meta?.hmrUrl;
260
261
  const assetPrefix = options?.assetPrefix ?? meta?.assetPrefix ?? '/';
261
262
  const clientEntry = options?.clientEntry ?? meta?.clientEntry;
263
+ const rsc = options?.rsc ?? false;
262
264
  const resolvedOptions = {
263
265
  ...options,
264
266
  root,
@@ -266,6 +268,7 @@ export function createRouter(manifest, options) {
266
268
  hmrUrl,
267
269
  assetPrefix,
268
270
  clientEntry,
271
+ rsc,
269
272
  onNotFound: options?.onNotFound ?? _defaultOnNotFound,
270
273
  onError: options?.onError ?? _defaultOnError,
271
274
  };
@@ -324,7 +327,12 @@ async function _handleRequestInner(req, compiledRoutes, manifest, resolvedOption
324
327
  return _safeCallHook('onNotFound', () => resolvedOptions.onNotFound(req), new Response('Not Found', { status: 404 }));
325
328
  }
326
329
  // ── Render pipeline ────────────────────────────────────
327
- const response = await _renderPipeline(req, match, manifest, resolvedOptions);
330
+ // Branch: RSC payload for client-side navigation,
331
+ // HTML for initial page loads and non-SPA clients.
332
+ const useRSC = resolvedOptions.rsc && _isRSCRequest(req);
333
+ const response = useRSC
334
+ ? await _renderRSCPipeline(req, match, manifest, resolvedOptions)
335
+ : await _renderPipeline(req, match, manifest, resolvedOptions);
328
336
  // HEAD requests: return headers only, strip body
329
337
  if (method === 'HEAD') {
330
338
  return new Response(null, {
@@ -1 +1 @@
1
- {"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/runtime/router.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,mEAAmE;AACnE,kCAAkC;AAClC,EAAE;AACF,wDAAwD;AACxD,uEAAuE;AAEvE,OAAO,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AAOpD,qEAAqE;AAErE;;;;;;;;;;GAUG;AACH,SAAS,kBAAkB,CAAC,GAAY;IACtC,uEAAuE;IACvE,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1D,OAAO,GAAG,CAAC;IACb,CAAC;IAED,MAAM,GAAG,GAAG,GAA8B,CAAC;IAE3C,8DAA8D;IAC9D,4DAA4D;IAC5D,IAAI,GAAG,CAAC,MAAM,IAAI,OAAO,GAAG,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACjD,MAAM,EAAE,GAAG,GAAG,CAAC,aAAa,CAAC;QAC7B,IAAI,EAAE,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;YACjC,MAAM,UAAU,GAAG,uBAAuB,CACxC,EAA6C,CAC9C,CAAC;YACF,IAAI,UAAU,KAAK,EAAE,EAAE,CAAC;gBACtB,OAAO,EAAE,GAAG,GAAG,EAAE,aAAa,EAAE,UAAU,EAAE,CAAC;YAC/C,CAAC;QACH,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,yEAAyE;IACzE,wEAAwE;IACxE,2EAA2E;IAC3E,MAAM,kBAAkB,GAAG,SAAS,IAAI,GAAG,IAAI,SAAS,IAAI,GAAG,CAAC;IAChE,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACxB,OAAO,GAAG,CAAC,CAAC,yDAAyD;IACvE,CAAC;IAED,uEAAuE;IACvE,MAAM,MAAM,GAA4B;QACtC,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE;QACxB,aAAa,EAAE,GAAG,CAAC,aAAa,IAAI,EAAE;QACtC,aAAa,EAAE,EAAE;KAClB,CAAC;IAEF,MAAM,EAAE,GAAG,GAAG,CAAC,aAAa,CAAC;IAC7B,IAAI,EAAE,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;QACjC,MAAM,CAAC,aAAa,GAAG,uBAAuB,CAC5C,EAA6C,CAC9C,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,uBAAuB,CAC9B,OAAgD;IAEhD,MAAM,MAAM,GAA4C,EAAE,CAAC;IAC3D,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAClD,0EAA0E;QAC1E,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;YACpC,MAAM,CAAC,EAAE,CAAC,GAAG;gBACX,QAAQ,EAAE,KAAK,CAAC,MAAM;gBACtB,UAAU,EAAE,KAAK,CAAC,IAAI,IAAI,SAAS;aACpC,CAAC;YACF,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC;QACrB,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;AACpC,CAAC;AAED,sEAAsE;AAEtE;;;;;GAKG;AACH,SAAS,iBAAiB,CAAC,QAAiB;IAC1C,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,MAAM,IAAI,uBAAuB,CAC/B,sCAAsC,CACvC,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,IAAI,uBAAuB,CAC/B,6CAA6C;YAC3C,wDAAwD,CAC3D,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,uBAAuB,CAC/B,kCAAkC;YAChC,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,QAAQ,CAAC,CAC3D,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,GAAG,QAAmC,CAAC;IAE9C,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC9C,MAAM,IAAI,uBAAuB,CAC/B,mEAAmE;YACjE,uCAAuC,CAC1C,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,CAAC,CAAC,aAAa,IAAI,OAAO,CAAC,CAAC,aAAa,KAAK,QAAQ,EAAE,CAAC;QAC5D,MAAM,IAAI,uBAAuB,CAC/B,0EAA0E;YACxE,mDAAmD,CACtD,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,CAAC,CAAC,aAAa,IAAI,OAAO,CAAC,CAAC,aAAa,KAAK,QAAQ,EAAE,CAAC;QAC5D,MAAM,IAAI,uBAAuB,CAC/B,0EAA0E;YACxE,8CAA8C,CACjD,CAAC;IACJ,CAAC;AACH,CAAC;AAED,sEAAsE;AAEtE,gBAAgB;AAChB,SAAS,kBAAkB,CAAC,GAAY;IACtC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,OAAO,IAAI,QAAQ,CAAC,cAAc,GAAG,CAAC,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;AACrE,CAAC;AAED,gBAAgB;AAChB,SAAS,eAAe,CAAC,KAAc,EAAE,IAAa;IACpD,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,KAAK,CAAC,CAAC;IACzD,OAAO,IAAI,QAAQ,CAAC,uBAAuB,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;AAChE,CAAC;AAED,sEAAsE;AAEtE;;;;;;GAMG;AACH,KAAK,UAAU,aAAa,CAC1B,QAAgB,EAChB,MAA4B,EAC5B,QAAW;IAEX,IAAI,CAAC;QACH,OAAO,MAAM,MAAM,EAAE,CAAC;IACxB,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,6DAA6D;QAC7D,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;YAC9B,OAAO,KAAU,CAAC;QACpB,CAAC;QAED,OAAO,CAAC,KAAK,CACX,IAAI,kBAAkB,CAAC,QAAQ,EAAE,KAAK,CAAC,CACxC,CAAC;QACF,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,cAAc,CAAC,EAAU;IAChC,IAAI,SAAwC,CAAC;IAC7C,MAAM,OAAO,GAAG,IAAI,OAAO,CAAW,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;QAClD,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;YAC1B,MAAM,CACJ,IAAI,QAAQ,CAAC,iBAAiB,EAAE;gBAC9B,MAAM,EAAE,GAAG;gBACX,OAAO,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE;aAC1C,CAAC,CACH,CAAC;QACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IACT,CAAC,CAAC,CAAC;IACH,OAAO;QACL,OAAO;QACP,KAAK,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC;KACrC,CAAC;AACJ,CAAC;AAGD,sEAAsE;AAEtE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsEG;AACH,MAAM,UAAU,YAAY,CAC1B,QAAwB,EACxB,OAAuB;IAEvB,iEAAiE;IACjE,MAAM,UAAU,GAAG,kBAAkB,CACnC,QAA8C,CAC/C,CAAC;IAEF,gEAAgE;IAChE,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAC9B,MAAM,gBAAgB,GAAG,UAAuC,CAAC;IAEjE,gEAAgE;IAChE,gEAAgE;IAChE,0DAA0D;IAC1D,MAAM,IAAI,GAAG,gBAAgB,CAAC,KAAK,CAAC;IACpC,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,GAAG,CAAC;IAC1C,MAAM,cAAc,GAAG,OAAO,EAAE,cAAc,IAAI,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,IAAI,EAAE,IAAI,CAAC;IACzC,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,IAAI,IAAI,IAAI,EAAE,IAAI,CAAC,KAAK,aAAa,CAAC;IAC9D,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,IAAI,EAAE,MAAM,CAAC;IAC/C,MAAM,WAAW,GAAG,OAAO,EAAE,WAAW,IAAI,IAAI,EAAE,WAAW,IAAI,GAAG,CAAC;IACrE,MAAM,WAAW,GAAG,OAAO,EAAE,WAAW,IAAI,IAAI,EAAE,WAAW,CAAC;IAC9D,MAAM,eAAe,GAAG;QACtB,GAAG,OAAO;QACV,IAAI;QACJ,KAAK;QACL,MAAM;QACN,WAAW;QACX,WAAW;QACX,UAAU,EAAE,OAAO,EAAE,UAAU,IAAI,kBAAkB;QACrD,OAAO,EAAE,OAAO,EAAE,OAAO,IAAI,eAAe;KAC7C,CAAC;IAEF,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,CAAC,GAAG,CAAC,gGAAgG,CAAC,CAAC;IAChH,CAAC;IAED,gEAAgE;IAChE,MAAM,cAAc,GAAqB,cAAc,CACrD,gBAAgB,CAAC,MAAM,EACvB,QAAQ,CACT,CAAC;IAEF,gEAAgE;IAChE,OAAO,KAAK,UAAU,aAAa,CAAC,GAAY;QAC9C,gEAAgE;QAChE,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,OAAO,GAAG,cAAc,CAAC,cAAc,CAAC,CAAC;YAC/C,IAAI,CAAC;gBACH,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC;oBACxB,mBAAmB,CAAC,GAAG,EAAE,cAAc,EAAE,gBAAgB,EAAE,eAAe,CAAC;oBAC3E,OAAO,CAAC,OAAO;iBAChB,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,MAAe,EAAE,CAAC;gBACzB,yCAAyC;gBACzC,IAAI,MAAM,YAAY,QAAQ,EAAE,CAAC;oBAC/B,OAAO,MAAM,CAAC;gBAChB,CAAC;gBACD,OAAO,eAAe,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YAC9C,CAAC;oBAAS,CAAC;gBACT,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,CAAC;QACH,CAAC;QAED,OAAO,mBAAmB,CAAC,GAAG,EAAE,cAAc,EAAE,gBAAgB,EAAE,eAAe,CAAC,CAAC;IACrF,CAAC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,mBAAmB,CAChC,GAAY,EACZ,cAAgC,EAChC,QAAwB,EACxB,eAMC;IAED,IAAI,CAAC;QACH,gEAAgE;QAChE,IAAI,eAAe,CAAC,eAAe,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,eAAe,CAAC,eAAe,CAAC;YAC/C,MAAM,aAAa,GAAG,MAAM,aAAa,CACvC,iBAAiB,EACjB,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EACjB,SAAS,CACV,CAAC;YACF,IAAI,aAAa,YAAY,QAAQ,EAAE,CAAC;gBACtC,OAAO,aAAa,CAAC;YACvB,CAAC;QACH,CAAC;QAED,8DAA8D;QAC9D,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QAExC,QAAQ,MAAM,EAAE,CAAC;YACf,KAAK,KAAK,CAAC;YACX,KAAK,MAAM,CAAC,CAAC,CAAC;gBACZ,0DAA0D;gBAC1D,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;gBAEnD,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,OAAO,aAAa,CAClB,YAAY,EACZ,GAAG,EAAE,CAAC,eAAe,CAAC,UAAU,CAAC,GAAG,CAAC,EACrC,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAC3C,CAAC;gBACJ,CAAC;gBAED,0DAA0D;gBAC1D,MAAM,QAAQ,GAAG,MAAM,eAAe,CACpC,GAAG,EACH,KAAK,EACL,QAAQ,EACR,eAAe,CAChB,CAAC;gBAEF,iDAAiD;gBACjD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;oBACtB,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE;wBACxB,MAAM,EAAE,QAAQ,CAAC,MAAM;wBACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;wBAC/B,OAAO,EAAE,QAAQ,CAAC,OAAO;qBAC1B,CAAC,CAAC;gBACL,CAAC;gBAED,OAAO,QAAQ,CAAC;YAClB,CAAC;YAED,KAAK,MAAM,CAAC,CAAC,CAAC;gBACZ,OAAO,qBAAqB,CAAC,GAAG,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;YAC/D,CAAC;YAED,OAAO,CAAC,CAAC,CAAC;gBACR,OAAO,IAAI,QAAQ,CAAC,oBAAoB,EAAE;oBACxC,MAAM,EAAE,GAAG;oBACX,OAAO,EAAE,EAAE,KAAK,EAAE,iBAAiB,EAAE;iBACtC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,MAAe,EAAE,CAAC;QACzB,4DAA4D;QAC5D,uDAAuD;QACvD,IAAI,MAAM,YAAY,QAAQ,EAAE,CAAC;YAC/B,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,4DAA4D;QAC5D,IAAI,eAAe,CAAC,KAAK,EAAE,CAAC;YAC1B,OAAO,CAAC,KAAK,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;YACrC,OAAO,IAAI,QAAQ,CACjB,wBAAwB,CAAC,MAAM,EAAE,GAAG,CAAC,EACrC;gBACE,MAAM,EAAE,GAAG;gBACX,OAAO,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE;aACxD,CACF,CAAC;QACJ,CAAC;QAED,6DAA6D;QAC7D,OAAO,aAAa,CAClB,SAAS,EACT,GAAG,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1C,IAAI,QAAQ,CAAC,uBAAuB,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CACvD,CAAC;IACJ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/runtime/router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import type { FlightManifest, RouterOptions, _RouteMatch } from './types.js';
2
+ /**
3
+ * The RSC content type used for payload negotiation.
4
+ * Requests with `Accept: text/x-component` receive RSC wire format.
5
+ * @internal
6
+ */
7
+ export declare const RSC_CONTENT_TYPE = "text/x-component";
8
+ /**
9
+ * Check if a request is asking for an RSC payload.
10
+ * @internal
11
+ */
12
+ export declare function _isRSCRequest(req: Request): boolean;
13
+ /**
14
+ * Build the webpack-compatible module map from the flight manifest.
15
+ * Maps client module specifiers to their chunk URLs and export names.
16
+ *
17
+ * react-server-dom-webpack expects:
18
+ * ```
19
+ * {
20
+ * [moduleSpecifier]: {
21
+ * [exportName]: { id: string, chunks: string[], name: string }
22
+ * }
23
+ * }
24
+ * ```
25
+ *
26
+ * @internal
27
+ */
28
+ export declare function _buildModuleMap(manifest: FlightManifest, assetPrefix?: string): Record<string, Record<string, {
29
+ id: string;
30
+ chunks: string[];
31
+ name: string;
32
+ }>>;
33
+ /**
34
+ * RSC render pipeline — produces React Flight wire format.
35
+ *
36
+ * Same component loading and layout wrapping as the HTML pipeline,
37
+ * but uses `react-server-dom-webpack/server` to serialize the React
38
+ * tree instead of `react-dom/server`.
39
+ *
40
+ * @internal
41
+ */
42
+ export declare function _renderRSCPipeline(req: Request, match: _RouteMatch, manifest: FlightManifest, options: Required<Pick<RouterOptions, 'onError'>> & RouterOptions & {
43
+ isDev?: boolean;
44
+ assetPrefix?: string;
45
+ }): Promise<Response>;
46
+ //# sourceMappingURL=rsc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rsc.d.ts","sourceRoot":"","sources":["../../src/runtime/rsc.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACb,WAAW,EACZ,MAAM,YAAY,CAAC;AAKpB;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AAEnD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAGnD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,cAAc,EACxB,WAAW,GAAE,MAAY,GACxB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAgBhF;AAED;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC,GAAG,aAAa,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5G,OAAO,CAAC,QAAQ,CAAC,CA+GnB"}
@@ -0,0 +1,149 @@
1
+ // ── juice/runtime RSC render pipeline ──────────────────────────────
2
+ // Handles RSC payload responses for client-side SPA navigation.
3
+ // Activated when `Accept: text/x-component` is present and `rsc: true`.
4
+ //
5
+ // Uses react-server-dom-webpack's renderToReadableStream to produce
6
+ // React Flight wire format instead of HTML.
7
+ // ────────────────────────────────────────────────────────────────────
8
+ import { createElement } from 'react';
9
+ import { ModuleLoadError } from './errors.js';
10
+ import { _resolveModulePath } from './resolve.js';
11
+ import { _bustModuleCache } from './dev.js';
12
+ /**
13
+ * The RSC content type used for payload negotiation.
14
+ * Requests with `Accept: text/x-component` receive RSC wire format.
15
+ * @internal
16
+ */
17
+ export const RSC_CONTENT_TYPE = 'text/x-component';
18
+ /**
19
+ * Check if a request is asking for an RSC payload.
20
+ * @internal
21
+ */
22
+ export function _isRSCRequest(req) {
23
+ const accept = req.headers.get('Accept') ?? '';
24
+ return accept.includes(RSC_CONTENT_TYPE);
25
+ }
26
+ /**
27
+ * Build the webpack-compatible module map from the flight manifest.
28
+ * Maps client module specifiers to their chunk URLs and export names.
29
+ *
30
+ * react-server-dom-webpack expects:
31
+ * ```
32
+ * {
33
+ * [moduleSpecifier]: {
34
+ * [exportName]: { id: string, chunks: string[], name: string }
35
+ * }
36
+ * }
37
+ * ```
38
+ *
39
+ * @internal
40
+ */
41
+ export function _buildModuleMap(manifest, assetPrefix = '/') {
42
+ const prefix = assetPrefix.endsWith('/') ? assetPrefix : `${assetPrefix}/`;
43
+ const moduleMap = {};
44
+ for (const [specifier, ref] of Object.entries(manifest.clientModules)) {
45
+ const chunks = ref.chunks.map((c) => `${prefix}${c}`);
46
+ moduleMap[specifier] = {
47
+ [ref.name]: {
48
+ id: specifier,
49
+ chunks,
50
+ name: ref.name,
51
+ },
52
+ };
53
+ }
54
+ return moduleMap;
55
+ }
56
+ /**
57
+ * RSC render pipeline — produces React Flight wire format.
58
+ *
59
+ * Same component loading and layout wrapping as the HTML pipeline,
60
+ * but uses `react-server-dom-webpack/server` to serialize the React
61
+ * tree instead of `react-dom/server`.
62
+ *
63
+ * @internal
64
+ */
65
+ export async function _renderRSCPipeline(req, match, manifest, options) {
66
+ const { entry, params } = match;
67
+ // ── 1. Dynamic import of the page module ─────────────────────
68
+ let importPath = _resolveModulePath(entry.moduleId, options.root);
69
+ if (options.isDev) {
70
+ importPath = _bustModuleCache(importPath);
71
+ }
72
+ let mod;
73
+ try {
74
+ mod = await import(importPath);
75
+ }
76
+ catch (cause) {
77
+ throw new ModuleLoadError(entry.moduleId, `route "${new URL(req.url).pathname}"` +
78
+ (options.root
79
+ ? ` (resolved to "${importPath}" from root "${options.root}")`
80
+ : ' (no root option set — pass { root: import.meta.url } to createRouter)'), cause);
81
+ }
82
+ const exportName = entry.exportName ?? 'default';
83
+ const Component = mod[exportName];
84
+ if (typeof Component !== 'function') {
85
+ throw new Error(`[juice/runtime] Route module "${entry.moduleId}" does not export ` +
86
+ `a valid component at "${exportName}".`);
87
+ }
88
+ // ── 2. Build props ───────────────────────────────────────────
89
+ const url = new URL(req.url);
90
+ const searchParams = Object.fromEntries(url.searchParams.entries());
91
+ // ── 3. Create the React element ──────────────────────────────
92
+ let element = createElement(Component, { params, searchParams });
93
+ // ── 3b. Wrap in layout chain (root → leaf) ───────────────────
94
+ if (entry.layouts && entry.layouts.length > 0) {
95
+ for (let i = entry.layouts.length - 1; i >= 0; i--) {
96
+ let layoutPath = _resolveModulePath(entry.layouts[i], options.root);
97
+ if (options.isDev) {
98
+ layoutPath = _bustModuleCache(layoutPath);
99
+ }
100
+ const layoutMod = await import(layoutPath);
101
+ const Layout = layoutMod.default;
102
+ if (typeof Layout === 'function') {
103
+ element = createElement(Layout, { request: req }, element);
104
+ }
105
+ }
106
+ }
107
+ // ── 4. Render to RSC wire format ─────────────────────────────
108
+ try {
109
+ // Dynamic import — react-server-dom-webpack is an optional dep
110
+ const { renderToReadableStream: renderRSC } = await import('react-server-dom-webpack/server.edge');
111
+ const moduleMap = _buildModuleMap(manifest, options.assetPrefix);
112
+ const stream = renderRSC(element, moduleMap);
113
+ return new Response(stream, {
114
+ status: 200,
115
+ headers: {
116
+ 'Content-Type': RSC_CONTENT_TYPE,
117
+ 'Cache-Control': 'no-cache',
118
+ },
119
+ });
120
+ }
121
+ catch (thrown) {
122
+ // Thrown Response from the component tree
123
+ if (thrown instanceof Response) {
124
+ return thrown;
125
+ }
126
+ // react-server-dom-webpack not installed or not configured correctly
127
+ if (thrown instanceof Error) {
128
+ const msg = thrown.message;
129
+ // Case 1: Package not installed
130
+ if (msg.includes('Cannot find module') || msg.includes('Cannot find package')) {
131
+ return new Response('[juice] RSC payload negotiation requires "react-server-dom-webpack".\n\n' +
132
+ ' npm install react-server-dom-webpack@canary\n', { status: 500, headers: { 'Content-Type': 'text/plain' } });
133
+ }
134
+ // Case 2: Running outside Vite (missing react-server export condition)
135
+ // This happens when running with tsx/node directly instead of
136
+ // through the Vite dev server or a proper build.
137
+ if (msg.includes('react-server') && msg.includes('condition')) {
138
+ return new Response('[juice] RSC payload negotiation requires the "react-server" export condition.\n\n' +
139
+ 'This is automatically configured by the Vite dev server and production builds.\n' +
140
+ 'If running directly with tsx/node, add: --conditions=react-server\n\n' +
141
+ ' node --conditions=react-server server.js\n' +
142
+ ' tsx --conditions=react-server server.ts\n', { status: 500, headers: { 'Content-Type': 'text/plain' } });
143
+ }
144
+ }
145
+ // Re-throw for the router's onError hook
146
+ throw thrown;
147
+ }
148
+ }
149
+ //# sourceMappingURL=rsc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rsc.js","sourceRoot":"","sources":["../../src/runtime/rsc.ts"],"names":[],"mappings":"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"}
@@ -229,6 +229,19 @@ export interface RouterOptions {
229
229
  * @example `'/src/entry-client.tsx'`
230
230
  */
231
231
  readonly clientEntry?: string;
232
+ /**
233
+ * Enable RSC payload negotiation for client-side SPA navigation.
234
+ *
235
+ * When `true`, requests with `Accept: text/x-component` receive
236
+ * a React Server Component wire-format payload instead of HTML.
237
+ * This enables the client-side Navigation API interceptor to
238
+ * fetch page updates without full page reloads.
239
+ *
240
+ * Requires `react-server-dom-webpack` as a peer dependency.
241
+ *
242
+ * @default false
243
+ */
244
+ readonly rsc?: boolean;
232
245
  }
233
246
  /**
234
247
  * A compiled route pairs a `URLPattern` with its manifest entry.
@@ -247,4 +260,85 @@ export interface _RouteMatch {
247
260
  readonly entry: RouteEntry;
248
261
  readonly params: Readonly<Record<string, string>>;
249
262
  }
263
+ /**
264
+ * Discriminated union returned by the runtime's body parser.
265
+ * The `kind` field lets you narrow the type at runtime without any casts.
266
+ *
267
+ * @example
268
+ * ```ts
269
+ * switch (parsed.kind) {
270
+ * case 'form': parsed.data; // FormData
271
+ * case 'json': parsed.data; // unknown (narrow with your own type)
272
+ * case 'text': parsed.data; // string
273
+ * }
274
+ * ```
275
+ */
276
+ export type ParsedBody = {
277
+ readonly kind: 'form';
278
+ readonly data: FormData;
279
+ } | {
280
+ readonly kind: 'json';
281
+ readonly data: unknown;
282
+ } | {
283
+ readonly kind: 'text';
284
+ readonly data: string;
285
+ };
286
+ /**
287
+ * Opt-in second argument passed to server action functions.
288
+ *
289
+ * The **first argument** is always the parsed body — `FormData` for
290
+ * form submissions, parsed JSON, or raw text — preserving full
291
+ * React 19 `<form action={fn}>` compatibility.
292
+ *
293
+ * Use `ActionContext` as the **second argument** when you need access
294
+ * to the raw `Request`, cookies, route params, or headers.
295
+ *
296
+ * @example
297
+ * ```ts
298
+ * // ── Simple form action (most common, React 19 native) ──
299
+ * 'use server'
300
+ * export async function addToCart(formData: FormData) {
301
+ * const id = formData.get('productId'); // ✅ just works
302
+ * }
303
+ *
304
+ * // ── Full context when you need power ────────────────────
305
+ * 'use server'
306
+ * export async function processWebhook(body: unknown, ctx: ActionContext) {
307
+ * const sig = ctx.request.headers.get('x-webhook-signature');
308
+ * const session = ctx.cookies.get('session_id');
309
+ * const id = ctx.params.id; // from /webhook/:id
310
+ * }
311
+ * ```
312
+ */
313
+ export interface ActionContext {
314
+ /**
315
+ * The original `Request` — your escape hatch for headers, method,
316
+ * URL, and anything the web platform gives you. Never consumed;
317
+ * the body has already been read and passed as the first argument.
318
+ */
319
+ readonly request: Request;
320
+ /** The parsed URL from the request (convenience). */
321
+ readonly url: URL;
322
+ /**
323
+ * Cookies parsed from the `Cookie` header.
324
+ * Lazy — only parsed on first access. Zero imports needed.
325
+ *
326
+ * @example
327
+ * ```ts
328
+ * const session = ctx.cookies.get('session_id');
329
+ * ```
330
+ */
331
+ readonly cookies: ReadonlyMap<string, string>;
332
+ /**
333
+ * Route parameters extracted from the URL pattern.
334
+ * Empty object `{}` when the action URL has no dynamic segments.
335
+ *
336
+ * @example
337
+ * ```ts
338
+ * // Route: /api/products/:id
339
+ * const productId = ctx.params.id; // '42'
340
+ * ```
341
+ */
342
+ readonly params: Readonly<Record<string, string>>;
343
+ }
250
344
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/runtime/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/runtime/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cmj/juice",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "Zero-bloat React 19 RSC framework — streaming SSR, server actions, zero config.",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -39,6 +39,10 @@
39
39
  "types": "./dist/runtime/index.d.ts",
40
40
  "import": "./dist/runtime/index.js"
41
41
  },
42
+ "./client": {
43
+ "types": "./dist/client/index.d.ts",
44
+ "import": "./dist/client/index.js"
45
+ },
42
46
  "./create": {
43
47
  "types": "./dist/cli/create.d.ts",
44
48
  "import": "./dist/cli/create.js"
@@ -53,6 +57,9 @@
53
57
  "runtime": [
54
58
  "dist/runtime/index.d.ts"
55
59
  ],
60
+ "client": [
61
+ "dist/client/index.d.ts"
62
+ ],
56
63
  "create": [
57
64
  "dist/cli/create.d.ts"
58
65
  ]
@@ -60,6 +67,7 @@
60
67
  },
61
68
  "files": [
62
69
  "dist/cli",
70
+ "dist/client",
63
71
  "dist/compiler",
64
72
  "dist/runtime",
65
73
  "README.md",
@@ -78,8 +86,14 @@
78
86
  "peerDependencies": {
79
87
  "react": "^19.0.0",
80
88
  "react-dom": "^19.0.0",
89
+ "react-server-dom-webpack": ">=19.0.0",
81
90
  "vite": "^6.0.0"
82
91
  },
92
+ "peerDependenciesMeta": {
93
+ "react-server-dom-webpack": {
94
+ "optional": true
95
+ }
96
+ },
83
97
  "devDependencies": {
84
98
  "@types/node": "^22.0.0",
85
99
  "@types/react": "^19.0.0",
@@ -87,6 +101,7 @@
87
101
  "acorn": "^8.16.0",
88
102
  "react": "^19.0.0",
89
103
  "react-dom": "^19.0.0",
104
+ "react-server-dom-webpack": "^19.3.0-canary-e0cc7202-20260227",
90
105
  "typescript": "^5.7.0",
91
106
  "urlpattern-polyfill": "^10.1.0",
92
107
  "vite": "^6.0.0",