@timber-js/app 0.2.0-alpha.207 → 0.2.0-alpha.209

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (526) hide show
  1. package/dist/_chunks/{primitives-DLAnvsrk.js → actions-BerlqoXA.js} +640 -410
  2. package/dist/_chunks/actions-BerlqoXA.js.map +1 -0
  3. package/dist/_chunks/{als-registry-C6kcfprT.js → als-registry-DaxkVjt5.js} +6 -2
  4. package/dist/_chunks/als-registry-DaxkVjt5.js.map +1 -0
  5. package/dist/_chunks/{build-manifest-DTmSGLRz.js → build-manifest-DWppEdLB.js} +2 -51
  6. package/dist/_chunks/build-manifest-DWppEdLB.js.map +1 -0
  7. package/dist/_chunks/{build-output-helper-9dqCv1pZ.js → build-output-helper-RV_BRcF1.js} +50 -53
  8. package/dist/_chunks/build-output-helper-RV_BRcF1.js.map +1 -0
  9. package/dist/_chunks/{cache-api-CUD9Ezaq.js → cache-api-CR23J_NC.js} +64 -32
  10. package/dist/_chunks/cache-api-CR23J_NC.js.map +1 -0
  11. package/dist/_chunks/{chains-B4bgOl2g.js → chains-CpFg56UB.js} +2 -2
  12. package/dist/_chunks/{chains-B4bgOl2g.js.map → chains-CpFg56UB.js.map} +1 -1
  13. package/dist/_chunks/{cli-check-G8o30ldg.js → cli-check-C6Ev6wBO.js} +11 -52
  14. package/dist/_chunks/cli-check-C6Ev6wBO.js.map +1 -0
  15. package/dist/_chunks/cli-context-By7k2xVo.js +70 -0
  16. package/dist/_chunks/cli-context-By7k2xVo.js.map +1 -0
  17. package/dist/_chunks/{cli-schema-sync--LZKs8Zn.js → cli-schema-sync-CbT2AUUI.js} +3 -3
  18. package/dist/_chunks/{cli-schema-sync--LZKs8Zn.js.map → cli-schema-sync-CbT2AUUI.js.map} +1 -1
  19. package/dist/_chunks/{cloudflare-BFb__LYG.js → cloudflare-Byxl8FWP.js} +96 -53
  20. package/dist/_chunks/{cloudflare-BFb__LYG.js.map → cloudflare-Byxl8FWP.js.map} +1 -1
  21. package/dist/_chunks/{convention-lint-5KzoMg_A.js → convention-lint-jKTwKwPe.js} +21 -6
  22. package/dist/_chunks/convention-lint-jKTwKwPe.js.map +1 -0
  23. package/dist/_chunks/{dev-server-BzBxgYAV.js → dev-server-C4WZdB7L.js} +15 -167
  24. package/dist/_chunks/dev-server-C4WZdB7L.js.map +1 -0
  25. package/dist/_chunks/{error-boundary-BndF-3Td.js → error-boundary-tA7kVfs4.js} +84 -104
  26. package/dist/_chunks/error-boundary-tA7kVfs4.js.map +1 -0
  27. package/dist/_chunks/{fs-identity-D7vb6GdI.js → fs-identity-BRKuL215.js} +3 -4
  28. package/dist/_chunks/fs-identity-BRKuL215.js.map +1 -0
  29. package/dist/_chunks/{graph-cache-CP4GEmf9.js → graph-cache-CYiUS2aS.js} +4 -5
  30. package/dist/_chunks/graph-cache-CYiUS2aS.js.map +1 -0
  31. package/dist/_chunks/{json-lossy-check-ClNvBM_3.js → json-lossy-check-ip0Qi0MT.js} +6 -3
  32. package/dist/_chunks/json-lossy-check-ip0Qi0MT.js.map +1 -0
  33. package/dist/_chunks/{live-graph-Bm5WTvcr.js → live-graph-Dv-JJCZw.js} +3 -3
  34. package/dist/_chunks/{live-graph-Bm5WTvcr.js.map → live-graph-Dv-JJCZw.js.map} +1 -1
  35. package/dist/_chunks/{logger-k2DQ4EUf.js → logger-DiDt5ppH.js} +192 -51
  36. package/dist/_chunks/logger-DiDt5ppH.js.map +1 -0
  37. package/dist/_chunks/{navigation-root-mHSK9psY.js → navigation-root-BQfo1-kG.js} +2 -2
  38. package/dist/_chunks/{navigation-root-mHSK9psY.js.map → navigation-root-BQfo1-kG.js.map} +1 -1
  39. package/dist/_chunks/{plugin-context-8idfR3UZ.js → plugin-context-BPBPc3lL.js} +28 -4
  40. package/dist/_chunks/plugin-context-BPBPc3lL.js.map +1 -0
  41. package/dist/_chunks/{poison-scan-DG5eI2_z.js → poison-scan-CpeT6_OJ.js} +2 -2
  42. package/dist/_chunks/{poison-scan-DG5eI2_z.js.map → poison-scan-CpeT6_OJ.js.map} +1 -1
  43. package/dist/_chunks/render-timeout-DOf_BBcO.js +46 -0
  44. package/dist/_chunks/render-timeout-DOf_BBcO.js.map +1 -0
  45. package/dist/_chunks/{rsc-payload-path-B_LBodc2.js → rsc-payload-path-dffcs4jp.js} +9 -3
  46. package/dist/_chunks/{rsc-payload-path-B_LBodc2.js.map → rsc-payload-path-dffcs4jp.js.map} +1 -1
  47. package/dist/_chunks/{scanner-BQ5sPIJ7.js → scanner-Bw0oq1HB.js} +2 -2
  48. package/dist/_chunks/{scanner-BQ5sPIJ7.js.map → scanner-Bw0oq1HB.js.map} +1 -1
  49. package/dist/_chunks/{navigation-context-D0TU0Jog.js → segment-context-xtPUGfdq.js} +36 -34
  50. package/dist/_chunks/segment-context-xtPUGfdq.js.map +1 -0
  51. package/dist/_chunks/{singleflight-2lUWfcAk.js → singleflight-BeVMMKi0.js} +4 -3
  52. package/dist/_chunks/{singleflight-2lUWfcAk.js.map → singleflight-BeVMMKi0.js.map} +1 -1
  53. package/dist/_chunks/{sizeof-lXffQ1Vr.js → sizeof-UwzwB1uM.js} +3 -2
  54. package/dist/_chunks/sizeof-UwzwB1uM.js.map +1 -0
  55. package/dist/_chunks/ssr-data-nA3I70_n.js +49 -0
  56. package/dist/_chunks/ssr-data-nA3I70_n.js.map +1 -0
  57. package/dist/_chunks/{state-FippDgxN.js → state-BhNGPsdi.js} +6 -8
  58. package/dist/_chunks/state-BhNGPsdi.js.map +1 -0
  59. package/dist/_chunks/{status-page-marker-DwQBrLBz.js → status-page-marker-gaihi0KZ.js} +140 -28
  60. package/dist/_chunks/status-page-marker-gaihi0KZ.js.map +1 -0
  61. package/dist/_chunks/{walkers-CN2N_bA-.js → walkers-BXExhzzk.js} +2 -2
  62. package/dist/_chunks/{walkers-CN2N_bA-.js.map → walkers-BXExhzzk.js.map} +1 -1
  63. package/dist/_chunks/write-file-atomic-D1qWqHb4.js +32 -0
  64. package/dist/_chunks/write-file-atomic-D1qWqHb4.js.map +1 -0
  65. package/dist/adapters/build-output-helper.d.ts +7 -7
  66. package/dist/adapters/build-output-helper.d.ts.map +1 -1
  67. package/dist/adapters/canonicalize-module.d.ts +8 -0
  68. package/dist/adapters/canonicalize-module.d.ts.map +1 -0
  69. package/dist/adapters/cloudflare-dev.js +1 -1
  70. package/dist/adapters/cloudflare-kv-cache.js +2 -2
  71. package/dist/adapters/cloudflare.d.ts +30 -8
  72. package/dist/adapters/cloudflare.d.ts.map +1 -1
  73. package/dist/adapters/cloudflare.js +2 -2
  74. package/dist/adapters/compress-module.d.ts +8 -0
  75. package/dist/adapters/compress-module.d.ts.map +1 -1
  76. package/dist/adapters/fs-identity.d.ts +2 -3
  77. package/dist/adapters/fs-identity.d.ts.map +1 -1
  78. package/dist/adapters/nitro-presets.d.ts +0 -6
  79. package/dist/adapters/nitro-presets.d.ts.map +1 -1
  80. package/dist/adapters/nitro-preview.d.ts +43 -11
  81. package/dist/adapters/nitro-preview.d.ts.map +1 -1
  82. package/dist/adapters/nitro.d.ts +1 -13
  83. package/dist/adapters/nitro.d.ts.map +1 -1
  84. package/dist/adapters/nitro.js +291 -176
  85. package/dist/adapters/nitro.js.map +1 -1
  86. package/dist/adapters/shared.d.ts +7 -2
  87. package/dist/adapters/shared.d.ts.map +1 -1
  88. package/dist/adapters/types.d.ts +105 -21
  89. package/dist/adapters/types.d.ts.map +1 -1
  90. package/dist/adapters/types.js +0 -0
  91. package/dist/analyze/crawl-entry.js +3 -3
  92. package/dist/analyze/graph-cache.d.ts.map +1 -1
  93. package/dist/analyze/graph-command.js +4 -4
  94. package/dist/cache/index.js +2 -2
  95. package/dist/cache/json-lossy-check.d.ts.map +1 -1
  96. package/dist/cache/singleflight.d.ts.map +1 -1
  97. package/dist/cache/sizeof.d.ts.map +1 -1
  98. package/dist/cache/stores/memory.js +1 -1
  99. package/dist/cache/tag-aware-handler.d.ts.map +1 -1
  100. package/dist/cdn/workers-cache-purge.js +1 -1
  101. package/dist/cli-check.d.ts +7 -37
  102. package/dist/cli-check.d.ts.map +1 -1
  103. package/dist/cli-context.d.ts +54 -0
  104. package/dist/cli-context.d.ts.map +1 -0
  105. package/dist/cli.d.ts +9 -9
  106. package/dist/cli.d.ts.map +1 -1
  107. package/dist/cli.js +20 -24
  108. package/dist/cli.js.map +1 -1
  109. package/dist/client/browser-dev.d.ts +1 -1
  110. package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -1
  111. package/dist/client/browser-entry/hydrate.d.ts +19 -29
  112. package/dist/client/browser-entry/hydrate.d.ts.map +1 -1
  113. package/dist/client/browser-entry/index.d.ts +7 -7
  114. package/dist/client/browser-entry/post-hydration.d.ts +6 -9
  115. package/dist/client/browser-entry/post-hydration.d.ts.map +1 -1
  116. package/dist/client/browser-entry/router-init.d.ts +6 -11
  117. package/dist/client/browser-entry/router-init.d.ts.map +1 -1
  118. package/dist/client/error-boundary.d.ts +4 -3
  119. package/dist/client/error-boundary.d.ts.map +1 -1
  120. package/dist/client/error-boundary.js +1 -1
  121. package/dist/client/error-reconstituter.d.ts +3 -9
  122. package/dist/client/error-reconstituter.d.ts.map +1 -1
  123. package/dist/client/history.d.ts +20 -11
  124. package/dist/client/history.d.ts.map +1 -1
  125. package/dist/client/index.d.ts +0 -1
  126. package/dist/client/index.d.ts.map +1 -1
  127. package/dist/client/index.js +5 -6
  128. package/dist/client/index.js.map +1 -1
  129. package/dist/client/internal.d.ts +3 -3
  130. package/dist/client/internal.d.ts.map +1 -1
  131. package/dist/client/internal.js +95 -108
  132. package/dist/client/internal.js.map +1 -1
  133. package/dist/client/navigation-commit.d.ts +20 -7
  134. package/dist/client/navigation-commit.d.ts.map +1 -1
  135. package/dist/client/navigation-context.d.ts +3 -5
  136. package/dist/client/navigation-context.d.ts.map +1 -1
  137. package/dist/client/react-root.d.ts +3 -2
  138. package/dist/client/react-root.d.ts.map +1 -1
  139. package/dist/client/router-pipeline.d.ts +3 -8
  140. package/dist/client/router-pipeline.d.ts.map +1 -1
  141. package/dist/client/router-types.d.ts +45 -39
  142. package/dist/client/router-types.d.ts.map +1 -1
  143. package/dist/client/router-url.d.ts +24 -0
  144. package/dist/client/router-url.d.ts.map +1 -0
  145. package/dist/client/router.d.ts.map +1 -1
  146. package/dist/client/rsc-fetch.d.ts +8 -4
  147. package/dist/client/rsc-fetch.d.ts.map +1 -1
  148. package/dist/client/segment-cache.d.ts +44 -4
  149. package/dist/client/segment-cache.d.ts.map +1 -1
  150. package/dist/client/ssr-data.d.ts +18 -64
  151. package/dist/client/ssr-data.d.ts.map +1 -1
  152. package/dist/client/state.d.ts +2 -5
  153. package/dist/client/state.d.ts.map +1 -1
  154. package/dist/client/use-pathname.d.ts +1 -1
  155. package/dist/config-types.d.ts +2 -1
  156. package/dist/config-types.d.ts.map +1 -1
  157. package/dist/config-validation.d.ts.map +1 -1
  158. package/dist/cookies/index.js +1 -1
  159. package/dist/dev-tools/dev-page-shell.d.ts +17 -0
  160. package/dist/dev-tools/dev-page-shell.d.ts.map +1 -1
  161. package/dist/dev-tools/index.d.ts +1 -1
  162. package/dist/dev-tools/index.d.ts.map +1 -1
  163. package/dist/dev-tools/instrumentation.d.ts +17 -2
  164. package/dist/dev-tools/instrumentation.d.ts.map +1 -1
  165. package/dist/dev-tools/overlay.d.ts +6 -27
  166. package/dist/dev-tools/overlay.d.ts.map +1 -1
  167. package/dist/index.d.ts.map +1 -1
  168. package/dist/index.js +632 -373
  169. package/dist/index.js.map +1 -1
  170. package/dist/plugin-context.d.ts +26 -40
  171. package/dist/plugin-context.d.ts.map +1 -1
  172. package/dist/plugins/build-manifest.d.ts.map +1 -1
  173. package/dist/plugins/build-report.d.ts +15 -2
  174. package/dist/plugins/build-report.d.ts.map +1 -1
  175. package/dist/plugins/dev-server.d.ts.map +1 -1
  176. package/dist/plugins/entries.d.ts.map +1 -1
  177. package/dist/plugins/fonts.d.ts +19 -1
  178. package/dist/plugins/fonts.d.ts.map +1 -1
  179. package/dist/plugins/post-build.d.ts +110 -0
  180. package/dist/plugins/post-build.d.ts.map +1 -0
  181. package/dist/plugins/prebuilt-capture.d.ts +11 -4
  182. package/dist/plugins/prebuilt-capture.d.ts.map +1 -1
  183. package/dist/plugins/prebuilt.d.ts +17 -1
  184. package/dist/plugins/prebuilt.d.ts.map +1 -1
  185. package/dist/plugins/prerender-sugar.d.ts.map +1 -1
  186. package/dist/plugins/react-resolve.d.ts +49 -0
  187. package/dist/plugins/react-resolve.d.ts.map +1 -0
  188. package/dist/plugins/rsc-assets-manifest.d.ts +33 -0
  189. package/dist/plugins/rsc-assets-manifest.d.ts.map +1 -0
  190. package/dist/plugins/shims.d.ts.map +1 -1
  191. package/dist/plugins/static-build.d.ts +32 -9
  192. package/dist/plugins/static-build.d.ts.map +1 -1
  193. package/dist/routing/codegen-write.d.ts +0 -9
  194. package/dist/routing/codegen-write.d.ts.map +1 -1
  195. package/dist/routing/index.js +2 -2
  196. package/dist/routing/segment-codegen.d.ts.map +1 -1
  197. package/dist/server/access-gate.d.ts.map +1 -1
  198. package/dist/server/action-handler.d.ts +5 -4
  199. package/dist/server/action-handler.d.ts.map +1 -1
  200. package/dist/server/actions.d.ts +46 -7
  201. package/dist/server/actions.d.ts.map +1 -1
  202. package/dist/server/als-registry.d.ts +58 -5
  203. package/dist/server/als-registry.d.ts.map +1 -1
  204. package/dist/server/children-interception.d.ts.map +1 -1
  205. package/dist/server/cookie-context.d.ts +2 -23
  206. package/dist/server/cookie-context.d.ts.map +1 -1
  207. package/dist/server/csp-nonce.d.ts +0 -9
  208. package/dist/server/csp-nonce.d.ts.map +1 -1
  209. package/dist/server/csrf.d.ts +27 -4
  210. package/dist/server/csrf.d.ts.map +1 -1
  211. package/dist/server/debug.d.ts +0 -1
  212. package/dist/server/debug.d.ts.map +1 -1
  213. package/dist/server/default-logger.d.ts +2 -1
  214. package/dist/server/default-logger.d.ts.map +1 -1
  215. package/dist/server/deny-boundary.d.ts +12 -6
  216. package/dist/server/deny-boundary.d.ts.map +1 -1
  217. package/dist/server/deny-renderer.d.ts +2 -2
  218. package/dist/server/deny-renderer.d.ts.map +1 -1
  219. package/dist/server/error-boundary-wrapper.d.ts +7 -3
  220. package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
  221. package/dist/server/fallback-error.d.ts +9 -2
  222. package/dist/server/fallback-error.d.ts.map +1 -1
  223. package/dist/server/head-response.d.ts +4 -4
  224. package/dist/server/html-injectors.d.ts.map +1 -1
  225. package/dist/server/index.d.ts +0 -1
  226. package/dist/server/index.d.ts.map +1 -1
  227. package/dist/server/index.js +3 -4
  228. package/dist/server/index.js.map +1 -1
  229. package/dist/server/instrumentation.d.ts +10 -3
  230. package/dist/server/instrumentation.d.ts.map +1 -1
  231. package/dist/server/internal.d.ts +1 -4
  232. package/dist/server/internal.d.ts.map +1 -1
  233. package/dist/server/internal.js +961 -581
  234. package/dist/server/internal.js.map +1 -1
  235. package/dist/server/json-status-response.d.ts +34 -0
  236. package/dist/server/json-status-response.d.ts.map +1 -0
  237. package/dist/server/logger.d.ts +26 -0
  238. package/dist/server/logger.d.ts.map +1 -1
  239. package/dist/server/param-coercion.d.ts +11 -6
  240. package/dist/server/param-coercion.d.ts.map +1 -1
  241. package/dist/server/pipeline-helpers.d.ts +95 -7
  242. package/dist/server/pipeline-helpers.d.ts.map +1 -1
  243. package/dist/server/pipeline-interception.d.ts +11 -0
  244. package/dist/server/pipeline-interception.d.ts.map +1 -1
  245. package/dist/server/pipeline-outcome.d.ts +11 -1
  246. package/dist/server/pipeline-outcome.d.ts.map +1 -1
  247. package/dist/server/pipeline-phases.d.ts +2 -2
  248. package/dist/server/pipeline-phases.d.ts.map +1 -1
  249. package/dist/server/pipeline.d.ts +23 -35
  250. package/dist/server/pipeline.d.ts.map +1 -1
  251. package/dist/server/prebuilt/capture-render.d.ts +25 -0
  252. package/dist/server/prebuilt/capture-render.d.ts.map +1 -0
  253. package/dist/server/prebuilt/capture-routes.d.ts +37 -0
  254. package/dist/server/prebuilt/capture-routes.d.ts.map +1 -0
  255. package/dist/server/prebuilt/capture-state.d.ts +79 -35
  256. package/dist/server/prebuilt/capture-state.d.ts.map +1 -1
  257. package/dist/server/prebuilt/lifetime.d.ts +38 -0
  258. package/dist/server/prebuilt/lifetime.d.ts.map +1 -0
  259. package/dist/server/prebuilt/slots.d.ts +7 -0
  260. package/dist/server/prebuilt/slots.d.ts.map +1 -1
  261. package/dist/server/prebuilt/synthetic-store.d.ts.map +1 -1
  262. package/dist/server/prebuilt-builder.d.ts.map +1 -1
  263. package/dist/server/prebuilt-runtime.d.ts.map +1 -1
  264. package/dist/server/primitives.d.ts +6 -81
  265. package/dist/server/primitives.d.ts.map +1 -1
  266. package/dist/server/react-cache-bridge.d.ts +59 -0
  267. package/dist/server/react-cache-bridge.d.ts.map +1 -0
  268. package/dist/server/react-cache-scope.d.ts +49 -0
  269. package/dist/server/react-cache-scope.d.ts.map +1 -0
  270. package/dist/server/render-timeout.d.ts +15 -0
  271. package/dist/server/render-timeout.d.ts.map +1 -1
  272. package/dist/server/render-utils.d.ts +9 -0
  273. package/dist/server/render-utils.d.ts.map +1 -1
  274. package/dist/server/request-context.d.ts +26 -5
  275. package/dist/server/request-context.d.ts.map +1 -1
  276. package/dist/server/route-element-builder.d.ts.map +1 -1
  277. package/dist/server/route-handler.d.ts.map +1 -1
  278. package/dist/server/route-matcher.d.ts +7 -0
  279. package/dist/server/route-matcher.d.ts.map +1 -1
  280. package/dist/server/rsc-entry/action-middleware-runner.d.ts +22 -22
  281. package/dist/server/rsc-entry/action-middleware-runner.d.ts.map +1 -1
  282. package/dist/server/rsc-entry/api-handler.d.ts +7 -0
  283. package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
  284. package/dist/server/rsc-entry/deny-fallback.d.ts +32 -6
  285. package/dist/server/rsc-entry/deny-fallback.d.ts.map +1 -1
  286. package/dist/server/rsc-entry/error-renderer.d.ts +11 -18
  287. package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
  288. package/dist/server/rsc-entry/helpers.d.ts +0 -1
  289. package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
  290. package/dist/server/rsc-entry/index.d.ts +5 -15
  291. package/dist/server/rsc-entry/index.d.ts.map +1 -1
  292. package/dist/server/rsc-entry/render-route.d.ts +5 -6
  293. package/dist/server/rsc-entry/render-route.d.ts.map +1 -1
  294. package/dist/server/rsc-entry/render-signals.d.ts +65 -0
  295. package/dist/server/rsc-entry/render-signals.d.ts.map +1 -0
  296. package/dist/server/rsc-entry/revalidate-renderer.d.ts +6 -16
  297. package/dist/server/rsc-entry/revalidate-renderer.d.ts.map +1 -1
  298. package/dist/server/rsc-entry/rsc-payload.d.ts +7 -3
  299. package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
  300. package/dist/server/rsc-entry/rsc-stream.d.ts +8 -53
  301. package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
  302. package/dist/server/rsc-entry/ssr-bridge.d.ts +2 -2
  303. package/dist/server/rsc-entry/ssr-bridge.d.ts.map +1 -1
  304. package/dist/server/rsc-entry/ssr-renderer.d.ts +9 -4
  305. package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
  306. package/dist/server/rsc-entry/wrap-action-dispatch.d.ts +1 -1
  307. package/dist/server/rsc-entry/wrap-action-dispatch.d.ts.map +1 -1
  308. package/dist/server/signal-identity.d.ts +43 -0
  309. package/dist/server/signal-identity.d.ts.map +1 -0
  310. package/dist/server/slot-resolver.d.ts +4 -3
  311. package/dist/server/slot-resolver.d.ts.map +1 -1
  312. package/dist/server/slot-subtree-contain.d.ts.map +1 -1
  313. package/dist/server/ssr-bridge-types.d.ts +91 -53
  314. package/dist/server/ssr-bridge-types.d.ts.map +1 -1
  315. package/dist/server/ssr-entry.d.ts +8 -5
  316. package/dist/server/ssr-entry.d.ts.map +1 -1
  317. package/dist/server/ssr-render.d.ts +26 -40
  318. package/dist/server/ssr-render.d.ts.map +1 -1
  319. package/dist/server/ssr-wrappers.d.ts +1 -1
  320. package/dist/server/static-generator.d.ts.map +1 -1
  321. package/dist/server/stream-utils.d.ts +12 -0
  322. package/dist/server/stream-utils.d.ts.map +1 -1
  323. package/dist/server/tracing.d.ts +12 -16
  324. package/dist/server/tracing.d.ts.map +1 -1
  325. package/dist/server/types.d.ts +1 -1
  326. package/dist/server/version-skew.d.ts +3 -3
  327. package/dist/shared/csrf-reject.d.ts +16 -0
  328. package/dist/shared/csrf-reject.d.ts.map +1 -0
  329. package/dist/shared/error-digest.d.ts +28 -0
  330. package/dist/shared/error-digest.d.ts.map +1 -0
  331. package/dist/shared/payload-root.d.ts +11 -10
  332. package/dist/shared/payload-root.d.ts.map +1 -1
  333. package/dist/shared/rsc-payload-path.d.ts +6 -0
  334. package/dist/shared/rsc-payload-path.d.ts.map +1 -1
  335. package/dist/utils/write-file-atomic.d.ts +17 -0
  336. package/dist/utils/write-file-atomic.d.ts.map +1 -0
  337. package/docs/api/30-api-server.mdx +17 -14
  338. package/docs/api/32-api-cache.mdx +51 -23
  339. package/docs/api/34-api-config.mdx +34 -6
  340. package/docs/api/36-cli.mdx +11 -1
  341. package/docs/learn/03-fetching-data.mdx +17 -1
  342. package/docs/learn/04-access-control.mdx +1 -1
  343. package/docs/learn/10-caching.mdx +29 -11
  344. package/docs/learn/11-middleware.mdx +8 -2
  345. package/docs/learn/12-error-handling.mdx +6 -1
  346. package/package.json +7 -3
  347. package/src/adapters/build-output-helper.ts +55 -53
  348. package/src/adapters/canonicalize-module.ts +29 -0
  349. package/src/adapters/cloudflare.ts +105 -63
  350. package/src/adapters/compress-module.ts +16 -5
  351. package/src/adapters/fs-identity.ts +2 -3
  352. package/src/adapters/nitro-presets.ts +0 -15
  353. package/src/adapters/nitro-preview.ts +272 -136
  354. package/src/adapters/nitro.ts +119 -82
  355. package/src/adapters/shared.ts +23 -14
  356. package/src/adapters/types.ts +110 -21
  357. package/src/analyze/graph-cache.ts +3 -4
  358. package/src/cache/json-lossy-check.ts +3 -9
  359. package/src/cache/singleflight.ts +5 -2
  360. package/src/cache/sizeof.ts +3 -1
  361. package/src/cache/tag-aware-handler.ts +43 -26
  362. package/src/cli-check.ts +8 -98
  363. package/src/cli-context.ts +119 -0
  364. package/src/cli.ts +19 -28
  365. package/src/client/browser-dev.ts +1 -1
  366. package/src/client/browser-entry/action-dispatch.ts +26 -4
  367. package/src/client/browser-entry/hydrate.ts +53 -58
  368. package/src/client/browser-entry/index.ts +16 -27
  369. package/src/client/browser-entry/post-hydration.ts +6 -40
  370. package/src/client/browser-entry/router-init.ts +66 -84
  371. package/src/client/error-boundary.tsx +9 -41
  372. package/src/client/error-reconstituter.tsx +10 -5
  373. package/src/client/history.ts +35 -21
  374. package/src/client/index.ts +0 -1
  375. package/src/client/internal.ts +2 -7
  376. package/src/client/navigation-commit.ts +41 -18
  377. package/src/client/navigation-context.ts +3 -39
  378. package/src/client/react-root.ts +3 -2
  379. package/src/client/router-pipeline.ts +96 -132
  380. package/src/client/router-types.ts +46 -44
  381. package/src/client/router-url.ts +32 -0
  382. package/src/client/router.ts +62 -21
  383. package/src/client/rsc-fetch.ts +117 -155
  384. package/src/client/segment-cache.ts +110 -11
  385. package/src/client/ssr-data.ts +19 -80
  386. package/src/client/state.ts +2 -9
  387. package/src/client/use-pathname.ts +1 -1
  388. package/src/config-types.ts +2 -1
  389. package/src/config-validation.ts +2 -1
  390. package/src/dev-tools/dev-page-shell.ts +18 -0
  391. package/src/dev-tools/index.ts +0 -2
  392. package/src/dev-tools/instrumentation.ts +50 -2
  393. package/src/dev-tools/overlay.ts +8 -238
  394. package/src/index.ts +26 -14
  395. package/src/plugin-context.ts +39 -40
  396. package/src/plugins/build-manifest.ts +4 -11
  397. package/src/plugins/build-report.ts +70 -70
  398. package/src/plugins/dev-server.ts +24 -44
  399. package/src/plugins/entries.ts +2 -1
  400. package/src/plugins/fonts.ts +35 -7
  401. package/src/plugins/post-build.ts +327 -0
  402. package/src/plugins/prebuilt-capture.ts +28 -32
  403. package/src/plugins/prebuilt.ts +54 -39
  404. package/src/plugins/prerender-sugar.ts +0 -4
  405. package/src/plugins/react-resolve.ts +149 -0
  406. package/src/plugins/{adapter-build.ts → rsc-assets-manifest.ts} +20 -109
  407. package/src/plugins/shims.ts +1 -0
  408. package/src/plugins/static-build.ts +42 -74
  409. package/src/routing/codegen-write.ts +25 -3
  410. package/src/routing/segment-codegen.ts +3 -2
  411. package/src/rsc-runtime/vendor-types.d.ts +8 -0
  412. package/src/server/access-gate.tsx +2 -1
  413. package/src/server/action-client.ts +1 -1
  414. package/src/server/action-handler.ts +253 -110
  415. package/src/server/actions.ts +73 -25
  416. package/src/server/als-registry.ts +73 -5
  417. package/src/server/chain-url-parts.ts +1 -1
  418. package/src/server/children-interception.ts +2 -1
  419. package/src/server/cookie-context.ts +18 -48
  420. package/src/server/csp-nonce.ts +0 -12
  421. package/src/server/csrf.ts +140 -8
  422. package/src/server/debug.ts +0 -1
  423. package/src/server/default-logger.ts +2 -1
  424. package/src/server/deny-boundary.ts +25 -13
  425. package/src/server/deny-renderer.ts +30 -97
  426. package/src/server/error-boundary-wrapper.ts +7 -3
  427. package/src/server/fallback-error.ts +26 -11
  428. package/src/server/flight-scripts.ts +1 -1
  429. package/src/server/head-response.ts +4 -4
  430. package/src/server/html-injector-core.ts +2 -2
  431. package/src/server/html-injectors.ts +2 -4
  432. package/src/server/index.ts +0 -4
  433. package/src/server/instrumentation.ts +10 -3
  434. package/src/server/internal.ts +1 -6
  435. package/src/server/json-status-response.ts +105 -0
  436. package/src/server/logger.ts +39 -3
  437. package/src/server/param-coercion.ts +15 -12
  438. package/src/server/pipeline-helpers.ts +257 -12
  439. package/src/server/pipeline-interception.ts +133 -0
  440. package/src/server/pipeline-outcome.ts +103 -31
  441. package/src/server/pipeline-phases.ts +127 -237
  442. package/src/server/pipeline.ts +204 -207
  443. package/src/server/prebuilt/capture-render.ts +118 -0
  444. package/src/server/prebuilt/capture-routes.ts +104 -0
  445. package/src/server/prebuilt/capture-state.ts +155 -48
  446. package/src/server/prebuilt/lifetime.ts +151 -0
  447. package/src/server/prebuilt/slots.ts +14 -2
  448. package/src/server/prebuilt/synthetic-store.ts +3 -0
  449. package/src/server/prebuilt-builder.ts +30 -320
  450. package/src/server/prebuilt-runtime.ts +125 -129
  451. package/src/server/primitives.ts +8 -168
  452. package/src/server/react-cache-bridge.ts +124 -0
  453. package/src/server/react-cache-scope.ts +104 -0
  454. package/src/server/render-timeout.ts +20 -0
  455. package/src/server/render-utils.ts +11 -1
  456. package/src/server/request-context.ts +36 -9
  457. package/src/server/route-element-builder.ts +11 -6
  458. package/src/server/route-handler.ts +36 -23
  459. package/src/server/route-matcher.ts +15 -1
  460. package/src/server/rsc-entry/action-middleware-runner.ts +79 -123
  461. package/src/server/rsc-entry/api-handler.ts +27 -103
  462. package/src/server/rsc-entry/deny-fallback.ts +93 -26
  463. package/src/server/rsc-entry/error-renderer.ts +39 -91
  464. package/src/server/rsc-entry/helpers.ts +2 -4
  465. package/src/server/rsc-entry/index.ts +64 -58
  466. package/src/server/rsc-entry/render-route.ts +15 -80
  467. package/src/server/rsc-entry/render-signals.ts +108 -0
  468. package/src/server/rsc-entry/revalidate-renderer.ts +56 -57
  469. package/src/server/rsc-entry/rsc-payload.ts +28 -61
  470. package/src/server/rsc-entry/rsc-stream.ts +113 -213
  471. package/src/server/rsc-entry/ssr-bridge.ts +2 -2
  472. package/src/server/rsc-entry/ssr-renderer.ts +182 -263
  473. package/src/server/rsc-entry/wrap-action-dispatch.ts +12 -14
  474. package/src/server/signal-identity.ts +112 -0
  475. package/src/server/slot-resolver.ts +18 -18
  476. package/src/server/slot-subtree-contain.ts +2 -1
  477. package/src/server/ssr-bridge-types.ts +92 -56
  478. package/src/server/ssr-entry.ts +87 -111
  479. package/src/server/ssr-render.ts +55 -64
  480. package/src/server/ssr-wrappers.tsx +2 -2
  481. package/src/server/static-generator.ts +7 -42
  482. package/src/server/static-not-found.ts +3 -3
  483. package/src/server/stream-utils.ts +51 -0
  484. package/src/server/tracing.ts +58 -75
  485. package/src/server/types.ts +1 -1
  486. package/src/server/version-skew.ts +5 -5
  487. package/src/shared/csrf-reject.ts +15 -0
  488. package/src/shared/error-digest.ts +46 -0
  489. package/src/shared/payload-root.ts +11 -10
  490. package/src/shared/rsc-payload-path.ts +8 -1
  491. package/src/utils/write-file-atomic.ts +32 -0
  492. package/dist/_chunks/actions-jNrXdzgs.js +0 -346
  493. package/dist/_chunks/actions-jNrXdzgs.js.map +0 -1
  494. package/dist/_chunks/als-registry-C6kcfprT.js.map +0 -1
  495. package/dist/_chunks/build-manifest-DTmSGLRz.js.map +0 -1
  496. package/dist/_chunks/build-output-helper-9dqCv1pZ.js.map +0 -1
  497. package/dist/_chunks/cache-api-CUD9Ezaq.js.map +0 -1
  498. package/dist/_chunks/cli-check-G8o30ldg.js.map +0 -1
  499. package/dist/_chunks/convention-lint-5KzoMg_A.js.map +0 -1
  500. package/dist/_chunks/dev-server-BzBxgYAV.js.map +0 -1
  501. package/dist/_chunks/error-boundary-BndF-3Td.js.map +0 -1
  502. package/dist/_chunks/fs-identity-D7vb6GdI.js.map +0 -1
  503. package/dist/_chunks/graph-cache-CP4GEmf9.js.map +0 -1
  504. package/dist/_chunks/json-lossy-check-ClNvBM_3.js.map +0 -1
  505. package/dist/_chunks/logger-k2DQ4EUf.js.map +0 -1
  506. package/dist/_chunks/navigation-context-D0TU0Jog.js.map +0 -1
  507. package/dist/_chunks/plugin-context-8idfR3UZ.js.map +0 -1
  508. package/dist/_chunks/primitives-DLAnvsrk.js.map +0 -1
  509. package/dist/_chunks/segment-context-D9_89u34.js +0 -34
  510. package/dist/_chunks/segment-context-D9_89u34.js.map +0 -1
  511. package/dist/_chunks/sizeof-lXffQ1Vr.js.map +0 -1
  512. package/dist/_chunks/ssr-data-D6T6Y3ef.js +0 -60
  513. package/dist/_chunks/ssr-data-D6T6Y3ef.js.map +0 -1
  514. package/dist/_chunks/state-FippDgxN.js.map +0 -1
  515. package/dist/_chunks/status-page-marker-DwQBrLBz.js.map +0 -1
  516. package/dist/client/types.d.ts +0 -14
  517. package/dist/client/types.d.ts.map +0 -1
  518. package/dist/plugins/adapter-build.d.ts +0 -38
  519. package/dist/plugins/adapter-build.d.ts.map +0 -1
  520. package/dist/server/asset-headers.d.ts +0 -32
  521. package/dist/server/asset-headers.d.ts.map +0 -1
  522. package/dist/server/dev-source-map.d.ts +0 -22
  523. package/dist/server/dev-source-map.d.ts.map +0 -1
  524. package/src/client/types.ts +0 -21
  525. package/src/server/asset-headers.ts +0 -59
  526. package/src/server/dev-source-map.ts +0 -31
