@timber-js/app 0.2.0-alpha.8 → 0.2.0-alpha.81

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 (571) hide show
  1. package/LICENSE +8 -0
  2. package/dist/_chunks/actions-Dg-ANYHb.js +421 -0
  3. package/dist/_chunks/actions-Dg-ANYHb.js.map +1 -0
  4. package/dist/_chunks/{als-registry-B7DbZ2hS.js → als-registry-HS0LGUl2.js} +1 -1
  5. package/dist/_chunks/als-registry-HS0LGUl2.js.map +1 -0
  6. package/dist/_chunks/chunk-DYhsFzuS.js +33 -0
  7. package/dist/_chunks/{debug-gwlJkDuf.js → debug-ECi_61pb.js} +2 -2
  8. package/dist/_chunks/debug-ECi_61pb.js.map +1 -0
  9. package/dist/_chunks/define-C77ScO0m.js +106 -0
  10. package/dist/_chunks/define-C77ScO0m.js.map +1 -0
  11. package/dist/_chunks/define-CZqDwhSu.js +199 -0
  12. package/dist/_chunks/define-CZqDwhSu.js.map +1 -0
  13. package/dist/_chunks/define-cookie-C2IkoFGN.js +94 -0
  14. package/dist/_chunks/define-cookie-C2IkoFGN.js.map +1 -0
  15. package/dist/_chunks/{format-DviM89f0.js → dev-warnings-DpGRGoDi.js} +5 -44
  16. package/dist/_chunks/dev-warnings-DpGRGoDi.js.map +1 -0
  17. package/dist/_chunks/format-CYBGxKtc.js +14 -0
  18. package/dist/_chunks/format-CYBGxKtc.js.map +1 -0
  19. package/dist/_chunks/{interception-BOoWmLUA.js → interception-Dpn_UfAD.js} +171 -97
  20. package/dist/_chunks/interception-Dpn_UfAD.js.map +1 -0
  21. package/dist/_chunks/merge-search-params-Cm_KIWDX.js +41 -0
  22. package/dist/_chunks/merge-search-params-Cm_KIWDX.js.map +1 -0
  23. package/dist/_chunks/{metadata-routes-Cjmvi3rQ.js → metadata-routes-DS3eKNmf.js} +1 -1
  24. package/dist/_chunks/{metadata-routes-Cjmvi3rQ.js.map → metadata-routes-DS3eKNmf.js.map} +1 -1
  25. package/dist/_chunks/request-context-qMsWgy9C.js +478 -0
  26. package/dist/_chunks/request-context-qMsWgy9C.js.map +1 -0
  27. package/dist/_chunks/schema-bridge-C3xl_vfb.js +86 -0
  28. package/dist/_chunks/schema-bridge-C3xl_vfb.js.map +1 -0
  29. package/dist/_chunks/segment-classify-BDNn6EzD.js +65 -0
  30. package/dist/_chunks/segment-classify-BDNn6EzD.js.map +1 -0
  31. package/dist/_chunks/segment-context-fHFLF1PE.js +34 -0
  32. package/dist/_chunks/segment-context-fHFLF1PE.js.map +1 -0
  33. package/dist/_chunks/{ssr-data-MjmprTmO.js → ssr-data-DzuI0bIV.js} +1 -1
  34. package/dist/_chunks/{ssr-data-MjmprTmO.js.map → ssr-data-DzuI0bIV.js.map} +1 -1
  35. package/dist/_chunks/stale-reload-BX5gL1r-.js +64 -0
  36. package/dist/_chunks/stale-reload-BX5gL1r-.js.map +1 -0
  37. package/dist/_chunks/{tracing-CemImE6h.js → tracing-CCYbKn5n.js} +60 -9
  38. package/dist/_chunks/tracing-CCYbKn5n.js.map +1 -0
  39. package/dist/_chunks/use-params-Br9YSUFV.js +295 -0
  40. package/dist/_chunks/use-params-Br9YSUFV.js.map +1 -0
  41. package/dist/_chunks/{use-query-states-D5KaffOK.js → use-query-states-Lo_s_pw2.js} +4 -4
  42. package/dist/_chunks/use-query-states-Lo_s_pw2.js.map +1 -0
  43. package/dist/adapters/cloudflare-dev.d.ts +109 -0
  44. package/dist/adapters/cloudflare-dev.d.ts.map +1 -0
  45. package/dist/adapters/cloudflare-dev.js +73 -0
  46. package/dist/adapters/cloudflare-dev.js.map +1 -0
  47. package/dist/adapters/cloudflare-kv-cache.d.ts +64 -0
  48. package/dist/adapters/cloudflare-kv-cache.d.ts.map +1 -0
  49. package/dist/adapters/cloudflare-kv-cache.js +95 -0
  50. package/dist/adapters/cloudflare-kv-cache.js.map +1 -0
  51. package/dist/adapters/cloudflare.d.ts +148 -12
  52. package/dist/adapters/cloudflare.d.ts.map +1 -1
  53. package/dist/adapters/cloudflare.js +135 -11
  54. package/dist/adapters/cloudflare.js.map +1 -1
  55. package/dist/adapters/compress-module.d.ts.map +1 -1
  56. package/dist/adapters/nitro.d.ts +17 -1
  57. package/dist/adapters/nitro.d.ts.map +1 -1
  58. package/dist/adapters/nitro.js +56 -13
  59. package/dist/adapters/nitro.js.map +1 -1
  60. package/dist/cache/cache-api.d.ts +24 -0
  61. package/dist/cache/cache-api.d.ts.map +1 -0
  62. package/dist/cache/handler-store.d.ts +31 -0
  63. package/dist/cache/handler-store.d.ts.map +1 -0
  64. package/dist/cache/index.d.ts +23 -7
  65. package/dist/cache/index.d.ts.map +1 -1
  66. package/dist/cache/index.js +142 -80
  67. package/dist/cache/index.js.map +1 -1
  68. package/dist/cache/singleflight.d.ts +18 -1
  69. package/dist/cache/singleflight.d.ts.map +1 -1
  70. package/dist/cache/sizeof.d.ts +22 -0
  71. package/dist/cache/sizeof.d.ts.map +1 -0
  72. package/dist/cache/timber-cache.d.ts +1 -1
  73. package/dist/cache/timber-cache.d.ts.map +1 -1
  74. package/dist/cli.d.ts +6 -1
  75. package/dist/cli.d.ts.map +1 -1
  76. package/dist/cli.js +8 -3
  77. package/dist/cli.js.map +1 -1
  78. package/dist/client/browser-dev.d.ts +27 -1
  79. package/dist/client/browser-dev.d.ts.map +1 -1
  80. package/dist/client/browser-entry/action-dispatch.d.ts +17 -0
  81. package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -0
  82. package/dist/client/browser-entry/hmr.d.ts +21 -0
  83. package/dist/client/browser-entry/hmr.d.ts.map +1 -0
  84. package/dist/client/browser-entry/hydrate.d.ts +46 -0
  85. package/dist/client/browser-entry/hydrate.d.ts.map +1 -0
  86. package/dist/client/browser-entry/index.d.ts +30 -0
  87. package/dist/client/browser-entry/index.d.ts.map +1 -0
  88. package/dist/client/browser-entry/post-hydration.d.ts +26 -0
  89. package/dist/client/browser-entry/post-hydration.d.ts.map +1 -0
  90. package/dist/client/browser-entry/router-init.d.ts +23 -0
  91. package/dist/client/browser-entry/router-init.d.ts.map +1 -0
  92. package/dist/client/browser-entry/rsc-stream.d.ts +24 -0
  93. package/dist/client/browser-entry/rsc-stream.d.ts.map +1 -0
  94. package/dist/client/browser-entry/scroll.d.ts +19 -0
  95. package/dist/client/browser-entry/scroll.d.ts.map +1 -0
  96. package/dist/client/error-boundary.d.ts +12 -5
  97. package/dist/client/error-boundary.d.ts.map +1 -1
  98. package/dist/client/error-boundary.js +10 -4
  99. package/dist/client/error-boundary.js.map +1 -1
  100. package/dist/client/error-reconstituter.d.ts +54 -0
  101. package/dist/client/error-reconstituter.d.ts.map +1 -0
  102. package/dist/client/form.d.ts +3 -3
  103. package/dist/client/form.d.ts.map +1 -1
  104. package/dist/client/history.d.ts +19 -4
  105. package/dist/client/history.d.ts.map +1 -1
  106. package/dist/client/index.d.ts +7 -21
  107. package/dist/client/index.d.ts.map +1 -1
  108. package/dist/client/index.js +210 -1017
  109. package/dist/client/index.js.map +1 -1
  110. package/dist/client/internal.d.ts +18 -0
  111. package/dist/client/internal.d.ts.map +1 -0
  112. package/dist/client/internal.js +890 -0
  113. package/dist/client/internal.js.map +1 -0
  114. package/dist/client/link-pending-store.d.ts +63 -0
  115. package/dist/client/link-pending-store.d.ts.map +1 -0
  116. package/dist/client/link.d.ts +90 -32
  117. package/dist/client/link.d.ts.map +1 -1
  118. package/dist/client/nav-link-store.d.ts +36 -0
  119. package/dist/client/nav-link-store.d.ts.map +1 -0
  120. package/dist/client/navigation-api-types.d.ts +90 -0
  121. package/dist/client/navigation-api-types.d.ts.map +1 -0
  122. package/dist/client/navigation-api.d.ts +115 -0
  123. package/dist/client/navigation-api.d.ts.map +1 -0
  124. package/dist/client/navigation-context.d.ts +13 -2
  125. package/dist/client/navigation-context.d.ts.map +1 -1
  126. package/dist/client/{transition-root.d.ts → navigation-root.d.ts} +42 -8
  127. package/dist/client/navigation-root.d.ts.map +1 -0
  128. package/dist/client/nuqs-adapter.d.ts.map +1 -1
  129. package/dist/client/router-ref.d.ts +1 -1
  130. package/dist/client/router.d.ts +70 -4
  131. package/dist/client/router.d.ts.map +1 -1
  132. package/dist/client/rsc-fetch.d.ts +38 -3
  133. package/dist/client/rsc-fetch.d.ts.map +1 -1
  134. package/dist/client/segment-cache.d.ts +1 -1
  135. package/dist/client/segment-cache.d.ts.map +1 -1
  136. package/dist/client/segment-outlet.d.ts +63 -0
  137. package/dist/client/segment-outlet.d.ts.map +1 -0
  138. package/dist/client/ssr-data.d.ts +13 -4
  139. package/dist/client/ssr-data.d.ts.map +1 -1
  140. package/dist/client/stale-reload.d.ts +15 -0
  141. package/dist/client/stale-reload.d.ts.map +1 -1
  142. package/dist/client/top-loader.d.ts +5 -5
  143. package/dist/client/top-loader.d.ts.map +1 -1
  144. package/dist/client/use-link-status.d.ts +5 -5
  145. package/dist/client/use-link-status.d.ts.map +1 -1
  146. package/dist/client/use-params.d.ts +6 -4
  147. package/dist/client/use-params.d.ts.map +1 -1
  148. package/dist/client/{use-navigation-pending.d.ts → use-pending-navigation.d.ts} +4 -4
  149. package/dist/client/use-pending-navigation.d.ts.map +1 -0
  150. package/dist/client/use-query-states.d.ts +1 -1
  151. package/dist/client/use-query-states.d.ts.map +1 -1
  152. package/dist/client/use-router.d.ts +1 -1
  153. package/dist/codec.d.ts +33 -0
  154. package/dist/codec.d.ts.map +1 -0
  155. package/dist/codec.js +2 -0
  156. package/dist/config-types.d.ts +227 -0
  157. package/dist/config-types.d.ts.map +1 -0
  158. package/dist/content/index.d.ts +1 -10
  159. package/dist/content/index.d.ts.map +1 -1
  160. package/dist/content/index.js +0 -2
  161. package/dist/cookies/define-cookie.d.ts +35 -14
  162. package/dist/cookies/define-cookie.d.ts.map +1 -1
  163. package/dist/cookies/index.js +1 -83
  164. package/dist/fonts/css.d.ts +1 -0
  165. package/dist/fonts/css.d.ts.map +1 -1
  166. package/dist/index.d.ts +45 -192
  167. package/dist/index.d.ts.map +1 -1
  168. package/dist/index.js +12357 -11925
  169. package/dist/index.js.map +1 -1
  170. package/dist/plugin-context.d.ts +107 -0
  171. package/dist/plugin-context.d.ts.map +1 -0
  172. package/dist/plugins/adapter-build.d.ts +1 -1
  173. package/dist/plugins/adapter-build.d.ts.map +1 -1
  174. package/dist/plugins/build-manifest.d.ts +2 -2
  175. package/dist/plugins/build-manifest.d.ts.map +1 -1
  176. package/dist/plugins/build-report.d.ts +3 -3
  177. package/dist/plugins/build-report.d.ts.map +1 -1
  178. package/dist/plugins/client-chunks.d.ts +32 -0
  179. package/dist/plugins/client-chunks.d.ts.map +1 -0
  180. package/dist/plugins/content.d.ts +1 -1
  181. package/dist/plugins/content.d.ts.map +1 -1
  182. package/dist/plugins/dev-browser-logs.d.ts +84 -0
  183. package/dist/plugins/dev-browser-logs.d.ts.map +1 -0
  184. package/dist/plugins/dev-error-overlay.d.ts +26 -1
  185. package/dist/plugins/dev-error-overlay.d.ts.map +1 -1
  186. package/dist/plugins/dev-logs.d.ts +1 -1
  187. package/dist/plugins/dev-logs.d.ts.map +1 -1
  188. package/dist/plugins/dev-server.d.ts +1 -1
  189. package/dist/plugins/dev-server.d.ts.map +1 -1
  190. package/dist/plugins/entries.d.ts +1 -1
  191. package/dist/plugins/entries.d.ts.map +1 -1
  192. package/dist/plugins/fonts.d.ts +19 -5
  193. package/dist/plugins/fonts.d.ts.map +1 -1
  194. package/dist/plugins/mdx.d.ts +1 -1
  195. package/dist/plugins/mdx.d.ts.map +1 -1
  196. package/dist/plugins/routing.d.ts +1 -1
  197. package/dist/plugins/routing.d.ts.map +1 -1
  198. package/dist/plugins/server-bundle.d.ts.map +1 -1
  199. package/dist/plugins/shims.d.ts +6 -5
  200. package/dist/plugins/shims.d.ts.map +1 -1
  201. package/dist/plugins/static-build.d.ts +4 -4
  202. package/dist/plugins/static-build.d.ts.map +1 -1
  203. package/dist/routing/codegen.d.ts +2 -2
  204. package/dist/routing/codegen.d.ts.map +1 -1
  205. package/dist/routing/index.d.ts +2 -0
  206. package/dist/routing/index.d.ts.map +1 -1
  207. package/dist/routing/index.js +3 -2
  208. package/dist/routing/scanner.d.ts.map +1 -1
  209. package/dist/routing/segment-classify.d.ts +46 -0
  210. package/dist/routing/segment-classify.d.ts.map +1 -0
  211. package/dist/routing/status-file-lint.d.ts +2 -1
  212. package/dist/routing/status-file-lint.d.ts.map +1 -1
  213. package/dist/routing/types.d.ts +16 -4
  214. package/dist/routing/types.d.ts.map +1 -1
  215. package/dist/rsc-runtime/rsc.d.ts +1 -1
  216. package/dist/rsc-runtime/rsc.d.ts.map +1 -1
  217. package/dist/rsc-runtime/ssr.d.ts +12 -0
  218. package/dist/rsc-runtime/ssr.d.ts.map +1 -1
  219. package/dist/schema-bridge.d.ts +76 -0
  220. package/dist/schema-bridge.d.ts.map +1 -0
  221. package/dist/search-params/define.d.ts +139 -0
  222. package/dist/search-params/define.d.ts.map +1 -0
  223. package/dist/search-params/index.d.ts +4 -7
  224. package/dist/search-params/index.d.ts.map +1 -1
  225. package/dist/search-params/index.js +32 -441
  226. package/dist/search-params/index.js.map +1 -1
  227. package/dist/search-params/registry.d.ts +2 -2
  228. package/dist/search-params/registry.d.ts.map +1 -1
  229. package/dist/search-params/wrappers.d.ts +53 -0
  230. package/dist/search-params/wrappers.d.ts.map +1 -0
  231. package/dist/segment-params/define.d.ts +78 -0
  232. package/dist/segment-params/define.d.ts.map +1 -0
  233. package/dist/segment-params/index.d.ts +3 -0
  234. package/dist/segment-params/index.d.ts.map +1 -0
  235. package/dist/segment-params/index.js +2 -0
  236. package/dist/server/access-gate.d.ts +4 -0
  237. package/dist/server/access-gate.d.ts.map +1 -1
  238. package/dist/server/action-client.d.ts +25 -6
  239. package/dist/server/action-client.d.ts.map +1 -1
  240. package/dist/server/action-encryption.d.ts +76 -0
  241. package/dist/server/action-encryption.d.ts.map +1 -0
  242. package/dist/server/action-handler.d.ts.map +1 -1
  243. package/dist/server/actions.d.ts +3 -6
  244. package/dist/server/actions.d.ts.map +1 -1
  245. package/dist/server/als-registry.d.ts +32 -4
  246. package/dist/server/als-registry.d.ts.map +1 -1
  247. package/dist/server/build-manifest.d.ts +2 -2
  248. package/dist/server/build-manifest.d.ts.map +1 -1
  249. package/dist/server/debug.d.ts +1 -1
  250. package/dist/server/default-logger.d.ts +22 -0
  251. package/dist/server/default-logger.d.ts.map +1 -0
  252. package/dist/server/deny-page-resolver.d.ts +52 -0
  253. package/dist/server/deny-page-resolver.d.ts.map +1 -0
  254. package/dist/server/deny-renderer.d.ts.map +1 -1
  255. package/dist/server/dev-holding-server.d.ts +52 -0
  256. package/dist/server/dev-holding-server.d.ts.map +1 -0
  257. package/dist/server/dev-warnings.d.ts +1 -21
  258. package/dist/server/dev-warnings.d.ts.map +1 -1
  259. package/dist/server/early-hints.d.ts +13 -5
  260. package/dist/server/early-hints.d.ts.map +1 -1
  261. package/dist/server/error-boundary-wrapper.d.ts +7 -1
  262. package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
  263. package/dist/server/fallback-error.d.ts +4 -3
  264. package/dist/server/fallback-error.d.ts.map +1 -1
  265. package/dist/server/flight-injection-state.d.ts +66 -0
  266. package/dist/server/flight-injection-state.d.ts.map +1 -0
  267. package/dist/server/flight-scripts.d.ts +42 -0
  268. package/dist/server/flight-scripts.d.ts.map +1 -0
  269. package/dist/server/flush.d.ts.map +1 -1
  270. package/dist/server/form-data.d.ts +29 -0
  271. package/dist/server/form-data.d.ts.map +1 -1
  272. package/dist/server/html-injectors.d.ts +51 -11
  273. package/dist/server/html-injectors.d.ts.map +1 -1
  274. package/dist/server/index.d.ts +5 -43
  275. package/dist/server/index.d.ts.map +1 -1
  276. package/dist/server/index.js +37 -2798
  277. package/dist/server/index.js.map +1 -1
  278. package/dist/server/internal.d.ts +46 -0
  279. package/dist/server/internal.d.ts.map +1 -0
  280. package/dist/server/internal.js +2883 -0
  281. package/dist/server/internal.js.map +1 -0
  282. package/dist/server/logger.d.ts +25 -7
  283. package/dist/server/logger.d.ts.map +1 -1
  284. package/dist/server/middleware-runner.d.ts +19 -4
  285. package/dist/server/middleware-runner.d.ts.map +1 -1
  286. package/dist/server/node-stream-transforms.d.ts +113 -0
  287. package/dist/server/node-stream-transforms.d.ts.map +1 -0
  288. package/dist/server/page-deny-boundary.d.ts +31 -0
  289. package/dist/server/page-deny-boundary.d.ts.map +1 -0
  290. package/dist/server/pipeline-interception.d.ts +1 -1
  291. package/dist/server/pipeline-interception.d.ts.map +1 -1
  292. package/dist/server/pipeline-metadata.d.ts +6 -0
  293. package/dist/server/pipeline-metadata.d.ts.map +1 -1
  294. package/dist/server/pipeline.d.ts +42 -10
  295. package/dist/server/pipeline.d.ts.map +1 -1
  296. package/dist/server/primitives.d.ts +69 -18
  297. package/dist/server/primitives.d.ts.map +1 -1
  298. package/dist/server/render-timeout.d.ts +51 -0
  299. package/dist/server/render-timeout.d.ts.map +1 -0
  300. package/dist/server/request-context.d.ts +112 -43
  301. package/dist/server/request-context.d.ts.map +1 -1
  302. package/dist/server/route-element-builder.d.ts +27 -1
  303. package/dist/server/route-element-builder.d.ts.map +1 -1
  304. package/dist/server/route-handler.d.ts.map +1 -1
  305. package/dist/server/route-matcher.d.ts +9 -2
  306. package/dist/server/route-matcher.d.ts.map +1 -1
  307. package/dist/server/rsc-entry/api-handler.d.ts +2 -2
  308. package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
  309. package/dist/server/rsc-entry/error-renderer.d.ts +26 -13
  310. package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
  311. package/dist/server/rsc-entry/helpers.d.ts +48 -5
  312. package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
  313. package/dist/server/rsc-entry/index.d.ts +8 -3
  314. package/dist/server/rsc-entry/index.d.ts.map +1 -1
  315. package/dist/server/rsc-entry/rsc-payload.d.ts +3 -3
  316. package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
  317. package/dist/server/rsc-entry/rsc-stream.d.ts +4 -1
  318. package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
  319. package/dist/server/rsc-entry/ssr-bridge.d.ts +1 -1
  320. package/dist/server/rsc-entry/ssr-bridge.d.ts.map +1 -1
  321. package/dist/server/rsc-entry/ssr-renderer.d.ts +19 -4
  322. package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
  323. package/dist/server/safe-load.d.ts +46 -0
  324. package/dist/server/safe-load.d.ts.map +1 -0
  325. package/dist/server/sitemap-generator.d.ts +129 -0
  326. package/dist/server/sitemap-generator.d.ts.map +1 -0
  327. package/dist/server/sitemap-handler.d.ts +22 -0
  328. package/dist/server/sitemap-handler.d.ts.map +1 -0
  329. package/dist/server/slot-resolver.d.ts +1 -1
  330. package/dist/server/slot-resolver.d.ts.map +1 -1
  331. package/dist/server/ssr-entry.d.ts +22 -0
  332. package/dist/server/ssr-entry.d.ts.map +1 -1
  333. package/dist/server/ssr-render.d.ts +39 -21
  334. package/dist/server/ssr-render.d.ts.map +1 -1
  335. package/dist/server/ssr-wrappers.d.ts +50 -0
  336. package/dist/server/ssr-wrappers.d.ts.map +1 -0
  337. package/dist/server/status-code-resolver.d.ts +1 -1
  338. package/dist/server/status-code-resolver.d.ts.map +1 -1
  339. package/dist/server/stream-utils.d.ts +36 -0
  340. package/dist/server/stream-utils.d.ts.map +1 -0
  341. package/dist/server/tracing.d.ts +4 -4
  342. package/dist/server/tracing.d.ts.map +1 -1
  343. package/dist/server/tree-builder.d.ts +22 -19
  344. package/dist/server/tree-builder.d.ts.map +1 -1
  345. package/dist/server/types.d.ts +1 -4
  346. package/dist/server/types.d.ts.map +1 -1
  347. package/dist/server/version-skew.d.ts +61 -0
  348. package/dist/server/version-skew.d.ts.map +1 -0
  349. package/dist/shared/merge-search-params.d.ts +22 -0
  350. package/dist/shared/merge-search-params.d.ts.map +1 -0
  351. package/dist/shims/font-google.d.ts +1 -1
  352. package/dist/shims/font-google.d.ts.map +1 -1
  353. package/dist/shims/font-google.js +42 -0
  354. package/dist/shims/font-google.js.map +1 -0
  355. package/dist/shims/font-local.d.ts +26 -0
  356. package/dist/shims/font-local.d.ts.map +1 -0
  357. package/dist/shims/font-local.js +20 -0
  358. package/dist/shims/font-local.js.map +1 -0
  359. package/dist/shims/headers.d.ts +2 -1
  360. package/dist/shims/headers.d.ts.map +1 -1
  361. package/dist/shims/navigation-client.d.ts +1 -1
  362. package/dist/shims/navigation-client.d.ts.map +1 -1
  363. package/dist/shims/navigation.d.ts +3 -2
  364. package/dist/shims/navigation.d.ts.map +1 -1
  365. package/dist/utils/directive-parser.d.ts +5 -2
  366. package/dist/utils/directive-parser.d.ts.map +1 -1
  367. package/dist/utils/state-machine.d.ts +80 -0
  368. package/dist/utils/state-machine.d.ts.map +1 -0
  369. package/package.json +56 -22
  370. package/src/adapters/cloudflare-dev.ts +177 -0
  371. package/src/adapters/cloudflare-kv-cache.ts +142 -0
  372. package/src/adapters/cloudflare.ts +342 -28
  373. package/src/adapters/compress-module.ts +24 -4
  374. package/src/adapters/nitro.ts +52 -8
  375. package/src/adapters/wrangler.d.ts +7 -0
  376. package/src/cache/cache-api.ts +38 -0
  377. package/src/cache/handler-store.ts +68 -0
  378. package/src/cache/index.ts +81 -18
  379. package/src/cache/singleflight.ts +62 -4
  380. package/src/cache/sizeof.ts +31 -0
  381. package/src/cache/timber-cache.ts +24 -20
  382. package/src/cli.ts +16 -6
  383. package/src/client/browser-dev.ts +128 -1
  384. package/src/client/browser-entry/action-dispatch.ts +116 -0
  385. package/src/client/browser-entry/hmr.ts +81 -0
  386. package/src/client/browser-entry/hydrate.ts +145 -0
  387. package/src/client/browser-entry/index.ts +138 -0
  388. package/src/client/browser-entry/post-hydration.ts +119 -0
  389. package/src/client/browser-entry/router-init.ts +193 -0
  390. package/src/client/browser-entry/rsc-stream.ts +157 -0
  391. package/src/client/browser-entry/scroll.ts +27 -0
  392. package/src/client/error-boundary.tsx +48 -16
  393. package/src/client/error-reconstituter.tsx +65 -0
  394. package/src/client/form.tsx +9 -7
  395. package/src/client/history.ts +26 -4
  396. package/src/client/index.ts +19 -38
  397. package/src/client/internal.ts +57 -0
  398. package/src/client/link-pending-store.ts +111 -0
  399. package/src/client/link.tsx +329 -97
  400. package/src/client/nav-link-store.ts +47 -0
  401. package/src/client/navigation-api-types.ts +112 -0
  402. package/src/client/navigation-api.ts +332 -0
  403. package/src/client/navigation-context.ts +31 -6
  404. package/src/client/navigation-root.tsx +342 -0
  405. package/src/client/nuqs-adapter.tsx +16 -3
  406. package/src/client/router-ref.ts +1 -1
  407. package/src/client/router.ts +299 -72
  408. package/src/client/rsc-fetch.ts +97 -8
  409. package/src/client/segment-cache.ts +1 -1
  410. package/src/client/segment-outlet.tsx +86 -0
  411. package/src/client/ssr-data.ts +13 -5
  412. package/src/client/stale-reload.ts +72 -3
  413. package/src/client/top-loader.tsx +16 -8
  414. package/src/client/use-link-status.ts +7 -7
  415. package/src/client/use-params.ts +7 -5
  416. package/src/client/{use-navigation-pending.ts → use-pending-navigation.ts} +6 -6
  417. package/src/client/use-query-states.ts +3 -3
  418. package/src/client/use-router.ts +1 -1
  419. package/src/codec.ts +49 -0
  420. package/src/config-types.ts +225 -0
  421. package/src/content/index.ts +5 -13
  422. package/src/cookies/define-cookie.ts +78 -25
  423. package/src/cookies/index.ts +8 -0
  424. package/src/fonts/css.ts +2 -1
  425. package/src/index.ts +295 -354
  426. package/src/plugin-context.ts +240 -0
  427. package/src/plugins/adapter-build.ts +9 -3
  428. package/src/plugins/build-manifest.ts +13 -2
  429. package/src/plugins/build-report.ts +3 -3
  430. package/src/plugins/client-chunks.ts +65 -0
  431. package/src/plugins/content.ts +1 -1
  432. package/src/plugins/dev-browser-logs.ts +288 -0
  433. package/src/plugins/dev-error-overlay.ts +70 -1
  434. package/src/plugins/dev-logs.ts +1 -1
  435. package/src/plugins/dev-server.ts +70 -9
  436. package/src/plugins/entries.ts +71 -10
  437. package/src/plugins/fonts.ts +168 -61
  438. package/src/plugins/mdx.ts +1 -1
  439. package/src/plugins/routing.ts +57 -17
  440. package/src/plugins/server-action-exports.ts +1 -1
  441. package/src/plugins/server-bundle.ts +32 -1
  442. package/src/plugins/shims.ts +135 -35
  443. package/src/plugins/static-build.ts +17 -11
  444. package/src/routing/codegen.ts +165 -105
  445. package/src/routing/index.ts +2 -0
  446. package/src/routing/scanner.ts +93 -23
  447. package/src/routing/segment-classify.ts +89 -0
  448. package/src/routing/status-file-lint.ts +3 -2
  449. package/src/routing/types.ts +17 -4
  450. package/src/rsc-runtime/rsc.ts +2 -0
  451. package/src/rsc-runtime/ssr.ts +50 -0
  452. package/src/rsc-runtime/vendor-types.d.ts +7 -0
  453. package/src/{search-params/codecs.ts → schema-bridge.ts} +57 -20
  454. package/src/search-params/define.ts +482 -0
  455. package/src/search-params/index.ts +14 -20
  456. package/src/search-params/registry.ts +2 -2
  457. package/src/search-params/wrappers.ts +85 -0
  458. package/src/segment-params/define.ts +279 -0
  459. package/src/segment-params/index.ts +9 -0
  460. package/src/server/access-gate.tsx +70 -29
  461. package/src/server/action-client.ts +46 -11
  462. package/src/server/action-encryption.ts +144 -0
  463. package/src/server/action-handler.ts +21 -4
  464. package/src/server/actions.ts +10 -9
  465. package/src/server/als-registry.ts +34 -6
  466. package/src/server/build-manifest.ts +10 -4
  467. package/src/server/compress.ts +25 -7
  468. package/src/server/debug.ts +1 -1
  469. package/src/server/default-logger.ts +99 -0
  470. package/src/server/deny-page-resolver.ts +154 -0
  471. package/src/server/deny-renderer.ts +24 -38
  472. package/src/server/dev-holding-server.ts +185 -0
  473. package/src/server/dev-warnings.ts +4 -49
  474. package/src/server/early-hints.ts +36 -15
  475. package/src/server/error-boundary-wrapper.ts +74 -22
  476. package/src/server/fallback-error.ts +31 -15
  477. package/src/server/flight-injection-state.ts +113 -0
  478. package/src/server/flight-scripts.ts +62 -0
  479. package/src/server/flush.ts +2 -1
  480. package/src/server/form-data.ts +76 -0
  481. package/src/server/html-injectors.ts +280 -120
  482. package/src/server/index.ts +25 -177
  483. package/src/server/internal.ts +169 -0
  484. package/src/server/logger.ts +44 -36
  485. package/src/server/middleware-runner.ts +31 -4
  486. package/src/server/node-stream-transforms.ts +509 -0
  487. package/src/server/page-deny-boundary.tsx +56 -0
  488. package/src/server/pipeline-interception.ts +17 -16
  489. package/src/server/pipeline-metadata.ts +13 -0
  490. package/src/server/pipeline.ts +227 -62
  491. package/src/server/primitives.ts +111 -28
  492. package/src/server/render-timeout.ts +108 -0
  493. package/src/server/request-context.ts +293 -132
  494. package/src/server/route-element-builder.ts +283 -191
  495. package/src/server/route-handler.ts +24 -4
  496. package/src/server/route-matcher.ts +24 -20
  497. package/src/server/rsc-entry/api-handler.ts +15 -16
  498. package/src/server/rsc-entry/error-renderer.ts +300 -89
  499. package/src/server/rsc-entry/helpers.ts +134 -5
  500. package/src/server/rsc-entry/index.ts +200 -112
  501. package/src/server/rsc-entry/rsc-payload.ts +65 -18
  502. package/src/server/rsc-entry/rsc-stream.ts +65 -13
  503. package/src/server/rsc-entry/ssr-bridge.ts +14 -5
  504. package/src/server/rsc-entry/ssr-renderer.ts +168 -38
  505. package/src/server/safe-load.ts +60 -0
  506. package/src/server/sitemap-generator.ts +338 -0
  507. package/src/server/sitemap-handler.ts +126 -0
  508. package/src/server/slot-resolver.ts +244 -229
  509. package/src/server/ssr-entry.ts +211 -32
  510. package/src/server/ssr-render.ts +289 -67
  511. package/src/server/ssr-wrappers.tsx +139 -0
  512. package/src/server/status-code-resolver.ts +1 -1
  513. package/src/server/stream-utils.ts +213 -0
  514. package/src/server/tracing.ts +20 -9
  515. package/src/server/tree-builder.ts +92 -58
  516. package/src/server/types.ts +3 -6
  517. package/src/server/version-skew.ts +104 -0
  518. package/src/shared/merge-search-params.ts +55 -0
  519. package/src/shims/font-google.ts +1 -1
  520. package/src/shims/font-local.ts +34 -0
  521. package/src/shims/headers.ts +5 -1
  522. package/src/shims/navigation-client.ts +1 -1
  523. package/src/shims/navigation.ts +7 -2
  524. package/src/utils/directive-parser.ts +5 -2
  525. package/src/utils/state-machine.ts +111 -0
  526. package/dist/_chunks/als-registry-B7DbZ2hS.js.map +0 -1
  527. package/dist/_chunks/debug-gwlJkDuf.js.map +0 -1
  528. package/dist/_chunks/format-DviM89f0.js.map +0 -1
  529. package/dist/_chunks/interception-BOoWmLUA.js.map +0 -1
  530. package/dist/_chunks/request-context-DIkVh_jG.js +0 -330
  531. package/dist/_chunks/request-context-DIkVh_jG.js.map +0 -1
  532. package/dist/_chunks/tracing-CemImE6h.js.map +0 -1
  533. package/dist/_chunks/use-cookie-DX-l1_5E.js +0 -91
  534. package/dist/_chunks/use-cookie-DX-l1_5E.js.map +0 -1
  535. package/dist/_chunks/use-query-states-D5KaffOK.js.map +0 -1
  536. package/dist/cache/register-cached-function.d.ts +0 -17
  537. package/dist/cache/register-cached-function.d.ts.map +0 -1
  538. package/dist/client/browser-entry.d.ts +0 -21
  539. package/dist/client/browser-entry.d.ts.map +0 -1
  540. package/dist/client/link-status-provider.d.ts +0 -11
  541. package/dist/client/link-status-provider.d.ts.map +0 -1
  542. package/dist/client/transition-root.d.ts.map +0 -1
  543. package/dist/client/use-navigation-pending.d.ts.map +0 -1
  544. package/dist/cookies/index.js.map +0 -1
  545. package/dist/plugins/cache-transform.d.ts +0 -36
  546. package/dist/plugins/cache-transform.d.ts.map +0 -1
  547. package/dist/plugins/dynamic-transform.d.ts +0 -72
  548. package/dist/plugins/dynamic-transform.d.ts.map +0 -1
  549. package/dist/search-params/analyze.d.ts +0 -54
  550. package/dist/search-params/analyze.d.ts.map +0 -1
  551. package/dist/search-params/builtin-codecs.d.ts +0 -105
  552. package/dist/search-params/builtin-codecs.d.ts.map +0 -1
  553. package/dist/search-params/codecs.d.ts +0 -53
  554. package/dist/search-params/codecs.d.ts.map +0 -1
  555. package/dist/search-params/create.d.ts +0 -106
  556. package/dist/search-params/create.d.ts.map +0 -1
  557. package/dist/server/prerender.d.ts +0 -77
  558. package/dist/server/prerender.d.ts.map +0 -1
  559. package/dist/server/response-cache.d.ts +0 -54
  560. package/dist/server/response-cache.d.ts.map +0 -1
  561. package/src/cache/register-cached-function.ts +0 -103
  562. package/src/client/browser-entry.ts +0 -678
  563. package/src/client/link-status-provider.tsx +0 -30
  564. package/src/client/transition-root.tsx +0 -166
  565. package/src/plugins/cache-transform.ts +0 -199
  566. package/src/plugins/dynamic-transform.ts +0 -161
  567. package/src/search-params/analyze.ts +0 -192
  568. package/src/search-params/builtin-codecs.ts +0 -228
  569. package/src/search-params/create.ts +0 -321
  570. package/src/server/prerender.ts +0 -139
  571. package/src/server/response-cache.ts +0 -410
