@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
@@ -0,0 +1,149 @@
1
+ /**
2
+ * timber-react-resolve — Deduplicate React across timber and user project.
3
+ *
4
+ * Without this plugin, pnpm's strict isolation can install two physical
5
+ * copies of React when the user's pinned version differs from timber's
6
+ * peer dep. Timber's 47 bare `from 'react'` imports resolve to one copy
7
+ * while react-dom uses the other — causing "Invalid hook call" hydration
8
+ * crashes with no indication of the real cause.
9
+ *
10
+ * The fix: inject `resolve.dedupe` entries so Vite always resolves React
11
+ * packages from the project root. Unlike `resolve.alias`, `dedupe`
12
+ * preserves Vite's per-environment export conditions — the RSC
13
+ * environment still gets the `react-server` build, SSR gets the SSR
14
+ * build, and the browser gets the browser build. The deduplication
15
+ * happens at the package level, not the file level.
16
+ *
17
+ * A `configResolved` check detects version mismatches between timber's
18
+ * resolved React and the project's React, and logs an actionable error.
19
+ *
20
+ * Design doc: 18-build-system.md §"Module Resolution"
21
+ * Task: TIM-1520
22
+ */
23
+
24
+ import { createRequire } from 'node:module';
25
+ import { dirname } from 'node:path';
26
+ import { fileURLToPath } from 'node:url';
27
+ import type { Plugin } from 'vite';
28
+
29
+ /**
30
+ * React packages to deduplicate. Vite's `resolve.dedupe` extracts the
31
+ * base package name (via `deepImportRE`) before checking, so subpath
32
+ * specifiers like `react/jsx-runtime` are covered by the base `react`
33
+ * entry — listing them separately has no effect.
34
+ */
35
+ export const REACT_DEDUPE_PACKAGES = ['react', 'react-dom'] as const;
36
+
37
+ // ANSI escape codes — match config-validation.ts style
38
+ const RED = '\x1b[31m';
39
+ const BOLD = '\x1b[1m';
40
+ const DIM = '\x1b[2m';
41
+ const RESET = '\x1b[0m';
42
+
43
+ /**
44
+ * Read the version from a package's package.json given a resolve root.
45
+ */
46
+ function readPackageVersion(packageName: string, resolveRoot: string): string | null {
47
+ try {
48
+ const req = createRequire(`${resolveRoot}/package.json`);
49
+ const pkgJsonPath = req.resolve(`${packageName}/package.json`);
50
+ const pkg = req(pkgJsonPath) as { version?: string };
51
+ return pkg.version ?? null;
52
+ } catch {
53
+ return null;
54
+ }
55
+ }
56
+
57
+ export interface ReactVersionMismatch {
58
+ specifier: string;
59
+ timberVersion: string;
60
+ projectVersion: string;
61
+ }
62
+
63
+ /**
64
+ * Check whether timber's React and the user project's React resolve to
65
+ * the same version. Returns mismatches if any.
66
+ */
67
+ export function detectReactMismatch(projectRoot: string): ReactVersionMismatch[] {
68
+ const mismatches: ReactVersionMismatch[] = [];
69
+ const timberRoot = dirname(dirname(fileURLToPath(import.meta.url)));
70
+
71
+ for (const pkg of ['react', 'react-dom'] as const) {
72
+ const timberVersion = readPackageVersion(pkg, timberRoot);
73
+ const projectVersion = readPackageVersion(pkg, projectRoot);
74
+
75
+ if (timberVersion && projectVersion && timberVersion !== projectVersion) {
76
+ mismatches.push({ specifier: pkg, timberVersion, projectVersion });
77
+ }
78
+ }
79
+
80
+ return mismatches;
81
+ }
82
+
83
+ /**
84
+ * Format React version mismatches as an actionable warning.
85
+ */
86
+ export function formatReactMismatch(mismatches: ReactVersionMismatch[]): string {
87
+ if (mismatches.length === 0) return '';
88
+
89
+ const lines: string[] = [];
90
+ lines.push(
91
+ `${RED}${BOLD}[timber]${RESET} ${RED}React version mismatch detected — this causes silent hydration crashes${RESET}`
92
+ );
93
+ lines.push('');
94
+ for (const m of mismatches) {
95
+ lines.push(
96
+ ` ${RED}✗${RESET} ${m.specifier}: timber has ${BOLD}${m.timberVersion}${RESET}, project has ${BOLD}${m.projectVersion}${RESET}`
97
+ );
98
+ }
99
+ lines.push('');
100
+ lines.push(
101
+ ` ${DIM}This typically causes "Invalid hook call" errors because two copies of${RESET}`
102
+ );
103
+ lines.push(` ${DIM}React are loaded. timber's resolve.dedupe should handle this, but${RESET}`);
104
+ lines.push(
105
+ ` ${DIM}if you see hook errors, ensure your React version satisfies timber's peer dep.${RESET}`
106
+ );
107
+ lines.push('');
108
+ lines.push(` ${DIM}Fix: update React in your project to match —${RESET}`);
109
+ lines.push(
110
+ ` ${BOLD}pnpm add react@${mismatches[0].timberVersion} react-dom@${mismatches[0].timberVersion}${RESET}`
111
+ );
112
+
113
+ return lines.join('\n');
114
+ }
115
+
116
+ /**
117
+ * Create the timber-react-resolve Vite plugin.
118
+ */
119
+ export function timberReactResolve(): Plugin {
120
+ return {
121
+ name: 'timber-react-resolve',
122
+ enforce: 'pre',
123
+
124
+ config(userConfig) {
125
+ // Merge with any existing dedupe entries the user may have set.
126
+ const existing = userConfig.resolve?.dedupe ?? [];
127
+ const merged = [...existing];
128
+
129
+ for (const pkg of REACT_DEDUPE_PACKAGES) {
130
+ if (!merged.includes(pkg)) {
131
+ merged.push(pkg);
132
+ }
133
+ }
134
+
135
+ return {
136
+ resolve: {
137
+ dedupe: merged,
138
+ },
139
+ };
140
+ },
141
+
142
+ configResolved(resolved) {
143
+ const mismatches = detectReactMismatch(resolved.root);
144
+ if (mismatches.length > 0) {
145
+ process.stderr.write(`${formatReactMismatch(mismatches)}\n\n`);
146
+ }
147
+ },
148
+ };
149
+ }
@@ -1,109 +1,21 @@
1
1
  /**
2
- * timber-adapter-build — Invoke the adapter's buildOutput after vite build.
2
+ * The RSC plugin's assets manifest (`__vite_rsc_assets_manifest.js`) — read
3
+ * into the build manifest, and stripped of JavaScript when client JS is off.
3
4
  *
4
- * After all environments are built and the RSC plugin has written its
5
- * asset manifests, calls `adapter.buildOutput()` to transform the output
6
- * into a deployable artifact (e.g., Cloudflare Workers entry + wrangler.jsonc).
5
+ * The RSC plugin writes the file to rsc/ and ssr/ as a standalone file, not
6
+ * a Rollup chunk, so no `generateBundle` can intercept it; both operations
7
+ * work on the written files. Both run once, from the post-build phase's
8
+ * manifest finalization step (plugins/post-build.ts), before anything
9
+ * imports the built bundle.
7
10
  *
8
- * Uses a `buildApp` hook with `order: 'post'` so that Vite calls the
9
- * RSC plugin's buildApp (which orchestrates all environment builds and
10
- * writes asset manifests) first, then runs this handler after everything
11
- * is complete.
12
- *
13
- * Design docs: design/11-platform.md, design/25-production-deployments.md
11
+ * Design doc: 18-build-system.md §"Post-Build Phase"
14
12
  */
