@timber-js/app 0.2.0-alpha.210 → 0.2.0-alpha.212
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/agent-skill.md +10 -5
- package/dist/_chunks/{actions-Rjk4htmA.js → actions-CCdnVtWm.js} +8 -6
- package/dist/_chunks/actions-CCdnVtWm.js.map +1 -0
- package/dist/_chunks/{als-registry-DaxkVjt5.js → als-registry-BZqHCtq-.js} +2 -4
- package/dist/_chunks/als-registry-BZqHCtq-.js.map +1 -0
- package/dist/_chunks/{cache-api-DGdYfNJn.js → cache-api-LA3sBpUS.js} +5 -5
- package/dist/_chunks/{cache-api-DGdYfNJn.js.map → cache-api-LA3sBpUS.js.map} +1 -1
- package/dist/_chunks/{chains-BoO51joc.js → chains-BfoPFraI.js} +5 -146
- package/dist/_chunks/chains-BfoPFraI.js.map +1 -0
- package/dist/_chunks/classify-BT66U83D.js +147 -0
- package/dist/_chunks/classify-BT66U83D.js.map +1 -0
- package/dist/_chunks/{cli-check-ajNY3B2e.js → cli-check-BfQ54-UJ.js} +3 -3
- package/dist/_chunks/{cli-check-ajNY3B2e.js.map → cli-check-BfQ54-UJ.js.map} +1 -1
- package/dist/_chunks/{cli-schema-sync-D2eI8jEg.js → cli-schema-sync-czh2dsLs.js} +2 -2
- package/dist/_chunks/{cli-schema-sync-D2eI8jEg.js.map → cli-schema-sync-czh2dsLs.js.map} +1 -1
- package/dist/_chunks/client-dep-entries-CQwpb8dI.js +66 -0
- package/dist/_chunks/client-dep-entries-CQwpb8dI.js.map +1 -0
- package/dist/_chunks/{convention-lint-DLmhGsRS.js → convention-lint-BEVW4EID.js} +3 -3
- package/dist/_chunks/{convention-lint-DLmhGsRS.js.map → convention-lint-BEVW4EID.js.map} +1 -1
- package/dist/_chunks/{dev-server-v97rQH4b.js → dev-server-FKxptbnI.js} +2 -2
- package/dist/_chunks/{dev-server-v97rQH4b.js.map → dev-server-FKxptbnI.js.map} +1 -1
- package/dist/_chunks/{json-lossy-check-CVuRs2hG.js → json-lossy-check-C8zBY2uZ.js} +2 -2
- package/dist/_chunks/{json-lossy-check-CVuRs2hG.js.map → json-lossy-check-C8zBY2uZ.js.map} +1 -1
- package/dist/_chunks/{live-graph-9cSnn_h9.js → live-graph-C_4v-fHv.js} +4 -3
- package/dist/_chunks/{live-graph-9cSnn_h9.js.map → live-graph-C_4v-fHv.js.map} +1 -1
- package/dist/_chunks/{logger-BP0LN6vP.js → logger-CbLdcy-W.js} +2 -2
- package/dist/_chunks/{logger-BP0LN6vP.js.map → logger-CbLdcy-W.js.map} +1 -1
- package/dist/_chunks/{poison-scan-vGV7Re0B.js → poison-scan-C92liMAr.js} +2 -4
- package/dist/_chunks/poison-scan-C92liMAr.js.map +1 -0
- package/dist/_chunks/{scanner-DmqdxzbW.js → scanner-CQt12vE2.js} +2 -2
- package/dist/_chunks/{scanner-DmqdxzbW.js.map → scanner-CQt12vE2.js.map} +1 -1
- package/dist/_chunks/{sizeof-BM1409x2.js → sizeof-QPE5nd3u.js} +2 -2
- package/dist/_chunks/{sizeof-BM1409x2.js.map → sizeof-QPE5nd3u.js.map} +1 -1
- package/dist/_chunks/{walkers-Czu2jXFq.js → walkers-DAT4avhZ.js} +3 -3
- package/dist/_chunks/{walkers-Czu2jXFq.js.map → walkers-DAT4avhZ.js.map} +1 -1
- package/dist/adapters/cloudflare-kv-cache.js +1 -1
- package/dist/analyze/classify.d.ts +2 -0
- package/dist/analyze/classify.d.ts.map +1 -1
- package/dist/analyze/crawl-entry.js +3 -2
- package/dist/analyze/crawl-entry.js.map +1 -1
- package/dist/analyze/graph-command.js +2 -2
- package/dist/analyze/poison-scan.d.ts.map +1 -1
- package/dist/cache/index.js +2 -2
- package/dist/cache/stores/memory.js +1 -1
- package/dist/cdn/workers-cache-purge.js +1 -1
- package/dist/cli.js +3 -3
- package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -1
- package/dist/client/browser-entry/hydrate.d.ts.map +1 -1
- package/dist/client/browser-entry/router-init.d.ts.map +1 -1
- package/dist/client/form.d.ts +17 -64
- package/dist/client/form.d.ts.map +1 -1
- package/dist/client/index.d.ts +2 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +23 -51
- package/dist/client/index.js.map +1 -1
- package/dist/client/internal.js +25 -25
- package/dist/client/internal.js.map +1 -1
- package/dist/client/navigation-api.d.ts +25 -63
- package/dist/client/navigation-api.d.ts.map +1 -1
- package/dist/client/router-lifecycle.d.ts +17 -11
- package/dist/client/router-lifecycle.d.ts.map +1 -1
- package/dist/client/router-pipeline.d.ts +0 -1
- package/dist/client/router-pipeline.d.ts.map +1 -1
- package/dist/client/router-types.d.ts +14 -45
- package/dist/client/router-types.d.ts.map +1 -1
- package/dist/client/router.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +44 -7
- package/dist/index.js.map +1 -1
- package/dist/plugins/client-dep-entries.d.ts +44 -0
- package/dist/plugins/client-dep-entries.d.ts.map +1 -0
- package/dist/plugins/content.d.ts.map +1 -1
- package/dist/plugins/entries.d.ts +6 -0
- package/dist/plugins/entries.d.ts.map +1 -1
- package/dist/plugins/shims.d.ts.map +1 -1
- package/dist/routing/index.js +2 -2
- package/dist/rsc-runtime/rsc.d.ts +1 -1
- package/dist/rsc-runtime/rsc.d.ts.map +1 -1
- package/dist/server/action-client.d.ts +9 -5
- package/dist/server/action-client.d.ts.map +1 -1
- package/dist/server/action-handler.d.ts +27 -8
- package/dist/server/action-handler.d.ts.map +1 -1
- package/dist/server/als-registry.d.ts +22 -2
- package/dist/server/als-registry.d.ts.map +1 -1
- package/dist/server/client-error-message.d.ts +12 -0
- package/dist/server/client-error-message.d.ts.map +1 -0
- package/dist/server/form-state-embed.d.ts +32 -0
- package/dist/server/form-state-embed.d.ts.map +1 -0
- package/dist/server/index.d.ts +0 -2
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +7 -40
- package/dist/server/index.js.map +1 -1
- package/dist/server/internal.js +10 -6
- package/dist/server/internal.js.map +1 -1
- package/dist/server/logger.d.ts +1 -0
- package/dist/server/logger.d.ts.map +1 -1
- package/dist/server/pipeline.d.ts +20 -6
- package/dist/server/pipeline.d.ts.map +1 -1
- package/dist/server/request-context.d.ts +27 -2
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/route-element-builder.d.ts.map +1 -1
- package/dist/server/rsc-entry/action-dispatcher.d.ts +6 -5
- package/dist/server/rsc-entry/action-dispatcher.d.ts.map +1 -1
- package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
- package/dist/server/ssr-bridge-types.d.ts +8 -0
- package/dist/server/ssr-bridge-types.d.ts.map +1 -1
- package/dist/server/ssr-entry.d.ts.map +1 -1
- package/dist/server/ssr-render.d.ts +3 -0
- package/dist/server/ssr-render.d.ts.map +1 -1
- package/docs/api/31-api-client.mdx +9 -3
- package/docs/learn/08-forms-and-actions.mdx +21 -28
- package/package.json +1 -1
- package/src/analyze/classify.ts +1 -1
- package/src/analyze/poison-scan.ts +1 -4
- package/src/client/browser-entry/action-dispatch.ts +74 -18
- package/src/client/browser-entry/hydrate.ts +18 -0
- package/src/client/browser-entry/router-init.ts +4 -18
- package/src/client/form.tsx +33 -98
- package/src/client/index.ts +2 -2
- package/src/client/navigation-api.ts +47 -173
- package/src/client/navigation-transition.ts +2 -2
- package/src/client/router-lifecycle.ts +40 -20
- package/src/client/router-pipeline.ts +3 -9
- package/src/client/router-types.ts +14 -49
- package/src/client/router.ts +38 -58
- package/src/index.ts +21 -2
- package/src/plugins/client-dep-entries.ts +78 -0
- package/src/plugins/content.ts +26 -1
- package/src/plugins/entries.ts +7 -0
- package/src/plugins/shims.ts +0 -2
- package/src/rsc-runtime/rsc.ts +3 -0
- package/src/rsc-runtime/vendor-types.d.ts +14 -0
- package/src/server/action-client.ts +18 -20
- package/src/server/action-handler.ts +133 -95
- package/src/server/als-registry.ts +23 -9
- package/src/server/client-error-message.ts +18 -0
- package/src/server/form-state-embed.ts +63 -0
- package/src/server/index.ts +0 -4
- package/src/server/logger.ts +6 -1
- package/src/server/pipeline.ts +27 -8
- package/src/server/request-context.ts +39 -2
- package/src/server/route-element-builder.ts +12 -1
- package/src/server/rsc-entry/action-dispatcher.ts +37 -34
- package/src/server/rsc-entry/error-renderer.ts +2 -1
- package/src/server/rsc-entry/rsc-stream.ts +20 -11
- package/src/server/rsc-entry/ssr-renderer.ts +14 -1
- package/src/server/ssr-bridge-types.ts +9 -0
- package/src/server/ssr-entry.ts +1 -0
- package/src/server/ssr-render.ts +5 -0
- package/dist/_chunks/actions-Rjk4htmA.js.map +0 -1
- package/dist/_chunks/als-registry-DaxkVjt5.js.map +0 -1
- package/dist/_chunks/chains-BoO51joc.js.map +0 -1
- package/dist/_chunks/poison-scan-vGV7Re0B.js.map +0 -1
- package/dist/server/form-flash.d.ts +0 -78
- package/dist/server/form-flash.d.ts.map +0 -1
- package/src/server/form-flash.ts +0 -89
package/dist/server/logger.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/server/logger.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/server/logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,6 +20,8 @@ import type { MiddlewareFn } from './middleware-runner.ts';
|
|
|
20
20
|
import { DenySignal } from './primitives.ts';
|
|
21
21
|
import type { ManifestSegmentNode } from './route-matcher.ts';
|
|
22
22
|
import type { CsrfConfig } from './csrf.ts';
|
|
23
|
+
import type { ReactFormState } from 'react-dom/client';
|
|
24
|
+
import type { ActionErrorForRender } from './als-registry.ts';
|
|
23
25
|
/**
|
|
24
26
|
* Result of matching a canonical pathname against the route tree.
|
|
25
27
|
*
|
|
@@ -201,17 +203,29 @@ export interface PipelineConfig {
|
|
|
201
203
|
* from `req.url` (which re-encodes).
|
|
202
204
|
*
|
|
203
205
|
* The `reenter` parameter is the full pipeline function (including proxy,
|
|
204
|
-
* ALS, tracing) for the no-JS
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
* the pipeline needing the same `Request` object to reach
|
|
206
|
+
* ALS, tracing) for the no-JS action rerender path — the synthetic GET
|
|
207
|
+
* flows through the complete pipeline. Its `cookies` become that request's
|
|
208
|
+
* parsed cookies and its `formState` the action's form state for SSR
|
|
209
|
+
* (`runWithRequestContext`'s options), so the rerender reads both without
|
|
210
|
+
* the pipeline needing the same `Request` object to reach them.
|
|
209
211
|
*
|
|
210
212
|
* Moved into the pipeline (TIM-1213) so proxy.ts runs on action POSTs,
|
|
211
213
|
* matching the design doc contract: "proxy.ts runs on every request,
|
|
212
214
|
* no exclusions."
|
|
213
215
|
*/
|
|
214
|
-
dispatchAction?: (req: Request, canonicalPath: string, reenter: (req: Request,
|
|
216
|
+
dispatchAction?: (req: Request, canonicalPath: string, reenter: (req: Request, reentry: PipelineReentry) => Promise<Response>) => Promise<Response | null>;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* What the no-JS action rerender hands the pipeline when it re-enters it:
|
|
220
|
+
* the action's post-mutation cookies and, when its form used
|
|
221
|
+
* `useActionState`, the form state React decoded from the submission — or,
|
|
222
|
+
* when the action threw, the error to render in place of the page.
|
|
223
|
+
*/
|
|
224
|
+
export interface PipelineReentry {
|
|
225
|
+
cookies: Map<string, string>;
|
|
226
|
+
formState?: ReactFormState;
|
|
227
|
+
/** The error a no-JS action threw, rendered where the page would be. */
|
|
228
|
+
actionError?: ActionErrorForRender;
|
|
215
229
|
}
|
|
216
230
|
/**
|
|
217
231
|
* Create the request handler from a pipeline configuration.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/server/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAa3D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/server/pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,9 +14,10 @@
|
|
|
14
14
|
* and design/11-platform.md §"AsyncLocalStorage".
|
|
15
15
|
*/
|
|
16
16
|
import type { CoercedParams } from '../shared/param-value.ts';
|
|
17
|
-
import { requestContextAls } from './als-registry.ts';
|
|
17
|
+
import { requestContextAls, type ActionErrorForRender } from './als-registry.ts';
|
|
18
18
|
import { type SlotParamsRecord } from '../shared/slot-params.ts';
|
|
19
19
|
import { type ReactCacheScope } from './react-cache-scope.ts';
|
|
20
|
+
import type { ReactFormState } from 'react-dom/client';
|
|
20
21
|
export { requestContextAls };
|
|
21
22
|
/**
|
|
22
23
|
* Returns a read-only view of the current request's headers.
|
|
@@ -154,6 +155,16 @@ export interface RequestContextOptions {
|
|
|
154
155
|
* (TIM-868).
|
|
155
156
|
*/
|
|
156
157
|
cookies?: Map<string, string>;
|
|
158
|
+
/**
|
|
159
|
+
* The form state of the no-JS action this render answers. Only the
|
|
160
|
+
* action dispatcher's re-entry passes it; see `RequestContextStore.formState`.
|
|
161
|
+
*/
|
|
162
|
+
formState?: ReactFormState;
|
|
163
|
+
/**
|
|
164
|
+
* The error of the no-JS action this render answers. Only the action
|
|
165
|
+
* dispatcher's re-entry passes it; see `RequestContextStore.actionError`.
|
|
166
|
+
*/
|
|
167
|
+
actionError?: ActionErrorForRender;
|
|
157
168
|
}
|
|
158
169
|
/**
|
|
159
170
|
* Run a callback within a request context. Used by the pipeline to establish
|
|
@@ -171,7 +182,7 @@ export interface RequestContextOptions {
|
|
|
171
182
|
* @param req - The incoming Request object.
|
|
172
183
|
* @param fn - The function to run within the request context.
|
|
173
184
|
*/
|
|
174
|
-
export declare function runWithRequestContext<T>(req: Request, fn: () => T, { reactCacheScope, cookies }?: RequestContextOptions): T;
|
|
185
|
+
export declare function runWithRequestContext<T>(req: Request, fn: () => T, { reactCacheScope, cookies, formState, actionError }?: RequestContextOptions): T;
|
|
175
186
|
/**
|
|
176
187
|
* Enable cookie mutation for the current context. Called by the framework
|
|
177
188
|
* when entering middleware.ts, server actions, or route.ts handlers.
|
|
@@ -199,4 +210,18 @@ export declare function markResponseFlushed(): void;
|
|
|
199
210
|
* See design/07-routing.md §"Request Header Injection"
|
|
200
211
|
*/
|
|
201
212
|
export declare function applyRequestHeaderOverlay(overlay: Headers): void;
|
|
213
|
+
/**
|
|
214
|
+
* The form state of the no-JS action this render answers, or `null`. Read by
|
|
215
|
+
* the SSR renderer only (`rsc-entry/ssr-renderer.ts`), which passes it to
|
|
216
|
+
* Fizz and embeds it for `hydrateRoot`. Framework-internal: not exported
|
|
217
|
+
* from `@timber-js/app/server`.
|
|
218
|
+
*/
|
|
219
|
+
export declare function getFormStateForSsr(): ReactFormState | null;
|
|
220
|
+
/**
|
|
221
|
+
* The error of the no-JS action this render answers, or `null`. Read by the
|
|
222
|
+
* route element builder, which renders it in place of the page, and by the
|
|
223
|
+
* Flight `onError`, which gives it the ID the action logged it with.
|
|
224
|
+
* Framework-internal: not exported from `@timber-js/app/server`.
|
|
225
|
+
*/
|
|
226
|
+
export declare function getActionErrorForRender(): ActionErrorForRender | null;
|
|
202
227
|
//# sourceMappingURL=request-context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../../src/server/request-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,
|
|
1
|
+
{"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../../src/server/request-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-element-builder.d.ts","sourceRoot":"","sources":["../../src/server/route-element-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAQ9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAMhE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"route-element-builder.d.ts","sourceRoot":"","sources":["../../src/server/route-element-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAQ9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAMhE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAS5D;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,mBAAmB,EAAE,EAC/B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,UAAU,GAChB,MAAM,EAAE,CAGV;AAED;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAID,+CAA+C;AAC/C,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;IAC3C,OAAO,EAAE,mBAAmB,CAAC;CAC9B;AAED,+CAA+C;AAC/C,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,OAAO,EAAE,cAAc,CAAC;IACxB,wDAAwD;IACxD,gBAAgB,EAAE,oBAAoB,EAAE,CAAC;IACzC,qCAAqC;IACrC,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,4DAA4D;IAC5D,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B;;;;OAIG;IACH,YAAY,EAAE,aAAa,EAAE,CAAC;IAC9B;;;;OAIG;IACH,aAAa,CAAC,EAAE,aAAa,EAAE,CAAC;CACjC;AA2DD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,UAAU,EACjB,YAAY,CAAC,EAAE,mBAAmB,EAClC,eAAe,CAAC,EAAE,eAAe,GAAG,IAAI,EACxC,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3C,OAAO,CAAC,kBAAkB,CAAC,CAua7B"}
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
* `createPipeline` calls it after proxy.ts runs (TIM-1213), so proxy.ts
|
|
9
9
|
* sees action POSTs — "proxy.ts runs on every request, no exclusions." It
|
|
10
10
|
* encapsulates action detection, the route-type check, action handler
|
|
11
|
-
* dispatch, and the no-JS
|
|
11
|
+
* dispatch, and the answer to a no-JS action that did not redirect: the
|
|
12
|
+
* page rerendered with React's form state, or the error page.
|
|
12
13
|
*
|
|
13
14
|
* The CSRF gate is not here: it runs in `createPipeline` before proxy.ts
|
|
14
15
|
* (`csrfGate` in pipeline-helpers.ts). The action handler repeats the
|
|
@@ -20,7 +21,7 @@
|
|
|
20
21
|
*/
|
|
21
22
|
import type { BodyLimitsConfig } from '../body-limits.ts';
|
|
22
23
|
import type { CsrfConfig } from '../csrf.ts';
|
|
23
|
-
import type { RouteMatcher } from '../pipeline.ts';
|
|
24
|
+
import type { PipelineReentry, RouteMatcher } from '../pipeline.ts';
|
|
24
25
|
import type { SensitiveFieldsOption } from '../sensitive-fields.ts';
|
|
25
26
|
import type { RevalidateRenderer } from '../actions.ts';
|
|
26
27
|
/**
|
|
@@ -57,11 +58,11 @@ export interface ActionDispatcherDeps {
|
|
|
57
58
|
*
|
|
58
59
|
* Called after proxy.ts runs (inside the pipeline) for every request.
|
|
59
60
|
* Checks if the request is a server action POST, handles the route-type
|
|
60
|
-
* check (TIM-870), dispatches to the action handler, and
|
|
61
|
-
*
|
|
61
|
+
* check (TIM-870), dispatches to the action handler, and answers a no-JS
|
|
62
|
+
* action that did not redirect.
|
|
62
63
|
*
|
|
63
64
|
* Returns `Response` if the request was handled as an action, `null` to
|
|
64
65
|
* fall through to normal routing.
|
|
65
66
|
*/
|
|
66
|
-
export declare function buildActionDispatcher(deps: ActionDispatcherDeps): (req: Request, canonicalPath: string, reenter: (req: Request,
|
|
67
|
+
export declare function buildActionDispatcher(deps: ActionDispatcherDeps): (req: Request, canonicalPath: string, reenter: (req: Request, reentry: PipelineReentry) => Promise<Response>) => Promise<Response | null>;
|
|
67
68
|
//# sourceMappingURL=action-dispatcher.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action-dispatcher.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/action-dispatcher.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"action-dispatcher.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/action-dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEpE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAIxD;;;;;;;;GAQG;AACH,MAAM,MAAM,yBAAyB,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,kBAAkB,CAAC;AAE7E,yEAAyE;AACzE,MAAM,WAAW,oBAAoB;IACnC,6EAA6E;IAC7E,UAAU,EAAE,UAAU,CAAC;IACvB,2DAA2D;IAC3D,UAAU,CAAC,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACxC,oEAAoE;IACpE,eAAe,CAAC,EAAE,qBAAqB,CAAC;IACxC,8DAA8D;IAC9D,uBAAuB,EAAE,yBAAyB,CAAC;IACnD;;;;;;OAMG;IACH,UAAU,EAAE,YAAY,CAAC;CAC1B;AAID;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,oBAAoB,GACzB,CACD,GAAG,EAAE,OAAO,EACZ,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,QAAQ,CAAC,KACnE,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CA8D5B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-renderer.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/error-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAIjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE/D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAGlE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"error-renderer.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/error-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAIjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE/D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAGlE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAevD;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;CAClB;AA+GD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,mBAAmB,EAAE,EAC/B,gBAAgB,EAAE,WAAW,EAAE,EAC/B,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,UAAU,EACjB,eAAe,EAAE,OAAO,EACxB,eAAe,EAAE,qBAAqB,EACtC,WAAW,CAAC,EAAE,eAAe,EAC7B,gBAAgB,SAAW,GAC1B,OAAO,CAAC,QAAQ,CAAC,CA6DnB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rsc-stream.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/rsc-stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAKnE,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"rsc-stream.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/rsc-stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAKnE,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAQ3E,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAG/E,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IACtC,OAAO,EAAE,aAAa,CAAC;CACxB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,cAAc,EACvB,GAAG,EAAE,OAAO,EACZ,aAAa,CAAC,EAAE,aAAa,EAAE,GAC9B,eAAe,CAiHjB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssr-renderer.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/ssr-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAMlE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"ssr-renderer.d.ts","sourceRoot":"","sources":["../../../src/server/rsc-entry/ssr-renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAMlE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AASzD,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AA8BzD;;;;;;;;GAQG;AACH,eAAO,MAAM,gCAAgC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAiB,CAAC;AAEhF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,iCAAiC,EAAE;IAAE,KAAK,EAAE,OAAO,CAAA;CAAqB,CAAC;AAEtF,UAAU,gBAAgB;IACxB,GAAG,EAAE,OAAO,CAAC;IACb,SAAS,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IACtC,OAAO,EAAE,aAAa,CAAC;IACvB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,gBAAgB,EAAE,oBAAoB,EAAE,CAAC;IACzC,KAAK,EAAE,UAAU,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IACzB,eAAe,EAAE,qBAAqB,CAAC;IACvC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,wDAAwD;IACxD,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,YAAY,CAAC,EAAE,aAAa,EAAE,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAsRjF"}
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
* See `design/02-rendering-pipeline.md` §"RSC → SSR → Client Hydration"
|
|
50
50
|
* and `CLAUDE.md` §"RSC and SSR Are Separate Vite Environments".
|
|
51
51
|
*/
|
|
52
|
+
import type { ReactFormState } from 'react-dom/client';
|
|
52
53
|
/**
|
|
53
54
|
* Navigation context passed from the RSC environment to SSR.
|
|
54
55
|
*
|
|
@@ -102,6 +103,13 @@ export interface NavContext {
|
|
|
102
103
|
/** Request cookies as name→value pairs. Used by useCookie() during SSR
|
|
103
104
|
* to return correct cookie values before hydration. */
|
|
104
105
|
cookies?: Map<string, string>;
|
|
106
|
+
/**
|
|
107
|
+
* The form state of the no-JS action this page answers (React's
|
|
108
|
+
* `decodeFormState`), passed to Fizz so the `useActionState` hook that
|
|
109
|
+
* submitted renders with the action's result. Absent on every other
|
|
110
|
+
* render. See design/08-forms-and-actions.md §"No-JS Result Round-Trip".
|
|
111
|
+
*/
|
|
112
|
+
formState?: ReactFormState;
|
|
105
113
|
/**
|
|
106
114
|
* Lazy thunk that produces the `<script>self.__timber_segments=…</script>`
|
|
107
115
|
* tag. Invoked by the SSR entry AFTER `renderSsrNodeStream` /
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssr-bridge-types.d.ts","sourceRoot":"","sources":["../../src/server/ssr-bridge-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAEH;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,6BAA6B;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;;;;;;OAUG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,eAAe,EAAE,OAAO,CAAC;IACzB,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,sBAAsB,EAAE,MAAM,CAAC;IAC/B;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,SAAS,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IACvC;;;0DAGsD;IACtD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;iFAE6E;IAC7E,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;4DACwD;IACxD,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B;;;;;;;;;;;;;;;;;OAiBG;IACH,oBAAoB,CAAC,EAAE,MAAM,MAAM,CAAC;IAEpC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,WAAW,CAAC;CAC5B;AAED;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,oFAAoF;IACpF,QAAQ,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,OAAO,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,UAAU,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,WAAW,eAAe;IAC9B,sEAAsE;IACtE,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,UAAU,CAAC;IACpB;;;;;;;;;;;;;;;;OAgBG;IACH,oBAAoB,EAAE,OAAO,CAAC;CAC/B"}
|
|
1
|
+
{"version":3,"file":"ssr-bridge-types.d.ts","sourceRoot":"","sources":["../../src/server/ssr-bridge-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,6BAA6B;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;;;;;;OAUG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,eAAe,EAAE,OAAO,CAAC;IACzB,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,sBAAsB,EAAE,MAAM,CAAC;IAC/B;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,SAAS,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IACvC;;;0DAGsD;IACtD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;iFAE6E;IAC7E,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;4DACwD;IACxD,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B;;;;;;;;;;;;;;;;;OAiBG;IACH,oBAAoB,CAAC,EAAE,MAAM,MAAM,CAAC;IAEpC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,WAAW,CAAC;CAC5B;AAED;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,oFAAoF;IACpF,QAAQ,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,OAAO,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,UAAU,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,WAAW,eAAe;IAC9B,sEAAsE;IACtE,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,UAAU,CAAC;IACpB;;;;;;;;;;;;;;;;OAgBG;IACH,oBAAoB,EAAE,OAAO,CAAC;CAC/B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssr-entry.d.ts","sourceRoot":"","sources":["../../src/server/ssr-entry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AA+BH,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAiDzE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,SAAS,CAC7B,SAAS,EAAE,cAAc,CAAC,UAAU,CAAC,EACrC,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,eAAe,CAAC,
|
|
1
|
+
{"version":3,"file":"ssr-entry.d.ts","sourceRoot":"","sources":["../../src/server/ssr-entry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AA+BH,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAiDzE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,SAAS,CAC7B,SAAS,EAAE,cAAc,CAAC,UAAU,CAAC,EACrC,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,eAAe,CAAC,CA4L1B;eAEc,SAAS"}
|
|
@@ -20,11 +20,14 @@
|
|
|
20
20
|
* 18-build-system.md §"Entry Files"
|
|
21
21
|
*/
|
|
22
22
|
import type { ReactNode } from 'react';
|
|
23
|
+
import type { ReactFormState } from 'react-dom/client';
|
|
23
24
|
/** Options shared by both SSR render paths (Node streams and Web Streams). */
|
|
24
25
|
export interface SsrStreamOptions {
|
|
25
26
|
bootstrapScriptContent?: string;
|
|
26
27
|
/** Request CSP nonce — stamped by Fizz on the bootstrap and runtime scripts. */
|
|
27
28
|
nonce?: string;
|
|
29
|
+
/** A no-JS action's form state, for the `useActionState` hook that submitted. */
|
|
30
|
+
formState?: ReactFormState;
|
|
28
31
|
deferSuspenseFor?: number;
|
|
29
32
|
signal?: AbortSignal;
|
|
30
33
|
renderTimeoutMs?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssr-render.d.ts","sourceRoot":"","sources":["../../src/server/ssr-render.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"ssr-render.d.ts","sourceRoot":"","sources":["../../src/server/ssr-render.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAiGvD,8EAA8E;AAC9E,MAAM,WAAW,gBAAgB;IAC/B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kEAAkE;IAClE,WAAW,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C;;;;;;OAMG;IACH,sBAAsB,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;CACtD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,SAAS,EAClB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAErC;AAED,wEAAwE;AACxE,eAAO,MAAM,cAAc,SAAkB,CAAC;AAU9C;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,SAAS,EAClB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,OAAO,aAAa,EAAE,QAAQ,CAAC,CAuGzC;AAED,6EAA6E;AAC7E,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,OAAO,aAAa,EAAE,QAAQ,GACvC,cAAc,CAAC,UAAU,CAAC,CAE5B;AAsGD;;;;;;;;;;;;GAYG;AACH,2CAA2C;AAC3C,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,EAClC,MAAM,CAAC,EAAE,WAAW,EACpB,KAAK,CAAC,EAAE,MAAM,GACb,cAAc,CAAC,UAAU,CAAC,CA2B5B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,cAAc,CAAC,UAAU,CAAC,EACtC,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,OAAO,GACvB,QAAQ,CAOV"}
|
|
@@ -123,12 +123,18 @@ const params = useSegmentParams(); // Partial<AllSegmentParams>
|
|
|
123
123
|
|
|
124
124
|
## Form Hooks
|
|
125
125
|
|
|
126
|
-
|
|
126
|
+
Forms use React's own `useActionState`, imported from `react`. An action built with `createActionClient` passes to it directly: `result` is typed from the action, and the dispatch accepts the submitted `FormData` or the schema's input.
|
|
127
127
|
|
|
128
|
-
|
|
128
|
+
### `parseFormErrors(result)`
|
|
129
|
+
|
|
130
|
+
Reads the errors out of an action result. `_root` validation errors are form-level; every other key is a field.
|
|
129
131
|
|
|
130
132
|
```tsx
|
|
131
|
-
|
|
133
|
+
import { useActionState } from 'react';
|
|
134
|
+
import { parseFormErrors } from '@timber-js/app/client';
|
|
135
|
+
|
|
136
|
+
const [result, action, isPending] = useActionState(createTodo, null);
|
|
137
|
+
const errors = parseFormErrors(result);
|
|
132
138
|
|
|
133
139
|
errors.hasErrors; // boolean
|
|
134
140
|
errors.fieldErrors; // Record<string, string[]>
|
|
@@ -51,11 +51,13 @@ The `.schema()` method accepts any Standard Schema-compatible validator — Zod,
|
|
|
51
51
|
```tsx title="app/todos/todo-form.tsx"
|
|
52
52
|
'use client';
|
|
53
53
|
|
|
54
|
-
import { useActionState } from '
|
|
54
|
+
import { useActionState } from 'react';
|
|
55
|
+
import { parseFormErrors } from '@timber-js/app/client';
|
|
55
56
|
import { createTodo } from './actions';
|
|
56
57
|
|
|
57
58
|
export default function TodoForm() {
|
|
58
|
-
const [state, action, pending
|
|
59
|
+
const [state, action, pending] = useActionState(createTodo, null);
|
|
60
|
+
const errors = parseFormErrors(state);
|
|
59
61
|
|
|
60
62
|
return (
|
|
61
63
|
<form action={action}>
|
|
@@ -76,14 +78,15 @@ export default function TodoForm() {
|
|
|
76
78
|
}
|
|
77
79
|
```
|
|
78
80
|
|
|
79
|
-
Without JS, this submits as a standard form POST. With JS, `useActionState` handles pending state and error display.
|
|
81
|
+
`useActionState` is React's own hook. An action built with `createActionClient` passes to it directly, and `state` is typed from the action's result. Without JS, this submits as a standard form POST. With JS, `useActionState` handles pending state and error display.
|
|
80
82
|
|
|
81
83
|
### Form Errors
|
|
82
84
|
|
|
83
|
-
`
|
|
85
|
+
`parseFormErrors` from `@timber-js/app/client` reads the errors out of the result:
|
|
84
86
|
|
|
85
87
|
```tsx
|
|
86
|
-
const [state, action, pending
|
|
88
|
+
const [state, action, pending] = useActionState(myAction, null);
|
|
89
|
+
const errors = parseFormErrors(state);
|
|
87
90
|
|
|
88
91
|
errors.fieldErrors; // Record<string, string[]>
|
|
89
92
|
errors.formErrors; // string[] (form-level errors)
|
|
@@ -102,37 +105,25 @@ errors.getFieldError('title'); // string | null (first error for field)
|
|
|
102
105
|
|
|
103
106
|
## Forms Without JavaScript
|
|
104
107
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
```tsx title="app/todos/page.tsx"
|
|
108
|
-
import { getFormFlash } from '@timber-js/app/server';
|
|
109
|
-
import { TodoForm } from './todo-form';
|
|
110
|
-
|
|
111
|
-
export default async function TodosPage() {
|
|
112
|
-
const flash = getFormFlash();
|
|
113
|
-
return <TodoForm flash={flash} />;
|
|
114
|
-
}
|
|
115
|
-
```
|
|
108
|
+
The same form works with JavaScript disabled, with no extra code. When a no-JS submission's action returns instead of redirecting, timber renders the page again and React hands the result to the `useActionState` hook that submitted it. `state` holds the result on both paths, so errors and repopulated fields render the same way:
|
|
116
109
|
|
|
117
110
|
```tsx title="app/todos/todo-form.tsx"
|
|
118
111
|
'use client';
|
|
119
112
|
|
|
120
|
-
import { useActionState } from '
|
|
113
|
+
import { useActionState } from 'react';
|
|
114
|
+
import { parseFormErrors } from '@timber-js/app/client';
|
|
121
115
|
import { createTodo } from './actions';
|
|
122
|
-
import type { FormFlashData } from '@timber-js/app/server';
|
|
123
116
|
|
|
124
|
-
export function TodoForm(
|
|
125
|
-
const [state, action, pending
|
|
126
|
-
|
|
127
|
-
const fieldError = (field: string) =>
|
|
128
|
-
errors.getFieldError(field) ?? flash?.validationErrors?.[field]?.[0];
|
|
129
|
-
const defaultValue = (field: string) =>
|
|
130
|
-
(flash?.submittedValues?.[field] as string) ?? '';
|
|
117
|
+
export function TodoForm() {
|
|
118
|
+
const [state, action, pending] = useActionState(createTodo, null);
|
|
119
|
+
const errors = parseFormErrors(state);
|
|
131
120
|
|
|
132
121
|
return (
|
|
133
122
|
<form action={action}>
|
|
134
|
-
<input name="title" defaultValue={
|
|
135
|
-
{
|
|
123
|
+
<input name="title" defaultValue={(state?.submittedValues?.title as string) ?? ''} />
|
|
124
|
+
{errors.getFieldError('title') && (
|
|
125
|
+
<p className="text-red-600">{errors.getFieldError('title')}</p>
|
|
126
|
+
)}
|
|
136
127
|
<button type="submit" disabled={pending}>
|
|
137
128
|
{pending ? 'Adding...' : 'Add Todo'}
|
|
138
129
|
</button>
|
|
@@ -141,6 +132,8 @@ export function TodoForm({ flash }: { flash?: FormFlashData | null }) {
|
|
|
141
132
|
}
|
|
142
133
|
```
|
|
143
134
|
|
|
144
|
-
|
|
135
|
+
The result goes only to the hook that submitted, so two forms on one page never see each other's results. Sensitive fields (password, apiKey, cvv, etc.) are automatically stripped from `submittedValues`.
|
|
136
|
+
|
|
137
|
+
A form that doesn't use `useActionState` gets no result back, just as with JavaScript, where React discards a plain `<form action>`'s return value. Such an action should `redirect()` to a page that shows the new state (post-redirect-get). An action that throws renders the nearest `error.tsx`: with JavaScript the action rejects to the nearest error boundary, and without it the page answers from the same `error.tsx` with a 500; return errors from `createActionClient` actions instead.
|
|
145
138
|
|
|
146
139
|
For advanced topics — coercion helpers, `parseFormData`, sensitive field stripping configuration, and the full end-to-end example — see [Advanced Forms](/docs/advanced-forms).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@timber-js/app",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.212",
|
|
4
4
|
"description": "Vite-native React framework built for Servers and Serverless Platforms — correct HTTP semantics, real status codes, pages that work without JavaScript",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cloudflare-workers",
|
package/src/analyze/classify.ts
CHANGED
|
@@ -105,7 +105,7 @@ export interface ModuleClassification {
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
/** File extensions eligible for directive detection. */
|
|
108
|
-
const PARSEABLE_EXTENSIONS = /\.(?:ts|tsx|js|jsx|mjs|cjs|mts|cts)$/;
|
|
108
|
+
export const PARSEABLE_EXTENSIONS = /\.(?:ts|tsx|js|jsx|mjs|cjs|mts|cts)$/;
|
|
109
109
|
|
|
110
110
|
/**
|
|
111
111
|
* Parse language for a source file, from its extension. Never force
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
import { parseAst } from 'vite';
|
|
21
21
|
import { EXPLICIT_MARKERS, INFERRED_RULES } from './poison-rules.ts';
|
|
22
|
-
import { langForFile, type ModuleKind } from './classify.ts';
|
|
22
|
+
import { langForFile, PARSEABLE_EXTENSIONS, type ModuleKind } from './classify.ts';
|
|
23
23
|
|
|
24
24
|
/** One poisoning finding on a module, in the JSON-contract shape. */
|
|
25
25
|
export interface Poisoning {
|
|
@@ -33,9 +33,6 @@ export interface Poisoning {
|
|
|
33
33
|
description: string;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
/** File extensions the specifier scan can parse. */
|
|
37
|
-
const PARSEABLE_EXTENSIONS = /\.(?:ts|tsx|js|jsx|mjs|cjs|mts|cts)$/;
|
|
38
|
-
|
|
39
36
|
/**
|
|
40
37
|
* A NON-EMPTY specifier list where every entry is type-only. Empty or
|
|
41
38
|
* absent lists return false — a bare `import 'pkg'` is a side-effect
|
|
@@ -25,20 +25,6 @@ import { RSC_CONTENT_TYPE } from '../../shared/rsc-media-type.ts';
|
|
|
25
25
|
import { CSRF_REJECT_HEADER, CSRF_REJECT_VALUE } from '../../shared/csrf-reject.ts';
|
|
26
26
|
import { createActionQueue } from './action-queue.ts';
|
|
27
27
|
|
|
28
|
-
/**
|
|
29
|
-
* Wait for a navigation or refresh to both settle (promise resolved) AND
|
|
30
|
-
* commit (pushState / the navigation's commit thunk ran). The queue must
|
|
31
|
-
* not release the next action until the URL is correct in the address bar
|
|
32
|
-
* — same rule `<Link>` uses for `isPending` (design/19 §Per-Link Pending
|
|
33
|
-
* State). `onCommit` fires exactly once: on commit, supersession, or
|
|
34
|
-
* failure, so nothing awaiting this can hang (codex on #1125).
|
|
35
|
-
*/
|
|
36
|
-
function settledAndCommitted(start: (onCommit: () => void) => Promise<void>): Promise<void> {
|
|
37
|
-
let commitResolve!: () => void;
|
|
38
|
-
const committed = new Promise<void>((r) => (commitResolve = r));
|
|
39
|
-
return Promise.all([start(commitResolve).catch(() => {}), committed]).then(() => {});
|
|
40
|
-
}
|
|
41
|
-
|
|
42
28
|
export function setupServerActions(): void {
|
|
43
29
|
const queue = createActionQueue({
|
|
44
30
|
refreshWhenIdle(): void {
|
|
@@ -60,8 +46,30 @@ export function setupServerActions(): void {
|
|
|
60
46
|
},
|
|
61
47
|
});
|
|
62
48
|
|
|
49
|
+
// An action that redirects settles — ending `useActionState`'s pending
|
|
50
|
+
// state — a full round trip before the destination is on screen, and the
|
|
51
|
+
// page that submitted stays mounted until then with its button enabled
|
|
52
|
+
// again. A second submit would run the mutation again (TIM-1568). So the
|
|
53
|
+
// departing page may not dispatch: `departing` is set from the redirect
|
|
54
|
+
// response until the router is next idle, and a call made
|
|
55
|
+
// meanwhile is never sent. It resolves at once with `undefined` — what the
|
|
56
|
+
// redirecting action itself returned. It must settle: React entangles every
|
|
57
|
+
// transition started while an action is pending, so one left pending would
|
|
58
|
+
// hold the redirect's own commit forever. `pageGen` names
|
|
59
|
+
// the page a call was made on, so one queued behind the redirecting
|
|
60
|
+
// action is dropped too. The check is here rather than in the DOM
|
|
61
|
+
// (`inert`) because it covers every way a call is made: a click inside a
|
|
62
|
+
// modal dialog or a shadow root, `requestSubmit()` from a keyboard
|
|
63
|
+
// shortcut, an effect.
|
|
64
|
+
let departing = false;
|
|
65
|
+
let pageGen = 0;
|
|
66
|
+
|
|
63
67
|
setServerCallback((id: string, args: unknown[]) => {
|
|
68
|
+
if (departing) return Promise.resolve(undefined);
|
|
69
|
+
const calledOn = pageGen;
|
|
64
70
|
return queue.run(async ({ hold }) => {
|
|
71
|
+
if (calledOn !== pageGen) return undefined;
|
|
72
|
+
|
|
65
73
|
// encodeReply inside the queue — preserves call order when two
|
|
66
74
|
// calls' args serialize in different numbers of microtasks.
|
|
67
75
|
const body = await encodeReply(args);
|
|
@@ -75,6 +83,9 @@ export function setupServerActions(): void {
|
|
|
75
83
|
let hasRevalidation = false;
|
|
76
84
|
let hasRedirect = false;
|
|
77
85
|
let invalidated = false;
|
|
86
|
+
// Set once the server answered the action itself — past the version
|
|
87
|
+
// skew and CSRF rejections, which run nothing.
|
|
88
|
+
let answered = false;
|
|
78
89
|
|
|
79
90
|
const actionHeaders: Record<string, string> = {
|
|
80
91
|
'Accept': RSC_CONTENT_TYPE,
|
|
@@ -104,10 +115,26 @@ export function setupServerActions(): void {
|
|
|
104
115
|
hasRevalidation = res.headers.get('X-Timber-Revalidation') === '1';
|
|
105
116
|
hasRedirect = res.headers.get('X-Timber-Redirect') != null;
|
|
106
117
|
invalidated = res.headers.get('X-Timber-Invalidated') === '1';
|
|
118
|
+
answered = true;
|
|
107
119
|
return res;
|
|
108
120
|
});
|
|
109
121
|
|
|
110
|
-
|
|
122
|
+
let decoded: unknown;
|
|
123
|
+
try {
|
|
124
|
+
decoded = await createFromFetch(response);
|
|
125
|
+
} catch (error) {
|
|
126
|
+
// A raw server function that throws arrives as a rejected root
|
|
127
|
+
// (TIM-1570). It may have mutated before it threw, so no payload
|
|
128
|
+
// cached before it may be reused, nor the mounted shared layouts on
|
|
129
|
+
// the next navigation. No refresh: the rejection renders the nearest
|
|
130
|
+
// error boundary, and a refresh would hand that boundary new
|
|
131
|
+
// children, which resets it and hides the error (error-boundary.tsx).
|
|
132
|
+
if (answered && router) {
|
|
133
|
+
router.suppressSegmentReuse();
|
|
134
|
+
router.evictStaleCaches();
|
|
135
|
+
}
|
|
136
|
+
throw error;
|
|
137
|
+
}
|
|
111
138
|
|
|
112
139
|
// The mutation happened server-side, and the next thing on screen is
|
|
113
140
|
// not a full render of the current page: revalidatePath named only
|
|
@@ -140,10 +167,12 @@ export function setupServerActions(): void {
|
|
|
140
167
|
// action scope settles — awaiting the commit inline would deadlock:
|
|
141
168
|
// React entangles the commit lane with the action scope, so the
|
|
142
169
|
// commit waits on the action while the action waits on the commit.
|
|
143
|
-
//
|
|
144
|
-
//
|
|
145
|
-
// the page
|
|
170
|
+
//
|
|
171
|
+
// Set before returning, so React never sees the action settle while
|
|
172
|
+
// the departing page can still dispatch (see `departing`).
|
|
146
173
|
if (hasRedirect) {
|
|
174
|
+
departing = true;
|
|
175
|
+
pageGen += 1;
|
|
147
176
|
const wrapper = decoded as { _redirect: string; _status: number };
|
|
148
177
|
const isExternal =
|
|
149
178
|
wrapper._redirect.startsWith('https://') || wrapper._redirect.startsWith('http://');
|
|
@@ -156,7 +185,34 @@ export function setupServerActions(): void {
|
|
|
156
185
|
}
|
|
157
186
|
try {
|
|
158
187
|
const r = getRouter();
|
|
188
|
+
// The redirect's own navigation takes the next sequence number.
|
|
189
|
+
// A tree handed to React before it — a refresh of this very page
|
|
190
|
+
// still suspended — can commit afterwards, and must not release
|
|
191
|
+
// the latch: it is the departing page again (codex on #1211).
|
|
192
|
+
const redirectSeq = r.epoch().seq + 1;
|
|
159
193
|
void r.navigate(wrapper._redirect);
|
|
194
|
+
// Released once the departing page can no longer be on screen:
|
|
195
|
+
// when any navigation's tree commits (a streamed destination
|
|
196
|
+
// commits its shell before its stream finishes, and is live from
|
|
197
|
+
// then), or when the router is idle with nothing committed (every
|
|
198
|
+
// navigation was abandoned; the user stays and may act again).
|
|
199
|
+
// Not on the redirect navigation's own outcome: a navigation the
|
|
200
|
+
// user starts meanwhile supersedes it at once, but the departing
|
|
201
|
+
// page stays until that successor commits (codex on #1211).
|
|
202
|
+
const stops: (() => void)[] = [];
|
|
203
|
+
const arrive = (): void => {
|
|
204
|
+
departing = false;
|
|
205
|
+
for (const stop of stops) stop();
|
|
206
|
+
};
|
|
207
|
+
stops.push(
|
|
208
|
+
r.onTreeCommit((seq) => {
|
|
209
|
+
if (seq >= redirectSeq) arrive();
|
|
210
|
+
}),
|
|
211
|
+
r.onIdle(arrive)
|
|
212
|
+
);
|
|
213
|
+
// A navigation that failed before taking the router never makes
|
|
214
|
+
// it busy, so no idle transition would come.
|
|
215
|
+
if (r.epoch().idle) arrive();
|
|
160
216
|
} catch (e) {
|
|
161
217
|
console.debug(
|
|
162
218
|
'[timber] action redirect: router not ready, using full navigation',
|