@@ -31,8 +31,27 @@ function generateHeadersFile(): string {
31
31
  // can access KV, D1, DO, R2, Queues, etc. via getCloudflareBindings().
32
32
  // No global fallback — if called outside a request, it throws.
33
33
  // See design/11-platform.md §"Platform Target" and design/25-production-deployments.md.
34
-
35
- const bindingsAls = new AsyncLocalStorage<Record<string, unknown>>();
34
+ //
35
+ // The ALS is stored on globalThis via Symbol.for so it survives Vite's
36
+ // module instance split in dev mode. The Vite host process (where
37
+ // cloudflareDevBindings → runWithBindings runs) and the RSC module runner
38
+ // (where getCloudflareBindings runs) load separate instances of this file,
39
+ // each with their own module-level variables. globalThis + Symbol.for
40
+ // ensures both share the same ALS — same pattern React uses for
41
+ // Symbol.for('react.element').
42
+
43
+ const BINDINGS_ALS_KEY = Symbol.for('timber:cf-bindings-als');
44
+
45
+ function getBindingsAls(): AsyncLocalStorage<Record<string, unknown>> {
46
+ let als = (globalThis as any)[BINDINGS_ALS_KEY] as
47
+ | AsyncLocalStorage<Record<string, unknown>>
48
+ | undefined;
49
+ if (!als) {
50
+ als = new AsyncLocalStorage<Record<string, unknown>>();
51
+ (globalThis as any)[BINDINGS_ALS_KEY] = als;
52
+ }
53
+ return als;
54
+ }
36
55
 
37
56
  /**
38
57
  * Get Cloudflare Worker bindings for the current request.
@@ -55,10 +74,8 @@ const bindingsAls = new AsyncLocalStorage<Record<string, unknown>>();
55
74
  * }
56
75
  * ```
57
76
  */
58
- export function getCloudflareBindings<
59
- T extends Record<string, unknown> = Record<string, unknown>,
60
- >(): T {
61
- const env = bindingsAls.getStore();
77
+ export function getCloudflareBindings<T = Record<string, unknown>>(): T {
78
+ const env = getBindingsAls().getStore();
62
79
  if (!env) {
63
80
  throw new Error(
64
81
  'getCloudflareBindings() called outside a Cloudflare Workers request context. ' +
@@ -74,7 +91,85 @@ export function getCloudflareBindings<
74
91
  * @internal Used by wrapWithExecutionContext.
75
92
  */
76
93
  export function runWithBindings<T>(env: Record<string, unknown>, fn: () => T): T {
77
- return bindingsAls.run(env, fn);
94
+ return getBindingsAls().run(env, fn);
95
+ }
96
+
97
+ // ─── Binding configuration types ──────────────────────────────────────────────
98
+ // Declarative binding config that maps to wrangler.jsonc binding sections.
99
+ // See design/35-cloudflare-primitives.md §"Binding Declarations in Adapter Config".
100
+
101
+ /** KV namespace binding. `id` defaults to `''` (filled in by wrangler or dashboard). */
102
+ export interface CloudflareKVBinding {
103
+ name: string;
104
+ id?: string;
105
+ }
106
+
107
+ /** D1 database binding. `database_id` is required (from Cloudflare dashboard). */
108
+ export interface CloudflareD1Binding {
109
+ name: string;
110
+ database_id: string;
111
+ }
112
+
113
+ /** R2 bucket binding. `bucket_name` must match the bucket created in Cloudflare. */
114
+ export interface CloudflareR2Binding {
115
+ name: string;
116
+ bucket_name: string;
117
+ }
118
+
119
+ /** Queue producer binding. `queue` is the queue name in Cloudflare. */
120
+ export interface CloudflareQueueProducer {
121
+ name: string;
122
+ queue: string;
123
+ }
124
+
125
+ /** Queue consumer declaration. Attached to the worker, not a binding name. */
126
+ export interface CloudflareQueueConsumer {
127
+ queue: string;
128
+ max_batch_size?: number;
129
+ max_retries?: number;
130
+ dead_letter_queue?: string;
131
+ }
132
+
133
+ /** Durable Object binding. `script_name` is for external DO references. */
134
+ export interface CloudflareDurableObjectBinding {
135
+ name: string;
136
+ class_name: string;
137
+ script_name?: string;
138
+ }
139
+
140
+ /**
141
+ * Declarative Cloudflare bindings configuration.
142
+ *
143
+ * These are converted to the appropriate wrangler.jsonc sections
144
+ * (`kv_namespaces`, `d1_databases`, `r2_buckets`, `queues`, `durable_objects`).
145
+ * The `wrangler` escape hatch overrides any generated binding sections
146
+ * if there's a conflict.
147
+ *
148
+ * @example
149
+ * ```ts
150
+ * cloudflare({
151
+ * bindings: {
152
+ * kv: [{ name: 'TIMBER_CACHE' }],
153
+ * d1: [{ name: 'MY_DB', database_id: 'xxxx' }],
154
+ * r2: [{ name: 'MY_BUCKET', bucket_name: 'my-bucket' }],
155
+ * queues: {
156
+ * producers: [{ name: 'EMAIL_QUEUE', queue: 'email-queue' }],
157
+ * consumers: [{ queue: 'email-queue', max_batch_size: 10 }],
158
+ * },
159
+ * durableObjects: [{ name: 'MY_DO', class_name: 'MyDurableObject' }],
160
+ * },
161
+ * })
162
+ * ```
163
+ */
164
+ export interface CloudflareBindings {
165
+ kv?: CloudflareKVBinding[];
166
+ d1?: CloudflareD1Binding[];
167
+ r2?: CloudflareR2Binding[];
168
+ queues?: {
169
+ producers?: CloudflareQueueProducer[];
170
+ consumers?: CloudflareQueueConsumer[];
171
+ };
172
+ durableObjects?: CloudflareDurableObjectBinding[];
78
173
  }
79
174
 
80
175
  /** Options for the Cloudflare Workers adapter. */
@@ -91,11 +186,42 @@ export interface CloudflareAdapterOptions {
91
186
  */
92
187
  compatibilityFlags?: string[];
93
188
 
189
+ /**
190
+ * Declarative Cloudflare bindings. Generates the appropriate
191
+ * `kv_namespaces`, `d1_databases`, `r2_buckets`, `queues`, and
192
+ * `durable_objects` sections in wrangler.jsonc.
193
+ *
194
+ * If both `bindings` and `wrangler` specify the same section,
195
+ * `wrangler` wins (it's the escape hatch).
196
+ */
197
+ bindings?: CloudflareBindings;
198
+
94
199
  /**
95
200
  * Custom wrangler.jsonc fields to merge.
96
- * Overrides generated values.
201
+ * Overrides generated values (including bindings-generated sections).
97
202
  */
98
203
  wrangler?: Record<string, unknown>;
204
+
205
+ /**
206
+ * Path to a module that exports additional Worker handlers (queue, scheduled, email, etc.).
207
+ * The module is imported in the generated `_worker.js` and its named exports are
208
+ * spread into the default export alongside `fetch`.
209
+ *
210
+ * The module receives `(batch/event, env, ctx)` — standard Cloudflare handler signatures.
211
+ * It does NOT have access to timber's request pipeline (no ALS, no getCloudflareBindings).
212
+ * Use `env` directly for bindings.
213
+ *
214
+ * @example
215
+ * ```ts
216
+ * // timber.config.ts
217
+ * adapter: cloudflare({ workerHandlers: './src/worker-handlers.ts' })
218
+ *
219
+ * // src/worker-handlers.ts
220
+ * export async function queue(batch, env) { ... }
221
+ * export async function scheduled(controller, env, ctx) { ... }
222
+ * ```
223
+ */
224
+ workerHandlers?: string;
99
225
  }
100
226
 
101
227
  /**
@@ -151,9 +277,35 @@ export function cloudflare(options: CloudflareAdapterOptions = {}): TimberPlatfo
151
277
  await writeFile(join(outDir, '_timber-manifest-init.js'), config.manifestInit);
152
278
  }
153
279
 
280
+ // Compile optional worker handlers (queue, scheduled, etc.)
281
+ // Uses Vite's build API to bundle the TypeScript source into ESM.
282
+ let hasWorkerHandlers = false;
283
+ if (options.workerHandlers) {
284
+ const handlersEntry = join(process.cwd(), options.workerHandlers);
285
+ const { build: viteBuild } = await import('vite');
286
+ await viteBuild({
287
+ configFile: false,
288
+ logLevel: 'info',
289
+ build: {
290
+ lib: {
291
+ entry: handlersEntry,
292
+ formats: ['es'],
293
+ fileName: () => '_worker-handlers.js',
294
+ },
295
+ outDir,
296
+ emptyOutDir: false,
297
+ minify: false,
298
+ rollupOptions: {
299
+ external: [/^node:/],
300
+ },
301
+ },
302
+ });
303
+ hasWorkerHandlers = true;
304
+ }
305
+
154
306
  // Generate the Workers entry point
155
307
  const hasManifestInit = !!config.manifestInit;
156
- const workerEntry = generateWorkerEntry(outDir, outDir, hasManifestInit);
308
+ const workerEntry = generateWorkerEntry(outDir, outDir, hasManifestInit, hasWorkerHandlers);
157
309
  await writeFile(join(outDir, '_worker.js'), workerEntry);
158
310
 
159
311
  // Generate wrangler.jsonc
@@ -184,12 +336,12 @@ export function cloudflare(options: CloudflareAdapterOptions = {}): TimberPlatfo
184
336
  export function wrapWithExecutionContext(
185
337
  adapter: TimberPlatformAdapter,
186
338
  handler: (req: Request) => Promise<Response>
187
- ): ExportedHandler<Record<string, unknown>> {
339
+ ): CfExportedHandler<Record<string, unknown>> {
188
340
  return {
189
341
  async fetch(
190
342
  request: Request,
191
343
  env: Record<string, unknown>,
192
- ctx: ExecutionContext
344
+ ctx: CfExecutionContext
193
345
  ): Promise<Response> {
194
346
  // Bind the adapter's waitUntil to the Workers execution context
195
347
  const originalWaitUntil = adapter.waitUntil;
@@ -214,7 +366,8 @@ export function wrapWithExecutionContext(
214
366
  export function generateWorkerEntry(
215
367
  buildDir: string,
216
368
  outDir: string,
217
- hasManifestInit = false
369
+ hasManifestInit = false,
370
+ hasWorkerHandlers = false
218
371
  ): string {
219
372
  // The RSC entry is the main request handler — it exports the fetch handler as default.
220
373
  // The Vite RSC plugin outputs it to rsc/index.js.
@@ -229,20 +382,171 @@ export function generateWorkerEntry(
229
382
  // ESM guarantees imports are evaluated in order.
230
383
  const manifestImport = hasManifestInit ? "import './_timber-manifest-init.js'\n" : '';
231
384
 
385
+ // Optional additional Worker handlers (queue, scheduled, email, etc.)
386
+ // Compiled by buildOutput via Vite's build API into _worker-handlers.js.
387
+ // The module's named exports are spread into the default export alongside fetch.
388
+ const handlersImport = hasWorkerHandlers
389
+ ? "import * as workerHandlers from './_worker-handlers.js'\n"
390
+ : '';
391
+ const handlersSpread = hasWorkerHandlers ? ' ...workerHandlers,\n' : '';
392
+
232
393
  return `// Generated by @timber-js/app/adapters/cloudflare
233
394
  // Do not edit — this file is regenerated on each build.
234
395
 
396
+ import { AsyncLocalStorage } from 'node:async_hooks'
235
397
  ${manifestImport}import handler from '${rscEntryRelative}'
236
-
398
+ ${handlersImport}
237
399
  // Set TIMBER_RUNTIME for instrumentation.ts conditional SDK initialization.
238
400
  // See design/25-production-deployments.md §"TIMBER_RUNTIME".
239
401
  globalThis.process ??= { env: {} }
240
402
  process.env.TIMBER_RUNTIME = 'cloudflare'
241
403
 
242
- export default { fetch: handler }
404
+ // Bind Cloudflare env to ALS so getCloudflareBindings() works at runtime.
405
+ // Uses the same Symbol.for key as getCloudflareBindings() reads from.
406
+ const ALS_KEY = Symbol.for('timber:cf-bindings-als')
407
+ let bindingsAls = globalThis[ALS_KEY]
408
+ if (!bindingsAls) {
409
+ bindingsAls = new AsyncLocalStorage()
410
+ globalThis[ALS_KEY] = bindingsAls
411
+ }
412
+
413
+ export default {
414
+ ${handlersSpread} async fetch(request, env, ctx) {
415
+ return bindingsAls.run(env, () => handler(request))
416
+ }
417
+ }
243
418
  `;
244
419
  }
245
420
 
421
+ /** Wrangler binding sections generated from `CloudflareBindings`. */
422
+ export interface WranglerBindingsConfig {
423
+ kv_namespaces?: Array<{ binding: string; id: string }>;
424
+ d1_databases?: Array<{ binding: string; database_id: string }>;
425
+ r2_buckets?: Array<{ binding: string; bucket_name: string }>;
426
+ queues?: {
427
+ producers?: Array<{ binding: string; queue: string }>;
428
+ consumers?: Array<Record<string, unknown>>;
429
+ };
430
+ durable_objects?: {
431
+ bindings: Array<Record<string, string>>;
432
+ };
433
+ }
434
+
435
+ /**
436
+ * Convert declarative `CloudflareBindings` into wrangler.jsonc binding sections.
437
+ *
438
+ * Maps:
439
+ * - `kv` → `kv_namespaces`
440
+ * - `d1` → `d1_databases`
441
+ * - `r2` → `r2_buckets`
442
+ * - `queues` → `queues` (producers + consumers)
443
+ * - `durableObjects` → `durable_objects`
444
+ *
445
+ * Empty arrays are omitted from the output.
446
+ *
447
+ * @internal Exported for testing.
448
+ */
449
+ export function generateBindingsConfig(
450
+ bindings: CloudflareBindings | undefined
451
+ ): WranglerBindingsConfig {
452
+ if (!bindings) return {};
453
+
454
+ const result: WranglerBindingsConfig = {};
455
+
456
+ // KV namespaces
457
+ if (bindings.kv && bindings.kv.length > 0) {
458
+ result.kv_namespaces = bindings.kv.map((kv) => ({
459
+ binding: kv.name,
460
+ id: kv.id ?? '',
461
+ }));
462
+ }
463
+
464
+ // D1 databases
465
+ if (bindings.d1 && bindings.d1.length > 0) {
466
+ result.d1_databases = bindings.d1.map((d1) => ({
467
+ binding: d1.name,
468
+ database_id: d1.database_id,
469
+ }));
470
+ }
471
+
472
+ // R2 buckets
473
+ if (bindings.r2 && bindings.r2.length > 0) {
474
+ result.r2_buckets = bindings.r2.map((r2) => ({
475
+ binding: r2.name,
476
+ bucket_name: r2.bucket_name,
477
+ }));
478
+ }
479
+
480
+ // Queues (producers and/or consumers)
481
+ if (bindings.queues) {
482
+ const queues: Record<string, unknown> = {};
483
+ if (bindings.queues.producers && bindings.queues.producers.length > 0) {
484
+ queues.producers = bindings.queues.producers.map((p) => ({
485
+ binding: p.name,
486
+ queue: p.queue,
487
+ }));
488
+ }
489
+ if (bindings.queues.consumers && bindings.queues.consumers.length > 0) {
490
+ queues.consumers = bindings.queues.consumers.map((c) => {
491
+ const consumer: Record<string, unknown> = { queue: c.queue };
492
+ if (c.max_batch_size !== undefined) consumer.max_batch_size = c.max_batch_size;
493
+ if (c.max_retries !== undefined) consumer.max_retries = c.max_retries;
494
+ if (c.dead_letter_queue !== undefined) consumer.dead_letter_queue = c.dead_letter_queue;
495
+ return consumer;
496
+ });
497
+ }
498
+ if (Object.keys(queues).length > 0) {
499
+ result.queues = queues;
500
+ }
501
+ }
502
+
503
+ // Durable Objects
504
+ if (bindings.durableObjects && bindings.durableObjects.length > 0) {
505
+ result.durable_objects = {
506
+ bindings: bindings.durableObjects.map((dobj) => {
507
+ const entry: Record<string, string> = {
508
+ name: dobj.name,
509
+ class_name: dobj.class_name,
510
+ };
511
+ if (dobj.script_name) entry.script_name = dobj.script_name;
512
+ return entry;
513
+ }),
514
+ };
515
+ }
516
+
517
+ return result;
518
+ }
519
+
520
+ /**
521
+ * One-level deep merge: for each key in `override`, if both the base and
522
+ * override values are plain objects (not arrays, not null), merge their
523
+ * keys with override winning on conflicts. Everything else (primitives,
524
+ * arrays, null) is replaced outright — matching the intuitive behavior
525
+ * where `kv_namespaces: [...]` replaces fully but
526
+ * `durable_objects: { migrations }` merges with generated `bindings`.
527
+ */
528
+ function shallowDeepMerge(
529
+ base: Record<string, unknown>,
530
+ override: Record<string, unknown>
531
+ ): Record<string, unknown> {
532
+ const result = { ...base };
533
+ for (const key of Object.keys(override)) {
534
+ const baseVal = result[key];
535
+ const overVal = override[key];
536
+ if (isPlainObject(baseVal) && isPlainObject(overVal)) {
537
+ result[key] = { ...baseVal, ...overVal };
538
+ } else {
539
+ result[key] = overVal;
540
+ }
541
+ }
542
+ return result;
543
+ }
544
+
545
+ /** True for `{}` literals — false for arrays, null, Date, etc. */
546
+ function isPlainObject(val: unknown): val is Record<string, unknown> {
547
+ return val !== null && typeof val === 'object' && !Array.isArray(val);
548
+ }
549
+
246
550
  /** @internal Exported for testing. */
247
551
  export function generateWranglerConfig(
248
552
  config: TimberConfig,
@@ -267,12 +571,20 @@ export function generateWranglerConfig(
267
571
  },
268
572
  };
269
573
 
270
- // Merge user overrides
574
+ // Layer 1: merge bindings-generated sections into base
575
+ const bindingsConfig = generateBindingsConfig(options.bindings);
576
+ const merged = { ...base, ...bindingsConfig };
577
+
578
+ // Layer 2: wrangler escape hatch with deep merge for nested plain objects.
579
+ // A shallow spread would replace entire sections like durable_objects and
580
+ // queues — e.g. adding migrations via wrangler would drop the generated
581
+ // durable_objects.bindings. Deep merge preserves generated keys while
582
+ // letting wrangler override on actual key-level conflicts.
271
583
  if (options.wrangler) {
272
- return { ...base, ...options.wrangler };
584
+ return shallowDeepMerge(merged, options.wrangler);
273
585
  }
274
586
 
275
- return base;
587
+ return merged;
276
588
  }
277
589
 
278
590
  // ─── Preview ─────────────────────────────────────────────────────────────────
@@ -310,16 +622,18 @@ function spawnPreviewProcess(command: string, args: string[], cwd: string): Prom
310
622
  }
311
623
 
312
624
  // ─── Cloudflare Workers type stubs ───────────────────────────────────────────
313
- // Minimal type declarations so this file compiles without @cloudflare/workers-types.
314
- // In production builds, users install @cloudflare/workers-types themselves.
315
-
316
- declare global {
317
- interface ExecutionContext {
318
- waitUntil(promise: Promise<unknown>): void;
319
- passThroughOnException(): void;
320
- }
625
+ // Local type declarations so this file compiles without @cloudflare/workers-types.
626
+ // These are NOT declared globally — that would clash with @cloudflare/workers-types
627
+ // when users install it. Instead, they're module-scoped and used only within
628
+ // this file's function signatures.
629
+
630
+ /** @internal Minimal stub — use @cloudflare/workers-types for full types. */
631
+ export interface CfExecutionContext {
632
+ waitUntil(promise: Promise<unknown>): void;
633
+ passThroughOnException(): void;
634
+ }
321
635
 
322
- interface ExportedHandler<Env = Record<string, unknown>> {
323
- fetch?(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> | Response;
324
- }
636
+ /** @internal Minimal stub use @cloudflare/workers-types for full types. */
637
+ export interface CfExportedHandler<Env = Record<string, unknown>> {
638
+ fetch?(request: Request, env: Env, ctx: CfExecutionContext): Promise<Response> | Response;
325
639
  }
@@ -22,9 +22,11 @@
22
22
  export function generateCompressModule(): string {
23
23
  return `// Generated by @timber-js/app — response compression for self-hosted deployments.
24
24
  // Do not edit — this file is regenerated on each build.
25
- // Uses CompressionStream (Web API) for gzip. Brotli is left to CDNs/reverse
26
- // proxies at streaming quality levels its ratio advantage is marginal and
27
- // node:zlib buffers output internally, breaking streaming.
25
+ // Uses node:zlib createGzip() (C++ native) on Node.js, falls back to
26
+ // CompressionStream (Web API) on other runtimes. Brotli is left to CDNs/reverse
27
+ // proxies at streaming quality levels its ratio advantage is marginal.
28
+ import { Readable } from 'node:stream';
29
+ import { createGzip, constants } from 'node:zlib';
28
30
 
29
31
  const COMPRESSIBLE_TYPES = new Set([
30
32
  'text/html', 'text/css', 'text/plain', 'text/xml', 'text/javascript',
@@ -71,7 +73,25 @@ function shouldCompress(response) {
71
73
  }
72
74
 
73
75
  function compressWithGzip(body) {
74
- return body.pipeThrough(new CompressionStream('gzip'));
76
+ // Use node:zlib (C++ native) for gzip compression. The Web Streams
77
+ // CompressionStream works but every chunk crosses the JS/Promise boundary.
78
+ // node:zlib.createGzip() compresses entirely in C++ with zero per-chunk
79
+ // Promise overhead.
80
+ //
81
+ // Convert: Web ReadableStream → Node Readable → pipe through gzip →
82
+ // Node Readable → Readable.toWeb() → Web ReadableStream
83
+ try {
84
+ const nodeReadable = Readable.fromWeb(body);
85
+ // Z_SYNC_FLUSH ensures each chunk is flushed immediately so the browser
86
+ // receives the HTML shell before Suspense boundaries resolve. Without it,
87
+ // gzip buffers internally and breaks streaming.
88
+ const gzip = createGzip({ flush: constants.Z_SYNC_FLUSH });
89
+ const compressed = nodeReadable.pipe(gzip);
90
+ return Readable.toWeb(compressed);
91
+ } catch {
92
+ // Fallback: CompressionStream (CF Workers, or if node:stream unavailable)
93
+ return body.pipeThrough(new CompressionStream('gzip'));
94
+ }
75
95
  }
76
96
 
77
97
  export function compressResponse(request, response) {
@@ -149,6 +149,23 @@ export interface NitroAdapterOptions {
149
149
  */
150
150
  preset?: NitroPreset;
151
151
 
152
+ /**
153
+ * Enable application-level gzip compression for HTML and RSC responses.
154
+ *
155
+ * When `true` (default), the origin compresses responses using the Web
156
+ * `CompressionStream` API. This is useful for self-hosted deployments
157
+ * where no reverse proxy or CDN handles compression.
158
+ *
159
+ * Set to `false` when deploying behind a reverse proxy (nginx, caddy)
160
+ * or CDN (Cloudflare, Fastly, Vercel) that compresses at the edge.
161
+ * Disabling origin compression saves CPU on the Node.js event loop —
162
+ * compressing 1MB+ streaming HTML responses takes 10-15ms of main
163
+ * thread time per request, directly reducing throughput under load.
164
+ *
165
+ * @default true
166
+ */
167
+ compress?: boolean;
168
+
152
169
  /**
153
170
  * Additional Nitro configuration to merge into the generated config.
154
171
  * Overrides default values for the selected preset.
@@ -176,6 +193,7 @@ export interface NitroAdapterOptions {
176
193
  */
177
194
  export function nitro(options: NitroAdapterOptions = {}): TimberPlatformAdapter {
178
195
  const preset = options.preset ?? 'node-server';
196
+ const compress = options.compress ?? true;
179
197
  const presetConfig = PRESET_CONFIGS[preset];
180
198
  const pendingPromises: Promise<unknown>[] = [];
181
199
 
@@ -229,7 +247,7 @@ export function nitro(options: NitroAdapterOptions = {}): TimberPlatformAdapter
229
247
  }
230
248
 
231
249
  // Generate the Nitro entry point (imports from ./rsc/ within nitro dir)
232
- const entry = generateNitroEntry(buildDir, outDir, preset);
250
+ const entry = generateNitroEntry(buildDir, outDir, preset, compress);
233
251
  await writeFile(join(outDir, 'entry.ts'), entry);
234
252
 
235
253
  // Run the Nitro build to produce a production-ready server bundle.
@@ -273,6 +291,7 @@ export function generateNitroEntry(
273
291
  buildDir: string,
274
292
  outDir: string,
275
293
  preset: NitroPreset,
294
+ compress = true,
276
295
  hasManifestInit = false
277
296
  ): string {
278
297
  // The RSC entry is the main request handler — it exports the fetch handler as default.
@@ -338,12 +357,14 @@ export function generateNitroEntry(
338
357
  // Import runWithWaitUntil only when the preset supports it.
339
358
  const waitUntilImport = supportsWaitUntil ? ', runWithWaitUntil' : '';
340
359
 
360
+ const compressImport = compress ? "import { compressResponse } from './_compress.mjs'\n" : '';
361
+ const compressCall = compress ? 'compressResponse(webRequest, webResponse)' : 'webResponse';
362
+
341
363
  return `// Generated by @timber-js/app/adapters/nitro
342
364
  // Do not edit — this file is regenerated on each build.
343
365
 
344
366
  ${manifestImport}import handler, { runWithEarlyHintsSender${waitUntilImport} } from '${serverEntryRelative}'
345
- import { compressResponse } from './_compress.mjs'
346
-
367
+ ${compressImport}
347
368
  // Set TIMBER_RUNTIME for instrumentation.ts conditional SDK initialization.
348
369
  // See design/25-production-deployments.md §"TIMBER_RUNTIME".
349
370
  process.env.TIMBER_RUNTIME = '${runtimeName}'
@@ -357,7 +378,7 @@ export default async function timberHandler(event) {
357
378
  // h3 v2: event.req is the Web Request
358
379
  const webRequest = event.req
359
380
  ${handlerCall}
360
- return compressResponse(webRequest, webResponse)
381
+ return ${compressCall}
361
382
  }
362
383
  `;
363
384
  }
@@ -544,14 +565,37 @@ const server = createServer(async (req, res) => {
544
565
 
545
566
  if (webResponse.body) {
546
567
  const reader = webResponse.body.getReader();
547
- const pump = async () => {
568
+
569
+ // Cancel the reader when the client disconnects. This causes any
570
+ // pending reader.read() to reject, breaking the pump loop. Critical
571
+ // for SSE and other infinite streams — without this, disconnected
572
+ // clients leak readers.
573
+ let clientDisconnected = false;
574
+ const onClose = () => {
575
+ clientDisconnected = true;
576
+ reader.cancel('Client disconnected').catch(() => {});
577
+ };
578
+ res.on('close', onClose);
579
+
580
+ try {
548
581
  while (true) {
549
582
  const { done, value } = await reader.read();
550
- if (done) { res.end(); return; }
583
+ if (done) break;
551
584
  res.write(value);
552
585
  }
553
- };
554
- await pump();
586
+ } catch (err) {
587
+ // reader.cancel() from the close handler causes read() to reject.
588
+ // This is expected on client disconnect — not an error.
589
+ if (!clientDisconnected) {
590
+ throw err;
591
+ }
592
+ } finally {
593
+ res.off('close', onClose);
594
+ reader.releaseLock();
595
+ if (!res.writableEnded) {
596
+ res.end();
597
+ }
598
+ }
555
599
  } else {
556
600
  res.end();
557
601
  }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Type stub for the optional `wrangler` peer dependency.
3
+ * Prevents TS2307 during declaration emit when wrangler is not installed.
4
+ */
5
+ declare module 'wrangler' {
6
+ export function getPlatformProxy(opts?: any): Promise<any>;
7
+ }
@@ -0,0 +1,38 @@
1
+ import type { CacheOptions } from './index';
2
+ import { createCache } from './timber-cache';
3
+ import { getCacheHandler } from './handler-store';
4
+
5
+ /**
6
+ * Public caching API: `cache(fn, opts)`.
7
+ *
8
+ * Wraps an async function with cross-request caching. Uses the configured
9
+ * cache handler (defaults to MemoryCacheHandler, overridable via timber.config.ts).
10
+ *
11
+ * ```ts
12
+ * import { cache } from '@timber-js/app/cache';
13
+ *
14
+ * const getUser = cache(
15
+ * async (id: string) => db.users.findUnique({ where: { id } }),
16
+ * { ttl: 60, tags: (id) => [`user:${id}`] }
17
+ * );
18
+ * ```
19
+ */
20
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
+ export function cache<Fn extends (...args: any[]) => Promise<any>>(
22
+ fn: Fn,
23
+ opts: CacheOptions<Fn>
24
+ ): Fn {
25
+ return createCache(fn, opts, getCacheHandler());
26
+ }
27
+
28
+ /**
29
+ * Invalidate cache entries by tag or key.
30
+ *
31
+ * ```ts
32
+ * cache.invalidate({ tag: 'products' });
33
+ * cache.invalidate({ key: 'user:abc' });
34
+ * ```
35
+ */
36
+ cache.invalidate = async function invalidate(opts: { key?: string; tag?: string }): Promise<void> {
37
+ await getCacheHandler().invalidate(opts);
38
+ };