@@ -20,12 +20,13 @@ import {
20
20
  renderToReadableStream,
21
21
  } from '../rsc-runtime/rsc.ts';
22
22
 
23
- import { validateCsrf, type CsrfConfig } from './csrf.ts';
24
- import { isDenySignal, isRedirectSignal } from './primitives.ts';
23
+ import { validateCsrf, csrfRejectionResponse, type CsrfConfig } from './csrf.ts';
24
+ import { isDenySignal, isRedirectSignal } from './signal-identity.ts';
25
25
  import { executeAction, type RevalidateRenderer } from './actions.ts';
26
26
  import { runWithRequestContext, setMutableCookieContext } from './request-context.ts';
27
+ import { runOutsideReactCacheScope, runWithReactCacheScope } from './react-cache-scope.ts';
27
28
  import { getSetCookieHeaders, getCookiesForSsr } from './cookie-context.ts';
28
- import { handleActionError } from './action-client.ts';
29
+ import { ActionError, handleActionError } from './action-client.ts';
29
30
  import { enforceBodyLimits, enforceFieldLimit, type BodyLimitsConfig } from './body-limits.ts';
30
31
  import { parseFormData } from './form-data.ts';
31
32
  import {
@@ -36,8 +37,9 @@ import {
36
37
  } from './sensitive-fields.ts';
37
38
  import type { FormFlashData } from './form-flash.ts';
38
39
  import { checkVersionSkew, applyReloadHeaders } from './version-skew.ts';
39
- import { logActionError } from './logger.ts';
40
- import { withTimeout, RenderTimeoutError } from './render-timeout.ts';
40
+ import { logActionError, swallow } from './logger.ts';
41
+ import { fireOnRequestError } from './pipeline-helpers.ts';
42
+ import { withTimeout, RenderTimeoutError, DEFAULT_RENDER_TIMEOUT_MS } from './render-timeout.ts';
41
43
  import { canonicalize } from './canonicalize.ts';
42
44
  import { RSC_CONTENT_TYPE } from '../shared/rsc-media-type.ts';
43
45
 
@@ -105,10 +107,11 @@ export function isActionRequest(req: Request): boolean {
105
107
  *
106
108
  * - `cookies`: the post-action read-your-own-writes view of the cookie
107
109
  * jar, as the same `Map<string, string>` shape used by the request
108
- * context's `parsedCookies`. The rerender dispatcher seeds this map
109
- * directly into the rerender request context via `seedRequestCookies`,
110
- * bypassing any string round-trip through a `Cookie:` header. The
111
- * direct-Map seed eliminates the value-smuggling primitive that the
110
+ * context's `parsedCookies`. The rerender dispatcher passes this map to
111
+ * the pipeline's re-entry, which makes it the rerender request
112
+ * context's cookies, bypassing any string round-trip through a
113
+ * `Cookie:` header. The
114
+ * direct Map eliminates the value-smuggling primitive that the
112
115
  * previous `cookieHeader: string` shape carried — see
113
116
  * ONGOING_SECURITY.md H-3 (TIM-868) and TIM-837.
114
117
  */
@@ -152,7 +155,7 @@ export async function handleActionRequest(
152
155
  // future entry point that bypasses the wrapper. See LOCAL-773.
153
156
  const csrfResult = validateCsrf(req, config.csrf);
154
157
  if (!csrfResult.ok) {
155
- return new Response(null, { status: csrfResult.status });
158
+ return csrfRejectionResponse(req, csrfResult);
156
159
  }
157
160
 
158
161
  // Body size limits — reject oversized requests before parsing.
@@ -167,47 +170,174 @@ export async function handleActionRequest(
167
170
 
168
171
  // Run inside request context so getHeaders(), getCookies() work in actions.
169
172
  // Actions are a mutable context — they can set cookies (design/29-cookies.md).
170
- return runWithRequestContext(req, async () => {
171
- setMutableCookieContext(true);
172
- const actionId = req.headers.get('x-rsc-action');
173
-
174
- let result: Response | FormRerender | null;
175
- if (actionId) {
176
- // With-JS path: client sent action ID in header, args in body
177
- result = await handleRscAction(req, actionId, config);
178
- } else {
179
- // No-JS path: form POST with React's hidden action fields
180
- result = await handleFormAction(req, config);
181
- }
173
+ //
174
+ // ...and outside any React.cache scope: dispatch runs inside the pipeline's
175
+ // request scope (after proxy.ts), and runWithRequestContext would open
176
+ // another. An action reads, writes cookies, and mutates, so a memoized read
177
+ // would go stale mid-action — React.cache in an action does not dedupe,
178
+ // same as stock React and Next.js (TIM-1529 D2). The revalidation render
179
+ // below re-enters its own fresh scope explicitly.
180
+ return runWithRequestContext(req, () =>
181
+ runOutsideReactCacheScope(async () => {
182
+ setMutableCookieContext(true);
183
+ const actionId = req.headers.get('x-rsc-action');
184
+
185
+ let result: Response | FormRerender | null;
186
+ if (actionId) {
187
+ // With-JS path: client sent action ID in header, args in body
188
+ result = await handleRscAction(req, actionId, config);
189
+ } else {
190
+ // No-JS path: form POST with React's hidden action fields
191
+ result = await handleFormAction(req, config);
192
+ }
182
193
 
183
- // Apply cookie jar to action responses.
184
- //
185
- // For Response results we append Set-Cookie directly. For FormRerender
186
- // signals we snapshot the headers here, before this ALS scope exits, so
187
- // the caller can apply them to the rerender pipeline's response (which
188
- // runs in its own request-context scope with a fresh cookie jar).
189
- // See LOCAL-740 — without this snapshot, cookies set inside a no-JS
190
- // form action that returns validation errors are silently dropped.
191
- if (result instanceof Response) {
192
- for (const value of getSetCookieHeaders()) {
193
- result.headers.append('Set-Cookie', value);
194
+ // Apply cookie jar to action responses.
195
+ //
196
+ // For Response results we append Set-Cookie directly. For FormRerender
197
+ // signals we snapshot the headers here, before this ALS scope exits, so
198
+ // the caller can apply them to the rerender pipeline's response (which
199
+ // runs in its own request-context scope with a fresh cookie jar).
200
+ // See LOCAL-740 — without this snapshot, cookies set inside a no-JS
201
+ // form action that returns validation errors are silently dropped.
202
+ if (result instanceof Response) {
203
+ for (const value of getSetCookieHeaders()) {
204
+ result.headers.append('Set-Cookie', value);
205
+ }
206
+ } else if (result && 'rerender' in result) {
207
+ result.setCookieHeaders = getSetCookieHeaders();
208
+ // Snapshot the post-action RYW cookie state as a Map so the rerender
209
+ // dispatcher can hand it to the rerender request context directly,
210
+ // with no string round-trip. See TIM-837
211
+ // and ONGOING_SECURITY.md H-3 (TIM-868). `getCookiesForSsr` already
212
+ // returns a defensive copy, so the rerender scope cannot mutate the
213
+ // snapshot through this reference.
214
+ result.cookies = getCookiesForSsr();
194
215
  }
195
- } else if (result && 'rerender' in result) {
196
- result.setCookieHeaders = getSetCookieHeaders();
197
- // Snapshot the post-action RYW cookie state as a Map so the rerender
198
- // dispatcher can seed it directly into the rerender request context
199
- // via `seedRequestCookies`, with no string round-trip. See TIM-837
200
- // and ONGOING_SECURITY.md H-3 (TIM-868). `getCookiesForSsr` already
201
- // returns a defensive copy, so the rerender scope cannot mutate the
202
- // snapshot through this reference.
203
- result.cookies = getCookiesForSsr();
204
- }
205
- return result;
206
- });
216
+ return result;
217
+ })
218
+ );
207
219
  }
208
220
 
209
221
  // ─── With-JS Action ───────────────────────────────────────────────────────
210
222
 
223
+ /**
224
+ * Log an action error and report it to `onRequestError` as phase
225
+ * `'action'`. An `ActionError` is not reported: it is an outcome the
226
+ * action chose to return, not an unhandled error.
227
+ */
228
+ async function reportActionError(req: Request, error: unknown): Promise<void> {
229
+ logActionError({ method: req.method, path: new URL(req.url).pathname, error });
230
+ if (error instanceof ActionError) return;
231
+ await fireOnRequestError(error, req, 'action');
232
+ }
233
+
234
+ /**
235
+ * Report errors the action survived after its body returned — from
236
+ * `executeAction`'s revalidation, or from serializing the revalidated tree.
237
+ * Each is logged where it was caught; this is its one `onRequestError`
238
+ * report, as phase `'action'`. Errors that are not reportable (a
239
+ * signal a revalidated page threw, an abort) and anything
240
+ * after the request aborted are skipped by the same rule as a page render.
241
+ */
242
+ async function reportRevalidationErrors(req: Request, errors: readonly unknown[]): Promise<void> {
243
+ for (const error of errors) {
244
+ await fireOnRequestError(error, req, 'action').catch((hookError: unknown) =>
245
+ swallow(hookError, 'onRequestError could not be called')
246
+ );
247
+ }
248
+ }
249
+
250
+ /**
251
+ * Answer an action request that failed before the action ran with a bare
252
+ * status, never a 200 action-error payload: a fabricated action id must not
253
+ * look like an action that ran (tests/e2e/security.test.ts). Either way it
254
+ * is logged and reported to `onRequestError` as phase `'action'` (TIM-1537).
255
+ *
256
+ * The status is chosen by what failed, not by matching error messages:
257
+ * - **400**: the request is wrong in a way the handler can see for itself.
258
+ * The body will not parse or decode, or the reference resolves to
259
+ * something that is not a function.
260
+ * - **500**: loading the action module failed. plugin-rsc rejects the same
261
+ * way for an unknown reference and for a real module that fails to import
262
+ * or evaluate, and the second is a server fault, so the load failure keeps
263
+ * the 5xx it had before this change. The no-JS path cannot make this
264
+ * split (`decodeAction` decodes and loads in one call) and answers 400;
265
+ * see `handleFormAction`.
266
+ */
267
+ async function rejectActionRequest(
268
+ req: Request,
269
+ error: unknown,
270
+ status: 400 | 500
271
+ ): Promise<Response> {
272
+ await reportActionError(req, error);
273
+ return new Response(null, { status });
274
+ }
275
+
276
+ /**
277
+ * The no-JS answer to an action error: re-render the page with the error as
278
+ * flash data. `handleActionError` produces `{ serverError }` for an
279
+ * ActionError and `{ serverError: { code: 'INTERNAL_ERROR' } }` otherwise.
280
+ */
281
+ function errorRerender(error: unknown, submittedValues: Record<string, unknown>): FormRerender {
282
+ return {
283
+ rerender: { ...handleActionError(error), submittedValues },
284
+ // Filled in by handleActionRequest before the ALS scope exits.
285
+ setCookieHeaders: [],
286
+ cookies: new Map(),
287
+ };
288
+ }
289
+
290
+ /**
291
+ * Load the action by reference ID and decode its args from the request body
292
+ * (RSC wire format). Returns a Response for a request that fails before the
293
+ * action can run: see `rejectActionRequest` for the status, and the field
294
+ * limit for its own.
295
+ */
296
+ async function decodeRscActionCall(
297
+ req: Request,
298
+ actionId: string,
299
+ config: ActionDispatchConfig
300
+ ): Promise<{ actionFn: (...args: unknown[]) => Promise<unknown>; args: unknown[] } | Response> {
301
+ let loaded: unknown;
302
+ try {
303
+ loaded = await loadServerAction(actionId);
304
+ } catch (error) {
305
+ return rejectActionRequest(req, error, 500);
306
+ }
307
+ if (typeof loaded !== 'function') {
308
+ // The module loaded but has no such export: a reference the client made up.
309
+ return rejectActionRequest(req, new Error(`Unknown server action "${actionId}"`), 400);
310
+ }
311
+ const actionFn = loaded as (...args: unknown[]) => Promise<unknown>;
312
+
313
+ let decoded: unknown;
314
+ try {
315
+ const contentType = req.headers.get('Content-Type') ?? '';
316
+ if (contentType.includes('multipart/form-data')) {
317
+ // FormData-based args (file uploads, etc.)
318
+ const formData = await req.formData();
319
+ // Enforce field count limit after parsing FormData.
320
+ const fieldResult = enforceFieldLimit(formData, config.bodyLimits ?? {});
321
+ if (!fieldResult.ok) {
322
+ return new Response(null, { status: fieldResult.status });
323
+ }
324
+ decoded = await decodeReply(formData);
325
+ } else {
326
+ // Text-based args
327
+ decoded = await decodeReply(await req.text());
328
+ }
329
+ } catch (error) {
330
+ return rejectActionRequest(req, error, 400);
331
+ }
332
+ // The client always encodes an argument list. Anything else would fail
333
+ // when `executeAction` spreads it, inside the action's own catch, and
334
+ // come back as a 200 INTERNAL_ERROR for what is the caller's mistake.
335
+ if (!Array.isArray(decoded)) {
336
+ return rejectActionRequest(req, new Error('Server action body is not an argument list'), 400);
337
+ }
338
+ return { actionFn, args: decoded };
339
+ }
340
+
211
341
  /**
212
342
  * Handle an RSC action request (JavaScript enabled).
213
343
  *
@@ -219,27 +349,10 @@ async function handleRscAction(
219
349
  actionId: string,
220
350
  config: ActionDispatchConfig
221
351
  ): Promise<Response> {
222
- // Load the server action function by reference ID
223
- const actionFn = (await loadServerAction(actionId)) as (...args: unknown[]) => Promise<unknown>;
224
-
225
- // Decode the args from the request body (RSC wire format)
226
- const contentType = req.headers.get('Content-Type') ?? '';
227
- let args: unknown[];
228
-
229
- if (contentType.includes('multipart/form-data')) {
230
- // FormData-based args (file uploads, etc.)
231
- const formData = await req.formData();
232
- // Enforce field count limit after parsing FormData.
233
- const fieldResult = enforceFieldLimit(formData, config.bodyLimits ?? {});
234
- if (!fieldResult.ok) {
235
- return new Response(null, { status: fieldResult.status });
236
- }
237
- args = (await decodeReply(formData)) as unknown[];
238
- } else {
239
- // Text-based args
240
- const body = await req.text();
241
- args = (await decodeReply(body)) as unknown[];
242
- }
352
+ // A request that fails before the action runs is answered here, not a
353
+ // rejection that escapes into the pipeline (TIM-1537).
354
+ const call = await decodeRscActionCall(req, actionId, config);
355
+ if (call instanceof Response) return call;
243
356
 
244
357
  // Execute the action with revalidation tracking.
245
358
  // Errors are caught here so raw 'use server' functions (not using
@@ -251,14 +364,13 @@ async function handleRscAction(
251
364
  // Canonicalize the request pathname so it matches the decoded form
252
365
  // that revalidationPathMatches uses on the target side.
253
366
  const canonical = canonicalize(requestUrl.pathname, true);
254
- result = await executeAction(actionFn, args, {
367
+ result = await executeAction(call.actionFn, call.args, {
255
368
  renderer: config.revalidateRenderer,
256
369
  requestPathname: canonical.ok ? canonical.pathname : requestUrl.pathname,
257
370
  requestSearch: requestUrl.search,
258
371
  });
259
372
  } catch (error) {
260
- // Log full error server-side for debugging
261
- logActionError({ method: req.method, path: new URL(req.url).pathname, error });
373
+ await reportActionError(req, error);
262
374
 
263
375
  // Return structured error response — ActionError gets its code/data,
264
376
  // unexpected errors get sanitized { code: 'INTERNAL_ERROR' }
@@ -269,6 +381,9 @@ async function handleRscAction(
269
381
  headers: { 'Content-Type': RSC_CONTENT_TYPE },
270
382
  });
271
383
  }
384
+ // Outside the try: the action succeeded, and a failure to report its
385
+ // revalidation must not turn it into an action error.
386
+ await reportRevalidationErrors(req, result.revalidationErrors);
272
387
 
273
388
  // Handle redirect — encode in RSC stream for client-side SPA navigation.
274
389
  // The client detects X-Timber-Redirect and calls router.navigate() instead
@@ -322,31 +437,46 @@ async function handleRscAction(
322
437
  | { kind: 'redirect'; location: string; status: number }
323
438
  | { kind: 'error' }
324
439
  | undefined;
325
- const rscStream = renderToReadableStream(revalidationPayload, {
326
- signal: req.signal,
327
- onError(error: unknown) {
328
- // ??= keeps the first signal (shallowest AccessGate in top-down render).
329
- if (isDenySignal(error)) {
330
- serializationSignal ??= { kind: 'deny', status: error.status };
331
- } else if (isRedirectSignal(error)) {
332
- serializationSignal ??= {
333
- kind: 'redirect',
334
- location: error.location,
335
- status: error.status,
336
- };
337
- } else {
338
- console.error('[timber] revalidation serialization error:', error);
339
- serializationSignal ??= { kind: 'error' };
340
- }
341
- },
342
- });
440
+ const serializationErrors: unknown[] = [];
441
+ //
442
+ // Rendered in the scope the revalidation middleware ran in, not this
443
+ // request context's: the action body read through that one before it
444
+ // mutated, and the revalidated tree must see post-mutation values
445
+ // (TIM-1529).
446
+ const rscStream = runWithReactCacheScope(
447
+ () =>
448
+ renderToReadableStream(revalidationPayload, {
449
+ signal: req.signal,
450
+ onError(error: unknown) {
451
+ // ??= keeps the first signal (shallowest AccessGate in top-down render).
452
+ if (isDenySignal(error)) {
453
+ serializationSignal ??= { kind: 'deny', status: error.status };
454
+ } else if (isRedirectSignal(error)) {
455
+ serializationSignal ??= {
456
+ kind: 'redirect',
457
+ location: error.location,
458
+ status: error.status,
459
+ };
460
+ } else {
461
+ console.error('[timber] revalidation serialization error:', error);
462
+ serializationErrors.push(error);
463
+ serializationSignal ??= { kind: 'error' };
464
+ }
465
+ },
466
+ }),
467
+ result.revalidation.reactCacheScope
468
+ );
343
469
 
344
470
  // Drain the stream to detect any signals before committing the response.
345
471
  // Timeout-guarded: the element tree may contain async server components
346
472
  // with stalled fetches. 30s matches the default renderTimeoutMs.
473
+ // Not readAllBytesWithDeadline: this timeout is per read, not one
474
+ // overall deadline; the loop stops at the first chunk after onError
475
+ // records a signal (the payload is dropped then); and the catch below
476
+ // branches on RenderTimeoutError, which the helper does not throw.
347
477
  const reader = rscStream.getReader();
348
478
  const chunks: Uint8Array[] = [];
349
- const drainTimeoutMs = 30_000;
479
+ const drainTimeoutMs = DEFAULT_RENDER_TIMEOUT_MS;
350
480
  try {
351
481
  for (;;) {
352
482
  const { done, value } = await withTimeout(
@@ -365,12 +495,17 @@ async function handleRscAction(
365
495
  reader.cancel().catch(() => {});
366
496
  if (drainError instanceof RenderTimeoutError) {
367
497
  console.error('[timber] revalidatePath dropped — stream drain timed out');
498
+ // A revalidated tree that never finished rendering is a failure,
499
+ // even though the action result still ships.
500
+ await reportRevalidationErrors(req, [...serializationErrors, drainError]);
368
501
  const fallbackStream = renderToReadableStream(result.actionResult);
369
502
  return new Response(fallbackStream, { status: 200, headers });
370
503
  }
504
+ await reportRevalidationErrors(req, serializationErrors);
371
505
  throw drainError;
372
506
  }
373
507
 
508
+ await reportRevalidationErrors(req, serializationErrors);
374
509
  if (serializationSignal) {
375
510
  if (serializationSignal.kind === 'redirect') {
376
511
  const redirectPayload = {
@@ -399,7 +534,10 @@ async function handleRscAction(
399
534
  // Clean serialization — return the buffered bytes with revalidation header.
400
535
  headers['X-Timber-Revalidation'] = '1';
401
536
  const buffered = concatUint8Arrays(chunks);
402
- return new Response(buffered.buffer as ArrayBuffer, { status: 200, headers });
537
+ return new Response(buffered.buffer as ArrayBuffer, {
538
+ status: 200,
539
+ headers,
540
+ });
403
541
  }
404
542
 
405
543
  const rscStream = renderToReadableStream(result.actionResult);
@@ -440,7 +578,13 @@ async function handleFormAction(
440
578
  // Clone before consuming — if this turns out not to be a server action form,
441
579
  // we return null and the original request body must remain readable for
442
580
  // downstream route handlers. Clone is cheap (shares the body buffer until read).
443
- const formData = await req.clone().formData();
581
+ // A body that will not parse is a bad request (TIM-1537).
582
+ let formData: FormData;
583
+ try {
584
+ formData = await req.clone().formData();
585
+ } catch (error) {
586
+ return rejectActionRequest(req, error, 400);
587
+ }
444
588
 
445
589
  // Enforce field count limit after parsing FormData.
446
590
  const fieldResult = enforceFieldLimit(formData, config.bodyLimits ?? {});
@@ -461,37 +605,36 @@ async function handleFormAction(
461
605
  // decodeAction resolves the action function from the form data's hidden fields.
462
606
  // Returns null when no $ACTION_REF_/$ACTION_ID_ fields are present — meaning
463
607
  // this is a regular form POST, not a React server action.
464
- const actionFn = (await decodeAction(formData)) as
465
- | ((...args: unknown[]) => Promise<unknown>)
466
- | null;
608
+ // Execute the action — no additional args needed (form data is already bound).
609
+ // Errors are caught to prevent stack traces from leaking in the response.
610
+ let actionFn: ((...args: unknown[]) => Promise<unknown>) | null;
611
+ try {
612
+ actionFn = (await decodeAction(formData)) as ((...args: unknown[]) => Promise<unknown>) | null;
613
+ } catch (error) {
614
+ // decodeAction both decodes the form's `$ACTION_REF_` metadata and loads
615
+ // the module, and React does not say which failed. On a no-JS POST that
616
+ // metadata is written by React into the form, so a failure is almost
617
+ // always a forged or truncated request: 400. A module that genuinely
618
+ // fails to import also breaks the RSC render of the page holding the
619
+ // form, which surfaces it as a 500 there.
620
+ return rejectActionRequest(req, error, 400);
621
+ }
467
622
  if (!actionFn) {
468
623
  return null;
469
624
  }
470
625
 
471
- // Execute the action — no additional args needed (form data is already bound).
472
- // Errors are caught to prevent stack traces from leaking in the response.
473
626
  let result;
474
627
  try {
475
628
  result = await executeAction(actionFn, [], {
476
629
  renderer: config.revalidateRenderer,
477
630
  });
478
631
  } catch (error) {
479
- logActionError({ method: req.method, path: new URL(req.url).pathname, error });
480
-
481
- // Return the error as flash data for re-render.
482
- // handleActionError produces { serverError } for ActionErrors
483
- // and { serverError: { code: 'INTERNAL_ERROR' } } for unexpected errors.
484
- const errorResult = handleActionError(error);
485
- return {
486
- rerender: {
487
- ...errorResult,
488
- submittedValues,
489
- },
490
- // Filled in by handleActionRequest before the ALS scope exits.
491
- setCookieHeaders: [],
492
- cookies: new Map(),
493
- };
632
+ await reportActionError(req, error);
633
+ return errorRerender(error, submittedValues);
494
634
  }
635
+ // Outside the try: the action succeeded, and a failure to report its
636
+ // revalidation must not turn it into an action error.
637
+ await reportRevalidationErrors(req, result.revalidationErrors);
495
638
 
496
639
  // Handle redirect from the action (e.g. redirect() called in the action body)
497
640
  if (result.redirectTo) {