@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
@@ -16,7 +16,7 @@ This is the number one confusion point. They are different things:
16
16
  | ------------------- | --------------------------- | -------------------- |
17
17
  | Scope | Cross-request (persistent) | Single request |
18
18
  | TTL/tags | Yes | No |
19
- | Works in middleware | Yes | No |
19
+ | Works in middleware | Yes | Yes (same request) |
20
20
  | Use case | Database queries, API calls | Request-scoped dedup |
21
21
 
22
22
  `React.cache` deduplicates within a single request — if three components call `getUser(id)`, only one database query runs. `timber.cache` persists across requests with TTL — the same query serves cached results for 60 seconds.
@@ -58,10 +58,10 @@ const getUser = cache.data(
58
58
  return db.users.findUnique({ where: { id: userId } });
59
59
  },
60
60
  {
61
- ttl: 60, // Cache for 60 seconds
62
- key: (userId) => `user:${userId}`, // Explicit cache key (optional)
63
- staleWhileRevalidate: true, // Serve stale while refetching
64
- tags: (userId) => [`user:${userId}`], // For tag-based invalidation
61
+ ttl: 60, // Cache for 60 seconds
62
+ key: (userId) => `user:${userId}`, // Explicit cache key (optional)
63
+ staleWhileRevalidate: true, // Serve stale while refetching
64
+ tags: (userId) => [`user:${userId}`], // For tag-based invalidation
65
65
  }
66
66
  );
67
67
  ```
@@ -101,7 +101,18 @@ revalidateTag('products');
101
101
  revalidateTag(`user:${userId}`);
102
102
  ```
103
103
 
104
- Invalidation wins races against in-flight cached functions: if a cached function is mid-execution when you invalidate one of its tags (the usual mutation flow — update the database, then `revalidateTag`), its result is not written back to the cache, and callers arriving after the invalidation re-execute instead of joining the superseded execution. This guard is per-process; with a shared handler (Redis/KV), an invalidation from a *different* instance can still race a concurrent write on this one.
104
+ `revalidateTag` works outside actions too. From a `route.ts` handler, say a CMS webhook, it invalidates immediately, and you await it before responding:
105
+
106
+ ```ts title="app/api/cms-webhook/route.ts"
107
+ export async function POST(ctx: RouteContext) {
108
+ await revalidateTag('products');
109
+ return new Response(null, { status: 204 });
110
+ }
111
+ ```
112
+
113
+ `revalidatePath` is different: it re-renders a page into a server action's response, so it only works inside an action.
114
+
115
+ Invalidation wins races against in-flight cached functions: if a cached function is mid-execution when you invalidate one of its tags (the usual mutation flow — update the database, then `revalidateTag`), its result is not written back to the cache, and callers arriving after the invalidation re-execute instead of joining the superseded execution. This guard is per-process; with a shared handler (Redis/KV), an invalidation from a _different_ instance can still race a concurrent write on this one.
105
116
 
106
117
  ## `staleWhileRevalidate`
107
118
 
@@ -129,7 +140,12 @@ const PostBody = cache.component(
129
140
  async function PostBody() {
130
141
  const { slug } = getSegmentParams();
131
142
  const post = await getPost(slug);
132
- return <article><h1>{post.title}</h1><PostContent content={post.content} /></article>;
143
+ return (
144
+ <article>
145
+ <h1>{post.title}</h1>
146
+ <PostContent content={post.content} />
147
+ </article>
148
+ );
133
149
  },
134
150
  { prerender: true }
135
151
  );
