@timber-js/app 0.2.0-alpha.10 → 0.2.0-alpha.101

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 (729) hide show
  1. package/LICENSE +8 -0
  2. package/dist/_chunks/actions-BsfxK6yu.js +1061 -0
  3. package/dist/_chunks/actions-BsfxK6yu.js.map +1 -0
  4. package/dist/_chunks/build-output-helper-DXnW0qjz.js +61 -0
  5. package/dist/_chunks/build-output-helper-DXnW0qjz.js.map +1 -0
  6. package/dist/_chunks/chunk-Cfpv9whK.js +32 -0
  7. package/dist/_chunks/define-B-Q_UMOD.js +195 -0
  8. package/dist/_chunks/define-B-Q_UMOD.js.map +1 -0
  9. package/dist/_chunks/define-cookie-BjpIt4UC.js +194 -0
  10. package/dist/_chunks/define-cookie-BjpIt4UC.js.map +1 -0
  11. package/dist/_chunks/define-k32T6NL2.js +123 -0
  12. package/dist/_chunks/define-k32T6NL2.js.map +1 -0
  13. package/dist/_chunks/format-Bcn-Iv1x.js +14 -0
  14. package/dist/_chunks/format-Bcn-Iv1x.js.map +1 -0
  15. package/dist/_chunks/handler-store-B-lqaGyh.js +54 -0
  16. package/dist/_chunks/handler-store-B-lqaGyh.js.map +1 -0
  17. package/dist/_chunks/logger-0m8MsKdc.js +291 -0
  18. package/dist/_chunks/logger-0m8MsKdc.js.map +1 -0
  19. package/dist/_chunks/merge-search-params-BphMdht_.js +122 -0
  20. package/dist/_chunks/merge-search-params-BphMdht_.js.map +1 -0
  21. package/dist/_chunks/{metadata-routes-Cjmvi3rQ.js → metadata-routes-BU684ls2.js} +1 -1
  22. package/dist/_chunks/{metadata-routes-Cjmvi3rQ.js.map → metadata-routes-BU684ls2.js.map} +1 -1
  23. package/dist/_chunks/navigation-root-yx917rG0.js +96 -0
  24. package/dist/_chunks/navigation-root-yx917rG0.js.map +1 -0
  25. package/dist/_chunks/registry-I2ss-lvy.js +20 -0
  26. package/dist/_chunks/registry-I2ss-lvy.js.map +1 -0
  27. package/dist/_chunks/router-ref-h3-UaCQv.js +28 -0
  28. package/dist/_chunks/router-ref-h3-UaCQv.js.map +1 -0
  29. package/dist/_chunks/schema-bridge-Cxu4l-7p.js +86 -0
  30. package/dist/_chunks/schema-bridge-Cxu4l-7p.js.map +1 -0
  31. package/dist/_chunks/segment-classify-BjfuctV2.js +137 -0
  32. package/dist/_chunks/segment-classify-BjfuctV2.js.map +1 -0
  33. package/dist/_chunks/segment-context-Dx_OizxD.js +34 -0
  34. package/dist/_chunks/segment-context-Dx_OizxD.js.map +1 -0
  35. package/dist/_chunks/{ssr-data-MjmprTmO.js → ssr-data-B4CdH7rE.js} +1 -1
  36. package/dist/_chunks/ssr-data-B4CdH7rE.js.map +1 -0
  37. package/dist/_chunks/stale-reload-Bab885FO.js +64 -0
  38. package/dist/_chunks/stale-reload-Bab885FO.js.map +1 -0
  39. package/dist/_chunks/tracing-C8V-YGsP.js +329 -0
  40. package/dist/_chunks/tracing-C8V-YGsP.js.map +1 -0
  41. package/dist/_chunks/{use-query-states-D5KaffOK.js → use-query-states-B2XTqxDR.js} +7 -20
  42. package/dist/_chunks/use-query-states-B2XTqxDR.js.map +1 -0
  43. package/dist/_chunks/use-segment-params-DlsOX1YS.js +185 -0
  44. package/dist/_chunks/use-segment-params-DlsOX1YS.js.map +1 -0
  45. package/dist/_chunks/walkers-Tg0Alwcg.js +850 -0
  46. package/dist/_chunks/walkers-Tg0Alwcg.js.map +1 -0
  47. package/dist/_chunks/{format-DviM89f0.js → warnings-Cg47l5sk.js} +6 -45
  48. package/dist/_chunks/warnings-Cg47l5sk.js.map +1 -0
  49. package/dist/adapters/build-output-helper.d.ts +28 -0
  50. package/dist/adapters/build-output-helper.d.ts.map +1 -0
  51. package/dist/adapters/cloudflare-dev.d.ts +109 -0
  52. package/dist/adapters/cloudflare-dev.d.ts.map +1 -0
  53. package/dist/adapters/cloudflare-dev.js +73 -0
  54. package/dist/adapters/cloudflare-dev.js.map +1 -0
  55. package/dist/adapters/cloudflare-kv-cache.d.ts +64 -0
  56. package/dist/adapters/cloudflare-kv-cache.d.ts.map +1 -0
  57. package/dist/adapters/cloudflare-kv-cache.js +95 -0
  58. package/dist/adapters/cloudflare-kv-cache.js.map +1 -0
  59. package/dist/adapters/cloudflare.d.ts +148 -12
  60. package/dist/adapters/cloudflare.d.ts.map +1 -1
  61. package/dist/adapters/cloudflare.js +142 -38
  62. package/dist/adapters/cloudflare.js.map +1 -1
  63. package/dist/adapters/compress-module.d.ts.map +1 -1
  64. package/dist/adapters/nitro.d.ts +17 -1
  65. package/dist/adapters/nitro.d.ts.map +1 -1
  66. package/dist/adapters/nitro.js +143 -45
  67. package/dist/adapters/nitro.js.map +1 -1
  68. package/dist/adapters/shared.d.ts +16 -0
  69. package/dist/adapters/shared.d.ts.map +1 -0
  70. package/dist/cache/cache-api.d.ts +24 -0
  71. package/dist/cache/cache-api.d.ts.map +1 -0
  72. package/dist/cache/handler-store.d.ts +31 -0
  73. package/dist/cache/handler-store.d.ts.map +1 -0
  74. package/dist/cache/index.d.ts +23 -7
  75. package/dist/cache/index.d.ts.map +1 -1
  76. package/dist/cache/index.js +150 -81
  77. package/dist/cache/index.js.map +1 -1
  78. package/dist/cache/singleflight.d.ts +18 -1
  79. package/dist/cache/singleflight.d.ts.map +1 -1
  80. package/dist/cache/sizeof.d.ts +22 -0
  81. package/dist/cache/sizeof.d.ts.map +1 -0
  82. package/dist/cache/timber-cache.d.ts +1 -1
  83. package/dist/cache/timber-cache.d.ts.map +1 -1
  84. package/dist/cli.d.ts +6 -1
  85. package/dist/cli.d.ts.map +1 -1
  86. package/dist/cli.js +8 -3
  87. package/dist/cli.js.map +1 -1
  88. package/dist/client/browser-dev.d.ts +34 -1
  89. package/dist/client/browser-dev.d.ts.map +1 -1
  90. package/dist/client/browser-entry/action-dispatch.d.ts +17 -0
  91. package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -0
  92. package/dist/client/browser-entry/hmr.d.ts +21 -0
  93. package/dist/client/browser-entry/hmr.d.ts.map +1 -0
  94. package/dist/client/browser-entry/hydrate.d.ts +46 -0
  95. package/dist/client/browser-entry/hydrate.d.ts.map +1 -0
  96. package/dist/client/browser-entry/index.d.ts +30 -0
  97. package/dist/client/browser-entry/index.d.ts.map +1 -0
  98. package/dist/client/browser-entry/post-hydration.d.ts +26 -0
  99. package/dist/client/browser-entry/post-hydration.d.ts.map +1 -0
  100. package/dist/client/browser-entry/router-init.d.ts +23 -0
  101. package/dist/client/browser-entry/router-init.d.ts.map +1 -0
  102. package/dist/client/browser-entry/rsc-stream.d.ts +24 -0
  103. package/dist/client/browser-entry/rsc-stream.d.ts.map +1 -0
  104. package/dist/client/browser-entry/scroll.d.ts +19 -0
  105. package/dist/client/browser-entry/scroll.d.ts.map +1 -0
  106. package/dist/client/error-boundary.d.ts +12 -5
  107. package/dist/client/error-boundary.d.ts.map +1 -1
  108. package/dist/client/error-boundary.js +26 -5
  109. package/dist/client/error-boundary.js.map +1 -1
  110. package/dist/client/error-reconstituter.d.ts +54 -0
  111. package/dist/client/error-reconstituter.d.ts.map +1 -0
  112. package/dist/client/form.d.ts +16 -27
  113. package/dist/client/form.d.ts.map +1 -1
  114. package/dist/client/history.d.ts +19 -4
  115. package/dist/client/history.d.ts.map +1 -1
  116. package/dist/client/index.d.ts +9 -24
  117. package/dist/client/index.d.ts.map +1 -1
  118. package/dist/client/index.js +261 -1100
  119. package/dist/client/index.js.map +1 -1
  120. package/dist/client/internal.d.ts +19 -0
  121. package/dist/client/internal.d.ts.map +1 -0
  122. package/dist/client/internal.js +964 -0
  123. package/dist/client/internal.js.map +1 -0
  124. package/dist/client/link-pending-store.d.ts +63 -0
  125. package/dist/client/link-pending-store.d.ts.map +1 -0
  126. package/dist/client/link.d.ts +62 -55
  127. package/dist/client/link.d.ts.map +1 -1
  128. package/dist/client/nav-link-store.d.ts +36 -0
  129. package/dist/client/nav-link-store.d.ts.map +1 -0
  130. package/dist/client/navigation-api-types.d.ts +90 -0
  131. package/dist/client/navigation-api-types.d.ts.map +1 -0
  132. package/dist/client/navigation-api.d.ts +115 -0
  133. package/dist/client/navigation-api.d.ts.map +1 -0
  134. package/dist/client/navigation-context.d.ts +13 -2
  135. package/dist/client/navigation-context.d.ts.map +1 -1
  136. package/dist/client/{transition-root.d.ts → navigation-root.d.ts} +42 -8
  137. package/dist/client/navigation-root.d.ts.map +1 -0
  138. package/dist/client/nuqs-adapter.d.ts.map +1 -1
  139. package/dist/client/router-ref.d.ts +1 -1
  140. package/dist/client/router.d.ts +70 -4
  141. package/dist/client/router.d.ts.map +1 -1
  142. package/dist/client/rsc-fetch.d.ts +38 -3
  143. package/dist/client/rsc-fetch.d.ts.map +1 -1
  144. package/dist/client/segment-cache.d.ts +1 -1
  145. package/dist/client/segment-cache.d.ts.map +1 -1
  146. package/dist/client/segment-outlet.d.ts +63 -0
  147. package/dist/client/segment-outlet.d.ts.map +1 -0
  148. package/dist/client/ssr-data.d.ts +13 -4
  149. package/dist/client/ssr-data.d.ts.map +1 -1
  150. package/dist/client/stale-reload.d.ts +15 -0
  151. package/dist/client/stale-reload.d.ts.map +1 -1
  152. package/dist/client/state.d.ts +1 -1
  153. package/dist/client/top-loader.d.ts +5 -5
  154. package/dist/client/top-loader.d.ts.map +1 -1
  155. package/dist/client/use-cookie.d.ts +8 -0
  156. package/dist/client/use-cookie.d.ts.map +1 -1
  157. package/dist/client/use-link-status.d.ts +5 -5
  158. package/dist/client/use-link-status.d.ts.map +1 -1
  159. package/dist/client/{use-navigation-pending.d.ts → use-pending-navigation.d.ts} +4 -4
  160. package/dist/client/use-pending-navigation.d.ts.map +1 -0
  161. package/dist/client/use-query-states.d.ts +1 -1
  162. package/dist/client/use-query-states.d.ts.map +1 -1
  163. package/dist/client/use-router.d.ts +1 -1
  164. package/dist/client/{use-params.d.ts → use-segment-params.d.ts} +7 -5
  165. package/dist/client/use-segment-params.d.ts.map +1 -0
  166. package/dist/codec.d.ts +33 -0
  167. package/dist/codec.d.ts.map +1 -0
  168. package/dist/codec.js +2 -0
  169. package/dist/config-types.d.ts +294 -0
  170. package/dist/config-types.d.ts.map +1 -0
  171. package/dist/config-validation.d.ts +51 -0
  172. package/dist/config-validation.d.ts.map +1 -0
  173. package/dist/content/index.d.ts +1 -10
  174. package/dist/content/index.d.ts.map +1 -1
  175. package/dist/content/index.js +0 -2
  176. package/dist/cookies/define-cookie.d.ts +98 -25
  177. package/dist/cookies/define-cookie.d.ts.map +1 -1
  178. package/dist/cookies/index.d.ts +2 -1
  179. package/dist/cookies/index.d.ts.map +1 -1
  180. package/dist/cookies/index.js +36 -72
  181. package/dist/cookies/index.js.map +1 -1
  182. package/dist/cookies/json-cookie.d.ts +64 -0
  183. package/dist/cookies/json-cookie.d.ts.map +1 -0
  184. package/dist/cookies/validation.d.ts +46 -0
  185. package/dist/cookies/validation.d.ts.map +1 -0
  186. package/dist/dev-tools/404-page.d.ts +46 -0
  187. package/dist/dev-tools/404-page.d.ts.map +1 -0
  188. package/dist/dev-tools/browser-logs.d.ts +84 -0
  189. package/dist/dev-tools/browser-logs.d.ts.map +1 -0
  190. package/dist/dev-tools/error-page.d.ts +58 -0
  191. package/dist/dev-tools/error-page.d.ts.map +1 -0
  192. package/dist/dev-tools/holding-server.d.ts +54 -0
  193. package/dist/dev-tools/holding-server.d.ts.map +1 -0
  194. package/dist/dev-tools/index.d.ts +31 -0
  195. package/dist/dev-tools/index.d.ts.map +1 -0
  196. package/dist/{server/dev-span-processor.d.ts → dev-tools/instrumentation.d.ts} +26 -6
  197. package/dist/dev-tools/instrumentation.d.ts.map +1 -0
  198. package/dist/{server/dev-logger.d.ts → dev-tools/logger.d.ts} +1 -1
  199. package/dist/dev-tools/logger.d.ts.map +1 -0
  200. package/dist/{plugins/dev-logs.d.ts → dev-tools/logs.d.ts} +2 -2
  201. package/dist/dev-tools/logs.d.ts.map +1 -0
  202. package/dist/dev-tools/overlay.d.ts +91 -0
  203. package/dist/dev-tools/overlay.d.ts.map +1 -0
  204. package/dist/dev-tools/stack-classifier.d.ts +34 -0
  205. package/dist/dev-tools/stack-classifier.d.ts.map +1 -0
  206. package/dist/dev-tools/terminal.d.ts +28 -0
  207. package/dist/dev-tools/terminal.d.ts.map +1 -0
  208. package/dist/{server/dev-warnings.d.ts → dev-tools/warnings.d.ts} +2 -22
  209. package/dist/dev-tools/warnings.d.ts.map +1 -0
  210. package/dist/fonts/ast.d.ts +98 -6
  211. package/dist/fonts/ast.d.ts.map +1 -1
  212. package/dist/fonts/bundle.d.ts +48 -0
  213. package/dist/fonts/bundle.d.ts.map +1 -0
  214. package/dist/fonts/css.d.ts +1 -0
  215. package/dist/fonts/css.d.ts.map +1 -1
  216. package/dist/fonts/dev-middleware.d.ts +22 -0
  217. package/dist/fonts/dev-middleware.d.ts.map +1 -0
  218. package/dist/fonts/local.d.ts +1 -1
  219. package/dist/fonts/pipeline.d.ts +167 -0
  220. package/dist/fonts/pipeline.d.ts.map +1 -0
  221. package/dist/fonts/transform.d.ts +78 -0
  222. package/dist/fonts/transform.d.ts.map +1 -0
  223. package/dist/fonts/types.d.ts +45 -1
  224. package/dist/fonts/types.d.ts.map +1 -1
  225. package/dist/fonts/virtual-modules.d.ts +103 -0
  226. package/dist/fonts/virtual-modules.d.ts.map +1 -0
  227. package/dist/index.d.ts +46 -190
  228. package/dist/index.d.ts.map +1 -1
  229. package/dist/index.js +5348 -13285
  230. package/dist/index.js.map +1 -1
  231. package/dist/plugin-context.d.ts +107 -0
  232. package/dist/plugin-context.d.ts.map +1 -0
  233. package/dist/plugins/adapter-build.d.ts +1 -1
  234. package/dist/plugins/adapter-build.d.ts.map +1 -1
  235. package/dist/plugins/build-manifest.d.ts +2 -2
  236. package/dist/plugins/build-manifest.d.ts.map +1 -1
  237. package/dist/plugins/build-report.d.ts +9 -7
  238. package/dist/plugins/build-report.d.ts.map +1 -1
  239. package/dist/plugins/client-chunks.d.ts +32 -0
  240. package/dist/plugins/client-chunks.d.ts.map +1 -0
  241. package/dist/plugins/content.d.ts +1 -1
  242. package/dist/plugins/content.d.ts.map +1 -1
  243. package/dist/plugins/dev-server.d.ts +1 -1
  244. package/dist/plugins/dev-server.d.ts.map +1 -1
  245. package/dist/plugins/entries.d.ts +1 -1
  246. package/dist/plugins/entries.d.ts.map +1 -1
  247. package/dist/plugins/fonts.d.ts +17 -73
  248. package/dist/plugins/fonts.d.ts.map +1 -1
  249. package/dist/plugins/mdx.d.ts +1 -1
  250. package/dist/plugins/mdx.d.ts.map +1 -1
  251. package/dist/plugins/routing.d.ts +1 -1
  252. package/dist/plugins/routing.d.ts.map +1 -1
  253. package/dist/plugins/server-bundle.d.ts.map +1 -1
  254. package/dist/plugins/shims.d.ts +6 -5
  255. package/dist/plugins/shims.d.ts.map +1 -1
  256. package/dist/plugins/static-build.d.ts +5 -26
  257. package/dist/plugins/static-build.d.ts.map +1 -1
  258. package/dist/routing/codegen-shared.d.ts +55 -0
  259. package/dist/routing/codegen-shared.d.ts.map +1 -0
  260. package/dist/routing/codegen-types.d.ts +52 -0
  261. package/dist/routing/codegen-types.d.ts.map +1 -0
  262. package/dist/routing/codegen.d.ts +2 -2
  263. package/dist/routing/codegen.d.ts.map +1 -1
  264. package/dist/routing/convention-lint.d.ts +41 -0
  265. package/dist/routing/convention-lint.d.ts.map +1 -0
  266. package/dist/routing/index.d.ts +5 -1
  267. package/dist/routing/index.d.ts.map +1 -1
  268. package/dist/routing/index.js +3 -2
  269. package/dist/routing/link-codegen.d.ts +90 -0
  270. package/dist/routing/link-codegen.d.ts.map +1 -0
  271. package/dist/routing/scanner.d.ts +1 -10
  272. package/dist/routing/scanner.d.ts.map +1 -1
  273. package/dist/routing/segment-classify.d.ts +75 -0
  274. package/dist/routing/segment-classify.d.ts.map +1 -0
  275. package/dist/routing/types.d.ts +77 -25
  276. package/dist/routing/types.d.ts.map +1 -1
  277. package/dist/routing/walkers.d.ts +51 -0
  278. package/dist/routing/walkers.d.ts.map +1 -0
  279. package/dist/rsc-runtime/rsc.d.ts +1 -1
  280. package/dist/rsc-runtime/rsc.d.ts.map +1 -1
  281. package/dist/rsc-runtime/ssr.d.ts +12 -0
  282. package/dist/rsc-runtime/ssr.d.ts.map +1 -1
  283. package/dist/schema-bridge.d.ts +76 -0
  284. package/dist/schema-bridge.d.ts.map +1 -0
  285. package/dist/search-params/define.d.ts +157 -0
  286. package/dist/search-params/define.d.ts.map +1 -0
  287. package/dist/search-params/index.d.ts +4 -7
  288. package/dist/search-params/index.d.ts.map +1 -1
  289. package/dist/search-params/index.js +34 -441
  290. package/dist/search-params/index.js.map +1 -1
  291. package/dist/search-params/registry.d.ts +2 -2
  292. package/dist/search-params/registry.d.ts.map +1 -1
  293. package/dist/search-params/wrappers.d.ts +53 -0
  294. package/dist/search-params/wrappers.d.ts.map +1 -0
  295. package/dist/segment-params/define.d.ts +95 -0
  296. package/dist/segment-params/define.d.ts.map +1 -0
  297. package/dist/segment-params/index.d.ts +3 -0
  298. package/dist/segment-params/index.d.ts.map +1 -0
  299. package/dist/segment-params/index.js +2 -0
  300. package/dist/server/access-gate.d.ts +8 -3
  301. package/dist/server/access-gate.d.ts.map +1 -1
  302. package/dist/server/action-client.d.ts +41 -6
  303. package/dist/server/action-client.d.ts.map +1 -1
  304. package/dist/server/action-encryption.d.ts +76 -0
  305. package/dist/server/action-encryption.d.ts.map +1 -0
  306. package/dist/server/action-handler.d.ts +35 -1
  307. package/dist/server/action-handler.d.ts.map +1 -1
  308. package/dist/server/actions.d.ts +3 -6
  309. package/dist/server/actions.d.ts.map +1 -1
  310. package/dist/server/als-registry.d.ts +33 -5
  311. package/dist/server/als-registry.d.ts.map +1 -1
  312. package/dist/server/asset-headers.d.ts +1 -15
  313. package/dist/server/asset-headers.d.ts.map +1 -1
  314. package/dist/server/build-manifest.d.ts +2 -2
  315. package/dist/server/build-manifest.d.ts.map +1 -1
  316. package/dist/server/cookie-context.d.ts +170 -0
  317. package/dist/server/cookie-context.d.ts.map +1 -0
  318. package/dist/server/cookie-parsing.d.ts +51 -0
  319. package/dist/server/cookie-parsing.d.ts.map +1 -0
  320. package/dist/server/debug.d.ts +1 -1
  321. package/dist/server/default-logger.d.ts +22 -0
  322. package/dist/server/default-logger.d.ts.map +1 -0
  323. package/dist/server/deny-boundary.d.ts +90 -0
  324. package/dist/server/deny-boundary.d.ts.map +1 -0
  325. package/dist/server/deny-renderer.d.ts.map +1 -1
  326. package/dist/server/dev-source-map.d.ts +22 -0
  327. package/dist/server/dev-source-map.d.ts.map +1 -0
  328. package/dist/server/early-hints-sender.d.ts.map +1 -1
  329. package/dist/server/early-hints.d.ts +13 -5
  330. package/dist/server/early-hints.d.ts.map +1 -1
  331. package/dist/server/error-boundary-wrapper.d.ts +7 -1
  332. package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
  333. package/dist/server/fallback-error.d.ts +12 -7
  334. package/dist/server/fallback-error.d.ts.map +1 -1
  335. package/dist/server/flight-injection-state.d.ts +66 -0
  336. package/dist/server/flight-injection-state.d.ts.map +1 -0
  337. package/dist/server/flight-scripts.d.ts +42 -0
  338. package/dist/server/flight-scripts.d.ts.map +1 -0
  339. package/dist/server/flush.d.ts.map +1 -1
  340. package/dist/server/form-data.d.ts +29 -0
  341. package/dist/server/form-data.d.ts.map +1 -1
  342. package/dist/server/html-injector-core.d.ts +212 -0
  343. package/dist/server/html-injector-core.d.ts.map +1 -0
  344. package/dist/server/html-injectors.d.ts +81 -41
  345. package/dist/server/html-injectors.d.ts.map +1 -1
  346. package/dist/server/index.d.ts +9 -46
  347. package/dist/server/index.d.ts.map +1 -1
  348. package/dist/server/index.js +155 -2905
  349. package/dist/server/index.js.map +1 -1
  350. package/dist/server/internal.d.ts +48 -0
  351. package/dist/server/internal.d.ts.map +1 -0
  352. package/dist/server/internal.js +2900 -0
  353. package/dist/server/internal.js.map +1 -0
  354. package/dist/server/logger.d.ts +39 -7
  355. package/dist/server/logger.d.ts.map +1 -1
  356. package/dist/server/middleware-runner.d.ts +36 -4
  357. package/dist/server/middleware-runner.d.ts.map +1 -1
  358. package/dist/server/node-stream-transforms.d.ts +110 -0
  359. package/dist/server/node-stream-transforms.d.ts.map +1 -0
  360. package/dist/server/param-coercion.d.ts +26 -0
  361. package/dist/server/param-coercion.d.ts.map +1 -0
  362. package/dist/server/pipeline-helpers.d.ts +95 -0
  363. package/dist/server/pipeline-helpers.d.ts.map +1 -0
  364. package/dist/server/pipeline-interception.d.ts +1 -1
  365. package/dist/server/pipeline-interception.d.ts.map +1 -1
  366. package/dist/server/pipeline-metadata.d.ts +6 -0
  367. package/dist/server/pipeline-metadata.d.ts.map +1 -1
  368. package/dist/server/pipeline-outcome.d.ts +49 -0
  369. package/dist/server/pipeline-outcome.d.ts.map +1 -0
  370. package/dist/server/pipeline-phases.d.ts +52 -0
  371. package/dist/server/pipeline-phases.d.ts.map +1 -0
  372. package/dist/server/pipeline.d.ts +93 -23
  373. package/dist/server/pipeline.d.ts.map +1 -1
  374. package/dist/server/port-resolution.d.ts +117 -0
  375. package/dist/server/port-resolution.d.ts.map +1 -0
  376. package/dist/server/primitives.d.ts +69 -18
  377. package/dist/server/primitives.d.ts.map +1 -1
  378. package/dist/server/render-timeout.d.ts +51 -0
  379. package/dist/server/render-timeout.d.ts.map +1 -0
  380. package/dist/server/request-context.d.ts +41 -109
  381. package/dist/server/request-context.d.ts.map +1 -1
  382. package/dist/server/route-element-builder.d.ts +27 -1
  383. package/dist/server/route-element-builder.d.ts.map +1 -1
  384. package/dist/server/route-handler.d.ts.map +1 -1
  385. package/dist/server/route-matcher.d.ts +21 -34
  386. package/dist/server/route-matcher.d.ts.map +1 -1
  387. package/dist/server/rsc-entry/action-middleware-runner.d.ts +66 -0
  388. package/dist/server/rsc-entry/action-middleware-runner.d.ts.map +1 -0
  389. package/dist/server/rsc-entry/api-handler.d.ts +2 -2
  390. package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
  391. package/dist/server/rsc-entry/error-renderer.d.ts +26 -13
  392. package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
  393. package/dist/server/rsc-entry/helpers.d.ts +49 -6
  394. package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
  395. package/dist/server/rsc-entry/index.d.ts +20 -3
  396. package/dist/server/rsc-entry/index.d.ts.map +1 -1
  397. package/dist/server/rsc-entry/render-route.d.ts +50 -0
  398. package/dist/server/rsc-entry/render-route.d.ts.map +1 -0
  399. package/dist/server/rsc-entry/rsc-payload.d.ts +3 -3
  400. package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
  401. package/dist/server/rsc-entry/rsc-stream.d.ts +14 -1
  402. package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
  403. package/dist/server/rsc-entry/ssr-bridge.d.ts +1 -1
  404. package/dist/server/rsc-entry/ssr-bridge.d.ts.map +1 -1
  405. package/dist/server/rsc-entry/ssr-renderer.d.ts +19 -4
  406. package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
  407. package/dist/server/rsc-entry/wrap-action-dispatch.d.ts +119 -0
  408. package/dist/server/rsc-entry/wrap-action-dispatch.d.ts.map +1 -0
  409. package/dist/server/safe-load.d.ts +46 -0
  410. package/dist/server/safe-load.d.ts.map +1 -0
  411. package/dist/server/sensitive-fields.d.ts +74 -0
  412. package/dist/server/sensitive-fields.d.ts.map +1 -0
  413. package/dist/server/sitemap-generator.d.ts +129 -0
  414. package/dist/server/sitemap-generator.d.ts.map +1 -0
  415. package/dist/server/sitemap-handler.d.ts +22 -0
  416. package/dist/server/sitemap-handler.d.ts.map +1 -0
  417. package/dist/server/slot-resolver.d.ts +1 -1
  418. package/dist/server/slot-resolver.d.ts.map +1 -1
  419. package/dist/server/ssr-entry.d.ts +23 -0
  420. package/dist/server/ssr-entry.d.ts.map +1 -1
  421. package/dist/server/ssr-render.d.ts +39 -21
  422. package/dist/server/ssr-render.d.ts.map +1 -1
  423. package/dist/server/ssr-wrappers.d.ts +50 -0
  424. package/dist/server/ssr-wrappers.d.ts.map +1 -0
  425. package/dist/server/state-tree-diff.d.ts.map +1 -1
  426. package/dist/server/status-code-resolver.d.ts +16 -11
  427. package/dist/server/status-code-resolver.d.ts.map +1 -1
  428. package/dist/server/stream-utils.d.ts +36 -0
  429. package/dist/server/stream-utils.d.ts.map +1 -0
  430. package/dist/server/tracing.d.ts +5 -5
  431. package/dist/server/tracing.d.ts.map +1 -1
  432. package/dist/server/tree-builder.d.ts +62 -30
  433. package/dist/server/tree-builder.d.ts.map +1 -1
  434. package/dist/server/types.d.ts +49 -4
  435. package/dist/server/types.d.ts.map +1 -1
  436. package/dist/server/utils/escape-html.d.ts +14 -0
  437. package/dist/server/utils/escape-html.d.ts.map +1 -0
  438. package/dist/server/version-skew.d.ts +61 -0
  439. package/dist/server/version-skew.d.ts.map +1 -0
  440. package/dist/shared/merge-search-params.d.ts +22 -0
  441. package/dist/shared/merge-search-params.d.ts.map +1 -0
  442. package/dist/shims/font-google.d.ts +1 -1
  443. package/dist/shims/font-google.d.ts.map +1 -1
  444. package/dist/shims/font-google.js +42 -0
  445. package/dist/shims/font-google.js.map +1 -0
  446. package/dist/shims/font-local.d.ts +26 -0
  447. package/dist/shims/font-local.d.ts.map +1 -0
  448. package/dist/shims/font-local.js +20 -0
  449. package/dist/shims/font-local.js.map +1 -0
  450. package/dist/shims/headers.d.ts +2 -1
  451. package/dist/shims/headers.d.ts.map +1 -1
  452. package/dist/shims/navigation-client.d.ts +3 -1
  453. package/dist/shims/navigation-client.d.ts.map +1 -1
  454. package/dist/shims/navigation.d.ts +11 -5
  455. package/dist/shims/navigation.d.ts.map +1 -1
  456. package/dist/utils/state-machine.d.ts +80 -0
  457. package/dist/utils/state-machine.d.ts.map +1 -0
  458. package/package.json +57 -22
  459. package/src/adapters/build-output-helper.ts +77 -0
  460. package/src/adapters/cloudflare-dev.ts +177 -0
  461. package/src/adapters/cloudflare-kv-cache.ts +142 -0
  462. package/src/adapters/cloudflare.ts +350 -76
  463. package/src/adapters/compress-module.ts +24 -4
  464. package/src/adapters/nitro.ts +142 -59
  465. package/src/adapters/shared.ts +40 -0
  466. package/src/adapters/wrangler.d.ts +7 -0
  467. package/src/cache/cache-api.ts +38 -0
  468. package/src/cache/handler-store.ts +68 -0
  469. package/src/cache/index.ts +81 -18
  470. package/src/cache/singleflight.ts +62 -4
  471. package/src/cache/sizeof.ts +31 -0
  472. package/src/cache/timber-cache.ts +25 -20
  473. package/src/cli.ts +16 -6
  474. package/src/client/browser-dev.ts +153 -1
  475. package/src/client/browser-entry/action-dispatch.ts +116 -0
  476. package/src/client/browser-entry/hmr.ts +81 -0
  477. package/src/client/browser-entry/hydrate.ts +145 -0
  478. package/src/client/browser-entry/index.ts +143 -0
  479. package/src/client/browser-entry/post-hydration.ts +119 -0
  480. package/src/client/browser-entry/router-init.ts +193 -0
  481. package/src/client/browser-entry/rsc-stream.ts +157 -0
  482. package/src/client/browser-entry/scroll.ts +27 -0
  483. package/src/client/error-boundary.tsx +97 -20
  484. package/src/client/error-reconstituter.tsx +65 -0
  485. package/src/client/form.tsx +31 -32
  486. package/src/client/history.ts +26 -4
  487. package/src/client/index.ts +77 -43
  488. package/src/client/internal.ts +58 -0
  489. package/src/client/link-pending-store.ts +111 -0
  490. package/src/client/link.tsx +342 -113
  491. package/src/client/nav-link-store.ts +47 -0
  492. package/src/client/navigation-api-types.ts +112 -0
  493. package/src/client/navigation-api.ts +332 -0
  494. package/src/client/navigation-context.ts +31 -6
  495. package/src/client/navigation-root.tsx +342 -0
  496. package/src/client/nuqs-adapter.tsx +16 -3
  497. package/src/client/router-ref.ts +1 -1
  498. package/src/client/router.ts +300 -73
  499. package/src/client/rsc-fetch.ts +112 -8
  500. package/src/client/segment-cache.ts +1 -1
  501. package/src/client/segment-outlet.tsx +86 -0
  502. package/src/client/ssr-data.ts +13 -5
  503. package/src/client/stale-reload.ts +72 -3
  504. package/src/client/state.ts +2 -2
  505. package/src/client/top-loader.tsx +18 -6
  506. package/src/client/use-cookie.ts +29 -0
  507. package/src/client/use-link-status.ts +7 -7
  508. package/src/client/{use-navigation-pending.ts → use-pending-navigation.ts} +6 -6
  509. package/src/client/use-query-states.ts +9 -3
  510. package/src/client/use-router.ts +1 -1
  511. package/src/client/{use-params.ts → use-segment-params.ts} +7 -5
  512. package/src/codec.ts +45 -0
  513. package/src/config-types.ts +292 -0
  514. package/src/config-validation.ts +303 -0
  515. package/src/content/index.ts +5 -13
  516. package/src/cookies/define-cookie.ts +301 -55
  517. package/src/cookies/index.ts +12 -1
  518. package/src/cookies/json-cookie.ts +105 -0
  519. package/src/cookies/validation.ts +134 -0
  520. package/src/dev-tools/404-page.ts +387 -0
  521. package/src/dev-tools/browser-logs.ts +288 -0
  522. package/src/dev-tools/error-page.ts +509 -0
  523. package/src/dev-tools/holding-server.ts +187 -0
  524. package/src/dev-tools/index.ts +90 -0
  525. package/src/dev-tools/instrumentation.ts +176 -0
  526. package/src/{plugins/dev-logs.ts → dev-tools/logs.ts} +3 -3
  527. package/src/dev-tools/overlay.ts +456 -0
  528. package/src/dev-tools/stack-classifier.ts +75 -0
  529. package/src/dev-tools/terminal.ts +183 -0
  530. package/src/{server/dev-warnings.ts → dev-tools/warnings.ts} +5 -50
  531. package/src/fonts/ast.ts +488 -16
  532. package/src/fonts/bundle.ts +142 -0
  533. package/src/fonts/css.ts +2 -1
  534. package/src/fonts/dev-middleware.ts +74 -0
  535. package/src/fonts/local.ts +1 -1
  536. package/src/fonts/pipeline.ts +314 -0
  537. package/src/fonts/transform.ts +317 -0
  538. package/src/fonts/types.ts +50 -1
  539. package/src/fonts/virtual-modules.ts +227 -0
  540. package/src/index.ts +390 -358
  541. package/src/plugin-context.ts +240 -0
  542. package/src/plugins/adapter-build.ts +12 -4
  543. package/src/plugins/build-manifest.ts +13 -2
  544. package/src/plugins/build-report.ts +16 -25
  545. package/src/plugins/client-chunks.ts +65 -0
  546. package/src/plugins/content.ts +1 -1
  547. package/src/plugins/dev-server.ts +162 -30
  548. package/src/plugins/entries.ts +111 -10
  549. package/src/plugins/fonts.ts +155 -654
  550. package/src/plugins/mdx.ts +43 -10
  551. package/src/plugins/routing.ts +217 -44
  552. package/src/plugins/server-bundle.ts +32 -1
  553. package/src/plugins/shims.ts +136 -35
  554. package/src/plugins/static-build.ts +15 -89
  555. package/src/routing/codegen-shared.ts +98 -0
  556. package/src/routing/codegen-types.ts +53 -0
  557. package/src/routing/codegen.ts +143 -176
  558. package/src/routing/convention-lint.ts +357 -0
  559. package/src/routing/index.ts +5 -1
  560. package/src/routing/interception.ts +1 -1
  561. package/src/routing/link-codegen.ts +294 -0
  562. package/src/routing/scanner.ts +107 -110
  563. package/src/routing/segment-classify.ts +188 -0
  564. package/src/routing/types.ts +78 -25
  565. package/src/routing/walkers.ts +90 -0
  566. package/src/rsc-runtime/rsc.ts +2 -0
  567. package/src/rsc-runtime/ssr.ts +50 -0
  568. package/src/rsc-runtime/vendor-types.d.ts +7 -0
  569. package/src/{search-params/codecs.ts → schema-bridge.ts} +57 -20
  570. package/src/search-params/define.ts +538 -0
  571. package/src/search-params/index.ts +14 -20
  572. package/src/search-params/registry.ts +2 -2
  573. package/src/search-params/wrappers.ts +92 -0
  574. package/src/segment-params/define.ts +332 -0
  575. package/src/segment-params/index.ts +9 -0
  576. package/src/server/access-gate.tsx +76 -34
  577. package/src/server/action-client.ts +88 -15
  578. package/src/server/action-encryption.ts +144 -0
  579. package/src/server/action-handler.ts +112 -14
  580. package/src/server/actions.ts +10 -9
  581. package/src/server/als-registry.ts +35 -7
  582. package/src/server/asset-headers.ts +8 -34
  583. package/src/server/build-manifest.ts +10 -4
  584. package/src/server/compress.ts +25 -7
  585. package/src/server/cookie-context.ts +468 -0
  586. package/src/server/cookie-parsing.ts +135 -0
  587. package/src/server/debug.ts +1 -1
  588. package/src/server/default-logger.ts +99 -0
  589. package/src/server/deny-boundary.ts +218 -0
  590. package/src/server/deny-renderer.ts +31 -50
  591. package/src/server/dev-source-map.ts +31 -0
  592. package/src/server/early-hints-sender.ts +3 -2
  593. package/src/server/early-hints.ts +36 -15
  594. package/src/server/error-boundary-wrapper.ts +74 -22
  595. package/src/server/fallback-error.ts +74 -102
  596. package/src/server/flight-injection-state.ts +113 -0
  597. package/src/server/flight-scripts.ts +62 -0
  598. package/src/server/flush.ts +2 -1
  599. package/src/server/form-data.ts +76 -0
  600. package/src/server/html-injector-core.ts +403 -0
  601. package/src/server/html-injectors.ts +244 -223
  602. package/src/server/index.ts +31 -184
  603. package/src/server/internal.ts +176 -0
  604. package/src/server/logger.ts +67 -36
  605. package/src/server/middleware-runner.ts +75 -4
  606. package/src/server/node-stream-transforms.ts +369 -0
  607. package/src/server/param-coercion.ts +76 -0
  608. package/src/server/pipeline-helpers.ts +204 -0
  609. package/src/server/pipeline-interception.ts +17 -16
  610. package/src/server/pipeline-metadata.ts +13 -0
  611. package/src/server/pipeline-outcome.ts +167 -0
  612. package/src/server/pipeline-phases.ts +409 -0
  613. package/src/server/pipeline.ts +128 -394
  614. package/src/server/port-resolution.ts +215 -0
  615. package/src/server/primitives.ts +111 -28
  616. package/src/server/render-timeout.ts +108 -0
  617. package/src/server/request-context.ts +94 -338
  618. package/src/server/route-element-builder.ts +288 -192
  619. package/src/server/route-handler.ts +24 -4
  620. package/src/server/route-matcher.ts +44 -65
  621. package/src/server/rsc-entry/action-middleware-runner.ts +167 -0
  622. package/src/server/rsc-entry/api-handler.ts +16 -17
  623. package/src/server/rsc-entry/error-renderer.ts +305 -89
  624. package/src/server/rsc-entry/helpers.ts +136 -12
  625. package/src/server/rsc-entry/index.ts +312 -341
  626. package/src/server/rsc-entry/render-route.ts +304 -0
  627. package/src/server/rsc-entry/rsc-payload.ts +65 -18
  628. package/src/server/rsc-entry/rsc-stream.ts +81 -13
  629. package/src/server/rsc-entry/ssr-bridge.ts +14 -5
  630. package/src/server/rsc-entry/ssr-renderer.ts +171 -38
  631. package/src/server/rsc-entry/wrap-action-dispatch.ts +449 -0
  632. package/src/server/safe-load.ts +60 -0
  633. package/src/server/sensitive-fields.ts +230 -0
  634. package/src/server/sitemap-generator.ts +338 -0
  635. package/src/server/sitemap-handler.ts +126 -0
  636. package/src/server/slot-resolver.ts +245 -230
  637. package/src/server/ssr-entry.ts +215 -32
  638. package/src/server/ssr-render.ts +289 -67
  639. package/src/server/ssr-wrappers.tsx +139 -0
  640. package/src/server/state-tree-diff.ts +4 -1
  641. package/src/server/status-code-resolver.ts +112 -128
  642. package/src/server/stream-utils.ts +213 -0
  643. package/src/server/tracing.ts +21 -10
  644. package/src/server/tree-builder.ts +202 -90
  645. package/src/server/types.ts +55 -6
  646. package/src/server/utils/escape-html.ts +20 -0
  647. package/src/server/version-skew.ts +104 -0
  648. package/src/shared/merge-search-params.ts +55 -0
  649. package/src/shims/font-google.ts +1 -1
  650. package/src/shims/font-local.ts +34 -0
  651. package/src/shims/headers.ts +5 -1
  652. package/src/shims/navigation-client.ts +4 -3
  653. package/src/shims/navigation.ts +14 -7
  654. package/src/utils/state-machine.ts +111 -0
  655. package/dist/_chunks/als-registry-B7DbZ2hS.js +0 -41
  656. package/dist/_chunks/als-registry-B7DbZ2hS.js.map +0 -1
  657. package/dist/_chunks/debug-gwlJkDuf.js +0 -108
  658. package/dist/_chunks/debug-gwlJkDuf.js.map +0 -1
  659. package/dist/_chunks/format-DviM89f0.js.map +0 -1
  660. package/dist/_chunks/interception-BOoWmLUA.js +0 -676
  661. package/dist/_chunks/interception-BOoWmLUA.js.map +0 -1
  662. package/dist/_chunks/request-context-DIkVh_jG.js +0 -330
  663. package/dist/_chunks/request-context-DIkVh_jG.js.map +0 -1
  664. package/dist/_chunks/ssr-data-MjmprTmO.js.map +0 -1
  665. package/dist/_chunks/tracing-CemImE6h.js +0 -187
  666. package/dist/_chunks/tracing-CemImE6h.js.map +0 -1
  667. package/dist/_chunks/use-cookie-DX-l1_5E.js +0 -91
  668. package/dist/_chunks/use-cookie-DX-l1_5E.js.map +0 -1
  669. package/dist/_chunks/use-query-states-D5KaffOK.js.map +0 -1
  670. package/dist/cache/register-cached-function.d.ts +0 -17
  671. package/dist/cache/register-cached-function.d.ts.map +0 -1
  672. package/dist/client/browser-entry.d.ts +0 -21
  673. package/dist/client/browser-entry.d.ts.map +0 -1
  674. package/dist/client/link-status-provider.d.ts +0 -11
  675. package/dist/client/link-status-provider.d.ts.map +0 -1
  676. package/dist/client/transition-root.d.ts.map +0 -1
  677. package/dist/client/use-navigation-pending.d.ts.map +0 -1
  678. package/dist/client/use-params.d.ts.map +0 -1
  679. package/dist/plugins/cache-transform.d.ts +0 -36
  680. package/dist/plugins/cache-transform.d.ts.map +0 -1
  681. package/dist/plugins/dev-error-overlay.d.ts +0 -60
  682. package/dist/plugins/dev-error-overlay.d.ts.map +0 -1
  683. package/dist/plugins/dev-logs.d.ts.map +0 -1
  684. package/dist/plugins/dynamic-transform.d.ts +0 -72
  685. package/dist/plugins/dynamic-transform.d.ts.map +0 -1
  686. package/dist/plugins/server-action-exports.d.ts +0 -26
  687. package/dist/plugins/server-action-exports.d.ts.map +0 -1
  688. package/dist/routing/status-file-lint.d.ts +0 -33
  689. package/dist/routing/status-file-lint.d.ts.map +0 -1
  690. package/dist/search-params/analyze.d.ts +0 -54
  691. package/dist/search-params/analyze.d.ts.map +0 -1
  692. package/dist/search-params/builtin-codecs.d.ts +0 -105
  693. package/dist/search-params/builtin-codecs.d.ts.map +0 -1
  694. package/dist/search-params/codecs.d.ts +0 -53
  695. package/dist/search-params/codecs.d.ts.map +0 -1
  696. package/dist/search-params/create.d.ts +0 -106
  697. package/dist/search-params/create.d.ts.map +0 -1
  698. package/dist/server/dev-fetch-instrumentation.d.ts +0 -22
  699. package/dist/server/dev-fetch-instrumentation.d.ts.map +0 -1
  700. package/dist/server/dev-logger.d.ts.map +0 -1
  701. package/dist/server/dev-span-processor.d.ts.map +0 -1
  702. package/dist/server/dev-warnings.d.ts.map +0 -1
  703. package/dist/server/manifest-status-resolver.d.ts +0 -58
  704. package/dist/server/manifest-status-resolver.d.ts.map +0 -1
  705. package/dist/server/prerender.d.ts +0 -77
  706. package/dist/server/prerender.d.ts.map +0 -1
  707. package/dist/server/response-cache.d.ts +0 -54
  708. package/dist/server/response-cache.d.ts.map +0 -1
  709. package/dist/utils/directive-parser.d.ts +0 -70
  710. package/dist/utils/directive-parser.d.ts.map +0 -1
  711. package/src/cache/register-cached-function.ts +0 -103
  712. package/src/client/browser-entry.ts +0 -678
  713. package/src/client/link-status-provider.tsx +0 -30
  714. package/src/client/transition-root.tsx +0 -166
  715. package/src/plugins/cache-transform.ts +0 -199
  716. package/src/plugins/dev-error-overlay.ts +0 -230
  717. package/src/plugins/dynamic-transform.ts +0 -161
  718. package/src/plugins/server-action-exports.ts +0 -220
  719. package/src/routing/status-file-lint.ts +0 -112
  720. package/src/search-params/analyze.ts +0 -192
  721. package/src/search-params/builtin-codecs.ts +0 -228
  722. package/src/search-params/create.ts +0 -321
  723. package/src/server/dev-fetch-instrumentation.ts +0 -96
  724. package/src/server/dev-span-processor.ts +0 -78
  725. package/src/server/manifest-status-resolver.ts +0 -215
  726. package/src/server/prerender.ts +0 -139
  727. package/src/server/response-cache.ts +0 -410
  728. package/src/utils/directive-parser.ts +0 -529
  729. /package/src/{server/dev-logger.ts → dev-tools/logger.ts} +0 -0
