@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 +30 -1
- package/dist/client/client.d.ts +57 -0
- package/dist/client/client.d.ts.map +1 -0
- package/dist/client/client.js +197 -0
- package/dist/client/client.js.map +1 -0
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +3 -0
- package/dist/client/index.js.map +1 -0
- package/dist/runtime/actions.d.ts +56 -4
- package/dist/runtime/actions.d.ts.map +1 -1
- package/dist/runtime/actions.js +94 -18
- package/dist/runtime/actions.js.map +1 -1
- package/dist/runtime/index.d.ts +3 -1
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +3 -1
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/router.d.ts.map +1 -1
- package/dist/runtime/router.js +9 -1
- package/dist/runtime/router.js.map +1 -1
- package/dist/runtime/rsc.d.ts +46 -0
- package/dist/runtime/rsc.d.ts.map +1 -0
- package/dist/runtime/rsc.js +149 -0
- package/dist/runtime/rsc.js.map +1 -0
- package/dist/runtime/types.d.ts +94 -0
- package/dist/runtime/types.d.ts.map +1 -1
- package/package.json +16 -1
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
|
|
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":"AAAA,qEAAqE;AACrE,oEAAoE;AACpE,6DAA6D;AAC7D,EAAE;AACF,oDAAoD;AACpD,+DAA+D;AAC/D,8CAA8C;AAC9C,uEAAuE;AAEvE,OAAO,EAAE,eAAe,EAAkB,MAAM,OAAO,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAE1E;;;GAGG;AACH,MAAM,gBAAgB,GAAG,kBAAkB,CAAC;AAgC5C,qEAAqE;AAErE,MAAM,aAAa,GAAG,IAAI,GAAG,EAA6B,CAAC;AAE3D,SAAS,WAAW,CAAC,GAAW;IAC9B,IAAI,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO;IAEnC,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,EAAE;QACzB,OAAO,EAAE,EAAE,QAAQ,EAAE,gBAAgB,EAAE;QACvC,QAAQ,EAAE,KAAwB;KACnC,CAAC,CAAC;IAEH,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAEhC,8CAA8C;IAC9C,UAAU,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;AACtD,CAAC;AAED,qEAAqE;AAErE,SAAS,gBAAgB;IACvB,uDAAuD;IACvD,QAAQ,CAAC,gBAAgB,CAAC,cAAc,EAAE,CAAC,CAAC,EAAE,EAAE;QAC9C,MAAM,MAAM,GAAI,CAAC,CAAC,MAAsB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC5D,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,MAAM,IAAI,GAAG,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,IAAI,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,WAAW,CAAC,IAAI,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;QACjD,CAAC;IACH,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAErC,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE;QACzC,MAAM,MAAM,GAAI,CAAC,CAAC,MAAsB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC5D,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,MAAM,IAAI,GAAG,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,IAAI,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,WAAW,CAAC,IAAI,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;QACjD,CAAC;IACH,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAErC,+CAA+C;IAC/C,IAAI,sBAAsB,IAAI,UAAU,EAAE,CAAC;QACzC,MAAM,QAAQ,GAAG,IAAI,oBAAoB,CAAC,CAAC,OAAO,EAAE,EAAE;YACpD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;oBACzB,MAAM,IAAI,GAAI,KAAK,CAAC,MAA4B,CAAC,IAAI,CAAC;oBACtD,IAAI,IAAI;wBAAE,WAAW,CAAC,IAAI,CAAC,CAAC;oBAC5B,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBACnC,CAAC;YACH,CAAC;QACH,CAAC,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;QAE5B,mDAAmD;QACnD,KAAK,MAAM,EAAE,IAAI,QAAQ,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,EAAE,CAAC;YAC/D,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACvB,CAAC;QAED,oDAAoD;QACpD,IAAI,gBAAgB,CAAC,CAAC,SAAS,EAAE,EAAE;YACjC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;gBACjC,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;oBACvC,IAAI,IAAI,YAAY,iBAAiB,IAAI,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,EAAE,CAAC;wBAC5E,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;oBACzB,CAAC;oBACD,IAAI,IAAI,YAAY,WAAW,EAAE,CAAC;wBAChC,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,EAAE,CAAC;4BAC3D,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;wBACvB,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAChE,CAAC;AACH,CAAC;AAED,qEAAqE;AAErE,SAAS,YAAY,CAAC,IAAY;IAChC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;QACzC,OAAO,GAAG,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,qEAAqE;AAErE,SAAS,kBAAkB,CAAC,OAAgB,EAAE,EAAc;IAC1D,IAAI,OAAO,IAAI,qBAAqB,IAAI,QAAQ,EAAE,CAAC;QAChD,QAAgB,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC;IAC5C,CAAC;SAAM,CAAC;QACN,EAAE,EAAE,CAAC;IACP,CAAC;AACH,CAAC;AAED,qEAAqE;AAErE;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,cAAc,CAC5B,OAAmB,EACnB,UAA6B,EAAE;IAE/B,MAAM,EACJ,eAAe,GAAG,IAAI,EACtB,QAAQ,GAAG,KAAK,EAChB,UAAU,GACX,GAAG,OAAO,CAAC;IAEZ,mCAAmC;IACnC,IAAI,CAAC,CAAC,YAAY,IAAI,UAAU,CAAC,EAAE,CAAC;QAClC,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,EAAE,CAAC;YAC3C,OAAO,CAAC,IAAI,CACV,+CAA+C;gBAC/C,6CAA6C,CAC9C,CAAC;QACJ,CAAC;QACD,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,GAAG,GAAI,UAAkB,CAAC,UAAU,CAAC;IAE3C,gCAAgC;IAChC,IAAI,QAAQ,EAAE,CAAC;QACb,gBAAgB,EAAE,CAAC;IACrB,CAAC;IAED,iEAAiE;IACjE,MAAM,OAAO,GAAG,CAAC,KAAU,EAAE,EAAE;QAC7B,2CAA2C;QAC3C,IAAI,CAAC,KAAK,CAAC,YAAY;YAAE,OAAO;QAEhC,6BAA6B;QAC7B,IAAI,KAAK,CAAC,UAAU;YAAE,OAAO;QAE7B,iBAAiB;QACjB,IAAI,KAAK,CAAC,eAAe;YAAE,OAAO;QAElC,oDAAoD;QACpD,IAAI,KAAK,CAAC,QAAQ;YAAE,OAAO;QAE3B,sCAAsC;QACtC,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACtD,IAAI,cAAc,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM;YAAE,OAAO;QAEtD,2BAA2B;QAC3B,KAAK,CAAC,SAAS,CAAC;YACd,sCAAsC;YACtC,MAAM,EAAE,kBAAkB;YAE1B,KAAK,CAAC,OAAO;gBACX,MAAM,GAAG,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC;gBAElC,uCAAuC;gBACvC,MAAM,YAAY,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC;oBACzC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAE;oBACzB,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;wBACT,OAAO,EAAE,EAAE,QAAQ,EAAE,gBAAgB,EAAE;wBACvC,MAAM,EAAE,KAAK,CAAC,MAAM;qBACrB,CAAC,CAAC;gBAEP,iCAAiC;gBACjC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAE1B,yBAAyB;gBACzB,MAAM,UAAU,GAAG,eAAe,CAAY,YAAY,EAAE;oBAC1D,UAAU;iBACX,CAAC,CAAC;gBAEH,8CAA8C;gBAC9C,kBAAkB,CAAC,eAAe,EAAE,GAAG,EAAE;oBACvC,eAAe,CAAC,GAAG,EAAE;wBACnB,OAAO,CAAC,UAAkC,CAAC,CAAC;oBAC9C,CAAC,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;YACL,CAAC;SACF,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,GAAG,CAAC,gBAAgB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAE1C,0BAA0B;IAC1B,OAAO,GAAG,EAAE;QACV,GAAG,CAAC,mBAAmB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -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 @@
|
|
|
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.
|
|
23
|
-
* 6.
|
|
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;
|
|
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"}
|
package/dist/runtime/actions.js
CHANGED
|
@@ -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` →
|
|
44
|
-
* - Everything else →
|
|
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
|
|
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.
|
|
70
|
-
* 6.
|
|
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
|
|
132
|
-
// ── 5.
|
|
133
|
-
const
|
|
134
|
-
// ── 6.
|
|
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":"AAAA,sEAAsE;AACtE,sEAAsE;AACtE,uEAAuE;AACvE,uEAAuE;AAEvE,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,GAAY;IAEZ,0DAA0D;IAC1D,MAAM,cAAc,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IAC5D,IAAI,cAAc;QAAE,OAAO,cAAc,CAAC;IAE1C,kEAAkE;IAClE,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;IAC1D,IACE,WAAW,CAAC,QAAQ,CAAC,qBAAqB,CAAC;QAC3C,WAAW,CAAC,QAAQ,CAAC,mCAAmC,CAAC,EACzD,CAAC;QACD,sEAAsE;QACtE,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,CAAC;QAC9C,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC5C,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxD,OAAO,QAAQ,CAAC;QAClB,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../../src/runtime/actions.ts"],"names":[],"mappings":"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"}
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export { createRouter } from './router.js';
|
|
2
|
-
export
|
|
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"}
|
package/dist/runtime/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
// ── juice/runtime ──────────────────────────────────────────────────
|
|
2
|
-
// Public API barrel.
|
|
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,
|
|
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":"
|
|
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"}
|
package/dist/runtime/router.js
CHANGED
|
@@ -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
|
-
|
|
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":"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
|
|
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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"}
|
package/dist/runtime/types.d.ts
CHANGED
|
@@ -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":"AAMA;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,mEAAmE;IACnE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAE7B;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,6CAA6C;IAC7C,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAEnC,yCAAyC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,mDAAmD;IACnD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,gDAAgD;IAChD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,cAAc;IAC7B,sEAAsE;IACtE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IAEtD,kEAAkE;IAClE,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC;IAElE,yDAAyD;IACzD,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC;IAElE;;;;;;;;OAQG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE;QACf,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,GAAG,YAAY,CAAC;QAC7C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QACzB,gEAAgE;QAChE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAC9B,sDAAsD;QACtD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;KAC/B,CAAC;CACH;AAID;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAE3B;;;;;;OAMG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,CACzB,GAAG,EAAE,OAAO,KACT,QAAQ,GAAG,IAAI,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAEhD;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAErE;;;;;;;OAOG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,CACjB,KAAK,EAAE,OAAO,EACd,GAAG,EAAE,OAAO,KACT,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAElC;;;;;;;;OAQG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IAEjC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,GAAG,YAAY,CAAC;IAE7C;;;;;;;;;;;;;;;;;OAiBG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAEzB;;;;;;;;;OASG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAE9B;;;;;;;;;OASG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;
|
|
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
|
+
"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",
|