@@ -188,10 +204,10 @@ export default async function BlogPost() {
188
204
  const user = await getUser(getCookieJar());
189
205
  return (
190
206
  <>
191
- <Nav user={user} /> {/* dynamic — personalized */}
192
- <PostBody /> {/* prerendered — from build artifact */}
207
+ <Nav user={user} /> {/* dynamic — personalized */}
208
+ <PostBody /> {/* prerendered — from build artifact */}
193
209
  <Suspense fallback={<CommentsSkeleton />}>
194
- <Comments /> {/* dynamic — streams per-request */}
210
+ <Comments /> {/* dynamic — streams per-request */}
195
211
  </Suspense>
196
212
  </>
197
213
  );
@@ -230,7 +246,9 @@ const Shell = cache.component(ExpensiveWrapper, {
230
246
  });
231
247
 
232
248
  // The shell serves from cache; children render live per request.
233
- <Shell theme="dark"><LiveUserFeed /></Shell>
249
+ <Shell theme="dark">
250
+ <LiveUserFeed />
251
+ </Shell>;
234
252
  ```
235
253
 
236
254
  Slot props are excluded from the cache key. Slots are runtime tier only — `prerender` is ignored when `slots` is active.
@@ -27,10 +27,16 @@ Before diving in, the first question: should this be middleware or `access.ts`?
27
27
  | ------------- | -------------------------------------- | --------------------------------- |
28
28
  | Runs | Before rendering | Inside React tree |
29
29
  | Purpose | Headers, redirects, cache warming | Auth, data gating |
30
- | `React.cache` | Not available | Active — shares scope with layout |
30
+ | `React.cache` | Active — shares scope with the render | Active — shares scope with layout |
31
31
  | Slots | N/A | Graceful degradation |
32
32
 
33
- Use `middleware.ts` for request-level decisions: should this request proceed? What headers does it need? Use `access.ts` for auth — it has `React.cache` and supports slot degradation.
33
+ Use `middleware.ts` for request-level decisions: should this request proceed? What headers does it need? Use `access.ts` for auth — it gates each segment, renders status pages with `deny()`, and supports slot degradation.
34
+
35
+ Both share one `React.cache` scope per request with your layouts and pages. A `React.cache`-wrapped `getUser()` called in middleware, `access.ts`, and a layout runs once. Middleware is a good place to start that fetch early.
36
+
37
+ If middleware changes a cookie, cached functions that already read it keep their old result. Have them take the cookie value as an argument (see [Fetching Data](/docs/fetching-data)); in development timber warns when this happens.
38
+
39
+ Middleware runs once, root to leaf, before any `access.ts`. A child `middleware.ts` that returns a `Response` responds before a parent's `access.ts` runs. Put authorization that must cover a whole subtree in `access.ts` or in a parent `middleware.ts`.
34
40
 
35
41
  ## `proxy.ts` — Global Middleware
36
42
 
@@ -111,21 +111,26 @@ The general error boundary. It's a client component:
111
111
 
112
112
  export default function DashboardError({
113
113
  error,
114
+ digest,
114
115
  reset,
115
116
  }: {
116
117
  error: Error;
118
+ digest: string | null;
117
119
  reset: () => void;
118
120
  }) {
119
121
  return (
120
122
  <div>
121
123
  <h2>Something went wrong</h2>
122
124
  <p>{error.message}</p>
125
+ {digest && <p>Reference: {digest}</p>}
123
126
  <button onClick={reset}>Try again</button>
124
127
  </div>
125
128
  );
126
129
  }
127
130
  ```
128
131
 
132
+ `digest` is the ID the server logged the error with: the `errorId` field on its log line. In production `error.message` is a generic string, so the digest is what a reader can quote to you and what you search your logs for. It is `null` when the boundary is serving a `deny()`, and for an error the server logged without an ID: one thrown in the browser, one a client component throws while the page renders on the server, or one raised before the page renders (a module that fails to load, say).
133
+
129
134
  Error boundaries wrap page content inside layouts — the layout shell (nav, sidebar) stays visible when an error fires.
130
135
 
131
136
  A status page renders inside the layouts **above and including the segment it lives in**, and none below it. A root `404.tsx` serving a `deny(404)` from `app/docs/[slug]/page.tsx` renders inside the root layout only — `docs/layout.tsx` and `[slug]/layout.tsx` do not appear, because the file that matched lives above them. Co-locate the status file with the segment whose chrome you want kept: move that `404.tsx` to `app/docs/` and the docs layout comes with it.
@@ -184,4 +189,4 @@ if (!product) {
184
189
  }
185
190
  ```
186
191
 
187
- The status-code file receives the structured data as the `data` prop, surviving the RSC → client boundary where plain error properties are stripped.
192
+ The status-code file receives the structured data as the `data` prop, surviving the RSC → client boundary where plain error properties are stripped. This works for any 4xx or 5xx status: `deny(503, { dangerouslyPassData })` renders `503.tsx` (or `5xx.tsx`, or `error.tsx`) with its `data`. A plain `throw` is for failures you did not plan for: outside `<Suspense>` it renders the error page with a 500, and in production the page gets a generic message and a `digest` to find the log line by.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timber-js/app",
3
- "version": "0.2.0-alpha.207",
3
+ "version": "0.2.0-alpha.209",
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",
@@ -133,6 +133,10 @@
133
133
  "types": "./dist/adapters/nitro.d.ts",
134
134
  "import": "./dist/adapters/nitro.js"
135
135
  },
136
+ "./adapters/types": {
137
+ "types": "./dist/adapters/types.d.ts",
138
+ "import": "./dist/adapters/types.js"
139
+ },
136
140
  "./fonts/google": {
137
141
  "types": "./dist/shims/font-google.d.ts",
138
142
  "import": "./dist/shims/font-google.js"
@@ -165,8 +169,8 @@
165
169
  "@vitejs/plugin-react": "^6.1.0",
166
170
  "@vitejs/plugin-rsc": ">=0.5.35",
167
171
  "nuqs": "^2.0.0",
168
- "react": "19.3.0",
169
- "react-dom": "19.3.0",
172
+ "react": "^19.3.0",
173
+ "react-dom": "^19.3.0",
170
174
  "satteri": "^0.9.5",
171
175
  "vite": "8.3.0",
172
176
  "vite-plugin-satteri": "^0.2.15",
@@ -23,15 +23,20 @@ import {
23
23
  USER_PLATFORM_DIR,
24
24
  } from '../shared/static-platform-files.ts';
25
25
  import { detectFsIdentity, fsKey } from './fs-identity.ts';
26
- import type { TimberConfig } from './types.ts';
26
+ import type {
27
+ BuildArtifacts,
28
+ ServerBuildArtifacts,
29
+ StaticBuildArtifacts,
30
+ TimberConfig,
31
+ } from './types.ts';
27
32
 
28
33
  /** Options for the shared build output steps. */
29
34
  export interface BuildOutputBaseOptions {
30
35
  /** Resolved timber config. */
31
36
  config: TimberConfig;
32
- /** Root build directory (e.g. `.timber/build`). */
33
- buildDir: string;
34
- /** Adapter-specific output directory (e.g. `.timber/build/nitro`). */
37
+ /** What the build produced. */
38
+ artifacts: ServerBuildArtifacts;
39
+ /** Adapter-specific output directory (e.g. `.timber/dist/nitro`). */
35
40
  outDir: string;
36
41
  /**
37
42
  * Name of the public/static directory within outDir.
@@ -52,7 +57,7 @@ export interface BuildOutputBaseOptions {
52
57
  * Returns the resolved public directory path for further adapter-specific use.
53
58
  */
54
59
  export async function runSharedBuildSteps(opts: BuildOutputBaseOptions): Promise<string> {
55
- const { config, buildDir, outDir, publicDirName } = opts;
60
+ const { config, artifacts, outDir, publicDirName } = opts;
56
61
 
57
62
  // 1. Create the output directory.
58
63
  await mkdir(outDir, { recursive: true });
@@ -60,9 +65,9 @@ export async function runSharedBuildSteps(opts: BuildOutputBaseOptions): Promise
60
65
  // 2. Copy client assets to public/static directory.
61
66
  // When client JavaScript is disabled, skip .js files — only CSS,
62
67
  // fonts, images, and other static assets are needed.
63
- const clientDir = join(buildDir, 'client');
64
68
  const publicDir = join(outDir, publicDirName);
65
69
  await mkdir(publicDir, { recursive: true });
70
+ const clientDir = artifacts.client.path;
66
71
  // Find WASM files that are referenced by client JS (legitimate client WASM)
67
72
  // vs orphaned server-only WASM (e.g. @takumi-rs for OG image generation).
68
73
  // Only strip orphaned WASM to avoid breaking client-side WASM usage.
@@ -77,39 +82,31 @@ export async function runSharedBuildSteps(opts: BuildOutputBaseOptions): Promise
77
82
  if (config.clientJavascriptDisabled && src.endsWith('.js')) return false;
78
83
  return true;
79
84
  },
80
- }).catch((e: NodeJS.ErrnoException) => {
81
- // Client dir may not exist when client JavaScript is disabled
82
- if (e.code !== 'ENOENT') throw e;
83
85
  });
84
86
 
85
87
  // 3. Write _headers file for static asset cache control.
86
88
  // Scan for unhashed files so they get per-file Cache-Control rules in the
87
89
  // _headers file. On platforms like Cloudflare Workers Static Assets, the
88
90
  // worker never sees static file requests — _headers is the only mechanism.
89
- await writeHeadersFile(publicDir, config, await findUnhashedStaticFiles(publicDir));
91
+ await writeHeadersFile(publicDir, config, artifacts);
90
92
 
91
- // 4. Copy RSC + SSR server bundles into the output directory.
92
- await cp(join(buildDir, 'rsc'), join(outDir, 'rsc'), { recursive: true });
93
- await cp(join(buildDir, 'ssr'), join(outDir, 'ssr'), { recursive: true }).catch(
94
- (e: NodeJS.ErrnoException) => {
95
- // SSR dir may not exist for static-only builds
96
- if (e.code !== 'ENOENT') throw e;
97
- }
98
- );
93
+ // 4. Copy RSC + SSR server bundles into the output directory. The RSC
94
+ // bundle imports the SSR one by a path the RSC plugin computed between the
95
+ // two *build* directories, which the build names `rsc/` and `ssr/` as
96
+ // siblings (index.ts); deploying them under the same names keeps it valid.
97
+ await cp(artifacts.rsc.path, join(outDir, 'rsc'), { recursive: true });
98
+ await cp(artifacts.ssr.path, join(outDir, 'ssr'), { recursive: true });
99
99
 
100
- // 4b. Copy prebuilt/ flight payloads if present (cache.component artifacts).
101
- // These are produced by the post-build capture pass (design/44) and read
102
- // at request time via the adapter's PrebuiltPayloadSource.
103
- await cp(join(buildDir, 'prebuilt'), join(outDir, 'prebuilt'), { recursive: true }).catch(
104
- (e: NodeJS.ErrnoException) => {
105
- // No prebuilt dir when the app has no cache.component calls
106
- if (e.code !== 'ENOENT') throw e;
107
- }
108
- );
100
+ // 4b. Copy prebuilt/ flight payloads (cache.component artifacts). These
101
+ // are produced by the post-build capture pass (design/44) and read at
102
+ // request time via the adapter's PrebuiltPayloadSource.
103
+ if (artifacts.prebuilt) {
104
+ await cp(artifacts.prebuilt.path, join(outDir, 'prebuilt'), { recursive: true });
105
+ }
109
106
 
110
107
  // 5. Write manifest-init module if present.
111
- if (config.manifestInit) {
112
- await writeFile(join(outDir, '_timber-manifest-init.js'), config.manifestInit);
108
+ if (artifacts.manifestInit) {
109
+ await writeFile(join(outDir, '_timber-manifest-init.js'), artifacts.manifestInit);
113
110
  }
114
111
 
115
112
  return publicDir;
@@ -120,9 +117,16 @@ export async function runSharedBuildSteps(opts: BuildOutputBaseOptions): Promise
120
117
  * Cache-Control rules in the `_headers` file.
121
118
  *
122
119
  * Excludes:
123
- * - Files under `assets/` and `_timber/` (covered by wildcard rules)
120
+ * - Files under the build's `immutableDirs` (covered by wildcard rules)
121
+ * - Files under `rsc/` and `ssr/` (server bundles, never served)
124
122
  * - Underscore-prefixed files (`_headers`, `_worker.js`, etc.)
125
123
  *
124
+ * Ordered for the rule cap: well-known metadata files, then everything
125
+ * else, then files under an underscore-prefixed directory — the
126
+ * framework's own output (unhashed RSC payloads in a static build with
127
+ * client JavaScript disabled, which nothing fetches). Those can number one
128
+ * per route, and must not take the budget from the app's real files.
129
+ *
126
130
  * @internal Exported for testing.
127
131
  */
128
132
  // Well-known metadata files that should be prioritized when capping
@@ -136,7 +140,10 @@ const PRIORITY_FILES = new Set([
136
140
  '/apple-touch-icon.png',
137
141
  ]);
138
142
 
139
- export async function findUnhashedStaticFiles(publicDir: string): Promise<string[]> {
143
+ export async function findUnhashedStaticFiles(
144
+ publicDir: string,
145
+ immutableDirs: readonly string[]
146
+ ): Promise<string[]> {
140
147
  let files: string[];
141
148
  try {
142
149
  files = await collectFiles(publicDir);
@@ -146,20 +153,23 @@ export async function findUnhashedStaticFiles(publicDir: string): Promise<string
146
153
 
147
154
  const priority: string[] = [];
148
155
  const rest: string[] = [];
156
+ const framework: string[] = [];
149
157
  for (const file of files) {
150
158
  const rel = relative(publicDir, file).replace(/\\/g, '/');
151
- if (rel.startsWith('assets/') || rel.startsWith('_timber/')) continue;
152
- if (rel.startsWith('rsc/') || rel.startsWith('ssr/') || rel.startsWith('_rsc/')) continue;
159
+ if (immutableDirs.some((dir) => rel.startsWith(`${dir}/`))) continue;
160
+ if (rel.startsWith('rsc/') || rel.startsWith('ssr/')) continue;
153
161
  if (basename(rel).startsWith('_')) continue;
154
162
  const urlPath = '/' + rel;
155
163
  if (PRIORITY_FILES.has(urlPath)) {
156
164
  priority.push(urlPath);
165
+ } else if (rel.startsWith('_')) {
166
+ framework.push(urlPath);
157
167
  } else {
158
168
  rest.push(urlPath);
159
169
  }
160
170
  }
161
171
 
162
- return [...priority.sort(), ...rest.sort()];
172
+ return [...priority.sort(), ...rest.sort(), ...framework.sort()];
163
173
  }
164
174
 
165
175
  /**
@@ -169,13 +179,7 @@ export async function findUnhashedStaticFiles(publicDir: string): Promise<string
169
179
  */
170
180
  async function findReferencedWasm(clientDir: string): Promise<Set<string>> {
171
181
  const referenced = new Set<string>();
172
-
173
- let files: string[];
174
- try {
175
- files = await collectFiles(clientDir);
176
- } catch {
177
- return referenced;
178
- }
182
+ const files = await collectFiles(clientDir);
179
183
 
180
184
  const jsFiles = files.filter((f) => f.endsWith('.js'));
181
185
  const wasmFiles = files.filter((f) => f.endsWith('.wasm')).map((f) => basename(f));
@@ -200,7 +204,7 @@ async function findReferencedWasm(clientDir: string): Promise<Set<string>> {
200
204
  */
201
205
  export async function buildStaticDirectoryOutput(
202
206
  config: TimberConfig,
203
- buildDir: string,
207
+ artifacts: StaticBuildArtifacts,
204
208
  outDir: string,
205
209
  publicDirName: string
206
210
  ): Promise<void> {
@@ -214,15 +218,12 @@ export async function buildStaticDirectoryOutput(
214
218
  await mkdir(publicDir, { recursive: true });
215
219
 
216
220
  // Copy client assets (JS, CSS, fonts, images).
217
- const clientDir = join(buildDir, 'client');
218
- await cp(clientDir, publicDir, {
221
+ await cp(artifacts.client.path, publicDir, {
219
222
  recursive: true,
220
223
  filter: (src: string) => {
221
224
  if (config.clientJavascriptDisabled && src.endsWith('.js')) return false;
222
225
  return true;
223
226
  },
224
- }).catch((e: NodeJS.ErrnoException) => {
225
- if (e.code !== 'ENOENT') throw e;
226
227
  });
227
228
 
228
229
  // Copy pre-rendered static pages (HTML + RSC flight + API routes).
@@ -231,10 +232,8 @@ export async function buildStaticDirectoryOutput(
231
232
  // into a single directory, and `cp` resolves an overlap by overwriting with
232
233
  // no diagnostic — the deployment then contains one of the two artifacts and
233
234
  // nothing recorded which. Refuse instead (TIM-1266).
234
- if (config.staticPagesDir) {
235
- await assertNoTreeCollision(config.staticPagesDir, publicDir);
236
- await cp(config.staticPagesDir, publicDir, { recursive: true });
237
- }
235
+ await assertNoTreeCollision(artifacts.pages.path, publicDir);
236
+ await cp(artifacts.pages.path, publicDir, { recursive: true });
238
237
  }
239
238
 
240
239
  /**
@@ -265,15 +264,18 @@ export async function buildStaticDirectoryOutput(
265
264
  export async function writeHeadersFile(
266
265
  dir: string,
267
266
  config: TimberConfig,
268
- unhashedPaths: string[]
267
+ artifacts: BuildArtifacts
269
268
  ): Promise<void> {
270
269
  const userRules = await readUserPlatformFile(config.root, HEADERS_FILE);
271
270
  await writeFile(
272
271
  join(dir, HEADERS_FILE),
273
272
  generateHeadersFile({
274
273
  base: adapterBase(config),
275
- unhashedPaths,
276
- contentTypes: config.staticContentTypes,
274
+ immutableDirs: artifacts.immutableDirs,
275
+ // Scanned from the directory being deployed, which holds everything
276
+ // the platform will serve from it.
277
+ unhashedPaths: await findUnhashedStaticFiles(dir, artifacts.immutableDirs),
278
+ contentTypes: artifacts.output === 'static' ? artifacts.contentTypes : undefined,
277
279
  userRules: userRules ?? undefined,
278
280
  })
279
281
  );
@@ -0,0 +1,29 @@
1
+ // Compiles server/canonicalize.ts into a standalone ESM module
2
+ // (_canonicalize.mjs) for the Nitro preview server, so preview answers a
3
+ // request path exactly as the runtime's request boundary does — the same
4
+ // rejections (encoded separators, null bytes, malformed encoding, escaping
5
+ // the root) and the same single decode — instead of a hand-kept copy of
6
+ // those rules drifting from them. Same mechanism as compress-module.ts:
7
+ // type-stripped, not bundled, so the source must stay import-free.
8
+
9
+ import { transformWithOxc } from 'vite';
10
+ // Vite's ?raw import embeds the file as a string at build time (see
11
+ // compress-module.ts).
12
+ import canonicalizeSource from '../server/canonicalize.ts?raw';
13
+ import { assertStandalone } from './compress-module.ts';
14
+
15
+ /**
16
+ * Compile server/canonicalize.ts into a standalone ESM module exporting
17
+ * `canonicalize`.
18
+ *
19
+ * @internal Exported for testing.
20
+ */
21
+ export async function generateCanonicalizeModule(): Promise<string> {
22
+ const result = await transformWithOxc(canonicalizeSource, 'canonicalize.ts', { lang: 'ts' });
23
+ assertStandalone(result.code, 'server/canonicalize.ts', '_canonicalize.mjs');
24
+ return (
25
+ '// Generated by @timber-js/app — compiled from server/canonicalize.ts.\n' +
26
+ '// Do not edit — this file is regenerated on each build.\n' +
27
+ result.code
28
+ );
29
+ }