15
13
 
16
- import type { Plugin } from 'vite';
17
14
  import { join } from 'node:path';
18
15
  import { pathToFileURL } from 'node:url';
19
16
  import { readFile, writeFile } from 'node:fs/promises';
20
- import type { PluginContext } from '../plugin-context.ts';
21
- import type { TimberPlatformAdapter, TimberConfig } from '../adapters/types.ts';
22
17
  import type { BuildManifest } from '../server/build-manifest.ts';
23
18
  import { swallow } from '../server/logger.ts';
24
- import { normalizeBasePath } from '../shared/base-path.ts';
25
-
26
- export function timberAdapterBuild(ctx: PluginContext): Plugin {
27
- return {
28
- name: 'timber-adapter-build',
29
-
30
- // order: 'post' causes Vite to run configBuilder.buildApp() (which
31
- // includes the RSC plugin's buildApp) before calling this handler.
32
- // By the time we run, all environments are built and asset manifests
33
- // are written — safe to copy the output.
34
- buildApp: {
35
- order: 'post' as const,
36
- async handler() {
37
- if (ctx.dev) return;
38
-
39
- const adapter = ctx.config.adapter as TimberPlatformAdapter | undefined;
40
- if (!adapter || typeof adapter.buildOutput !== 'function') return;
41
-
42
- const buildDir = ctx.buildDir;
43
-
44
- // Merge per-route CSS and client reference JS from the RSC plugin's
45
- // assets manifest into the build manifest. This data enables
46
- // <link rel="stylesheet"> and <link rel="modulepreload"> tags in
47
- // <head> for server component routes (TIM-1014).
48
- if (ctx.buildManifest) {
49
- await mergeRscAssetsManifest(
50
- buildDir,
51
- ctx.root,
52
- ctx.buildManifest,
53
- ctx.routeClientRefKeys
54
- );
55
- }
56
-
57
- // Serialize the build manifest as a JS module that sets the global.
58
- // The adapter writes this as _timber-manifest-init.mjs and imports it
59
- // before the RSC handler, so globalThis.__TIMBER_BUILD_MANIFEST__ is
60
- // available when virtual:timber-build-manifest evaluates.
61
- let manifestInit: string | undefined;
62
- if (ctx.buildManifest) {
63
- // Strip JS/modulepreload from manifest when client JS is disabled —
64
- // those files aren't served, so hints for them are useless.
65
- const manifest = ctx.clientJavascript.disabled
66
- ? { ...ctx.buildManifest, js: {}, modulepreload: {} }
67
- : ctx.buildManifest;
68
- const json = JSON.stringify(manifest);
69
- manifestInit = `globalThis.__TIMBER_BUILD_MANIFEST__ = ${json};\n`;
70
-
71
- // Embed the deployment ID for version skew detection (TIM-446).
72
- // The server reads this at startup via setDeploymentId().
73
- if (ctx.deploymentId) {
74
- manifestInit += `globalThis.__TIMBER_DEPLOYMENT_ID__ = ${JSON.stringify(ctx.deploymentId)};\n`;
75
- }
76
- }
77
-
78
- // Strip JS from the RSC plugin's assets manifest when client JS
79
- // is disabled. The RSC plugin writes __vite_rsc_assets_manifest.js
80
- // with clientReferenceDeps containing JS URLs — used to inject
81
- // <link rel="modulepreload"> tags. Must happen before the adapter
82
- // copies files to the output directory.
83
- if (ctx.clientJavascript.disabled) {
84
- await stripJsFromRscAssetsManifests(buildDir);
85
- }
86
-
87
- const adapterConfig: TimberConfig = {
88
- root: ctx.root,
89
- // Normalized once here, not in each adapter: the platform files
90
- // adapters write address deployed-URL space (TIM-1274).
91
- base: normalizeBasePath(ctx.base),
92
- output: ctx.config.output ?? 'server',
93
- clientJavascriptDisabled: ctx.clientJavascript.disabled,
94
- manifestInit,
95
- staticPagesDir:
96
- (ctx.config.output ?? 'server') === 'static'
97
- ? join(buildDir, 'static-pages')
98
- : undefined,
99
- staticContentTypes: ctx.staticContentTypes,
100
- };
101
-
102
- await adapter.buildOutput(adapterConfig, buildDir);
103
- },
104
- },
105
- };
106
- }
107
19
 
