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

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 (722) hide show
  1. package/LICENSE +8 -0
  2. package/dist/_chunks/actions-CQ8Z8VGL.js +1061 -0
  3. package/dist/_chunks/actions-CQ8Z8VGL.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-BYIpzuS7.js +39 -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-CfBPoJb0.js +123 -0
  10. package/dist/_chunks/define-CfBPoJb0.js.map +1 -0
  11. package/dist/_chunks/define-cookie-BjpIt4UC.js +194 -0
  12. package/dist/_chunks/define-cookie-BjpIt4UC.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-BCYczjml.js +96 -0
  24. package/dist/_chunks/navigation-root-BCYczjml.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-BkpKAQ7D.js +185 -0
  44. package/dist/_chunks/use-segment-params-BkpKAQ7D.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/bundle.d.ts +48 -0
  211. package/dist/fonts/bundle.d.ts.map +1 -0
  212. package/dist/fonts/css.d.ts +1 -0
  213. package/dist/fonts/css.d.ts.map +1 -1
  214. package/dist/fonts/dev-middleware.d.ts +22 -0
  215. package/dist/fonts/dev-middleware.d.ts.map +1 -0
  216. package/dist/fonts/pipeline.d.ts +167 -0
  217. package/dist/fonts/pipeline.d.ts.map +1 -0
  218. package/dist/fonts/transform.d.ts +64 -0
  219. package/dist/fonts/transform.d.ts.map +1 -0
  220. package/dist/fonts/types.d.ts +45 -1
  221. package/dist/fonts/types.d.ts.map +1 -1
  222. package/dist/fonts/virtual-modules.d.ts +103 -0
  223. package/dist/fonts/virtual-modules.d.ts.map +1 -0
  224. package/dist/index.d.ts +46 -190
  225. package/dist/index.d.ts.map +1 -1
  226. package/dist/index.js +14569 -12451
  227. package/dist/index.js.map +1 -1
  228. package/dist/plugin-context.d.ts +107 -0
  229. package/dist/plugin-context.d.ts.map +1 -0
  230. package/dist/plugins/adapter-build.d.ts +1 -1
  231. package/dist/plugins/adapter-build.d.ts.map +1 -1
  232. package/dist/plugins/build-manifest.d.ts +2 -2
  233. package/dist/plugins/build-manifest.d.ts.map +1 -1
  234. package/dist/plugins/build-report.d.ts +9 -7
  235. package/dist/plugins/build-report.d.ts.map +1 -1
  236. package/dist/plugins/client-chunks.d.ts +32 -0
  237. package/dist/plugins/client-chunks.d.ts.map +1 -0
  238. package/dist/plugins/content.d.ts +1 -1
  239. package/dist/plugins/content.d.ts.map +1 -1
  240. package/dist/plugins/dev-server.d.ts +1 -1
  241. package/dist/plugins/dev-server.d.ts.map +1 -1
  242. package/dist/plugins/entries.d.ts +1 -1
  243. package/dist/plugins/entries.d.ts.map +1 -1
  244. package/dist/plugins/fonts.d.ts +17 -73
  245. package/dist/plugins/fonts.d.ts.map +1 -1
  246. package/dist/plugins/mdx.d.ts +1 -1
  247. package/dist/plugins/mdx.d.ts.map +1 -1
  248. package/dist/plugins/routing.d.ts +1 -1
  249. package/dist/plugins/routing.d.ts.map +1 -1
  250. package/dist/plugins/server-bundle.d.ts.map +1 -1
  251. package/dist/plugins/shims.d.ts +6 -5
  252. package/dist/plugins/shims.d.ts.map +1 -1
  253. package/dist/plugins/static-build.d.ts +4 -4
  254. package/dist/plugins/static-build.d.ts.map +1 -1
  255. package/dist/routing/codegen-shared.d.ts +55 -0
  256. package/dist/routing/codegen-shared.d.ts.map +1 -0
  257. package/dist/routing/codegen-types.d.ts +52 -0
  258. package/dist/routing/codegen-types.d.ts.map +1 -0
  259. package/dist/routing/codegen.d.ts +2 -2
  260. package/dist/routing/codegen.d.ts.map +1 -1
  261. package/dist/routing/convention-lint.d.ts +41 -0
  262. package/dist/routing/convention-lint.d.ts.map +1 -0
  263. package/dist/routing/index.d.ts +5 -1
  264. package/dist/routing/index.d.ts.map +1 -1
  265. package/dist/routing/index.js +3 -2
  266. package/dist/routing/link-codegen.d.ts +90 -0
  267. package/dist/routing/link-codegen.d.ts.map +1 -0
  268. package/dist/routing/scanner.d.ts +1 -10
  269. package/dist/routing/scanner.d.ts.map +1 -1
  270. package/dist/routing/segment-classify.d.ts +75 -0
  271. package/dist/routing/segment-classify.d.ts.map +1 -0
  272. package/dist/routing/status-file-lint.d.ts +2 -1
  273. package/dist/routing/status-file-lint.d.ts.map +1 -1
  274. package/dist/routing/types.d.ts +77 -25
  275. package/dist/routing/types.d.ts.map +1 -1
  276. package/dist/routing/walkers.d.ts +51 -0
  277. package/dist/routing/walkers.d.ts.map +1 -0
  278. package/dist/rsc-runtime/rsc.d.ts +1 -1
  279. package/dist/rsc-runtime/rsc.d.ts.map +1 -1
  280. package/dist/rsc-runtime/ssr.d.ts +12 -0
  281. package/dist/rsc-runtime/ssr.d.ts.map +1 -1
  282. package/dist/schema-bridge.d.ts +76 -0
  283. package/dist/schema-bridge.d.ts.map +1 -0
  284. package/dist/search-params/define.d.ts +157 -0
  285. package/dist/search-params/define.d.ts.map +1 -0
  286. package/dist/search-params/index.d.ts +4 -7
  287. package/dist/search-params/index.d.ts.map +1 -1
  288. package/dist/search-params/index.js +34 -441
  289. package/dist/search-params/index.js.map +1 -1
  290. package/dist/search-params/registry.d.ts +2 -2
  291. package/dist/search-params/registry.d.ts.map +1 -1
  292. package/dist/search-params/wrappers.d.ts +53 -0
  293. package/dist/search-params/wrappers.d.ts.map +1 -0
  294. package/dist/segment-params/define.d.ts +95 -0
  295. package/dist/segment-params/define.d.ts.map +1 -0
  296. package/dist/segment-params/index.d.ts +3 -0
  297. package/dist/segment-params/index.d.ts.map +1 -0
  298. package/dist/segment-params/index.js +2 -0
  299. package/dist/server/access-gate.d.ts +8 -3
  300. package/dist/server/access-gate.d.ts.map +1 -1
  301. package/dist/server/action-client.d.ts +41 -6
  302. package/dist/server/action-client.d.ts.map +1 -1
  303. package/dist/server/action-encryption.d.ts +76 -0
  304. package/dist/server/action-encryption.d.ts.map +1 -0
  305. package/dist/server/action-handler.d.ts +35 -1
  306. package/dist/server/action-handler.d.ts.map +1 -1
  307. package/dist/server/actions.d.ts +3 -6
  308. package/dist/server/actions.d.ts.map +1 -1
  309. package/dist/server/als-registry.d.ts +33 -5
  310. package/dist/server/als-registry.d.ts.map +1 -1
  311. package/dist/server/asset-headers.d.ts +1 -15
  312. package/dist/server/asset-headers.d.ts.map +1 -1
  313. package/dist/server/build-manifest.d.ts +2 -2
  314. package/dist/server/build-manifest.d.ts.map +1 -1
  315. package/dist/server/cookie-context.d.ts +170 -0
  316. package/dist/server/cookie-context.d.ts.map +1 -0
  317. package/dist/server/cookie-parsing.d.ts +51 -0
  318. package/dist/server/cookie-parsing.d.ts.map +1 -0
  319. package/dist/server/debug.d.ts +1 -1
  320. package/dist/server/default-logger.d.ts +22 -0
  321. package/dist/server/default-logger.d.ts.map +1 -0
  322. package/dist/server/deny-boundary.d.ts +90 -0
  323. package/dist/server/deny-boundary.d.ts.map +1 -0
  324. package/dist/server/deny-renderer.d.ts.map +1 -1
  325. package/dist/server/dev-source-map.d.ts +22 -0
  326. package/dist/server/dev-source-map.d.ts.map +1 -0
  327. package/dist/server/early-hints-sender.d.ts.map +1 -1
  328. package/dist/server/early-hints.d.ts +13 -5
  329. package/dist/server/early-hints.d.ts.map +1 -1
  330. package/dist/server/error-boundary-wrapper.d.ts +7 -1
  331. package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
  332. package/dist/server/fallback-error.d.ts +12 -7
  333. package/dist/server/fallback-error.d.ts.map +1 -1
  334. package/dist/server/flight-injection-state.d.ts +66 -0
  335. package/dist/server/flight-injection-state.d.ts.map +1 -0
  336. package/dist/server/flight-scripts.d.ts +42 -0
  337. package/dist/server/flight-scripts.d.ts.map +1 -0
  338. package/dist/server/flush.d.ts.map +1 -1
  339. package/dist/server/form-data.d.ts +29 -0
  340. package/dist/server/form-data.d.ts.map +1 -1
  341. package/dist/server/html-injector-core.d.ts +212 -0
  342. package/dist/server/html-injector-core.d.ts.map +1 -0
  343. package/dist/server/html-injectors.d.ts +81 -41
  344. package/dist/server/html-injectors.d.ts.map +1 -1
  345. package/dist/server/index.d.ts +9 -46
  346. package/dist/server/index.d.ts.map +1 -1
  347. package/dist/server/index.js +155 -2905
  348. package/dist/server/index.js.map +1 -1
  349. package/dist/server/internal.d.ts +48 -0
  350. package/dist/server/internal.d.ts.map +1 -0
  351. package/dist/server/internal.js +2900 -0
  352. package/dist/server/internal.js.map +1 -0
  353. package/dist/server/logger.d.ts +39 -7
  354. package/dist/server/logger.d.ts.map +1 -1
  355. package/dist/server/middleware-runner.d.ts +36 -4
  356. package/dist/server/middleware-runner.d.ts.map +1 -1
  357. package/dist/server/node-stream-transforms.d.ts +110 -0
  358. package/dist/server/node-stream-transforms.d.ts.map +1 -0
  359. package/dist/server/param-coercion.d.ts +26 -0
  360. package/dist/server/param-coercion.d.ts.map +1 -0
  361. package/dist/server/pipeline-helpers.d.ts +95 -0
  362. package/dist/server/pipeline-helpers.d.ts.map +1 -0
  363. package/dist/server/pipeline-interception.d.ts +1 -1
  364. package/dist/server/pipeline-interception.d.ts.map +1 -1
  365. package/dist/server/pipeline-metadata.d.ts +6 -0
  366. package/dist/server/pipeline-metadata.d.ts.map +1 -1
  367. package/dist/server/pipeline-outcome.d.ts +49 -0
  368. package/dist/server/pipeline-outcome.d.ts.map +1 -0
  369. package/dist/server/pipeline-phases.d.ts +52 -0
  370. package/dist/server/pipeline-phases.d.ts.map +1 -0
  371. package/dist/server/pipeline.d.ts +93 -23
  372. package/dist/server/pipeline.d.ts.map +1 -1
  373. package/dist/server/port-resolution.d.ts +117 -0
  374. package/dist/server/port-resolution.d.ts.map +1 -0
  375. package/dist/server/primitives.d.ts +69 -18
  376. package/dist/server/primitives.d.ts.map +1 -1
  377. package/dist/server/render-timeout.d.ts +51 -0
  378. package/dist/server/render-timeout.d.ts.map +1 -0
  379. package/dist/server/request-context.d.ts +41 -109
  380. package/dist/server/request-context.d.ts.map +1 -1
  381. package/dist/server/route-element-builder.d.ts +27 -1
  382. package/dist/server/route-element-builder.d.ts.map +1 -1
  383. package/dist/server/route-handler.d.ts.map +1 -1
  384. package/dist/server/route-matcher.d.ts +21 -34
  385. package/dist/server/route-matcher.d.ts.map +1 -1
  386. package/dist/server/rsc-entry/action-middleware-runner.d.ts +66 -0
  387. package/dist/server/rsc-entry/action-middleware-runner.d.ts.map +1 -0
  388. package/dist/server/rsc-entry/api-handler.d.ts +2 -2
  389. package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
  390. package/dist/server/rsc-entry/error-renderer.d.ts +26 -13
  391. package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
  392. package/dist/server/rsc-entry/helpers.d.ts +49 -6
  393. package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
  394. package/dist/server/rsc-entry/index.d.ts +20 -3
  395. package/dist/server/rsc-entry/index.d.ts.map +1 -1
  396. package/dist/server/rsc-entry/render-route.d.ts +50 -0
  397. package/dist/server/rsc-entry/render-route.d.ts.map +1 -0
  398. package/dist/server/rsc-entry/rsc-payload.d.ts +3 -3
  399. package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
  400. package/dist/server/rsc-entry/rsc-stream.d.ts +14 -1
  401. package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
  402. package/dist/server/rsc-entry/ssr-bridge.d.ts +1 -1
  403. package/dist/server/rsc-entry/ssr-bridge.d.ts.map +1 -1
  404. package/dist/server/rsc-entry/ssr-renderer.d.ts +19 -4
  405. package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
  406. package/dist/server/rsc-entry/wrap-action-dispatch.d.ts +119 -0
  407. package/dist/server/rsc-entry/wrap-action-dispatch.d.ts.map +1 -0
  408. package/dist/server/safe-load.d.ts +46 -0
  409. package/dist/server/safe-load.d.ts.map +1 -0
  410. package/dist/server/sensitive-fields.d.ts +74 -0
  411. package/dist/server/sensitive-fields.d.ts.map +1 -0
  412. package/dist/server/sitemap-generator.d.ts +129 -0
  413. package/dist/server/sitemap-generator.d.ts.map +1 -0
  414. package/dist/server/sitemap-handler.d.ts +22 -0
  415. package/dist/server/sitemap-handler.d.ts.map +1 -0
  416. package/dist/server/slot-resolver.d.ts +1 -1
  417. package/dist/server/slot-resolver.d.ts.map +1 -1
  418. package/dist/server/ssr-entry.d.ts +23 -0
  419. package/dist/server/ssr-entry.d.ts.map +1 -1
  420. package/dist/server/ssr-render.d.ts +39 -21
  421. package/dist/server/ssr-render.d.ts.map +1 -1
  422. package/dist/server/ssr-wrappers.d.ts +50 -0
  423. package/dist/server/ssr-wrappers.d.ts.map +1 -0
  424. package/dist/server/state-tree-diff.d.ts.map +1 -1
  425. package/dist/server/status-code-resolver.d.ts +16 -11
  426. package/dist/server/status-code-resolver.d.ts.map +1 -1
  427. package/dist/server/stream-utils.d.ts +36 -0
  428. package/dist/server/stream-utils.d.ts.map +1 -0
  429. package/dist/server/tracing.d.ts +5 -5
  430. package/dist/server/tracing.d.ts.map +1 -1
  431. package/dist/server/tree-builder.d.ts +62 -30
  432. package/dist/server/tree-builder.d.ts.map +1 -1
  433. package/dist/server/types.d.ts +49 -4
  434. package/dist/server/types.d.ts.map +1 -1
  435. package/dist/server/utils/escape-html.d.ts +14 -0
  436. package/dist/server/utils/escape-html.d.ts.map +1 -0
  437. package/dist/server/version-skew.d.ts +61 -0
  438. package/dist/server/version-skew.d.ts.map +1 -0
  439. package/dist/shared/merge-search-params.d.ts +22 -0
  440. package/dist/shared/merge-search-params.d.ts.map +1 -0
  441. package/dist/shims/font-google.d.ts +1 -1
  442. package/dist/shims/font-google.d.ts.map +1 -1
  443. package/dist/shims/font-google.js +42 -0
  444. package/dist/shims/font-google.js.map +1 -0
  445. package/dist/shims/font-local.d.ts +26 -0
  446. package/dist/shims/font-local.d.ts.map +1 -0
  447. package/dist/shims/font-local.js +20 -0
  448. package/dist/shims/font-local.js.map +1 -0
  449. package/dist/shims/headers.d.ts +2 -1
  450. package/dist/shims/headers.d.ts.map +1 -1
  451. package/dist/shims/navigation-client.d.ts +3 -1
  452. package/dist/shims/navigation-client.d.ts.map +1 -1
  453. package/dist/shims/navigation.d.ts +11 -5
  454. package/dist/shims/navigation.d.ts.map +1 -1
  455. package/dist/utils/directive-parser.d.ts +1 -43
  456. package/dist/utils/directive-parser.d.ts.map +1 -1
  457. package/dist/utils/state-machine.d.ts +80 -0
  458. package/dist/utils/state-machine.d.ts.map +1 -0
  459. package/package.json +56 -22
  460. package/src/adapters/build-output-helper.ts +77 -0
  461. package/src/adapters/cloudflare-dev.ts +177 -0
  462. package/src/adapters/cloudflare-kv-cache.ts +142 -0
  463. package/src/adapters/cloudflare.ts +350 -76
  464. package/src/adapters/compress-module.ts +24 -4
  465. package/src/adapters/nitro.ts +142 -59
  466. package/src/adapters/shared.ts +40 -0
  467. package/src/adapters/wrangler.d.ts +7 -0
  468. package/src/cache/cache-api.ts +38 -0
  469. package/src/cache/handler-store.ts +68 -0
  470. package/src/cache/index.ts +81 -18
  471. package/src/cache/singleflight.ts +62 -4
  472. package/src/cache/sizeof.ts +31 -0
  473. package/src/cache/timber-cache.ts +25 -20
  474. package/src/cli.ts +16 -6
  475. package/src/client/browser-dev.ts +153 -1
  476. package/src/client/browser-entry/action-dispatch.ts +116 -0
  477. package/src/client/browser-entry/hmr.ts +81 -0
  478. package/src/client/browser-entry/hydrate.ts +145 -0
  479. package/src/client/browser-entry/index.ts +143 -0
  480. package/src/client/browser-entry/post-hydration.ts +119 -0
  481. package/src/client/browser-entry/router-init.ts +193 -0
  482. package/src/client/browser-entry/rsc-stream.ts +157 -0
  483. package/src/client/browser-entry/scroll.ts +27 -0
  484. package/src/client/error-boundary.tsx +97 -20
  485. package/src/client/error-reconstituter.tsx +65 -0
  486. package/src/client/form.tsx +31 -32
  487. package/src/client/history.ts +26 -4
  488. package/src/client/index.ts +77 -43
  489. package/src/client/internal.ts +58 -0
  490. package/src/client/link-pending-store.ts +111 -0
  491. package/src/client/link.tsx +342 -113
  492. package/src/client/nav-link-store.ts +47 -0
  493. package/src/client/navigation-api-types.ts +112 -0
  494. package/src/client/navigation-api.ts +332 -0
  495. package/src/client/navigation-context.ts +31 -6
  496. package/src/client/navigation-root.tsx +342 -0
  497. package/src/client/nuqs-adapter.tsx +16 -3
  498. package/src/client/router-ref.ts +1 -1
  499. package/src/client/router.ts +300 -73
  500. package/src/client/rsc-fetch.ts +112 -8
  501. package/src/client/segment-cache.ts +1 -1
  502. package/src/client/segment-outlet.tsx +86 -0
  503. package/src/client/ssr-data.ts +13 -5
  504. package/src/client/stale-reload.ts +72 -3
  505. package/src/client/state.ts +2 -2
  506. package/src/client/top-loader.tsx +18 -6
  507. package/src/client/use-cookie.ts +29 -0
  508. package/src/client/use-link-status.ts +7 -7
  509. package/src/client/{use-navigation-pending.ts → use-pending-navigation.ts} +6 -6
  510. package/src/client/use-query-states.ts +9 -3
  511. package/src/client/use-router.ts +1 -1
  512. package/src/client/{use-params.ts → use-segment-params.ts} +7 -5
  513. package/src/codec.ts +45 -0
  514. package/src/config-types.ts +292 -0
  515. package/src/config-validation.ts +303 -0
  516. package/src/content/index.ts +5 -13
  517. package/src/cookies/define-cookie.ts +301 -55
  518. package/src/cookies/index.ts +12 -1
  519. package/src/cookies/json-cookie.ts +105 -0
  520. package/src/cookies/validation.ts +134 -0
  521. package/src/dev-tools/404-page.ts +387 -0
  522. package/src/dev-tools/browser-logs.ts +288 -0
  523. package/src/dev-tools/error-page.ts +509 -0
  524. package/src/dev-tools/holding-server.ts +187 -0
  525. package/src/dev-tools/index.ts +90 -0
  526. package/src/dev-tools/instrumentation.ts +176 -0
  527. package/src/{plugins/dev-logs.ts → dev-tools/logs.ts} +3 -3
  528. package/src/dev-tools/overlay.ts +456 -0
  529. package/src/dev-tools/stack-classifier.ts +75 -0
  530. package/src/dev-tools/terminal.ts +183 -0
  531. package/src/{server/dev-warnings.ts → dev-tools/warnings.ts} +5 -50
  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/pipeline.ts +314 -0
  536. package/src/fonts/transform.ts +406 -0
  537. package/src/fonts/types.ts +50 -1
  538. package/src/fonts/virtual-modules.ts +227 -0
  539. package/src/index.ts +376 -356
  540. package/src/plugin-context.ts +240 -0
  541. package/src/plugins/adapter-build.ts +12 -4
  542. package/src/plugins/build-manifest.ts +13 -2
  543. package/src/plugins/build-report.ts +16 -25
  544. package/src/plugins/client-chunks.ts +65 -0
  545. package/src/plugins/content.ts +1 -1
  546. package/src/plugins/dev-server.ts +154 -21
  547. package/src/plugins/entries.ts +111 -10
  548. package/src/plugins/fonts.ts +155 -654
  549. package/src/plugins/mdx.ts +43 -10
  550. package/src/plugins/routing.ts +225 -41
  551. package/src/plugins/server-action-exports.ts +1 -1
  552. package/src/plugins/server-bundle.ts +32 -1
  553. package/src/plugins/shims.ts +136 -35
  554. package/src/plugins/static-build.ts +17 -11
  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/status-file-lint.ts +10 -7
  565. package/src/routing/types.ts +78 -25
  566. package/src/routing/walkers.ts +90 -0
  567. package/src/rsc-runtime/rsc.ts +2 -0
  568. package/src/rsc-runtime/ssr.ts +50 -0
  569. package/src/rsc-runtime/vendor-types.d.ts +7 -0
  570. package/src/{search-params/codecs.ts → schema-bridge.ts} +57 -20
  571. package/src/search-params/define.ts +538 -0
  572. package/src/search-params/index.ts +14 -20
  573. package/src/search-params/registry.ts +2 -2
  574. package/src/search-params/wrappers.ts +92 -0
  575. package/src/segment-params/define.ts +332 -0
  576. package/src/segment-params/index.ts +9 -0
  577. package/src/server/access-gate.tsx +76 -34
  578. package/src/server/action-client.ts +88 -15
  579. package/src/server/action-encryption.ts +144 -0
  580. package/src/server/action-handler.ts +112 -14
  581. package/src/server/actions.ts +10 -9
  582. package/src/server/als-registry.ts +35 -7
  583. package/src/server/asset-headers.ts +8 -34
  584. package/src/server/build-manifest.ts +10 -4
  585. package/src/server/compress.ts +25 -7
  586. package/src/server/cookie-context.ts +468 -0
  587. package/src/server/cookie-parsing.ts +135 -0
  588. package/src/server/debug.ts +1 -1
  589. package/src/server/default-logger.ts +99 -0
  590. package/src/server/deny-boundary.ts +218 -0
  591. package/src/server/deny-renderer.ts +31 -50
  592. package/src/server/dev-source-map.ts +31 -0
  593. package/src/server/early-hints-sender.ts +3 -2
  594. package/src/server/early-hints.ts +36 -15
  595. package/src/server/error-boundary-wrapper.ts +74 -22
  596. package/src/server/fallback-error.ts +74 -102
  597. package/src/server/flight-injection-state.ts +113 -0
  598. package/src/server/flight-scripts.ts +62 -0
  599. package/src/server/flush.ts +2 -1
  600. package/src/server/form-data.ts +76 -0
  601. package/src/server/html-injector-core.ts +403 -0
  602. package/src/server/html-injectors.ts +244 -223
  603. package/src/server/index.ts +31 -184
  604. package/src/server/internal.ts +176 -0
  605. package/src/server/logger.ts +67 -36
  606. package/src/server/middleware-runner.ts +75 -4
  607. package/src/server/node-stream-transforms.ts +369 -0
  608. package/src/server/param-coercion.ts +76 -0
  609. package/src/server/pipeline-helpers.ts +204 -0
  610. package/src/server/pipeline-interception.ts +17 -16
  611. package/src/server/pipeline-metadata.ts +13 -0
  612. package/src/server/pipeline-outcome.ts +167 -0
  613. package/src/server/pipeline-phases.ts +409 -0
  614. package/src/server/pipeline.ts +128 -394
  615. package/src/server/port-resolution.ts +215 -0
  616. package/src/server/primitives.ts +111 -28
  617. package/src/server/render-timeout.ts +108 -0
  618. package/src/server/request-context.ts +94 -338
  619. package/src/server/route-element-builder.ts +288 -192
  620. package/src/server/route-handler.ts +24 -4
  621. package/src/server/route-matcher.ts +44 -65
  622. package/src/server/rsc-entry/action-middleware-runner.ts +167 -0
  623. package/src/server/rsc-entry/api-handler.ts +16 -17
  624. package/src/server/rsc-entry/error-renderer.ts +305 -89
  625. package/src/server/rsc-entry/helpers.ts +136 -12
  626. package/src/server/rsc-entry/index.ts +312 -341
  627. package/src/server/rsc-entry/render-route.ts +304 -0
  628. package/src/server/rsc-entry/rsc-payload.ts +65 -18
  629. package/src/server/rsc-entry/rsc-stream.ts +81 -13
  630. package/src/server/rsc-entry/ssr-bridge.ts +14 -5
  631. package/src/server/rsc-entry/ssr-renderer.ts +171 -38
  632. package/src/server/rsc-entry/wrap-action-dispatch.ts +449 -0
  633. package/src/server/safe-load.ts +60 -0
  634. package/src/server/sensitive-fields.ts +230 -0
  635. package/src/server/sitemap-generator.ts +338 -0
  636. package/src/server/sitemap-handler.ts +126 -0
  637. package/src/server/slot-resolver.ts +245 -230
  638. package/src/server/ssr-entry.ts +215 -32
  639. package/src/server/ssr-render.ts +289 -67
  640. package/src/server/ssr-wrappers.tsx +139 -0
  641. package/src/server/state-tree-diff.ts +4 -1
  642. package/src/server/status-code-resolver.ts +112 -128
  643. package/src/server/stream-utils.ts +213 -0
  644. package/src/server/tracing.ts +21 -10
  645. package/src/server/tree-builder.ts +202 -90
  646. package/src/server/types.ts +55 -6
  647. package/src/server/utils/escape-html.ts +20 -0
  648. package/src/server/version-skew.ts +104 -0
  649. package/src/shared/merge-search-params.ts +55 -0
  650. package/src/shims/font-google.ts +1 -1
  651. package/src/shims/font-local.ts +34 -0
  652. package/src/shims/headers.ts +5 -1
  653. package/src/shims/navigation-client.ts +4 -3
  654. package/src/shims/navigation.ts +14 -7
  655. package/src/utils/directive-parser.ts +1 -390
  656. package/src/utils/state-machine.ts +111 -0
  657. package/dist/_chunks/als-registry-B7DbZ2hS.js +0 -41
  658. package/dist/_chunks/als-registry-B7DbZ2hS.js.map +0 -1
  659. package/dist/_chunks/debug-gwlJkDuf.js +0 -108
  660. package/dist/_chunks/debug-gwlJkDuf.js.map +0 -1
  661. package/dist/_chunks/format-DviM89f0.js.map +0 -1
  662. package/dist/_chunks/interception-BOoWmLUA.js +0 -676
  663. package/dist/_chunks/interception-BOoWmLUA.js.map +0 -1
  664. package/dist/_chunks/request-context-DIkVh_jG.js +0 -330
  665. package/dist/_chunks/request-context-DIkVh_jG.js.map +0 -1
  666. package/dist/_chunks/ssr-data-MjmprTmO.js.map +0 -1
  667. package/dist/_chunks/tracing-CemImE6h.js +0 -187
  668. package/dist/_chunks/tracing-CemImE6h.js.map +0 -1
  669. package/dist/_chunks/use-cookie-DX-l1_5E.js +0 -91
  670. package/dist/_chunks/use-cookie-DX-l1_5E.js.map +0 -1
  671. package/dist/_chunks/use-query-states-D5KaffOK.js.map +0 -1
  672. package/dist/cache/register-cached-function.d.ts +0 -17
  673. package/dist/cache/register-cached-function.d.ts.map +0 -1
  674. package/dist/client/browser-entry.d.ts +0 -21
  675. package/dist/client/browser-entry.d.ts.map +0 -1
  676. package/dist/client/link-status-provider.d.ts +0 -11
  677. package/dist/client/link-status-provider.d.ts.map +0 -1
  678. package/dist/client/transition-root.d.ts.map +0 -1
  679. package/dist/client/use-navigation-pending.d.ts.map +0 -1
  680. package/dist/client/use-params.d.ts.map +0 -1
  681. package/dist/plugins/cache-transform.d.ts +0 -36
  682. package/dist/plugins/cache-transform.d.ts.map +0 -1
  683. package/dist/plugins/dev-error-overlay.d.ts +0 -60
  684. package/dist/plugins/dev-error-overlay.d.ts.map +0 -1
  685. package/dist/plugins/dev-logs.d.ts.map +0 -1
  686. package/dist/plugins/dynamic-transform.d.ts +0 -72
  687. package/dist/plugins/dynamic-transform.d.ts.map +0 -1
  688. package/dist/search-params/analyze.d.ts +0 -54
  689. package/dist/search-params/analyze.d.ts.map +0 -1
  690. package/dist/search-params/builtin-codecs.d.ts +0 -105
  691. package/dist/search-params/builtin-codecs.d.ts.map +0 -1
  692. package/dist/search-params/codecs.d.ts +0 -53
  693. package/dist/search-params/codecs.d.ts.map +0 -1
  694. package/dist/search-params/create.d.ts +0 -106
  695. package/dist/search-params/create.d.ts.map +0 -1
  696. package/dist/server/dev-fetch-instrumentation.d.ts +0 -22
  697. package/dist/server/dev-fetch-instrumentation.d.ts.map +0 -1
  698. package/dist/server/dev-logger.d.ts.map +0 -1
  699. package/dist/server/dev-span-processor.d.ts.map +0 -1
  700. package/dist/server/dev-warnings.d.ts.map +0 -1
  701. package/dist/server/manifest-status-resolver.d.ts +0 -58
  702. package/dist/server/manifest-status-resolver.d.ts.map +0 -1
  703. package/dist/server/prerender.d.ts +0 -77
  704. package/dist/server/prerender.d.ts.map +0 -1
  705. package/dist/server/response-cache.d.ts +0 -54
  706. package/dist/server/response-cache.d.ts.map +0 -1
  707. package/src/cache/register-cached-function.ts +0 -103
  708. package/src/client/browser-entry.ts +0 -678
  709. package/src/client/link-status-provider.tsx +0 -30
  710. package/src/client/transition-root.tsx +0 -166
  711. package/src/plugins/cache-transform.ts +0 -199
  712. package/src/plugins/dev-error-overlay.ts +0 -230
  713. package/src/plugins/dynamic-transform.ts +0 -161
  714. package/src/search-params/analyze.ts +0 -192
  715. package/src/search-params/builtin-codecs.ts +0 -228
  716. package/src/search-params/create.ts +0 -321
  717. package/src/server/dev-fetch-instrumentation.ts +0 -96
  718. package/src/server/dev-span-processor.ts +0 -78
  719. package/src/server/manifest-status-resolver.ts +0 -215
  720. package/src/server/prerender.ts +0 -139
  721. package/src/server/response-cache.ts +0 -410
  722. /package/src/{server/dev-logger.ts → dev-tools/logger.ts} +0 -0
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Cookie parsing and serialization helpers — pure string ↔ structure
3
+ * functions with no ALS dependency. Split out of `cookie-context.ts`
4
+ * (TIM-853) so the API surface and the wire-format codecs can each be
5
+ * read on their own.
6
+ *
7
+ * The functions in this module are total over arbitrary input. They
8
+ * never throw and never call `assertValid*` (the security validators
9
+ * live in the API surface — `cookie-context.ts` invokes them at every
10
+ * jar entry point so the smuggling-primitive invariant from TIM-868
11
+ * is enforced regardless of which path produced the bytes).
12
+ */
13
+
14
+ import type { CookieEntry } from './als-registry.js';
15
+ import type { CookieOptions } from './cookie-context.js';
16
+
17
+ /**
18
+ * Parse a Cookie header string into a Map of name → value pairs.
19
+ * Follows RFC 6265 §4.2.1: cookies are semicolon-separated key=value pairs.
20
+ *
21
+ * Values are auto-decoded with `decodeURIComponent` so they round-trip
22
+ * losslessly with `getCookies().set()` (which auto-encodes). Malformed
23
+ * `%`-escapes from third-party cookies fall back to the raw byte sequence
24
+ * — the parser must be total over arbitrary inbound headers, including
25
+ * non-conforming values from other servers, browser extensions, etc.
26
+ */
27
+ export function parseCookieHeader(header: string): Map<string, string> {
28
+ const map = new Map<string, string>();
29
+ if (!header) return map;
30
+
31
+ for (const pair of header.split(';')) {
32
+ const eqIndex = pair.indexOf('=');
33
+ if (eqIndex === -1) continue;
34
+ const name = pair.slice(0, eqIndex).trim();
35
+ const value = pair.slice(eqIndex + 1).trim();
36
+ if (name) {
37
+ map.set(name, safeDecodeCookieValue(value));
38
+ }
39
+ }
40
+
41
+ return map;
42
+ }
43
+
44
+ /**
45
+ * Decode a single cookie value with `decodeURIComponent`, falling back to
46
+ * the raw byte sequence if the input contains a malformed `%`-escape.
47
+ *
48
+ * Used by both `parseCookieHeader` (incoming Cookie: header) and the
49
+ * `setRaw` forwarding path (outgoing Set-Cookie from upstream services).
50
+ * Total — never throws.
51
+ */
52
+ export function safeDecodeCookieValue(raw: string): string {
53
+ try {
54
+ return decodeURIComponent(raw);
55
+ } catch {
56
+ return raw;
57
+ }
58
+ }
59
+
60
+ /** Serialize a CookieEntry into a Set-Cookie header value. */
61
+ export function serializeCookieEntry(entry: CookieEntry): string {
62
+ const parts = [`${entry.name}=${entry.value}`];
63
+ const opts = entry.options;
64
+
65
+ if (opts.domain) parts.push(`Domain=${opts.domain}`);
66
+ if (opts.path) parts.push(`Path=${opts.path}`);
67
+ if (opts.expires) parts.push(`Expires=${opts.expires.toUTCString()}`);
68
+ if (opts.maxAge !== undefined) parts.push(`Max-Age=${opts.maxAge}`);
69
+ if (opts.httpOnly) parts.push('HttpOnly');
70
+ if (opts.secure) parts.push('Secure');
71
+ if (opts.sameSite) {
72
+ parts.push(`SameSite=${opts.sameSite.charAt(0).toUpperCase()}${opts.sameSite.slice(1)}`);
73
+ }
74
+ if (opts.partitioned) parts.push('Partitioned');
75
+
76
+ return parts.join('; ');
77
+ }
78
+
79
+ /**
80
+ * Parse a raw `Set-Cookie` header string into name, value, and options.
81
+ * Handles all standard attributes: Path, Domain, Max-Age, Expires,
82
+ * SameSite, Secure, HttpOnly, Partitioned.
83
+ *
84
+ * Does NOT apply DEFAULT_COOKIE_OPTIONS — the caller decides whether
85
+ * to merge defaults (e.g. `set()` does, but `setRaw()` should preserve
86
+ * the original header's intent).
87
+ */
88
+ export function parseSetCookie(
89
+ header: string
90
+ ): { name: string; value: string; options: CookieOptions } | null {
91
+ const segments = header.split(';');
92
+ const nameValue = segments[0];
93
+ const eqIdx = nameValue.indexOf('=');
94
+ if (eqIdx <= 0) return null;
95
+
96
+ const name = nameValue.slice(0, eqIdx).trim();
97
+ const value = nameValue.slice(eqIdx + 1).trim();
98
+ const options: CookieOptions = {};
99
+
100
+ for (let i = 1; i < segments.length; i++) {
101
+ const seg = segments[i].trim();
102
+ if (!seg) continue;
103
+ const [attrName, ...rest] = seg.split('=');
104
+ const key = attrName.trim().toLowerCase();
105
+ const val = rest.join('=').trim();
106
+ switch (key) {
107
+ case 'path':
108
+ options.path = val || '/';
109
+ break;
110
+ case 'domain':
111
+ options.domain = val;
112
+ break;
113
+ case 'max-age':
114
+ options.maxAge = Number(val);
115
+ break;
116
+ case 'expires':
117
+ options.expires = new Date(val);
118
+ break;
119
+ case 'samesite':
120
+ options.sameSite = val.toLowerCase() as 'strict' | 'lax' | 'none';
121
+ break;
122
+ case 'secure':
123
+ options.secure = true;
124
+ break;
125
+ case 'httponly':
126
+ options.httpOnly = true;
127
+ break;
128
+ case 'partitioned':
129
+ options.partitioned = true;
130
+ break;
131
+ }
132
+ }
133
+
134
+ return { name, value, options };
135
+ }
@@ -48,7 +48,7 @@
48
48
  *
