@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
@@ -1,139 +1,179 @@
1
1
  // Nitro local preview — standalone server codegen and process spawning.
2
2
  //
3
- // `timber preview` runs the adapter's preview() for locally-runnable
4
- // presets (node-server, bun), which writes and spawns the generated
5
- // `_preview-server.mjs`. See design/25-production-deployments.md §Preview.
3
+ // `buildOutput` writes `_preview-server.mjs` into the Nitro output directory,
4
+ // generated from the build's own artifacts; `timber preview` runs the
5
+ // adapter's preview(), which spawns it. See design/25-production-deployments.md
6
+ // §Preview.
6
7
 
7
8
  import { execFile } from 'node:child_process';
8
- import { join, relative } from 'node:path';
9
- import { getPresetConfig, LOCALLY_PREVIEWABLE, type NitroPreset } from './nitro-presets.ts';
9
+ import { IMMUTABLE_CACHE, STATIC_CACHE } from './shared.ts';
10
10
 
11
11
  /**
12
- * Generate a standalone preview server script that uses Node's built-in
13
- * HTTP server. This bypasses Nitro entirely — the Nitro entry.ts imports
14
- * h3 which isn't available outside a Nitro build. For local preview we
15
- * just need to serve static files and route requests to the RSC handler.
16
- *
17
- * @internal Exported for testing.
12
+ * Content-Type by file extension for the preview server. Static hosts decide
13
+ * this themselves; the table covers the file types a web build ships so the
14
+ * preview does not turn ordinary files into downloads. An extension missing
15
+ * here is served as `application/octet-stream`.
18
16
  */