108
20
  /**
109
21
  * Parse the RSC assets manifest at `manifestPath`. Tries JSON.parse first
@@ -215,14 +127,6 @@ function clearBootstrapScriptContent(src: string): string {
215
127
  return src.slice(0, idx) + '"bootstrapScriptContent": ""' + src.slice(i);
216
128
  }
217
129
 
218
- /**
219
- * Strip JS references from the RSC plugin's assets manifest files.
220
- *
221
- * The RSC plugin writes `__vite_rsc_assets_manifest.js` to rsc/ and ssr/
222
- * as standalone files (not Rollup chunks), so generateBundle can't
223
- * intercept them. This rewrites the files on disk after all builds
224
- * complete but before the adapter copies them to the output directory.
225
- */
226
130
  /**
227
131
  * Read the RSC plugin's assets manifest and merge per-route CSS and
228
132
  * per-route JS modulepreloads into the build manifest.
@@ -233,12 +137,12 @@ function clearBootstrapScriptContent(src: string): string {
233
137
  * module graph walk) to produce per-route modulepreload entries.
234
138
  */
235
139
  export async function mergeRscAssetsManifest(
236
- buildDir: string,
140
+ rscDir: string,
237
141
  root: string,
238
142
  buildManifest: BuildManifest,
239
143
  routeClientRefKeys?: Map<string, Set<string>>
240
144
  ): Promise<void> {
241
- const manifestPath = join(buildDir, 'rsc', '__vite_rsc_assets_manifest.js');
145
+ const manifestPath = join(rscDir, '__vite_rsc_assets_manifest.js');
242
146
  let content: string;
243
147
  try {
244
148
  content = await readFile(manifestPath, 'utf-8');
@@ -290,9 +194,16 @@ export async function mergeRscAssetsManifest(
290
194
  }
291
195
  }
292
196
 
293
- export async function stripJsFromRscAssetsManifests(buildDir: string): Promise<void> {
294
- const manifestName = '__vite_rsc_assets_manifest.js';
295
- const paths = [join(buildDir, 'rsc', manifestName), join(buildDir, 'ssr', manifestName)];
197
+ /**
198
+ * Strip JS references from the RSC plugin's assets manifest files.
199
+ *
200
+ * The RSC plugin writes `__vite_rsc_assets_manifest.js` to rsc/ and ssr/
201
+ * as standalone files (not Rollup chunks), so generateBundle can't
202
+ * intercept them. This rewrites the files on disk after all builds
203
+ * complete but before the adapter copies them to the output directory.
204
+ */
205
+ export async function stripJsFromRscAssetsManifests(serverDirs: string[]): Promise<void> {
206
+ const paths = serverDirs.map((dir) => join(dir, '__vite_rsc_assets_manifest.js'));
296
207
 
297
208
  for (const path of paths) {
298
209
  let content: string;
@@ -70,6 +70,7 @@ export const SUBPATH_SRC_MAP: Record<string, string> = {
70
70
  'adapters/cloudflare/cache': 'adapters/cloudflare-kv-cache.ts',
71
71
  'adapters/cloudflare/dev': 'adapters/cloudflare-dev.ts',
72
72
  'adapters/nitro': 'adapters/nitro.ts',
73
+ 'adapters/types': 'adapters/types.ts',
73
74
  };
74
75
 
75
76
  /**
@@ -1,31 +1,34 @@
1
1
  /**
2
2
  * timber-static-build — Vite sub-plugin for static output mode.
3
3
  *
4
- * When `output: 'static'` is set in timber.config.ts, this plugin:
5
- * 1. Validates that no dynamic APIs (getCookies(), getHeaders()) are used
6
- * 2. After the build, renders all routes to static HTML + RSC flight files
4
+ * When `output: 'static'` is set in timber.config.ts:
5
+ * 1. The plugin validates that no dynamic APIs (getCookies(), getHeaders())
6
+ * are used
7
+ * 2. `runStaticGeneration`, the static generation step of the post-build
8
+ * phase (plugins/post-build.ts), renders all routes to static HTML + RSC
9
+ * flight files
7
10
  *
8
11
  * Design doc: design/11-platform.md §"static output mode"
9
12
  */
10
13
 
11
14
  import type { Plugin } from 'vite';
12
- import { existsSync } from 'node:fs';
13
15
  import { mkdir, readdir, readFile, writeFile, rename, rm, stat } from 'node:fs/promises';
14
16
  import { createHash, randomUUID } from 'node:crypto';
15
17
  import { dirname, extname, isAbsolute, join, resolve, relative } from 'node:path';
16
18
  import { pathToFileURL } from 'node:url';
19
+ import { writeFileAtomic } from '../utils/write-file-atomic.ts';
17
20
  import type { PluginContext } from '../plugin-context.ts';
21
+ import type { DirectoryArtifact } from '../adapters/types.ts';
18
22
  import type {
19
23
  StaticGenerationOptions,
20
24
  StaticGenerationSummary,
21
25
  StaticPageEntry,
22
26
  StaticRedirectEntry,
23
27
  } from '../server/static-generator.ts';
24
- import { mergeRscAssetsManifest } from './adapter-build.ts';
25
28
  import { isRelativeBase, normalizeBasePath, withBasePath } from '../shared/base-path.ts';
26
29
  import type { RscManifest, RscManifestEntry } from '../shared/rsc-manifest.ts';
27
30
  import { htmlEscapeJsonString } from '../server/flight-scripts.ts';
28
- import { rscPayloadPath } from '../shared/rsc-payload-path.ts';
31
+ import { RSC_PAYLOAD_DIR, rscPayloadPath } from '../shared/rsc-payload-path.ts';
29
32
  import { REDIRECTS_FILE, RESERVED_OUTPUT_PATHS } from '../shared/static-platform-files.ts';
30
33
  import {
31
34
  detectFsIdentity,
@@ -138,13 +141,6 @@ export function generateRedirectsFile(redirects: StaticRedirectEntry[], base: st
138
141
  // File output helpers
139
142
  // ---------------------------------------------------------------------------
140
143
 
141
- /** Write a file atomically: temp sibling + rename. */
142
- async function writeFileAtomic(path: string, data: Uint8Array | string): Promise<void> {
143
- const tmp = `${path}.tmp`;
144
- await writeFile(tmp, data);
145
- await rename(tmp, path);
146
- }
147
-
148
144
  /**
149
145
  * Determine the output file path for a static page entry.
150
146
  *
@@ -204,7 +200,7 @@ export function staticOutputPath(entry: StaticPageEntry): string {
204
200
  * API route, `about/index.html` from a page). The filesystem does refuse that
205
201
  * one — `EISDIR` on the rename, `ENOTDIR` on the mkdir, depending on which
206
202
  * lands second — but an errno names a path, and in the rename case the path
207
- * it names is `about.tmp`. Reported here instead, so the message says which
203
+ * it names is the write's temp file. Reported here instead, so the message says which
208
204
  * two routes.
209
205
  *
210
206
  * Collisions are **collected, not thrown**. `onEntry` runs inside the
@@ -391,7 +387,7 @@ export class StaticSiteWriter {
391
387
  * @internal Exported for testing.
392
388
  */
393
389
  export async function cleanConditionalArtifacts(staticDir: string): Promise<void> {
394
- await rm(join(staticDir, '_rsc'), { recursive: true, force: true }).catch(() => {});
390
+ await rm(join(staticDir, RSC_PAYLOAD_DIR), { recursive: true, force: true }).catch(() => {});
395
391
  await rm(join(staticDir, REDIRECTS_FILE), { force: true }).catch(() => {});
396
392
  }
397
393
 
@@ -454,37 +450,33 @@ export async function withSchedulerPortsReleased<T>(fn: () => Promise<T>): Promi
454
450
  }
455
451
  }
456
452
 
453
+ /** The pre-rendered site a static generation pass wrote. */
454
+ export interface StaticSite {
455
+ pages: DirectoryArtifact;
456
+ /** Content-Type per URL path for extensionless API outputs (TIM-1241). */
457
+ contentTypes: Record<string, string>;
458
+ /** `[RSC_PAYLOAD_DIR]` when payloads were written and content-hashed, else none. */
459
+ immutableDirs: string[];
460
+ }
461
+
457
462
  /**
458
- * Load the built RSC entry and run the static generation pass.
463
+ * Load the built RSC entry and run the static generation pass — the static
464
+ * generation step of the post-build phase (plugins/post-build.ts).
459
465
  *
460
- * Unlike prebuilt capture, this needs the FULL pipeline handler, so
466
+ * The build manifest it renders with is already final: the phase merged the
467
+ * RSC assets manifest into it and published it before this step. Unlike
468
+ * prebuilt capture, this needs the FULL pipeline handler, so
461
469
  * __TIMBER_CAPTURE_MODE__ must be false.
470
+ *
471
+ * Returns the site only once it is complete, so an adapter is never handed a
472
+ * directory a failed pass left half-written — a failure throws instead.
462
473
  */
463
- async function runStaticGeneration(ctx: PluginContext): Promise<StaticGenerationSummary> {
464
- const entryPath = join(ctx.buildDir, 'rsc', 'index.js');
465
- if (!existsSync(entryPath)) {
466
- throw new Error(
467
- `[timber] Static generation: built RSC entry not found at ${entryPath} — ` +
468
- `the build output is missing`
469
- );
470
- }
471
-
472
- const g = globalThis as Record<string, unknown>;
473
-
474
- // Set up the build manifest (same as adapter-build and prebuilt-capture).
475
- if (ctx.buildManifest) g.__TIMBER_BUILD_MANIFEST__ ??= ctx.buildManifest;
476
- if (ctx.deploymentId) g.__TIMBER_DEPLOYMENT_ID__ ??= ctx.deploymentId;
474
+ export async function runStaticGeneration(ctx: PluginContext, rscDir: string): Promise<StaticSite> {
475
+ const entryPath = join(rscDir, 'index.js');
476
+ warnUnusableBase(ctx);
477
477
 
478
478
  // Ensure capture mode is off — we need the full handler.
479
- g.__TIMBER_CAPTURE_MODE__ = false;
480
-
481
- // Merge per-route CSS and modulepreload entries from the RSC assets
482
- // manifest into the build manifest BEFORE rendering, so rendered HTML
483
- // includes all <link> tags. This same merge normally runs in
484
- // adapter-build, but static generation runs first.
485
- if (ctx.buildManifest) {
486
- await mergeRscAssetsManifest(ctx.buildDir, ctx.root, ctx.buildManifest, ctx.routeClientRefKeys);
487
- }
479
+ (globalThis as Record<string, unknown>).__TIMBER_CAPTURE_MODE__ = false;
488
480
 
489
481
  console.log('[timber] Static generation: building site…');
490
482
 
@@ -512,6 +504,7 @@ async function runStaticGeneration(ctx: PluginContext): Promise<StaticGeneration
512
504
  const entryUrl = `${pathToFileURL(entryPath).href}?t=${Date.now()}`;
513
505
  mod = (await import(/* @vite-ignore */ entryUrl)) as StaticGenerateModule;
514
506
  } catch (error) {
507
+ // A missing entry lands here too: the import is the existence check.
515
508
  throw new Error(
516
509
  `[timber] Static generation: failed to load the built RSC entry (${entryPath}). ` +
517
510
  `The full request handler must initialize for static rendering.`,
@@ -556,22 +549,17 @@ async function runStaticGeneration(ctx: PluginContext): Promise<StaticGeneration
556
549
  // ambiguous, not that a page failed, and the message names both routes.
557
550
  writer.assertNoCollisions();
558
551
 
559
- // Store content-type mappings on the plugin context so adapters
560
- // can include them in the _headers file. TIM-1241.
561
- if (Object.keys(writer.contentTypes).length > 0) {
562
- ctx.staticContentTypes = writer.contentTypes;
563
- }
564
-
565
552
  // Hash RSC flight payloads for immutable caching (TIM-1254).
566
553
  // Renames _rsc/*.rsc → _rsc/*-<hash>.rsc and injects a manifest
567
554
  // into each HTML file so the client can resolve hashed URLs.
568
555
  // Skip when client JS is disabled — no SPA navigation, no RSC fetches,
569
556
  // and injecting a <script> tag would violate the no-JS contract.
557
+ const immutableDirs: string[] = [];
570
558
  if (!ctx.clientJavascript.disabled) {
571
559
  const rscManifest = await hashRscPayloads(staticDir);
572
560
  if (Object.keys(rscManifest).length > 0) {
561
+ immutableDirs.push(RSC_PAYLOAD_DIR);
573
562
  await injectRscManifestIntoHtml(staticDir, rscManifest);
574
- ctx.rscManifest = rscManifest;
575
563
  console.log(
576
564
  `[timber] Static generation: hashed ${Object.keys(rscManifest).length} RSC flight payloads`
577
565
  );
@@ -600,7 +588,9 @@ async function runStaticGeneration(ctx: PluginContext): Promise<StaticGeneration
600
588
  }
601
589
  }
602
590
 
603
- return summary;
591
+ // Content types travel with the site because they describe it: a static
592
+ // host cannot infer the type of an extensionless API output (TIM-1241).
593
+ return { pages: { path: staticDir }, contentTypes: writer.contentTypes, immutableDirs };
604
594
  }
605
595
 
606
596
  // ---------------------------------------------------------------------------
@@ -694,7 +684,7 @@ async function walkDir(dir: string): Promise<string[]> {
694
684
  * @internal Exported for testing.
695
685
  */
696
686
  export async function hashRscPayloads(staticDir: string): Promise<RscManifest> {
697
- const rscDir = join(staticDir, '_rsc');
687
+ const rscDir = join(staticDir, RSC_PAYLOAD_DIR);
698
688
  const files = await walkDir(rscDir);
699
689
  const manifest: RscManifest = {};
700
690
 
@@ -777,11 +767,9 @@ export async function readUserRedirects(root: string): Promise<string | null> {
777
767
  /**
778
768
  * Create the timber-static-build Vite plugin.
779
769
  *
780
- * Only active when output: 'static' is configured.
781
- *
782
- * Hooks:
783
- * - transform: Validates source files for static mode violations
784
- * - buildApp (post): Renders all routes to static HTML after the build
770
+ * Only active when output: 'static' is configured. Validates source files
771
+ * for static mode violations; rendering the site is `runStaticGeneration`,
772
+ * which the post-build phase calls.
785
773
  */
786
774
  export function timberStaticBuild(ctx: PluginContext): Plugin {
787
775
  return {
@@ -825,25 +813,5 @@ export function timberStaticBuild(ctx: PluginContext): Plugin {
825
813
 
826
814
  return null;
827
815
  },
828
-
829
- /**
830
- * After all environments are built, render every route to static HTML.
831
- *
832
- * Runs with order: 'post' so the RSC plugin's buildApp completes first,
833
- * producing the built entry we import. Must run BEFORE the adapter
834
- * build copies output to its platform-specific directory.
835
- */
836
- buildApp: {
837
- order: 'post' as const,
838
- async handler() {
839
- if (ctx.dev) return;
840
-
841
- const isStatic = ctx.config.output === 'static';
842
- if (!isStatic) return;
843
-
844
- warnUnusableBase(ctx);
845
- await runStaticGeneration(ctx);
846
- },
847
- },
848
816
  };
849
817
  }
@@ -15,10 +15,11 @@
15
15
  * Design docs: 09-typescript.md §"Typed Routes", 18-build-system.md
16
16
  */
17
17
 
18
- import { writeFile, mkdir } from 'node:fs/promises';
18
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
19
19
  import { join } from 'node:path';
20
20
  import { generateRouteMap } from './codegen.ts';
21
21
  import { writeSegmentTypes } from './segment-codegen.ts';
22
+ import { writeFileAtomic } from '../utils/write-file-atomic.ts';
22
23
  import type { RouteTree } from './types.ts';
23
24
 
24
25
  /**
@@ -114,6 +115,22 @@ export async function flushCodegenWrites(): Promise<void> {
114
115
  * dependency) and logs instead; `timber check` awaits it and fails the command.
115
116
  * Either way the write is registered with `flushCodegenWrites()`.
116
117
  */
118
+ /**
119
+ * Write `timber-env.d.ts` only when its content differs.
120
+ *
121
+ * Its content is constant per timber version, so almost every call is a no-op
122
+ * — and a file that is not rewritten cannot be read half-written. It is not
123
+ * replaced atomically because it lives in the user's project root, often
124
+ * committed: a rename would turn a symlink into a regular file, reset its
125
+ * permissions, and a process killed mid-write would leave a temp file next to
126
+ * their source. The in-place write happens only on first run or a timber
127
+ * upgrade.
128
+ */
129
+ async function writeEnvDts(envPath: string): Promise<void> {
130
+ const existing = await readFile(envPath, 'utf-8').catch(() => null);
131
+ if (existing !== TIMBER_ENV_DTS) await writeFile(envPath, TIMBER_ENV_DTS, 'utf-8');
132
+ }
133
+
117
134
  export function writeRouteCodegen(tree: RouteTree, appDir: string, root: string): Promise<void> {
118
135
  const timberDir = join(root, '.timber');
119
136
  const content = generateRouteMap(tree, { appDir, outputDir: timberDir });
@@ -122,9 +139,14 @@ export function writeRouteCodegen(tree: RouteTree, appDir: string, root: string)
122
139
 
123
140
  const done = mkdir(timberDir, { recursive: true })
124
141
  .then(() =>
142
+ // The type checker can read these while they are being rewritten — an
143
+ // editor's TS server during `timber dev`, a `tsgo` run during `vite
144
+ // build`. A truncating write shows it an empty route map for the length
145
+ // of the write, and every typed route degrades to `any` (TIM-1562).
146
+ // The generated files under `.timber/` are replaced atomically.
125
147
  Promise.all([
126
- writeFile(routesPath, content, 'utf-8'),
127
- writeFile(envPath, TIMBER_ENV_DTS, 'utf-8'),
148
+ writeFileAtomic(routesPath, content),
149
+ writeEnvDts(envPath),
128
150
  writeSegmentTypes(tree, appDir, root),
129
151
  ])
130
152
  )
@@ -8,8 +8,9 @@
8
8
  * Design doc: design/41-global-params.md §The $segment Module
9
9
  */
10
10
 
11
- import { writeFile, mkdir } from 'node:fs/promises';
11
+ import { mkdir } from 'node:fs/promises';
12
12
  import { join } from 'node:path';
13
+ import { writeFileAtomic } from '../utils/write-file-atomic.ts';
13
14
  import type { RouteTree, SegmentNode } from './types.ts';
14
15
 
15
16
  /** Info carried per directory for type generation. */
@@ -90,7 +91,7 @@ export async function writeSegmentTypes(
90
91
  const content = generateSegmentDts(info);
91
92
 
92
93
  writes.push(
93
- mkdir(segmentDir, { recursive: true }).then(() => writeFile(segmentFile, content, 'utf-8'))
94
+ mkdir(segmentDir, { recursive: true }).then(() => writeFileAtomic(segmentFile, content))
94
95
  );
95
96
  }
96
97
 
@@ -16,4 +16,12 @@ declare module '@vitejs/plugin-rsc/vendor/react-server-dom/server.edge' {
16
16
  onPostpone?: (reason: string) => void;
17
17
  }
18
18
  ): ReadableStream<Uint8Array>;
19
+
20
+ // src decodes replies through plugin-rsc's wrapper; tests call the vendored
21
+ // server directly to exercise its array size limit (CVE-2025-55184).
22
+ export function decodeReply(
23
+ body: string | FormData,
24
+ manifest: unknown,
25
+ options?: { temporaryReferences?: unknown; arraySizeLimit?: number }
26
+ ): Promise<unknown[]>;
19
27
  }
@@ -13,7 +13,8 @@
13
13
  * See design/04-authorization.md and design/02-rendering-pipeline.md §"AccessGate"
14
14
  */
15
15
 
16
- import { isDenySignal, isRedirectSignal, DenySignal, RedirectSignal } from './primitives.ts';
16
+ import { DenySignal, RedirectSignal } from './primitives.ts';
17
+ import { isDenySignal, isRedirectSignal } from './signal-identity.ts';
17
18
  import { withSpan, setSpanAttribute } from './tracing.ts';
18
19
  import { isDebug } from './debug.ts';
19
20
  import type { DenyPageEntry } from './deny-boundary.ts';
@@ -225,7 +225,7 @@ async function runActionMiddleware<TCtx>(
225
225
  import { parseFormData } from './form-data.ts';
226
226
  import { formatSize } from '../utils/format.ts';
227
227
  import { isDebug, isDevMode } from './debug.ts';
228
- import { isDenySignal, isRedirectSignal } from './primitives.ts';
228
+ import { isDenySignal, isRedirectSignal } from './signal-identity.ts';
229
229
  import {
230
230
  stripSensitiveFields,
231
231
  resolveSensitivePredicate,