49
49
  * This is the ONLY function that should gate client-visible dev behavior:
50
50
  * - Dev error pages with stack traces
51
- * - Detailed Server-Timing response headers
51
+ * - Server-Timing mode default (`'detailed'` in dev, `'total'` in prod)
52
52
  * - Error messages in action `INTERNAL_ERROR` payloads
53
53
  * - Pipeline error handler wiring (Vite overlay)
54
54
  *
@@ -0,0 +1,99 @@
1
+ /**
2
+ * DefaultLogger — human-readable stderr logging when no custom logger is configured.
3
+ *
4
+ * Ships as the fallback so production deployments always have error visibility,
5
+ * even without an `instrumentation.ts` logger export. Output is one line per
6
+ * event, designed for `fly logs`, `kubectl logs`, Cloudflare dashboard tails, etc.
7
+ *
8
+ * Format:
9
+ * [timber] ERROR message key=value key=value trace_id=4bf92f35
10
+ * [timber] WARN message key=value key=value trace_id=4bf92f35
11
+ * [timber] INFO message method=GET path=/dashboard status=200 durationMs=43 trace_id=4bf92f35
12
+ *
13
+ * Behavior:
14
+ * - Suppressed entirely in dev mode (dev logging handles all output)
15
+ * - `debug` suppressed unless TIMBER_DEBUG is set
16
+ * - Replaced entirely when a custom logger is set via `setLogger()`
17
+ *
18
+ * See design/17-logging.md §"DefaultLogger"
19
+ */
20
+
21
+ import { isDevMode, isDebug } from './debug.js';
22
+ import { formatSsrError } from './error-formatter.js';
23
+ import type { TimberLogger } from './logger.js';
24
+
25
+ /**
26
+ * Format data fields as `key=value` pairs for human-readable output.
27
+ * - `error` key is serialized via formatSsrError for stack trace cleanup
28
+ * - `trace_id` is truncated to 8 chars for readability (full ID in OTEL)
29
+ * - Other values are stringified inline
30
+ */
31
+ function formatDataFields(data?: Record<string, unknown>): string {
32
+ if (!data) return '';
33
+
34
+ const parts: string[] = [];
35
+ let traceId: string | undefined;
36
+
37
+ for (const [key, value] of Object.entries(data)) {
38
+ if (key === 'trace_id') {
39
+ // Defer trace_id to the end
40
+ traceId = typeof value === 'string' ? value : String(value);
41
+ continue;
42
+ }
43
+ if (key === 'error') {
44
+ // Serialize errors with formatSsrError for clean output
45
+ parts.push(`error=${formatSsrError(value)}`);
46
+ continue;
47
+ }
48
+ if (value === undefined || value === null) continue;
49
+ parts.push(`${key}=${value}`);
50
+ }
51
+
52
+ // trace_id always last, truncated to 8 chars for readability
53
+ if (traceId) {
54
+ parts.push(`trace_id=${traceId.slice(0, 8)}`);
55
+ }
56
+
57
+ return parts.length > 0 ? ' ' + parts.join(' ') : '';
58
+ }
59
+
60
+ /** Pad level string to fixed width for alignment. */
61
+ function padLevel(level: string): string {
62
+ return level.padEnd(5);
63
+ }
64
+
65
+ export function createDefaultLogger(): TimberLogger {
66
+ return {
67
+ error(msg: string, data?: Record<string, unknown>): void {
68
+ // Errors are ALWAYS logged, including dev mode. Suppressing errors
69
+ // in dev causes silent 500s with no stack trace, making route.ts
70
+ // and render errors impossible to debug. See TIM-555.
71
+ const fields = formatDataFields(data);
72
+ process.stderr.write(`[timber] ${padLevel('ERROR')} ${msg}${fields}\n`);
73
+ },
74
+
75
+ warn(msg: string, data?: Record<string, unknown>): void {
76
+ // Warnings are always logged — same rationale as errors.
77
+ const fields = formatDataFields(data);
78
+ process.stderr.write(`[timber] ${padLevel('WARN')} ${msg}${fields}\n`);
79
+ },
80
+
81
+ info(msg: string, data?: Record<string, unknown>): void {
82
+ // info is suppressed by default — per-request lines are too noisy
83
+ // without a custom logger. Enable with TIMBER_DEBUG.
84
+ if (isDevMode()) return;
85
+ if (!isDebug()) return;
86
+ const fields = formatDataFields(data);
87
+ process.stderr.write(`[timber] ${padLevel('INFO')} ${msg}${fields}\n`);
88
+ },
89
+
90
+ debug(msg: string, data?: Record<string, unknown>): void {
91
+ // debug is suppressed in dev (dev logger handles it) and in
92
+ // production unless TIMBER_DEBUG is explicitly set.
93
+ if (isDevMode()) return;
94
+ if (!isDebug()) return;
95
+ const fields = formatDataFields(data);
96
+ process.stderr.write(`[timber] ${padLevel('DEBUG')} ${msg}${fields}\n`);
97
+ },
98
+ };
99
+ }
@@ -0,0 +1,218 @@
1
+ /**
2
+ * Deny boundary subsystem — the in-tree DenySignal flow.
3
+ *
4
+ * Three things live together here because they form a single flow:
5
+ *
6
+ * 1. **Chain construction** (`buildDenyPageChain`) — walks the matched
7
+ * segment chain at element-tree build time and produces a list of
8
+ * `DenyPageEntry` records ordered by specificity (specific status →
9
+ * category catch-all → `error.tsx`).
10
+ *
11
+ * 2. **Runtime matching** (`renderMatchingDenyPage`) — picks the first
12
+ * chain entry whose status filter matches the thrown DenySignal and
13
+ * returns a React element for the matching component. Used by
14
+ * `AccessGate` and `PageDenyBoundary` when they catch a deny.
15
+ *
16
+ * 3. **The page boundary itself** (`PageDenyBoundary`) — the async server
17
+ * component that wraps a server-component page, calls it, and catches
18
+ * `DenySignal` so the deny page renders in-tree (no throw reaches
19
+ * React Flight, single render pass).
20
+ *
21
+ * Plus the ALS helpers (`setDenyStatus` / `getDenyStatus`) the boundary
22
+ * uses to thread the matched status code back to the pipeline so the
23
+ * HTTP status reflects the deny.
24
+ *
25
+ * Folded into one module from the former `deny-page-resolver.ts` and
26
+ * `page-deny-boundary.tsx` (TIM-853) — the names were misleading and the
27
+ * three pieces only made sense together.
28
+ *
29
+ * See design/04-authorization.md, design/10-error-handling.md, TIM-666.
30
+ */
31
+
32
+ import { createElement } from 'react';
33
+
34
+ import { requestContextAls } from './als-registry.js';
35
+ import { DenySignal } from './primitives.js';
36
+ import { loadModule } from './safe-load.js';
37
+ import { withSpan } from './tracing.js';
38
+ import type { ManifestSegmentNode } from './route-matcher.js';
39
+
40
+ // ─── Types ────────────────────────────────────────────────────────────────
41
+
42
+ /** A single entry in the deny page fallback chain. */
43
+ export interface DenyPageEntry {
44
+ /** Status code filter: specific (403), category (400 = any 4xx), or null (catch-all). */
45
+ status: number | null;
46
+ /** The component to render (server or client — both work). */
47
+ component: (...args: unknown[]) => unknown;
48
+ }
49
+
50
+ // ─── Chain Construction ──────────────────────────────────────────────────
51
+
52
+ /**
53
+ * Build the deny page fallback chain from the segment chain.
54
+ *
55
+ * Walks segments from `startIndex` outward (toward root) and collects
56
+ * status-code file components in fallback order:
57
+ * 1. Specific status files (403.tsx, 404.tsx) — exact match
58
+ * 2. Category catch-alls (4xx.tsx) — matches any 4xx
59
+ * 3. error.tsx — catches everything
60
+ *
61
+ * Each segment is checked in this order. The chain is ordered so the
62
+ * FIRST match wins at catch time.
63
+ */
64
+ export async function buildDenyPageChain(
65
+ segments: ManifestSegmentNode[],
66
+ startIndex: number
67
+ ): Promise<DenyPageEntry[]> {
68
+ const chain: DenyPageEntry[] = [];
69
+
70
+ // Pass 1: Status files (specific + category) across ALL segments.
71
+ // These have higher priority than error.tsx — a root 4xx.tsx should
72
+ // match before a leaf error.tsx. Walking inner → outer ensures the
73
+ // nearest match wins within each priority tier.
74
+ for (let i = startIndex; i >= 0; i--) {
75
+ const segment = segments[i];
76
+ if (!segment.statusFiles) continue;
77
+
78
+ // Specific status files (403.tsx, 404.tsx, etc.)
79
+ for (const [key, file] of Object.entries(segment.statusFiles)) {
80
+ if (key !== '4xx' && key !== '5xx') {
81
+ const status = parseInt(key, 10);
82
+ if (!isNaN(status)) {
83
+ const mod = await loadModule(file).catch(() => null);
84
+ if (mod?.default) {
85
+ chain.push({ status, component: mod.default as (...args: unknown[]) => unknown });
86
+ }
87
+ }
88
+ }
89
+ }
90
+
91
+ // Category catch-alls (4xx.tsx, 5xx.tsx)
92
+ for (const [key, file] of Object.entries(segment.statusFiles)) {
93
+ if (key === '4xx' || key === '5xx') {
94
+ const mod = await loadModule(file).catch(() => null);
95
+ if (mod?.default) {
96
+ const categoryStatus = key === '4xx' ? 400 : 500;
97
+ chain.push({
98
+ status: categoryStatus,
99
+ component: mod.default as (...args: unknown[]) => unknown,
100
+ });
101
+ }
102
+ }
103
+ }
104
+ }
105
+
106
+ // Pass 2: error.tsx files — lowest priority catch-all.
107
+ // Only added AFTER all status files so they never shadow a specific
108
+ // or category status file from an ancestor segment.
109
+ for (let i = startIndex; i >= 0; i--) {
110
+ const segment = segments[i];
111
+ if (segment.error) {
112
+ const mod = await loadModule(segment.error).catch(() => null);
113
+ if (mod?.default) {
114
+ chain.push({ status: null, component: mod.default as (...args: unknown[]) => unknown });
115
+ }
116
+ }
117
+ }
118
+
119
+ return chain;
120
+ }
121
+
122
+ // ─── Runtime Matcher ──────────────────────────────────────────────────────
123
+
124
+ /**
125
+ * Find the first deny page in the chain that matches the given status code.
126
+ * Returns a React element for the matching component, or null if no match.
127
+ */
128
+ export function renderMatchingDenyPage(
129
+ chain: DenyPageEntry[],
130
+ status: number,
131
+ data: unknown
132
+ ): React.ReactElement | null {
133
+ const h = createElement as (...args: unknown[]) => React.ReactElement;
134
+
135
+ for (const entry of chain) {
136
+ if (entry.status === status) {
137
+ return h(entry.component, { status, dangerouslyPassData: data });
138
+ }
139
+ if (entry.status === 400 && status >= 400 && status <= 499) {
140
+ return h(entry.component, { status, dangerouslyPassData: data });
141
+ }
142
+ if (entry.status === 500 && status >= 500 && status <= 599) {
143
+ return h(entry.component, { status, dangerouslyPassData: data });
144
+ }
145
+ if (entry.status === null) {
146
+ return h(entry.component, { status, dangerouslyPassData: data });
147
+ }
148
+ }
149
+ return null;
150
+ }
151
+
152
+ // ─── Page Boundary ────────────────────────────────────────────────────────
153
+
154
+ /**
155
+ * Async server component that wraps a page call with DenySignal catching.
156
+ *
157
+ * Calls the page component as an async function (the same thing React
158
+ * Flight does internally), awaits it, and catches DenySignal. On catch,
159
+ * renders the matching deny page in-tree. On success, returns the page's
160
+ * rendered output normally.
161
+ *
162
+ * Client component pages ('use client') are NOT wrapped — they can't call
163
+ * deny() (server-only API) and must go through createElement normally.
164
+ *
165
+ * No error reaches React Flight — the Flight stream is clean, SSR succeeds,
166
+ * and the entire request uses a single renderToReadableStream call.
167
+ */
168
+ export async function PageDenyBoundary({
169
+ Page,
170
+ route,
171
+ denyPages,
172
+ }: {
173
+ /** The page server component function. */
174
+ Page: (...args: unknown[]) => unknown;
175
+ /** Route path for OTEL tracing. */
176
+ route: string;
177
+ /** Deny page fallback chain from the segment chain. */
178
+ denyPages: DenyPageEntry[];
179
+ }): Promise<React.ReactElement> {
180
+ try {
181
+ // Call the page as an async function — same as React Flight does.
182
+ // Wrap in OTEL span for tracing (replaces the TracedPage wrapper).
183
+ const result = await withSpan('timber.page', { 'timber.route': route }, () => Page({}));
184
+ return result as React.ReactElement;
185
+ } catch (error: unknown) {
186
+ if (error instanceof DenySignal) {
187
+ const denyElement = renderMatchingDenyPage(denyPages, error.status, error.data);
188
+ if (denyElement) {
189
+ setDenyStatus(error.status);
190
+ return denyElement;
191
+ }
192
+ }
193
+ // Non-deny errors (RedirectSignal, runtime errors) propagate normally.
194
+ throw error;
195
+ }
196
+ }
197
+
198
+ // ─── ALS Helpers ──────────────────────────────────────────────────────────
199
+
200
+ /**
201
+ * Set the deny status in the request context ALS.
202
+ * Called from AccessGate / PageDenyBoundary when a DenySignal is caught.
203
+ * The pipeline reads this after render to set the HTTP status code.
204
+ */
205
+ export function setDenyStatus(status: number): void {
206
+ const store = requestContextAls.getStore();
207
+ if (store) {
208
+ store.denyStatus = status;
209
+ }
210
+ }
211
+
212
+ /**
213
+ * Read the deny status from the request context ALS.
214
+ * Returns undefined if no deny was caught during render.
215
+ */
216
+ export function getDenyStatus(): number | undefined {
217
+ return requestContextAls.getStore()?.denyStatus;
218
+ }
@@ -16,18 +16,22 @@
16
16
  */