19
- export function generatePreviewScript(buildDir: string, preset: NitroPreset): string {
20
- const rscEntryRelative = relative(join(buildDir, 'nitro'), join(buildDir, 'rsc', 'index.js'));
21
- const rscEntry = rscEntryRelative.startsWith('.') ? rscEntryRelative : './' + rscEntryRelative;
22
- const publicDir = './public';
23
- const manifestInitPath = './_timber-manifest-init.js';
24
- const runtimeName = getPresetConfig(preset).runtimeName;
25
-
26
- return `// Generated by @timber-js/app — standalone preview server.
27
- // Uses Node's built-in HTTP server to serve static assets and route
28
- // dynamic requests through the RSC handler. No Nitro/h3 dependency.
29
-
30
- import { createServer } from 'node:http';
31
- import { readFile, stat } from 'node:fs/promises';
32
- import { join, extname } from 'node:path';
33
- import { fileURLToPath } from 'node:url';
34
- import { existsSync } from 'node:fs';
35
-
36
- // Set runtime before importing the handler.
37
- process.env.TIMBER_RUNTIME = '${runtimeName}';
38
-
39
- // Load the build manifest if it exists.
40
- const __dirname = fileURLToPath(new URL('.', import.meta.url));
41
- const manifestPath = join(__dirname, '${manifestInitPath}');
42
- if (existsSync(manifestPath)) {
43
- await import('${manifestInitPath}');
44
- }
45
-
46
- // Import the RSC handler (default export is the fetch-like handler).
47
- const { default: handler, runWithEarlyHintsSender } = await import('${rscEntry}');
48
-
49
- // Import compression helper for self-hosted response compression.
50
- const { compressResponse } = await import('./_compress.mjs');
51
-
52
- // Web→Node response bridge with backpressure (TIM-1154).
53
- const { sendNodeResponse } = await import('./_send-response.mjs');
54
-
55
- const MIME_TYPES = {
56
- '.html': 'text/html',
57
- '.js': 'application/javascript',
58
- '.mjs': 'application/javascript',
59
- '.css': 'text/css',
60
- '.json': 'application/json',
17
+ const PREVIEW_MIME_TYPES: Readonly<Record<string, string>> = {
18
+ // Documents and code
19
+ '.html': 'text/html; charset=utf-8',
20
+ '.htm': 'text/html; charset=utf-8',
21
+ '.css': 'text/css; charset=utf-8',
22
+ '.js': 'text/javascript; charset=utf-8',
23
+ '.mjs': 'text/javascript; charset=utf-8',
24
+ '.cjs': 'text/javascript; charset=utf-8',
25
+ '.map': 'application/json; charset=utf-8',
26
+ '.json': 'application/json; charset=utf-8',
27
+ '.jsonld': 'application/ld+json',
28
+ '.webmanifest': 'application/manifest+json',
29
+ '.xml': 'application/xml',
30
+ '.rss': 'application/rss+xml',
31
+ '.atom': 'application/atom+xml',
32
+ '.txt': 'text/plain; charset=utf-8',
33
+ '.md': 'text/markdown; charset=utf-8',
34
+ '.csv': 'text/csv; charset=utf-8',
35
+ '.ics': 'text/calendar; charset=utf-8',
36
+ '.vtt': 'text/vtt; charset=utf-8',
37
+ '.pdf': 'application/pdf',
38
+ '.wasm': 'application/wasm',
39
+ '.zip': 'application/zip',
40
+ '.gz': 'application/gzip',
41
+ // Images
61
42
  '.png': 'image/png',
43
+ '.apng': 'image/apng',
62
44
  '.jpg': 'image/jpeg',
63
45
  '.jpeg': 'image/jpeg',
64
46
  '.gif': 'image/gif',
65
47
  '.svg': 'image/svg+xml',
66
48
  '.ico': 'image/x-icon',
49
+ '.webp': 'image/webp',
50
+ '.avif': 'image/avif',
51
+ '.bmp': 'image/bmp',
52
+ '.tif': 'image/tiff',
53
+ '.tiff': 'image/tiff',
54
+ // Fonts
67
55
  '.woff': 'font/woff',
68
56
  '.woff2': 'font/woff2',
69
57
  '.ttf': 'font/ttf',
70
58
  '.otf': 'font/otf',
71
- '.webp': 'image/webp',
72
- '.avif': 'image/avif',
73
- '.webm': 'video/webm',
59
+ // Audio and video
60
+ '.mp3': 'audio/mpeg',
61
+ '.wav': 'audio/wav',
62
+ '.ogg': 'audio/ogg',
63
+ '.oga': 'audio/ogg',
64
+ '.m4a': 'audio/mp4',
65
+ '.flac': 'audio/flac',
74
66
  '.mp4': 'video/mp4',
75
- '.txt': 'text/plain',
76
- '.xml': 'application/xml',
77
- '.wasm': 'application/wasm',
67
+ '.webm': 'video/webm',
68
+ '.ogv': 'video/ogg',
69
+ '.mov': 'video/quicktime',
78
70
  };
79
71
 
80
- const publicDir = join(__dirname, '${publicDir}');
72
+ /** What the generated preview server serves, as `buildOutput` knows it. */
73
+ export type PreviewScriptOptions = StaticPreviewScriptOptions | ServerPreviewScriptOptions;
81
74
 
82
- // Port resolution (TIM-842):
83
- // - Default to 3000
84
- // - If PORT env var is set, honor it strictly (fail loudly on conflict)
85
- // - Otherwise auto-bump from 3000 until a free port is found
86
- // Mirrors the dev server behavior so timber dev/preview/production all
87
- // behave the same way around port selection.
88
- const envPort = process.env.PORT ? parseInt(process.env.PORT, 10) : null;
89
- const portIsExplicit = envPort != null && Number.isFinite(envPort) && envPort > 0;
90
- const startPort = portIsExplicit ? envPort : 3000;
91
- const host = process.env.HOST || 'localhost';
75
+ interface PreviewScriptOptionsBase {
76
+ /**
77
+ * `BuildArtifacts.immutableDirs` — served with a one-year immutable
78
+ * `Cache-Control`, every other file with a revalidating one.
79
+ */
80
+ immutableDirs: readonly string[];
81
+ /**
82
+ * The deployment base, normalized (`/` or `/repo/`). Requests arrive in
83
+ * deployed-URL space; files are laid out in route space, so the script
84
+ * strips it before looking anything up.
85
+ */
86
+ base: string;
87
+ }
92
88
 
93
- // Set after listenWithBump() resolves so request handlers can build
94
- // absolute URLs from the actual bound port (which may differ from
95
- // startPort after an auto-bump).
96
- let boundPort = startPort;
89
+ /** A static build: serve the pre-rendered site and nothing else. */
90
+ export interface StaticPreviewScriptOptions extends PreviewScriptOptionsBase {
91
+ output: 'static';
92
+ /** `StaticBuildArtifacts.contentTypes` — extensionless API route outputs. */
93
+ contentTypes: Readonly<Record<string, string>>;
94
+ }
97
95
 
98
- const server = createServer(async (req, res) => {
99
- // Scheme from the socket's TLS state — a hardcoded http:// breaks CSRF
100
- // origin comparison and absolute-URL construction when TLS is terminated
101
- // at this server (TIM-1073; mirrors the dev-server fix in TIM-1067).
102
- // X-Forwarded-Proto is intentionally not consulted here: on a direct
103
- // connection it would be attacker-controlled. The CSRF layer honors it
104
- // separately for reverse-proxy deployments.
105
- const scheme = req.socket?.encrypted ? 'https' : 'http';
106
- const url = new URL(req.url || '/', \`\${scheme}://\${host}:\${boundPort}\`);
96
+ /** A server build: serve `public/`, route everything else to the RSC handler. */
97
+ export interface ServerPreviewScriptOptions extends PreviewScriptOptionsBase {
98
+ output: 'server';
99
+ /** Value for `TIMBER_RUNTIME`, set before the handler evaluates. */
100
+ runtimeName: string;
101
+ /** Import specifier of the RSC handler, relative to the script. */
102
+ rscEntry: string;
103
+ /**
104
+ * Whether this build wrote `_timber-manifest-init.js` beside the script.
105
+ * Recorded from the build, never probed: the Nitro output directory is not
106
+ * cleaned between server builds, so a file on disk can be a stale one.
107
+ */
108
+ hasManifestInit: boolean;
109
+ }
107
110
 
108
- // Try serving static files from the public directory first.
109
- const filePath = join(publicDir, url.pathname);
110
- // Prevent path traversal.
111
- if (filePath.startsWith(publicDir)) {
112
- try {
113
- const fileStat = await stat(filePath);
114
- if (fileStat.isFile()) {
115
- const ext = extname(filePath);
116
- const contentType = MIME_TYPES[ext] || 'application/octet-stream';
117
- const body = await readFile(filePath);
118
- // Hashed assets get immutable cache, others get short cache.
119
- const isImmutable =
120
- url.pathname.startsWith('/assets/') || url.pathname.startsWith('/_timber/fonts/');
121
- const cacheControl = isImmutable
122
- ? 'public, max-age=31536000, immutable'
123
- : 'public, max-age=3600, must-revalidate';
124
- res.writeHead(200, {
125
- 'Content-Type': contentType,
126
- 'Content-Length': body.length,
127
- 'Cache-Control': cacheControl,
128
- });
129
- res.end(body);
130
- return;
131
- }
132
- } catch {
133
- // File not found — fall through to the RSC handler.
134
- }
111
+ /**
112
+ * Generate a standalone preview server script that uses Node's built-in
113
+ * HTTP server. This bypasses Nitro entirely — the Nitro entry.ts imports
114
+ * h3 which isn't available outside a Nitro build. For local preview we
115
+ * just need to serve static files and, in a server build, route requests
116
+ * to the RSC handler.
117
+ *
118
+ * Generated at build time rather than at preview time, so everything it
119
+ * serves comes from the build's artifacts instead of guesses about the
120
+ * directory it runs in.
121
+ *
122
+ * @internal Exported for testing.
123
+ */
124
+ export function generatePreviewScript(options: PreviewScriptOptions): string {
125
+ const immutablePrefixes = options.immutableDirs.map((dir) => `/${dir}/`);
126
+ const contentTypes = options.output === 'static' ? options.contentTypes : {};
127
+
128
+ // A server build loads its handler (after the runtime and manifest are in
129
+ // place); a static build has no handler to load.
130
+ const handlerSetup =
131
+ options.output === 'server'
132
+ ? `// Set runtime before importing the handler.
133
+ process.env.TIMBER_RUNTIME = ${JSON.stringify(options.runtimeName)};
134
+ ${
135
+ options.hasManifestInit
136
+ ? `
137
+ // Load the build manifest before the handler reads it.
138
+ await import('./_timber-manifest-init.js');
139
+ `
140
+ : ''
141
+ }
142
+ // Import the RSC handler (default export is the fetch-like handler).
143
+ const { default: handler, runWithEarlyHintsSender } = await import(${JSON.stringify(options.rscEntry)});
144
+
145
+ // Import compression helper for self-hosted response compression.
146
+ const { compressResponse } = await import('./_compress.mjs');
147
+
148
+ // Web→Node response bridge with backpressure (TIM-1154).
149
+ const { sendNodeResponse } = await import('./_send-response.mjs');
150
+ `
151
+ : '';
152
+
153
+ // What happens when no file matches: a static build answers with its own
154
+ // 404 page, a server build hands the request to the RSC handler.
155
+ const fallback =
156
+ options.output === 'static'
157
+ ? ` if (badPath) {
158
+ res.writeHead(400, { 'Content-Type': 'text/plain' });
159
+ res.end('Bad Request');
160
+ return;
135
161
  }
162
+ const notFound = await findFile('/404.html');
163
+ if (notFound) {
164
+ await sendFile(req, res, notFound, 404, 'text/html', 'public, max-age=0, must-revalidate');
165
+ return;
166
+ }
167
+ res.writeHead(404, { 'Content-Type': 'text/plain' });
168
+ res.end('Not Found');
169
+ `
170
+ : ` await handleDynamic(req, res, url);
171
+ `;
136
172
 
173
+ const dynamicHandler =
174
+ options.output === 'server'
175
+ ? `
176
+ async function handleDynamic(req, res, url) {
137
177
  // Convert Node request to Web Request.
138
178
  const headers = new Headers();
139
179
  for (const [key, value] of Object.entries(req.headers)) {
@@ -187,7 +227,128 @@ const server = createServer(async (req, res) => {
187
227
  }
188
228
  res.end('Internal Server Error');
189
229
  }
190
- });
230
+ }
231
+ `
232
+ : '';
233
+
234
+ return `// Generated by @timber-js/app — standalone preview server.
235
+ // Do not edit — this file is regenerated on each build.
236
+ // Uses Node's built-in HTTP server to serve the build's files${
237
+ options.output === 'server' ? ' and route\n// dynamic requests through the RSC handler' : ''
238
+ }. No Nitro/h3 dependency.
239
+
240
+ import { createServer } from 'node:http';
241
+ import { readFile, stat } from 'node:fs/promises';
242
+ import { join, extname, sep } from 'node:path';
243
+ import { fileURLToPath } from 'node:url';
244
+ import { canonicalize } from './_canonicalize.mjs';
245
+
246
+ const __dirname = fileURLToPath(new URL('.', import.meta.url));
247
+
248
+ ${handlerSetup}
249
+ const MIME_TYPES = ${JSON.stringify(PREVIEW_MIME_TYPES, null, 2)};
250
+
251
+ // Recorded by the build: content-hashed directories, and the Content-Type of
252
+ // each extensionless API route output (a file name cannot say it). Both are
253
+ // decoded route-space paths, matched against the decoded request path.
254
+ const IMMUTABLE_PREFIXES = ${JSON.stringify(immutablePrefixes)};
255
+ const BASE = ${JSON.stringify(options.base)};
256
+ const CONTENT_TYPES = ${JSON.stringify(contentTypes)};
257
+ const SERVE_DIRECTORY_INDEX = ${options.output === 'static'};
258
+
259
+ const publicDir = join(__dirname, 'public');
260
+
261
+ /**
262
+ * The file under publicDir that a decoded URL path names, or null. A static
263
+ * build lays its pages out as <path>/index.html, so a directory serves its
264
+ * index there.
265
+ */
266
+ async function findFile(pathname) {
267
+ const filePath = join(publicDir, pathname);
268
+ // Prevent path traversal (and a sibling like public-other/ passing a bare
269
+ // prefix check).
270
+ if (!filePath.startsWith(publicDir + sep)) return null;
271
+ try {
272
+ const fileStat = await stat(filePath);
273
+ if (fileStat.isFile()) return filePath;
274
+ if (SERVE_DIRECTORY_INDEX && fileStat.isDirectory()) {
275
+ const index = join(filePath, 'index.html');
276
+ if ((await stat(index)).isFile()) return index;
277
+ }
278
+ } catch {
279
+ // Not found.
280
+ }
281
+ return null;
282
+ }
283
+
284
+ /**
285
+ * The route-space path for a request path, or null when the request is
286
+ * outside the deployment base (it names no file of this build).
287
+ */
288
+ function stripBase(pathname) {
289
+ if (BASE === '/') return pathname;
290
+ if (pathname === BASE.slice(0, -1)) return '/';
291
+ if (!pathname.startsWith(BASE)) return null;
292
+ return pathname.slice(BASE.length - 1);
293
+ }
294
+
295
+ async function sendFile(req, res, filePath, status, contentType, cacheControl) {
296
+ const body = await readFile(filePath);
297
+ res.writeHead(status, {
298
+ 'Content-Type': contentType,
299
+ 'Content-Length': body.length,
300
+ 'Cache-Control': cacheControl,
301
+ });
302
+ res.end(req.method === 'HEAD' ? undefined : body);
303
+ }
304
+ ${dynamicHandler}
305
+ // Port resolution (TIM-842):
306
+ // - Default to 3000
307
+ // - If PORT env var is set, honor it strictly (fail loudly on conflict)
308
+ // - Otherwise auto-bump from 3000 until a free port is found
309
+ // Mirrors the dev server behavior so timber dev/preview/production all
310
+ // behave the same way around port selection.
311
+ const envPort = process.env.PORT ? parseInt(process.env.PORT, 10) : null;
312
+ const portIsExplicit = envPort != null && Number.isFinite(envPort) && envPort > 0;
313
+ const startPort = portIsExplicit ? envPort : 3000;
314
+ const host = process.env.HOST || 'localhost';
315
+
316
+ // Set after listenWithBump() resolves so request handlers can build
317
+ // absolute URLs from the actual bound port (which may differ from
318
+ // startPort after an auto-bump).
319
+ let boundPort = startPort;
320
+
321
+ const server = createServer(async (req, res) => {
322
+ // Scheme from the socket's TLS state — a hardcoded http:// breaks CSRF
323
+ // origin comparison and absolute-URL construction when TLS is terminated
324
+ // at this server (TIM-1073; mirrors the dev-server fix in TIM-1067).
325
+ // X-Forwarded-Proto is intentionally not consulted here: on a direct
326
+ // connection it would be attacker-controlled. The CSRF layer honors it
327
+ // separately for reverse-proxy deployments.
328
+ const scheme = req.socket?.encrypted ? 'https' : 'http';
329
+ const url = new URL(req.url || '/', \`\${scheme}://\${host}:\${boundPort}\`);
330
+
331
+ // The runtime's own request-boundary canonicalizer (_canonicalize.mjs,
332
+ // compiled from server/canonicalize.ts): one decode, and the same 400s for
333
+ // encoded separators, null bytes, malformed encoding, and escaping the root
334
+ // (design/13-security.md). The base is stripped from its canonical result,
335
+ // so an encoded spelling of the base is the same path. What remains, in
336
+ // route space, is looked up in public/; null names no file.
337
+ const canonical = canonicalize(url.pathname, false);
338
+ const badPath = !canonical.ok;
339
+ const pathname = canonical.ok ? stripBase(canonical.pathname) : null;
340
+ const filePath = pathname === null ? null : await findFile(pathname);
341
+ if (filePath) {
342
+ const contentType =
343
+ CONTENT_TYPES[pathname] || MIME_TYPES[extname(filePath).toLowerCase()] || 'application/octet-stream';
344
+ // Hashed assets get immutable cache, others get short cache.
345
+ const isImmutable = IMMUTABLE_PREFIXES.some((prefix) => pathname.startsWith(prefix));
346
+ const cacheControl = isImmutable ? ${JSON.stringify(IMMUTABLE_CACHE)} : ${JSON.stringify(STATIC_CACHE)};
347
+ await sendFile(req, res, filePath, 200, contentType, cacheControl);
348
+ return;
349
+ }
350
+
351
+ ${fallback}});
191
352
 
192
353
  function listenWithBump(port, attempt = 0) {
193
354
  return new Promise((resolveListen, rejectListen) => {
@@ -235,31 +396,6 @@ try {
235
396
  `;
236
397
  }
237
398
 
238
- /** Command descriptor for Nitro preview — testable without spawning. */
239
- export interface NitroPreviewCommand {
240
- command: string;
241
- args: string[];
242
- cwd: string;
243
- }
244
-
245
- /** @internal Exported for testing. */
246
- export function generateNitroPreviewCommand(
247
- buildDir: string,
248
- preset: NitroPreset
249
- ): NitroPreviewCommand | null {
250
- if (!LOCALLY_PREVIEWABLE.has(preset)) return null;
251
-
252
- const nitroDir = join(buildDir, 'nitro');
253
- const entryPath = join(nitroDir, 'entry.ts');
254
-
255
- const command = preset === 'bun' ? 'bun' : 'node';
256
- return {
257
- command,
258
- args: [entryPath],
259
- cwd: nitroDir,
260
- };
261
- }
262
-
263
399
  /** Spawn a Nitro preview process and pipe stdio. */
264
400
  export function spawnNitroPreview(command: string, args: string[], cwd: string): Promise<void> {
265
401
  return new Promise<void>((resolve, reject) => {