@@ -3,24 +3,82 @@
3
3
  * execution. All callers receive the same result (or error).
4
4
  *
5
5
  * Per-process, in-memory. Each process coalesces independently.
6
+ *
7
+ * An optional `timeoutMs` prevents hung `fn()` calls from permanently
8
+ * blocking all future callers for that key. When set, `fn()` is raced
9
+ * against a timeout — if the timeout fires first, the promise rejects
10
+ * with `SingleflightTimeoutError`, `finally` cleans up the key, and
11
+ * subsequent callers can retry. See TIM-518.
6
12
  */
13
+
14
+ export interface SingleflightOptions {
15
+ /** Maximum time (ms) a coalesced call may run before being rejected. */
16
+ timeoutMs?: number;
17
+ }
18
+
7
19
  export interface Singleflight {
8
20
  do<T>(key: string, fn: () => Promise<T>): Promise<T>;
9
21
  }
10
22
 
11
- export function createSingleflight(): Singleflight {
23
+ /**
24
+ * Error thrown when a singleflight call exceeds `timeoutMs`.
25
+ * Exported so callers can distinguish timeout from other errors.
26
+ */
27
+ export class SingleflightTimeoutError extends Error {
28
+ constructor(key: string, timeoutMs: number) {
29
+ super(`Singleflight timeout: key "${key}" exceeded ${timeoutMs}ms`);
30
+ this.name = 'SingleflightTimeoutError';
31
+ }
32
+ }
33
+
34
+ export function createSingleflight(opts?: SingleflightOptions): Singleflight {
12
35
  const inflight = new Map<string, Promise<unknown>>();
36
+ const timeoutMs = opts?.timeoutMs;
13
37
 
14
38
  return {
15
39
  do<T>(key: string, fn: () => Promise<T>): Promise<T> {
16
40
  const existing = inflight.get(key);
17
41
  if (existing) return existing as Promise<T>;
18
42
 
19
- const promise = fn().finally(() => {
43
+ let promise: Promise<T>;
44
+
45
+ if (timeoutMs != null && timeoutMs > 0) {
46
+ // Race fn() against a timeout to prevent hung calls from
47
+ // permanently blocking the key. See TIM-518.
48
+ promise = new Promise<T>((resolve, reject) => {
49
+ const timer = setTimeout(
50
+ () => reject(new SingleflightTimeoutError(key, timeoutMs)),
51
+ timeoutMs
52
+ );
53
+ // Wrap in try/catch so a synchronous throw from fn()
54
+ // (e.g. argument validation) still clears the timer.
55
+ // Without this, the timer leaks until expiry.
56
+ try {
57
+ fn().then(
58
+ (value) => {
59
+ clearTimeout(timer);
60
+ resolve(value);
61
+ },
62
+ (err) => {
63
+ clearTimeout(timer);
64
+ reject(err);
65
+ }
66
+ );
67
+ } catch (err) {
68
+ clearTimeout(timer);
69
+ reject(err);
70
+ }
71
+ });
72
+ } else {
73
+ promise = fn();
74
+ }
75
+
76
+ const tracked = promise.finally(() => {
20
77
  inflight.delete(key);
21
78
  });
22
- inflight.set(key, promise);
23
- return promise;
79
+
80
+ inflight.set(key, tracked);
81
+ return tracked as Promise<T>;
24
82
  },
25
83
  };
26
84
  }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Lightweight byte-size estimation for cache entries.
3
+ *
4
+ * Estimates the in-memory byte cost of a JavaScript value using
5
+ * JSON.stringify().length * 2 (UTF-16 char width). This is a rough
6
+ * approximation — it doesn't account for V8 object overhead, Map
7
+ * metadata, or non-serializable values — but it's fast and good
8
+ * enough for cache budget enforcement.
9
+ *
10
+ * Values that fail JSON serialization (circular references, BigInt,
11
+ * etc.) return 0, allowing the entry to be cached without counting
12
+ * toward the byte budget. This is a conservative choice: it's better
13
+ * to cache and undercount than to reject the entry.
14
+ */
15
+
16
+ /**
17
+ * Estimate the byte size of a value.
18
+ *
19
+ * Uses `JSON.stringify(value).length * 2` to approximate UTF-16
20
+ * in-memory size. Returns 0 if the value is not serializable.
21
+ */
22
+ export function estimateByteSize(value: unknown): number {
23
+ try {
24
+ const json = JSON.stringify(value);
25
+ if (json === undefined) return 0;
26
+ // Each JS string character is 2 bytes (UTF-16)
27
+ return json.length * 2;
28
+ } catch {
29
+ return 0;
30
+ }
31
+ }
@@ -1,10 +1,11 @@
1
1
  import type { CacheHandler, CacheOptions } from './index';
2
2
  import { stableStringify } from './stable-stringify';
3
3
  import { createSingleflight } from './singleflight';
4
- import { addSpanEventSync } from '#/server/tracing.js';
4
+ import { addSpanEventSync } from '../server/tracing.js';
5
+ import { logSwrRefetchFailed } from '../server/logger.js';
5
6
  import { fnv1aHash } from './fast-hash.js';
6
7
 
7
- const singleflight = createSingleflight();
8
+ const defaultSingleflight = createSingleflight();
8
9
 
9
10
  /**
10
11
  * Generate a cache key from function identity and serialized args.
@@ -53,10 +54,16 @@ export function createCache<Fn extends (...args: any[]) => Promise<any>>(
53
54
  fn: Fn,
54
55
  opts: CacheOptions<Fn>,
55
56
  handler: CacheHandler
56
- ): (...args: Parameters<Fn>) => Promise<Awaited<ReturnType<Fn>>> {
57
+ ): Fn {
57
58
  const fnId = `timber-cache:${fnIdCounter++}`;
59
+ const sf = opts.timeoutMs
60
+ ? createSingleflight({ timeoutMs: opts.timeoutMs })
61
+ : defaultSingleflight;
58
62
 
59
- return async (...args: Parameters<Fn>): Promise<Awaited<ReturnType<Fn>>> => {
63
+ // Cast to Fn to preserve the original function's generic call signature.
64
+ // Without this, generic type parameters (e.g. <T> in apiFetch<T>) are
65
+ // erased and callers lose type safety on the return type.
66
+ return (async (...args: Parameters<Fn>): Promise<Awaited<ReturnType<Fn>>> => {
60
67
  const key = opts.key ? opts.key(...args) : defaultKeyGenerator(fnId, args);
61
68
 
62
69
  const cacheStart = performance.now();
@@ -80,25 +87,23 @@ export function createCache<Fn extends (...args: any[]) => Promise<any>>(
80
87
  stale: true,
81
88
  });
82
89
  // Serve stale immediately, trigger background refetch
83
- singleflight
84
- .do(`swr:${key}`, async () => {
85
- try {
86
- const fresh = await fn(...args);
87
- const tags = resolveTags(opts, args);
88
- await handler.set(key, fresh, { ttl: opts.ttl, tags });
89
- } catch {
90
- // Failed refetch — stale entry continues to be served.
91
- // Error is swallowed per design doc: "Error is logged."
92
- }
93
- })
94
- .catch(() => {
95
- // Singleflight promise rejection handled — stale continues.
96
- });
90
+ sf.do(`swr:${key}`, async () => {
91
+ try {
92
+ const fresh = await fn(...args);
93
+ const tags = resolveTags(opts, args);
94
+ await handler.set(key, fresh, { ttl: opts.ttl, tags });
95
+ } catch (err) {
96
+ // Failed refetch — stale entry continues to be served.
97
+ logSwrRefetchFailed({ cacheKey: key, error: err });
98
+ }
99
+ }).catch(() => {
100
+ // Singleflight promise rejection handled — stale continues.
101
+ });
97
102
  return cached.value as Awaited<ReturnType<Fn>>;
98
103
  }
99
104
 
100
105
  // Cache miss (or stale without SWR) — execute with singleflight
101
- const result = await singleflight.do(key, () => fn(...args));
106
+ const result = await sf.do(key, () => fn(...args));
102
107
  const tags = resolveTags(opts, args);
103
108
  await handler.set(key, result, { ttl: opts.ttl, tags });
104
109
 
@@ -109,7 +114,7 @@ export function createCache<Fn extends (...args: any[]) => Promise<any>>(
109
114
  });
110
115
 
111
116
  return result as Awaited<ReturnType<Fn>>;
112
- };
117
+ }) as unknown as Fn;
113
118
  }
114
119
 
115
120
  /**
package/src/cli.ts CHANGED
@@ -63,7 +63,12 @@ export interface ViteDeps {
63
63
 
64
64
  /**
65
65
  * Start the Vite dev server.
66
- * Middleware re-runs on file change via HMR wiring in timber-routing.
66
+ *
67
+ * The timber plugin binds the port immediately with a holding page
68
+ * (in rootSync's config hook) so browsers see a "starting..." page
69
+ * instead of ERR_CONNECTION_REFUSED during initialization.
70
+ *
71
+ * See design/21-dev-server.md, TIM-665.
67
72
  */
68
73
  export async function runDev(options: CommandOptions, _deps?: ViteDeps): Promise<void> {
69
74
  const createServer = _deps?.createServer ?? (await import('vite')).createServer;
@@ -105,9 +110,11 @@ export function resolvePreviewStrategy(
105
110
  * Returns the config object with adapter, output, etc.
106
111
  * Returns null if no config file is found.
107
112
  */
108
- async function loadTimberConfig(
109
- root: string
110
- ): Promise<{ adapter?: import('./adapters/types').TimberPlatformAdapter; output?: string } | null> {
113
+ async function loadTimberConfig(root: string): Promise<{
114
+ adapter?: import('./adapters/types').TimberPlatformAdapter;
115
+ output?: string;
116
+ buildDir?: string;
117
+ } | null> {
111
118
  const { existsSync } = await import('node:fs');
112
119
  const { join } = await import('node:path');
113
120
  const { pathToFileURL } = await import('node:url');
@@ -131,7 +138,7 @@ async function loadTimberConfig(
131
138
  * Otherwise falls back to Vite's built-in preview server.
132
139
  */
133
140
  export async function runPreview(options: CommandOptions, _deps?: ViteDeps): Promise<void> {
134
- const { join } = await import('node:path');
141
+ const { join, resolve } = await import('node:path');
135
142
 
136
143
  // Try to load timber config for adapter-specific preview
137
144
  const root = process.cwd();
@@ -139,7 +146,10 @@ export async function runPreview(options: CommandOptions, _deps?: ViteDeps): Pro
139
146
  const adapter = config?.adapter as import('./adapters/types').TimberPlatformAdapter | undefined;
140
147
 
141
148
  if (resolvePreviewStrategy(adapter) === 'adapter') {
142
- const buildDir = join(root, 'dist');
149
+ // Resolve build directory: timber config > default .timber/dist
150
+ const buildDir = config?.buildDir
151
+ ? resolve(root, config.buildDir)
152
+ : join(root, '.timber', 'dist');
143
153
  const timberConfig = { output: (config?.output ?? 'server') as 'server' | 'static' };
144
154
  await adapter!.preview!(timberConfig, buildDir);
145
155
  return;
@@ -1,5 +1,6 @@
1
1
  /**
2
- * Dev-only browser helpers — server log replay and client error forwarding.
2
+ * Dev-only browser helpers — server log replay, client error forwarding,
3
+ * and compiling overlay.
3
4
  *
4
5
  * These are only active when import.meta.hot is available (Vite dev mode).
5
6
  * Extracted from browser-entry.ts to keep files under 500 lines.
@@ -100,6 +101,132 @@ export function setupServerLogReplay(hot: Pick<HotInterface, 'on'>): void {
100
101
  });
101
102
  }
102
103
 
104
+ // ─── Compiling Overlay ──────────────────────────────────────────
105
+
106
+ /**
107
+ * Compiling overlay state.
108
+ *
109
+ * A small non-blocking indicator in the bottom-left corner that shows
110
+ * "Compiling..." during HMR/module updates. Uses a 200ms debounce so
111
+ * near-instant updates never flash the indicator.
112
+ *
113
+ * The overlay is lazily created on first show and reused thereafter.
114
+ * All styles are inline — no external CSS dependency.
115
+ */
116
+
117
+ let overlayEl: HTMLDivElement | null = null;
118
+ let showTimeoutId: ReturnType<typeof setTimeout> | null = null;
119
+ let pendingUpdates = 0;
120
+
121
+ /** Debounce delay before showing the overlay (ms). */
122
+ const SHOW_DELAY_MS = 200;
123
+
124
+ /**
125
+ * Get the effective debounce delay.
126
+ * Checks for a test override on `window.__timber_compiling_debounce`
127
+ * (number) to allow E2E tests to bypass the debounce.
128
+ */
129
+ function getShowDelay(): number {
130
+ const win = window as unknown as { __timber_compiling_debounce?: number };
131
+ return typeof win.__timber_compiling_debounce === 'number'
132
+ ? win.__timber_compiling_debounce
133
+ : SHOW_DELAY_MS;
134
+ }
135
+
136
+ /**
137
+ * Lazily create the overlay DOM element.
138
+ * Appended to document.body with fixed positioning in the bottom-left.
139
+ */
140
+ function getOrCreateOverlay(): HTMLDivElement {
141
+ if (overlayEl) return overlayEl;
142
+
143
+ const el = document.createElement('div');
144
+ el.setAttribute('data-timber-compiling-overlay', '');
145
+ Object.assign(el.style, {
146
+ position: 'fixed',
147
+ bottom: '16px',
148
+ left: '16px',
149
+ padding: '6px 12px',
150
+ background: 'rgba(0, 0, 0, 0.85)',
151
+ color: '#fff',
152
+ fontSize: '13px',
153
+ fontFamily:
154
+ '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif',
155
+ fontWeight: '500',
156
+ borderRadius: '6px',
157
+ zIndex: '2147483647',
158
+ pointerEvents: 'none',
159
+ opacity: '0',
160
+ transition: 'opacity 150ms ease',
161
+ boxShadow: '0 2px 8px rgba(0, 0, 0, 0.3)',
162
+ lineHeight: '1',
163
+ });
164
+ el.textContent = 'Compiling…';
165
+ document.body.appendChild(el);
166
+ overlayEl = el;
167
+ return el;
168
+ }
169
+
170
+ /**
171
+ * Signal that an HMR/module update has started.
172
+ *
173
+ * If an update is already tracked, this increments the counter.
174
+ * The overlay is shown after SHOW_DELAY_MS to avoid flashing
175
+ * for fast updates.
176
+ *
177
+ * When the delay is 0 (E2E test override), the overlay is shown
178
+ * synchronously to eliminate the race where hideCompilingOverlay()
179
+ * clears the show timeout before it fires.
180
+ */
181
+ export function showCompilingOverlay(): void {
182
+ pendingUpdates++;
183
+ if (pendingUpdates === 1) {
184
+ const delay = getShowDelay();
185
+ if (delay <= 0) {
186
+ // Synchronous show — no setTimeout race with hideCompilingOverlay().
187
+ // Used by E2E tests to guarantee the overlay is visible before
188
+ // the async HMR refresh begins its network roundtrip.
189
+ const el = getOrCreateOverlay();
190
+ el.style.opacity = '1';
191
+ } else {
192
+ // Production path — debounce to avoid flashing for fast updates
193
+ showTimeoutId = setTimeout(() => {
194
+ showTimeoutId = null;
195
+ const el = getOrCreateOverlay();
196
+ el.style.opacity = '1';
197
+ }, delay);
198
+ }
199
+ }
200
+ }
201
+
202
+ /**
203
+ * Signal that an HMR/module update has completed.
204
+ *
205
+ * When all pending updates are resolved, the overlay is hidden.
206
+ * If the overlay was never shown (update completed within the
207
+ * debounce window), the timeout is cleared — no visual flash.
208
+ *
209
+ * Test hook: if `window.__timber_hold_compiling_overlay` is true,
210
+ * the overlay stays visible. E2E tests use this to avoid a race
211
+ * where the RSC refresh completes between polling intervals,
212
+ * making the overlay impossible to observe.
213
+ */
214
+ export function hideCompilingOverlay(): void {
215
+ const win = window as unknown as { __timber_hold_compiling_overlay?: boolean };
216
+ if (win.__timber_hold_compiling_overlay) return;
217
+
218
+ pendingUpdates = Math.max(0, pendingUpdates - 1);
219
+ if (pendingUpdates === 0) {
220
+ if (showTimeoutId !== null) {
221
+ clearTimeout(showTimeoutId);
222
+ showTimeoutId = null;
223
+ }
224
+ if (overlayEl) {
225
+ overlayEl.style.opacity = '0';
226
+ }
227
+ }
228
+ }
229
+
103
230
  // ─── Client Error Forwarding ────────────────────────────────────────
104
231
 
105
232
  /**
@@ -115,6 +242,10 @@ export function setupClientErrorForwarding(hot: Pick<HotInterface, 'send'>): voi
115
242
  if (!event.error && !event.message) return;
116
243
  // Skip errors during page unload — these are abort-related, not application errors
117
244
  if (isPageUnloading()) return;
245
+ // Skip framework signal digests (redirect/deny) — these are control-flow
246
+ // signals, not application errors. They should never surface as dev
247
+ // overlays even if they escape an error boundary. See TIM-838.
248
+ if (isFrameworkSignalError(event.error)) return;
118
249
 
119
250
  const error = event.error;
120
251
  hot.send('timber:client-error', {
@@ -129,6 +260,8 @@ export function setupClientErrorForwarding(hot: Pick<HotInterface, 'send'>): voi
129
260
  if (!reason) return;
130
261
  // Skip rejections during page unload — aborted fetches/streams cause these
131
262
  if (isPageUnloading()) return;
263
+ // Skip framework signal digests (redirect/deny). See TIM-838.
264
+ if (isFrameworkSignalError(reason)) return;
132
265
 
133
266
  const message = reason instanceof Error ? reason.message : String(reason);
134
267
  const stack = reason instanceof Error ? (reason.stack ?? '') : '';
@@ -140,3 +273,22 @@ export function setupClientErrorForwarding(hot: Pick<HotInterface, 'send'>): voi
140
273
  });
141
274
  });
142
275
  }
276
+
277
+ /**
278
+ * Detect errors whose `digest` marks them as a framework control-flow signal
279
+ * (RedirectSignal, DenySignal). These must never surface as dev overlays —
280
+ * they are expected during navigation and are handled by the error boundary
281
+ * and router. Exported for tests.
282
+ */
283
+ export function isFrameworkSignalError(error: unknown): boolean {
284
+ if (!error || typeof error !== 'object') return false;
285
+ const digest = (error as { digest?: unknown }).digest;
286
+ if (typeof digest !== 'string') return false;
287
+ try {
288
+ const parsed = JSON.parse(digest) as { type?: unknown } | null;
289
+ if (!parsed || typeof parsed !== 'object') return false;
290
+ return parsed.type === 'redirect' || parsed.type === 'deny';
291
+ } catch {
292
+ return false;
293
+ }
294
+ }
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Server Action Dispatch — registers the callServer callback.
3
+ *
4
+ * When React encounters a server reference (from `'use server'` modules),
5
+ * it calls `callServer(id, args)` to dispatch the action to the server.
6
+ * The RSC plugin delegates to `globalThis.__viteRscCallServer` which is
7
+ * set by `setServerCallback`.
8
+ *
9
+ * The callback:
10
+ * 1. Serializes args via `encodeReply` (RSC wire format)
11
+ * 2. POSTs to the current URL with `Accept: text/x-component`
12
+ * 3. Decodes the RSC response stream
13
+ *
14
+ * See design/08-forms-and-actions.md §"Client-Side Form Mechanics"
15
+ */
16
+
17
+ import { setServerCallback, encodeReply, createFromFetch } from '../../rsc-runtime/browser.js';
18
+ import { getRouter } from '#client-internal';
19
+ import { setHardNavigating } from '../navigation-root.js';
20
+ import { isStaleClientReference, triggerStaleReload } from '../stale-reload.js';
21
+ import { getClientDeploymentId, DEPLOYMENT_ID_HEADER, RELOAD_HEADER } from '../rsc-fetch.js';
22
+
23
+ export function setupServerActions(): void {
24
+ setServerCallback(async (id: string, args: unknown[]) => {
25
+ const body = await encodeReply(args);
26
+
27
+ // Track the X-Timber-Revalidation header from the response.
28
+ // We intercept the fetch promise to read headers before createFromFetch
29
+ // consumes the body stream.
30
+ let hasRevalidation = false;
31
+ let hasRedirect = false;
32
+ let headElementsJson: string | null = null;
33
+
34
+ // Build action request headers. Include deployment ID for version
35
+ // skew detection (TIM-446) — the server rejects stale actions gracefully.
36
+ const actionHeaders: Record<string, string> = {
37
+ 'Accept': 'text/x-component',
38
+ 'x-rsc-action': id,
39
+ };
40
+ const actionDeploymentId = getClientDeploymentId();
41
+ if (actionDeploymentId) {
42
+ actionHeaders[DEPLOYMENT_ID_HEADER] = actionDeploymentId;
43
+ }
44
+
45
+ const response = fetch(window.location.href, {
46
+ method: 'POST',
47
+ headers: actionHeaders,
48
+ body,
49
+ }).then((res) => {
50
+ // Version skew detection (TIM-446): if the server signals a reload,
51
+ // trigger a full page load to pick up the new deployment.
52
+ if (res.headers.get(RELOAD_HEADER) === '1') {
53
+ window.location.reload();
54
+ throw new Error('Version skew detected — reloading page');
55
+ }
56
+ hasRevalidation = res.headers.get('X-Timber-Revalidation') === '1';
57
+ hasRedirect = res.headers.get('X-Timber-Redirect') != null;
58
+ headElementsJson = res.headers.get('X-Timber-Head');
59
+ return res;
60
+ });
61
+
62
+ let decoded: unknown;
63
+ try {
64
+ decoded = await createFromFetch(response);
65
+ } catch (error) {
66
+ if (isStaleClientReference(error)) {
67
+ triggerStaleReload();
68
+ // Return a never-resolving promise to prevent further processing
69
+ return new Promise(() => {});
70
+ }
71
+ throw error;
72
+ }
73
+
74
+ // Handle redirect — server encoded the redirect location in the RSC stream
75
+ // instead of returning HTTP 302. Perform a client-side SPA navigation.
76
+ if (hasRedirect) {
77
+ const wrapper = decoded as { _redirect: string; _status: number };
78
+ try {
79
+ const router = getRouter();
80
+ void router.navigate(wrapper._redirect);
81
+ } catch {
82
+ // Router not yet initialized — fall back to full navigation.
83
+ // Set hard-navigating flag to prevent Navigation API interception
84
+ // and React from rendering during page teardown. See TIM-626.
85
+ setHardNavigating(true);
86
+ window.location.href = wrapper._redirect;
87
+ }
88
+ return undefined;
89
+ }
90
+
91
+ if (hasRevalidation) {
92
+ // Piggybacked response: wrapper object { _action, _tree }
93
+ // Apply the revalidated tree directly — no separate router.refresh() needed.
94
+ const wrapper = decoded as { _action: unknown; _tree: unknown };
95
+ try {
96
+ const router = getRouter();
97
+ const headElements = headElementsJson ? JSON.parse(headElementsJson) : null;
98
+ router.applyRevalidation(wrapper._tree, headElements);
99
+ } catch {
100
+ // Router not yet initialized — fall through
101
+ }
102
+ return wrapper._action;
103
+ }
104
+
105
+ // No piggybacked revalidation — refresh to pick up any mutations.
106
+ // This covers actions that don't call revalidatePath().
107
+ try {
108
+ const router = getRouter();
109
+ void router.refresh();
110
+ } catch {
111
+ // Router not yet initialized (rare edge case during bootstrap)
112
+ }
113
+
114
+ return decoded;
115
+ });
116
+ }
@@ -0,0 +1,81 @@
1
+ /**
2
+ * HMR & Dev Tooling — dev-only wiring for hot module replacement.
3
+ *
4
+ * Handles:
5
+ * - RSC module invalidation (rsc:update → router.refresh())
6
+ * - Dev warnings forwarded from server via WebSocket
7
+ * - Server console log replay in browser
8
+ * - Client error forwarding to Vite error overlay
9
+ *
10
+ * See design/21-dev-server.md §"HMR Wiring"
11
+ */
12
+
13
+ import type { RouterInstance } from '#client-internal';
14
+ import {
15
+ setupServerLogReplay,
16
+ setupClientErrorForwarding,
17
+ showCompilingOverlay,
18
+ hideCompilingOverlay,
19
+ } from '../browser-dev.js';
20
+
21
+ type HotApi = {
22
+ on(event: string, cb: (...args: unknown[]) => void): void;
23
+ send(event: string, data: unknown): void;
24
+ };
25
+
26
+ /**
27
+ * Set up HMR and dev tool integration.
28
+ *
29
+ * Reads `import.meta.hot` to register dev-only event listeners.
30
+ * In production builds, `import.meta.hot` is undefined and this
31
+ * function is a no-op.
32
+ */
33
+ export function setupHmr(router: RouterInstance): void {
34
+ // Vite injects import.meta.hot in dev mode. Cast to access it without
35
+ // requiring vite/client types in the package tsconfig.
36
+ const hot = (import.meta as unknown as { hot?: HotApi }).hot;
37
+ if (!hot) return;
38
+
39
+ // ─── Compiling overlay: Vite client HMR updates ──────────────
40
+ // vite:beforeUpdate fires when Vite begins applying client-side
41
+ // module updates (React Fast Refresh, CSS hot update, etc.).
42
+ // vite:afterUpdate fires once all updates are applied.
43
+ hot.on('vite:beforeUpdate', () => {
44
+ showCompilingOverlay();
45
+ });
46
+ hot.on('vite:afterUpdate', () => {
47
+ hideCompilingOverlay();
48
+ });
49
+
50
+ // ─── RSC module invalidation ─────────────────────────────────
51
+ // rsc:update fires when a server component is edited.
52
+ // Show the compiling overlay while the RSC refresh is in flight.
53
+ hot.on('rsc:update', () => {
54
+ showCompilingOverlay();
55
+ void router.refresh().finally(() => {
56
+ hideCompilingOverlay();
57
+ });
58
+ });
59
+
60
+ // Listen for dev warnings forwarded from the server via WebSocket.
61
+ // See dev-warnings.ts — emitOnce() sends these via server.hot.send().
62
+ hot.on('timber:dev-warning', (data: unknown) => {
63
+ const warning = data as { level: string; message: string };
64
+ if (warning.level === 'error') {
65
+ console.error(warning.message);
66
+ } else {
67
+ console.warn(warning.message);
68
+ }
69
+ });
70
+
71
+ // Listen for server console logs forwarded via WebSocket.
72
+ // Replays them in the browser console with a [SERVER] prefix
73
+ // so developers can see server output without switching to the terminal.
74
+ // See plugins/dev-logs.ts.
75
+ setupServerLogReplay(hot);
76
+
77
+ // Forward uncaught client errors to the server for the dev overlay.
78
+ // The server source-maps the stack and sends it back via Vite's
79
+ // error overlay protocol. See dev-server.ts §client error listener.
80
+ setupClientErrorForwarding(hot);
81
+ }