17
17
 
18
18
  import { createElement } from 'react';
19
- import { renderToReadableStream } from '#/rsc-runtime/rsc.js';
19
+ import { renderToReadableStream } from '../rsc-runtime/rsc.js';
20
20
 
21
21
  import { DenySignal } from './primitives.js';
22
22
  import { logRenderError } from './logger.js';
23
+ import { loadModule } from './safe-load.js';
23
24
  import { isDebug } from './debug.js';
25
+ import { escapeHtml } from './utils/escape-html.js';
24
26
  import { resolveMetadata, renderMetadataToElements } from './metadata.js';
25
- import { resolveManifestStatusFile } from './manifest-status-resolver.js';
27
+ import { resolveStatusFile } from './status-code-resolver.js';
26
28
  import type { ManifestSegmentNode } from './route-matcher.js';
27
29
  import type { RouteMatch } from './pipeline.js';
28
30
  import type { NavContext } from './ssr-entry.js';
31
+ import { flightInitScript } from './flight-scripts.js';
29
32
  import type { ClientBootstrapConfig } from './html-injectors.js';
30
33
  import type { Metadata } from './types.js';
34
+ import { teeWithErrorPropagation } from './stream-utils.js';
31
35
 
32
36
  /** RSC content type for client navigation payload requests. */
33
37
  const RSC_CONTENT_TYPE = 'text/x-component';
@@ -84,7 +88,7 @@ export async function renderDenyPage(
84
88
  }
85
89
 
86
90
  // Page routes → component chain first, JSON fallback only if no component found.
87
- const resolution = resolveManifestStatusFile(deny.status, segments, 'component');
91
+ const resolution = resolveStatusFile(deny.status, segments, 'component');
88
92
 
89
93
  // No component status file — try JSON chain before bare fallback
90
94
  if (!resolution) {
@@ -96,7 +100,7 @@ export async function renderDenyPage(
96
100
  // Dev warning: JSON status file exists but is shadowed by the component chain.
97
101
  // This helps developers understand why their .json file isn't being served.
98
102
  if (isDebug()) {
99
- const jsonResolution = resolveManifestStatusFile(deny.status, segments, 'json');
103
+ const jsonResolution = resolveStatusFile(deny.status, segments, 'json');
100
104
  if (jsonResolution) {
101
105
  console.warn(
102
106
  `[timber] ${jsonResolution.file.filePath} exists but is shadowed by ` +
@@ -108,7 +112,7 @@ export async function renderDenyPage(
108
112
  }
109
113
 
110
114
  // Load the status-code page component
111
- const mod = (await resolution.file.load()) as Record<string, unknown>;
115
+ const mod = await loadModule(resolution.file);
112
116
  if (!mod.default) {
113
117
  return new Response(null, { status: deny.status, headers: responseHeaders });
114
118
  }
@@ -116,9 +120,6 @@ export async function renderDenyPage(
116
120
  const ErrorPageComponent = mod.default as (...args: unknown[]) => unknown;
117
121
  const h = createElement as (...args: unknown[]) => React.ReactElement;
118
122
 
119
- // Check shell opt-out: export const shell = false
120
- const shellEnabled = mod.shell !== false;
121
-
122
123
  // 4xx status-code pages receive { status, dangerouslyPassData }
123
124
  // per design/10-error-handling.md §"Status-Code File Props"
124
125
  let element = h(ErrorPageComponent, {
@@ -126,23 +127,14 @@ export async function renderDenyPage(
126
127
  dangerouslyPassData: deny.data,
127
128
  });
128
129
 
129
- // Wrap in layouts unless shell is explicitly disabled
130
- if (shellEnabled) {
131
- const resolvedSegments = new Set(segments.slice(0, resolution.segmentIndex + 1));
132
- const layoutsToWrap = layoutComponents.filter((lc) => resolvedSegments.has(lc.segment));
133
- for (let i = layoutsToWrap.length - 1; i >= 0; i--) {
134
- const { component } = layoutsToWrap[i];
135
- element = h(component, null, element);
136
- }
137
- } else if (isDebug()) {
138
- // Dev-mode: warn if shell=false might conflict with Suspense
139
- // The actual Suspense boundary check happens at render time in the pipeline.
140
- // This is a preemptive log for developer awareness.
141
- console.warn(
142
- `[timber] Status-code file ${resolution.file.filePath} exports shell = false. ` +
143
- 'If deny() fires inside a Suspense boundary, layouts are already committed and ' +
144
- 'cannot be unwrapped. The shell opt-out will be ignored in that case.'
145
- );
130
+ // Always wrap in layout shell.
131
+ // NOTE: Shell opt-out (export const shell = false) is a future feature
132
+ // pending a proper design doc. See design backlog.
133
+ const resolvedSegments = new Set(segments.slice(0, resolution.segmentIndex + 1));
134
+ const layoutsToWrap = layoutComponents.filter((lc) => resolvedSegments.has(lc.segment));
135
+ for (let i = layoutsToWrap.length - 1; i >= 0; i--) {
136
+ const { component } = layoutsToWrap[i];
137
+ element = h(component, null, element);
146
138
  }
147
139
 
148
140
  // Build head HTML from error page metadata (if any)
@@ -170,15 +162,15 @@ export async function renderDenyPage(
170
162
  debugChannel: createDebugChannelSink(),
171
163
  });
172
164
 
173
- const [ssrStream, inlineStream] = rscStream.tee();
165
+ const [ssrStream, inlineStream] = teeWithErrorPropagation(rscStream);
174
166
 
175
167
  const navContext: NavContext = {
176
168
  pathname: new URL(req.url).pathname,
177
- params: match.params,
169
+ params: match.segmentParams,
178
170
  searchParams: Object.fromEntries(new URL(req.url).searchParams),
179
171
  statusCode: deny.status,
180
172
  responseHeaders,
181
- headHtml,
173
+ headHtml: headHtml + flightInitScript(),
182
174
  bootstrapScriptContent: clientBootstrap.bootstrapScriptContent,
183
175
  rscStream: inlineStream,
184
176
  };
@@ -199,14 +191,14 @@ export async function renderDenyPageAsRsc(
199
191
  responseHeaders: Headers,
200
192
  createDebugChannelSink: DebugChannelFactory
201
193
  ): Promise<Response> {
202
- const resolution = resolveManifestStatusFile(deny.status, segments, 'component');
194
+ const resolution = resolveStatusFile(deny.status, segments, 'component');
203
195
 
204
196
  if (!resolution) {
205
197
  responseHeaders.set('content-type', `${RSC_CONTENT_TYPE}; charset=utf-8`);
206
198
  return new Response(null, { status: deny.status, headers: responseHeaders });
207
199
  }
208
200
 
209
- const mod = (await resolution.file.load()) as Record<string, unknown>;
201
+ const mod = await loadModule(resolution.file);
210
202
  if (!mod.default) {
211
203
  responseHeaders.set('content-type', `${RSC_CONTENT_TYPE}; charset=utf-8`);
212
204
  return new Response(null, { status: deny.status, headers: responseHeaders });
@@ -215,22 +207,17 @@ export async function renderDenyPageAsRsc(
215
207
  const ErrorPageComponent = mod.default as (...args: unknown[]) => unknown;
216
208
  const h = createElement as (...args: unknown[]) => React.ReactElement;
217
209
 
218
- // Check shell opt-out
219
- const shellEnabled = mod.shell !== false;
220
-
221
210
  let element = h(ErrorPageComponent, {
222
211
  status: deny.status,
223
212
  dangerouslyPassData: deny.data,
224
213
  });
225
214
 
226
- // Wrap in layouts unless shell is explicitly disabled
227
- if (shellEnabled) {
228
- const resolvedSegments = new Set(segments.slice(0, resolution.segmentIndex + 1));
229
- const layoutsToWrap = layoutComponents.filter((lc) => resolvedSegments.has(lc.segment));
230
- for (let i = layoutsToWrap.length - 1; i >= 0; i--) {
231
- const { component } = layoutsToWrap[i];
232
- element = h(component, null, element);
233
- }
215
+ // Always wrap in layout shell.
216
+ const resolvedSegments = new Set(segments.slice(0, resolution.segmentIndex + 1));
217
+ const layoutsToWrap = layoutComponents.filter((lc) => resolvedSegments.has(lc.segment));
218
+ for (let i = layoutsToWrap.length - 1; i >= 0; i--) {
219
+ const { component } = layoutsToWrap[i];
220
+ element = h(component, null, element);
234
221
  }
235
222
 
236
223
  const rscStream = renderToReadableStream(element, {
@@ -263,7 +250,7 @@ async function renderDenyPageJson(
263
250
  segments: ManifestSegmentNode[],
264
251
  responseHeaders: Headers
265
252
  ): Promise<Response | null> {
266
- const resolution = resolveManifestStatusFile(deny.status, segments, 'json');
253
+ const resolution = resolveStatusFile(deny.status, segments, 'json');
267
254
 
268
255
  if (!resolution) {
269
256
  return null;
@@ -272,7 +259,7 @@ async function renderDenyPageJson(
272
259
  // JSON status files are loaded as modules that export the JSON content.
273
260
  // The manifest's load() imports the .json file, which Vite handles as a
274
261
  // default export of the parsed JSON object.
275
- const mod = (await resolution.file.load()) as Record<string, unknown>;
262
+ const mod = await loadModule(resolution.file);
276
263
  const jsonContent = mod.default ?? mod;
277
264
 
278
265
  responseHeaders.set('content-type', 'application/json; charset=utf-8');
@@ -294,10 +281,4 @@ function bareJsonResponse(status: number, responseHeaders: Headers): Response {
294
281
  });
295
282
  }
296
283
 
297
- function escapeHtml(str: string): string {
298
- return str
299
- .replace(/&/g, '&amp;')
300
- .replace(/</g, '&lt;')
301
- .replace(/>/g, '&gt;')
302
- .replace(/"/g, '&quot;');
303
- }
284
+ // escapeHtml imported from server/utils/escape-html.ts
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Dev-only error source-mapping bridge.
3
+ *
4
+ * Stores a callback that rewrites an error's stack trace using the Vite
5
+ * dev server's module graph. Set by the RSC entry on startup (via
6
+ * setDevSourceMapHandler), consumed by error renderers before generating
7
+ * error pages.
8
+ *
9
+ * In production, the callback is never set — all calls are no-ops.
10
+ *
11
+ * See TIM-811.
12
+ */
13
+
14
+ let _sourceMapError: ((error: Error) => void) | undefined;
15
+
16
+ /**
17
+ * Set the source-map callback. Called once during dev server initialization.
18
+ */
19
+ export function setSourceMapCallback(fn: (error: Error) => void): void {
20
+ _sourceMapError = fn;
21
+ }
22
+
23
+ /**
24
+ * Source-map an error's stack trace in-place if the callback is available.
25
+ * No-op in production or before the dev server initializes.
26
+ */
27
+ export function sourceMapError(error: unknown): void {
28
+ if (_sourceMapError && error instanceof Error) {
29
+ _sourceMapError(error);
30
+ }
31
+ }