@timber-js/app 0.2.0-alpha.191 → 0.2.0-alpha.194

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 (672) hide show
  1. package/agent-skill.md +2 -0
  2. package/dist/_chunks/{actions-BjbbNRFN.js → actions-CWYtq6ii.js} +3 -3
  3. package/dist/_chunks/actions-CWYtq6ii.js.map +1 -0
  4. package/dist/_chunks/als-registry-C6kcfprT.js.map +1 -1
  5. package/dist/_chunks/als-slots-BEEIPKYm.js.map +1 -1
  6. package/dist/_chunks/{build-output-helper-C3DrfzZR.js → build-output-helper-9dqCv1pZ.js} +3 -2
  7. package/dist/_chunks/build-output-helper-9dqCv1pZ.js.map +1 -0
  8. package/dist/_chunks/{cache-api-DllJ-Lyw.js → cache-api-CQeYzA5g.js} +6 -8
  9. package/dist/_chunks/cache-api-CQeYzA5g.js.map +1 -0
  10. package/dist/_chunks/chains-h7EO-u3n.js +412 -0
  11. package/dist/_chunks/chains-h7EO-u3n.js.map +1 -0
  12. package/dist/_chunks/{cli-check-DJZDc22E.js → cli-check-BVthpfLS.js} +43 -6
  13. package/dist/_chunks/cli-check-BVthpfLS.js.map +1 -0
  14. package/dist/_chunks/{cli-schema-sync-D4_AZVUb.js → cli-schema-sync-ZwM9u_ob.js} +6 -5
  15. package/dist/_chunks/{cli-schema-sync-D4_AZVUb.js.map → cli-schema-sync-ZwM9u_ob.js.map} +1 -1
  16. package/dist/_chunks/{cloudflare-CGP6BZKO.js → cloudflare-BKJC3SC_.js} +28 -22
  17. package/dist/_chunks/{cloudflare-CGP6BZKO.js.map → cloudflare-BKJC3SC_.js.map} +1 -1
  18. package/dist/_chunks/codec-registry-oOUxugz3.js.map +1 -1
  19. package/dist/_chunks/{convention-lint-CpteIpTm.js → convention-lint-DO10_pVl.js} +93 -7
  20. package/dist/_chunks/convention-lint-DO10_pVl.js.map +1 -0
  21. package/dist/_chunks/dist-DtrJyBbw.js +386 -0
  22. package/dist/_chunks/dist-DtrJyBbw.js.map +1 -0
  23. package/dist/_chunks/error-boundary-D-ODYX41.js.map +1 -1
  24. package/dist/_chunks/{file-cache-DmX7OqZP.js → file-cache-Dw6BJPG7.js} +5 -1
  25. package/dist/_chunks/{file-cache-DmX7OqZP.js.map → file-cache-Dw6BJPG7.js.map} +1 -1
  26. package/dist/_chunks/{format-CfwjgPz9.js → format-BKclgVbk.js} +3 -3
  27. package/dist/_chunks/{format-CfwjgPz9.js.map → format-BKclgVbk.js.map} +1 -1
  28. package/dist/_chunks/graph-cache-CP4GEmf9.js +304 -0
  29. package/dist/_chunks/graph-cache-CP4GEmf9.js.map +1 -0
  30. package/dist/_chunks/href-validation-CMc5JRls.js.map +1 -1
  31. package/dist/_chunks/live-graph-Bx4HodF1.js +150 -0
  32. package/dist/_chunks/live-graph-Bx4HodF1.js.map +1 -0
  33. package/dist/_chunks/{logger-CH7IcMmg.js → logger-pumCm3Il.js} +25 -7
  34. package/dist/_chunks/{logger-CH7IcMmg.js.map → logger-pumCm3Il.js.map} +1 -1
  35. package/dist/_chunks/{mdx-file-C005ay-P.js → mdx-file-CXyHGUpS.js} +3 -3
  36. package/dist/_chunks/mdx-file-CXyHGUpS.js.map +1 -0
  37. package/dist/_chunks/{plugin-context-rCinWLiE.js → plugin-context-8idfR3UZ.js} +2 -2
  38. package/dist/_chunks/plugin-context-8idfR3UZ.js.map +1 -0
  39. package/dist/_chunks/poison-rules-DoEhbqaY.js +110 -0
  40. package/dist/_chunks/poison-rules-DoEhbqaY.js.map +1 -0
  41. package/dist/_chunks/poison-scan-BAxfTT5L.js +101 -0
  42. package/dist/_chunks/poison-scan-BAxfTT5L.js.map +1 -0
  43. package/dist/_chunks/resolve-schema-CBR6Lm4i.js.map +1 -1
  44. package/dist/_chunks/rolldown-runtime-D7D4PA-g.js +13 -0
  45. package/dist/_chunks/router-ref-DuYuV_0Q.js.map +1 -1
  46. package/dist/_chunks/{rsc-media-type-DRqE_lD_.js → rsc-media-type-DDc7duTD.js} +17 -2
  47. package/dist/_chunks/{rsc-media-type-DRqE_lD_.js.map → rsc-media-type-DDc7duTD.js.map} +1 -1
  48. package/dist/_chunks/scan-BoP17W3w.js +140 -0
  49. package/dist/_chunks/scan-BoP17W3w.js.map +1 -0
  50. package/dist/_chunks/{scanner-CAietmj4.js → scanner-BRIOmHE2.js} +43 -4
  51. package/dist/_chunks/scanner-BRIOmHE2.js.map +1 -0
  52. package/dist/_chunks/schema-bridge-C83xa9lT.js.map +1 -1
  53. package/dist/_chunks/segment-classify-C539Pa2O.js.map +1 -1
  54. package/dist/_chunks/{segment-keys-BawYuNFO.js → segment-keys-BhqoHiLc.js} +14 -2
  55. package/dist/_chunks/{segment-keys-BawYuNFO.js.map → segment-keys-BhqoHiLc.js.map} +1 -1
  56. package/dist/_chunks/slot-params-BCTmZkQB.js.map +1 -1
  57. package/dist/_chunks/ssr-data-14MXm7Pj.js.map +1 -1
  58. package/dist/_chunks/use-query-states-I3JMng6J.js.map +1 -1
  59. package/dist/_chunks/use-segment-params-C4r4BD9T.js.map +1 -1
  60. package/dist/_chunks/{walkers-BsVLmD1S.js → walkers-uCu3WW6_.js} +9 -6
  61. package/dist/_chunks/{walkers-BsVLmD1S.js.map → walkers-uCu3WW6_.js.map} +1 -1
  62. package/dist/adapters/build-output-helper.d.ts +1 -1
  63. package/dist/adapters/build-output-helper.d.ts.map +1 -1
  64. package/dist/adapters/cloudflare-dev.d.ts.map +1 -1
  65. package/dist/adapters/cloudflare-dev.js +2 -1
  66. package/dist/adapters/cloudflare-dev.js.map +1 -1
  67. package/dist/adapters/cloudflare-kv-cache.d.ts +1 -1
  68. package/dist/adapters/cloudflare-kv-cache.d.ts.map +1 -1
  69. package/dist/adapters/cloudflare-kv-cache.js +7 -8
  70. package/dist/adapters/cloudflare-kv-cache.js.map +1 -1
  71. package/dist/adapters/cloudflare.d.ts +1 -1
  72. package/dist/adapters/cloudflare.d.ts.map +1 -1
  73. package/dist/adapters/cloudflare.js +1 -1
  74. package/dist/adapters/nitro-presets.d.ts +37 -0
  75. package/dist/adapters/nitro-presets.d.ts.map +1 -0
  76. package/dist/adapters/nitro-preview.d.ts +32 -0
  77. package/dist/adapters/nitro-preview.d.ts.map +1 -0
  78. package/dist/adapters/nitro.d.ts +28 -51
  79. package/dist/adapters/nitro.d.ts.map +1 -1
  80. package/dist/adapters/nitro.js +224 -171
  81. package/dist/adapters/nitro.js.map +1 -1
  82. package/dist/analyze/chains.d.ts +124 -0
  83. package/dist/analyze/chains.d.ts.map +1 -0
  84. package/dist/analyze/classify.d.ts +150 -0
  85. package/dist/analyze/classify.d.ts.map +1 -0
  86. package/dist/analyze/crawl-entry.d.ts +17 -0
  87. package/dist/analyze/crawl-entry.d.ts.map +1 -0
  88. package/dist/analyze/crawl-entry.js +313 -0
  89. package/dist/analyze/crawl-entry.js.map +1 -0
  90. package/dist/analyze/crawl.d.ts +134 -0
  91. package/dist/analyze/crawl.d.ts.map +1 -0
  92. package/dist/analyze/graph-cache.d.ts +104 -0
  93. package/dist/analyze/graph-cache.d.ts.map +1 -0
  94. package/dist/analyze/graph-command.d.ts +43 -0
  95. package/dist/analyze/graph-command.d.ts.map +1 -0
  96. package/dist/analyze/graph-command.js +472 -0
  97. package/dist/analyze/graph-command.js.map +1 -0
  98. package/dist/analyze/live-graph.d.ts +81 -0
  99. package/dist/analyze/live-graph.d.ts.map +1 -0
  100. package/dist/analyze/poison-rules.d.ts +72 -0
  101. package/dist/analyze/poison-rules.d.ts.map +1 -0
  102. package/dist/analyze/poison-scan.d.ts +48 -0
  103. package/dist/analyze/poison-scan.d.ts.map +1 -0
  104. package/dist/analyze/scan.d.ts +73 -0
  105. package/dist/analyze/scan.d.ts.map +1 -0
  106. package/dist/cache/cache-api.d.ts +2 -2
  107. package/dist/cache/cache-api.d.ts.map +1 -1
  108. package/dist/cache/index.d.ts +8 -8
  109. package/dist/cache/index.d.ts.map +1 -1
  110. package/dist/cache/index.js +1 -1
  111. package/dist/cache/redis-handler.d.ts +1 -1
  112. package/dist/cache/redis-handler.d.ts.map +1 -1
  113. package/dist/cache/stores/cloudflare-kv.d.ts +1 -1
  114. package/dist/cache/stores/cloudflare-kv.d.ts.map +1 -1
  115. package/dist/cache/stores/cloudflare-kv.js.map +1 -1
  116. package/dist/cache/stores/memory.d.ts +1 -1
  117. package/dist/cache/stores/memory.d.ts.map +1 -1
  118. package/dist/cache/stores/memory.js.map +1 -1
  119. package/dist/cache/stores/redis.d.ts +1 -1
  120. package/dist/cache/stores/redis.d.ts.map +1 -1
  121. package/dist/cache/stores/redis.js.map +1 -1
  122. package/dist/cache/stores/vercel.d.ts +1 -1
  123. package/dist/cache/stores/vercel.d.ts.map +1 -1
  124. package/dist/cache/stores/vercel.js.map +1 -1
  125. package/dist/cache/tag-aware-handler.d.ts +2 -2
  126. package/dist/cache/tag-aware-handler.d.ts.map +1 -1
  127. package/dist/cache/timber-cache.d.ts +1 -1
  128. package/dist/cache/timber-cache.d.ts.map +1 -1
  129. package/dist/cdn/cloudflare-purge.d.ts +1 -1
  130. package/dist/cdn/cloudflare-purge.d.ts.map +1 -1
  131. package/dist/cdn/cloudflare-purge.js.map +1 -1
  132. package/dist/cdn/fastly-purge.d.ts +1 -1
  133. package/dist/cdn/fastly-purge.d.ts.map +1 -1
  134. package/dist/cdn/fastly-purge.js.map +1 -1
  135. package/dist/cdn/index.d.ts +4 -4
  136. package/dist/cdn/index.d.ts.map +1 -1
  137. package/dist/cdn/workers-cache-purge.d.ts +5 -1
  138. package/dist/cdn/workers-cache-purge.d.ts.map +1 -1
  139. package/dist/cdn/workers-cache-purge.js.map +1 -1
  140. package/dist/cli-check.d.ts +10 -0
  141. package/dist/cli-check.d.ts.map +1 -1
  142. package/dist/cli.d.ts +12 -4
  143. package/dist/cli.d.ts.map +1 -1
  144. package/dist/cli.js +30 -6
  145. package/dist/cli.js.map +1 -1
  146. package/dist/client/browser-entry/hydrate.d.ts +2 -2
  147. package/dist/client/browser-entry/hydrate.d.ts.map +1 -1
  148. package/dist/client/browser-entry/post-hydration.d.ts +2 -2
  149. package/dist/client/browser-entry/router-init.d.ts +2 -2
  150. package/dist/client/browser-entry/rsc-stream.d.ts +1 -1
  151. package/dist/client/form.d.ts +2 -2
  152. package/dist/client/form.d.ts.map +1 -1
  153. package/dist/client/history.d.ts +2 -2
  154. package/dist/client/index.d.ts +18 -18
  155. package/dist/client/index.d.ts.map +1 -1
  156. package/dist/client/index.js.map +1 -1
  157. package/dist/client/internal.d.ts +19 -19
  158. package/dist/client/internal.d.ts.map +1 -1
  159. package/dist/client/internal.js +11 -15
  160. package/dist/client/internal.js.map +1 -1
  161. package/dist/client/link.d.ts +3 -3
  162. package/dist/client/navigation-commit.d.ts +5 -5
  163. package/dist/client/navigation-root.d.ts +1 -1
  164. package/dist/client/navigation-root.d.ts.map +1 -1
  165. package/dist/client/params-context.d.ts +3 -3
  166. package/dist/client/router-pipeline.d.ts +7 -7
  167. package/dist/client/router-ref.d.ts +1 -1
  168. package/dist/client/router-types.d.ts +6 -6
  169. package/dist/client/router-types.d.ts.map +1 -1
  170. package/dist/client/router.d.ts +1 -1
  171. package/dist/client/rsc-fetch.d.ts +4 -4
  172. package/dist/client/rsc-fetch.d.ts.map +1 -1
  173. package/dist/client/segment-cache.d.ts +2 -2
  174. package/dist/client/slot-provider.d.ts +1 -1
  175. package/dist/client/ssr-data.d.ts +2 -2
  176. package/dist/client/state.d.ts +4 -4
  177. package/dist/client/use-query-states.d.ts +1 -1
  178. package/dist/client/use-segment-params.d.ts +3 -3
  179. package/dist/codec.d.ts +2 -2
  180. package/dist/codec.js.map +1 -1
  181. package/dist/config-types.d.ts +24 -6
  182. package/dist/config-types.d.ts.map +1 -1
  183. package/dist/config-validation.d.ts +1 -1
  184. package/dist/cookies/define-cookie.d.ts +3 -3
  185. package/dist/cookies/index.d.ts +3 -3
  186. package/dist/cookies/index.js +3 -4
  187. package/dist/cookies/index.js.map +1 -1
  188. package/dist/cookies/json-cookie.d.ts +1 -1
  189. package/dist/dev-tools/404-page.d.ts +2 -2
  190. package/dist/dev-tools/error-page.d.ts +2 -2
  191. package/dist/dev-tools/index.d.ts +12 -12
  192. package/dist/dev-tools/instrumentation.d.ts +1 -1
  193. package/dist/dev-tools/logs.d.ts +1 -1
  194. package/dist/dev-tools/overlay.d.ts +2 -2
  195. package/dist/dev-tools/terminal.d.ts +1 -1
  196. package/dist/fonts/ast.d.ts +4 -4
  197. package/dist/fonts/bundle.d.ts +3 -3
  198. package/dist/fonts/css.d.ts +1 -1
  199. package/dist/fonts/dev-middleware.d.ts +1 -1
  200. package/dist/fonts/google.d.ts +1 -1
  201. package/dist/fonts/local.d.ts +1 -1
  202. package/dist/fonts/pipeline.d.ts +3 -3
  203. package/dist/fonts/transform.d.ts +2 -2
  204. package/dist/fonts/types.d.ts +1 -1
  205. package/dist/fonts/virtual-modules.d.ts +1 -1
  206. package/dist/index.d.ts +3 -3
  207. package/dist/index.d.ts.map +1 -1
  208. package/dist/index.js +816 -310
  209. package/dist/index.js.map +1 -1
  210. package/dist/params/codec-registry.d.ts +1 -1
  211. package/dist/params/define-schema.d.ts +2 -2
  212. package/dist/params/index.d.ts +4 -4
  213. package/dist/params/index.js.map +1 -1
  214. package/dist/params/resolve-schema.d.ts +1 -1
  215. package/dist/plugin-context.d.ts +9 -9
  216. package/dist/plugin-context.d.ts.map +1 -1
  217. package/dist/plugins/adapter-build.d.ts +2 -2
  218. package/dist/plugins/build-manifest.d.ts +2 -2
  219. package/dist/plugins/build-report.d.ts +5 -5
  220. package/dist/plugins/cache.d.ts +1 -1
  221. package/dist/plugins/callsite-jsx.d.ts +2 -2
  222. package/dist/plugins/chunks.d.ts +1 -1
  223. package/dist/plugins/chunks.d.ts.map +1 -1
  224. package/dist/plugins/cloudflare-wasm.d.ts +1 -1
  225. package/dist/plugins/content.d.ts +1 -1
  226. package/dist/plugins/content.d.ts.map +1 -1
  227. package/dist/plugins/dev-discovery.d.ts +123 -0
  228. package/dist/plugins/dev-discovery.d.ts.map +1 -0
  229. package/dist/plugins/dev-server.d.ts +1 -1
  230. package/dist/plugins/dev-server.d.ts.map +1 -1
  231. package/dist/plugins/entries.d.ts +1 -1
  232. package/dist/plugins/fonts.d.ts +3 -3
  233. package/dist/plugins/fonts.d.ts.map +1 -1
  234. package/dist/plugins/graph-endpoint.d.ts +112 -0
  235. package/dist/plugins/graph-endpoint.d.ts.map +1 -0
  236. package/dist/plugins/mdx.d.ts +18 -5
  237. package/dist/plugins/mdx.d.ts.map +1 -1
  238. package/dist/plugins/prebuilt-capture.d.ts +2 -2
  239. package/dist/plugins/prebuilt-options-analysis.d.ts +1 -1
  240. package/dist/plugins/prebuilt.d.ts +1 -1
  241. package/dist/plugins/prerender-sugar.d.ts +11 -14
  242. package/dist/plugins/prerender-sugar.d.ts.map +1 -1
  243. package/dist/plugins/request-dep/analysis.d.ts +1 -1
  244. package/dist/plugins/request-dep/index.d.ts +5 -5
  245. package/dist/plugins/request-dep/origin.d.ts +1 -1
  246. package/dist/plugins/routing.d.ts +1 -1
  247. package/dist/plugins/routing.d.ts.map +1 -1
  248. package/dist/plugins/server-bundle.d.ts.map +1 -1
  249. package/dist/plugins/shims.d.ts +1 -1
  250. package/dist/plugins/shims.d.ts.map +1 -1
  251. package/dist/plugins/static-build.d.ts +5 -5
  252. package/dist/routing/codegen-shared.d.ts +1 -1
  253. package/dist/routing/codegen-write.d.ts +1 -1
  254. package/dist/routing/codegen.d.ts +1 -1
  255. package/dist/routing/collision-probe.d.ts +1 -1
  256. package/dist/routing/collision-spaces.d.ts +1 -1
  257. package/dist/routing/convention-lint.d.ts +1 -1
  258. package/dist/routing/convention-lint.d.ts.map +1 -1
  259. package/dist/routing/index.d.ts +13 -13
  260. package/dist/routing/index.js +3 -3
  261. package/dist/routing/interception.d.ts +1 -1
  262. package/dist/routing/interception.d.ts.map +1 -1
  263. package/dist/routing/link-codegen.d.ts +1 -1
  264. package/dist/routing/manifest-codegen.d.ts +1 -1
  265. package/dist/routing/scanner.d.ts +14 -1
  266. package/dist/routing/scanner.d.ts.map +1 -1
  267. package/dist/routing/schema-validation.d.ts +1 -1
  268. package/dist/routing/segment-classify.d.ts +1 -1
  269. package/dist/routing/segment-codegen.d.ts +1 -1
  270. package/dist/routing/segment-keys.d.ts +1 -1
  271. package/dist/routing/slot-placement.d.ts +1 -1
  272. package/dist/routing/walkers.d.ts +1 -1
  273. package/dist/rsc-runtime/transforms.d.ts +13 -0
  274. package/dist/rsc-runtime/transforms.d.ts.map +1 -0
  275. package/dist/schema-bridge.d.ts +1 -1
  276. package/dist/search-params/define.d.ts +3 -3
  277. package/dist/search-params/index.d.ts +3 -3
  278. package/dist/search-params/index.js.map +1 -1
  279. package/dist/search-params/wrappers.d.ts +1 -1
  280. package/dist/server/access-gate.d.ts +1 -1
  281. package/dist/server/action-client.d.ts +1 -1
  282. package/dist/server/action-handler.d.ts +5 -5
  283. package/dist/server/actions.d.ts +2 -2
  284. package/dist/server/als-registry.d.ts +8 -8
  285. package/dist/server/asset-headers.d.ts +1 -1
  286. package/dist/server/chain-url-parts.d.ts +3 -3
  287. package/dist/server/children-interception.d.ts +2 -2
  288. package/dist/server/cookie-context.d.ts +1 -1
  289. package/dist/server/cookie-parsing.d.ts +2 -2
  290. package/dist/server/default-logger.d.ts +1 -1
  291. package/dist/server/deny-boundary.d.ts +2 -2
  292. package/dist/server/deny-renderer.d.ts +5 -5
  293. package/dist/server/early-hints.d.ts +1 -1
  294. package/dist/server/error-boundary-wrapper.d.ts +2 -4
  295. package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
  296. package/dist/server/fallback-error.d.ts +5 -5
  297. package/dist/server/flight-injection-state.d.ts +1 -1
  298. package/dist/server/form-flash.d.ts +1 -1
  299. package/dist/server/html-injector-core.d.ts +2 -2
  300. package/dist/server/html-injectors.d.ts +1 -1
  301. package/dist/server/index.d.ts +18 -18
  302. package/dist/server/index.d.ts.map +1 -1
  303. package/dist/server/index.js +33 -32
  304. package/dist/server/index.js.map +1 -1
  305. package/dist/server/instrumentation.d.ts +1 -1
  306. package/dist/server/internal.d.ts +50 -50
  307. package/dist/server/internal.d.ts.map +1 -1
  308. package/dist/server/internal.js +1023 -1025
  309. package/dist/server/internal.js.map +1 -1
  310. package/dist/server/metadata-collector.d.ts +2 -2
  311. package/dist/server/metadata-platform.d.ts +2 -2
  312. package/dist/server/metadata-render.d.ts +2 -2
  313. package/dist/server/metadata-routes.d.ts +3 -3
  314. package/dist/server/metadata-social.d.ts +2 -2
  315. package/dist/server/metadata.d.ts +2 -2
  316. package/dist/server/middleware-runner.d.ts +1 -1
  317. package/dist/server/node-stream-transforms.d.ts +1 -1
  318. package/dist/server/param-coercion.d.ts +4 -4
  319. package/dist/server/pipeline-helpers.d.ts +3 -3
  320. package/dist/server/pipeline-interception.d.ts +1 -1
  321. package/dist/server/pipeline-metadata.d.ts +1 -1
  322. package/dist/server/pipeline-outcome.d.ts +2 -2
  323. package/dist/server/pipeline-phases.d.ts +3 -3
  324. package/dist/server/pipeline-phases.d.ts.map +1 -1
  325. package/dist/server/pipeline.d.ts +9 -9
  326. package/dist/server/prebuilt/cache-key.d.ts +1 -1
  327. package/dist/server/prebuilt/capture-state.d.ts +1 -1
  328. package/dist/server/prebuilt/key-discipline.d.ts +1 -1
  329. package/dist/server/prebuilt/manifest-tag-index.d.ts +1 -1
  330. package/dist/server/prebuilt/overlay.d.ts +2 -2
  331. package/dist/server/prebuilt/payload-source.d.ts +1 -1
  332. package/dist/server/prebuilt/slots.d.ts +1 -1
  333. package/dist/server/prebuilt/synthetic-store.d.ts +2 -2
  334. package/dist/server/prebuilt-builder.d.ts +2 -2
  335. package/dist/server/primitives.d.ts +2 -2
  336. package/dist/server/publish-params.d.ts +1 -1
  337. package/dist/server/request-context.d.ts +3 -3
  338. package/dist/server/route-element-builder.d.ts +16 -6
  339. package/dist/server/route-element-builder.d.ts.map +1 -1
  340. package/dist/server/route-handler.d.ts +1 -1
  341. package/dist/server/route-matcher.d.ts +4 -4
  342. package/dist/server/rsc-cache-key-guard.d.ts.map +1 -1
  343. package/dist/server/rsc-entry/action-middleware-runner.d.ts +2 -2
  344. package/dist/server/rsc-entry/api-handler.d.ts +1 -1
  345. package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
  346. package/dist/server/rsc-entry/deny-fallback.d.ts +3 -3
  347. package/dist/server/rsc-entry/error-renderer.d.ts +4 -4
  348. package/dist/server/rsc-entry/helpers.d.ts +6 -6
  349. package/dist/server/rsc-entry/index.d.ts +7 -6
  350. package/dist/server/rsc-entry/index.d.ts.map +1 -1
  351. package/dist/server/rsc-entry/render-route.d.ts +4 -4
  352. package/dist/server/rsc-entry/revalidate-renderer.d.ts +4 -4
  353. package/dist/server/rsc-entry/rsc-payload.d.ts +4 -4
  354. package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
  355. package/dist/server/rsc-entry/rsc-stream.d.ts +3 -3
  356. package/dist/server/rsc-entry/ssr-bridge.d.ts +1 -1
  357. package/dist/server/rsc-entry/ssr-renderer.d.ts +7 -7
  358. package/dist/server/rsc-entry/wrap-action-dispatch.d.ts +5 -5
  359. package/dist/server/sitemap-generator.d.ts +2 -2
  360. package/dist/server/sitemap-handler.d.ts +1 -1
  361. package/dist/server/skippable-prefix.d.ts +3 -3
  362. package/dist/server/slot-interception.d.ts +2 -2
  363. package/dist/server/slot-resolver.d.ts +3 -7
  364. package/dist/server/slot-resolver.d.ts.map +1 -1
  365. package/dist/server/ssr-bridge-types.d.ts +2 -2
  366. package/dist/server/ssr-entry.d.ts +1 -1
  367. package/dist/server/static-generator.d.ts +1 -1
  368. package/dist/server/static-not-found.d.ts +1 -1
  369. package/dist/server/status-code-resolver.d.ts +1 -1
  370. package/dist/server/tracing.d.ts +3 -3
  371. package/dist/server/tree-builder.d.ts +3 -3
  372. package/dist/server/tree-match.d.ts +1 -1
  373. package/dist/server/types.d.ts +2 -2
  374. package/dist/server/utils/mdx-file.d.ts +2 -0
  375. package/dist/server/utils/mdx-file.d.ts.map +1 -1
  376. package/dist/server/workers-cache-bridge.d.ts +1 -1
  377. package/dist/shared/als-slots.d.ts +1 -1
  378. package/dist/shared/payload-root.d.ts +2 -2
  379. package/dist/shared/rsc-media-type.d.ts +12 -0
  380. package/dist/shared/rsc-media-type.d.ts.map +1 -1
  381. package/dist/shared/slot-params.d.ts +1 -1
  382. package/dist/shims/font-google.d.ts +1 -1
  383. package/dist/shims/font-google.js.map +1 -1
  384. package/dist/shims/font-local.d.ts +1 -1
  385. package/dist/shims/font-local.js.map +1 -1
  386. package/dist/shims/navigation-client.d.ts +4 -4
  387. package/dist/shims/navigation.d.ts +2 -2
  388. package/docs/api/34-api-config.mdx +9 -8
  389. package/docs/api/36-cli.mdx +23 -3
  390. package/docs/learn/11-error-handling.mdx +11 -0
  391. package/docs/more/01-advanced-routing.mdx +1 -0
  392. package/docs/more/04b-mdx.mdx +38 -18
  393. package/package.json +23 -18
  394. package/src/adapters/build-output-helper.ts +4 -4
  395. package/src/adapters/cloudflare-dev.ts +7 -1
  396. package/src/adapters/cloudflare-kv-cache.ts +11 -8
  397. package/src/adapters/cloudflare.ts +21 -15
  398. package/src/adapters/compress-module.ts +2 -2
  399. package/src/adapters/nitro-presets.ts +139 -0
  400. package/src/adapters/nitro-preview.ts +340 -0
  401. package/src/adapters/nitro.ts +100 -465
  402. package/src/adapters/shared.ts +1 -1
  403. package/src/analyze/chains.ts +411 -0
  404. package/src/analyze/classify.ts +258 -0
  405. package/src/analyze/crawl-entry.ts +68 -0
  406. package/src/analyze/crawl.ts +500 -0
  407. package/src/analyze/graph-cache.ts +332 -0
  408. package/src/analyze/graph-command.ts +762 -0
  409. package/src/analyze/live-graph.ts +232 -0
  410. package/src/analyze/poison-rules.ts +165 -0
  411. package/src/analyze/poison-scan.ts +162 -0
  412. package/src/analyze/scan.ts +149 -0
  413. package/src/cache/cache-api.ts +7 -7
  414. package/src/cache/index.ts +9 -9
  415. package/src/cache/redis-handler.ts +2 -2
  416. package/src/cache/stores/cloudflare-kv.ts +1 -1
  417. package/src/cache/stores/memory.ts +2 -2
  418. package/src/cache/stores/redis.ts +1 -1
  419. package/src/cache/stores/vercel.ts +1 -1
  420. package/src/cache/tag-aware-handler.ts +2 -2
  421. package/src/cache/timber-cache.ts +8 -8
  422. package/src/cdn/cloudflare-purge.ts +1 -1
  423. package/src/cdn/fastly-purge.ts +1 -1
  424. package/src/cdn/index.ts +10 -4
  425. package/src/cdn/workers-cache-purge.ts +6 -2
  426. package/src/cli-check.ts +53 -4
  427. package/src/cli-schema-sync.ts +3 -3
  428. package/src/cli.ts +50 -11
  429. package/src/client/browser-dev.ts +1 -1
  430. package/src/client/browser-entry/action-dispatch.ts +5 -5
  431. package/src/client/browser-entry/hmr.ts +1 -1
  432. package/src/client/browser-entry/hydrate.ts +9 -9
  433. package/src/client/browser-entry/index.ts +10 -10
  434. package/src/client/browser-entry/post-hydration.ts +5 -5
  435. package/src/client/browser-entry/router-init.ts +9 -9
  436. package/src/client/browser-entry/rsc-stream.ts +3 -3
  437. package/src/client/error-boundary.tsx +4 -4
  438. package/src/client/form.tsx +7 -2
  439. package/src/client/history.ts +2 -2
  440. package/src/client/index.ts +21 -18
  441. package/src/client/internal.ts +19 -19
  442. package/src/client/link.tsx +9 -9
  443. package/src/client/navigation-api.ts +1 -1
  444. package/src/client/navigation-commit.ts +5 -5
  445. package/src/client/navigation-context.ts +1 -1
  446. package/src/client/navigation-root.tsx +1 -1
  447. package/src/client/nuqs-adapter.tsx +2 -2
  448. package/src/client/params-context.ts +4 -4
  449. package/src/client/router-effects.ts +3 -3
  450. package/src/client/router-lifecycle.ts +2 -2
  451. package/src/client/router-pipeline.ts +10 -10
  452. package/src/client/router-ref.ts +2 -2
  453. package/src/client/router-skew.ts +2 -2
  454. package/src/client/router-types.ts +6 -6
  455. package/src/client/router.ts +13 -13
  456. package/src/client/rsc-fetch.ts +11 -16
  457. package/src/client/segment-cache.ts +2 -2
  458. package/src/client/segment-outlet.tsx +1 -1
  459. package/src/client/shallow-url.ts +1 -1
  460. package/src/client/slot-outlet.tsx +1 -1
  461. package/src/client/slot-provider.tsx +1 -1
  462. package/src/client/ssr-data.ts +3 -3
  463. package/src/client/stale-client.ts +1 -1
  464. package/src/client/state.ts +4 -4
  465. package/src/client/top-loader.tsx +1 -1
  466. package/src/client/unload-guard.ts +1 -1
  467. package/src/client/use-cookie.ts +2 -2
  468. package/src/client/use-pathname.ts +2 -2
  469. package/src/client/use-pending-navigation.ts +1 -1
  470. package/src/client/use-query-states.ts +3 -3
  471. package/src/client/use-router.ts +2 -2
  472. package/src/client/use-search-params.ts +3 -3
  473. package/src/client/use-segment-params.ts +6 -6
  474. package/src/client/use-selected-layout-segment.ts +2 -2
  475. package/src/codec.ts +2 -2
  476. package/src/config-types.ts +27 -7
  477. package/src/config-validation.ts +1 -1
  478. package/src/cookies/define-cookie.ts +6 -6
  479. package/src/cookies/index.ts +3 -3
  480. package/src/cookies/json-cookie.ts +1 -1
  481. package/src/dev-tools/404-page.ts +4 -4
  482. package/src/dev-tools/dev-page-shell.ts +1 -1
  483. package/src/dev-tools/error-page.ts +4 -4
  484. package/src/dev-tools/index.ts +12 -12
  485. package/src/dev-tools/instrumentation.ts +1 -1
  486. package/src/dev-tools/logs.ts +1 -1
  487. package/src/dev-tools/overlay.ts +3 -3
  488. package/src/dev-tools/terminal.ts +2 -2
  489. package/src/fonts/ast.ts +5 -5
  490. package/src/fonts/bundle.ts +5 -5
  491. package/src/fonts/css.ts +1 -1
  492. package/src/fonts/dev-middleware.ts +2 -2
  493. package/src/fonts/google.ts +2 -2
  494. package/src/fonts/local.ts +4 -4
  495. package/src/fonts/pipeline.ts +8 -8
  496. package/src/fonts/transform.ts +5 -5
  497. package/src/fonts/types.ts +1 -1
  498. package/src/fonts/virtual-modules.ts +1 -1
  499. package/src/index.ts +46 -37
  500. package/src/params/codec-registry.ts +1 -1
  501. package/src/params/define-schema.ts +2 -2
  502. package/src/params/index.ts +4 -4
  503. package/src/params/resolve-schema.ts +2 -2
  504. package/src/plugin-context.ts +10 -10
  505. package/src/plugins/adapter-build.ts +5 -5
  506. package/src/plugins/build-manifest.ts +4 -4
  507. package/src/plugins/build-report.ts +6 -6
  508. package/src/plugins/cache.ts +3 -3
  509. package/src/plugins/callsite-ast.ts +1 -1
  510. package/src/plugins/callsite-jsx.ts +2 -2
  511. package/src/plugins/chunks.ts +1 -1
  512. package/src/plugins/cloudflare-wasm.ts +1 -1
  513. package/src/plugins/content.ts +5 -1
  514. package/src/plugins/dev-discovery.ts +218 -0
  515. package/src/plugins/dev-server.ts +97 -12
  516. package/src/plugins/entries.ts +1 -1
  517. package/src/plugins/fonts.ts +17 -10
  518. package/src/plugins/graph-endpoint.ts +532 -0
  519. package/src/plugins/mdx.ts +73 -38
  520. package/src/plugins/prebuilt-capture.ts +3 -3
  521. package/src/plugins/prebuilt-options-analysis.ts +1 -1
  522. package/src/plugins/prebuilt.ts +7 -7
  523. package/src/plugins/prerender-sugar.ts +11 -19
  524. package/src/plugins/request-dep/analysis.ts +1 -1
  525. package/src/plugins/request-dep/index.ts +8 -8
  526. package/src/plugins/request-dep/origin.ts +1 -1
  527. package/src/plugins/routing.ts +12 -7
  528. package/src/plugins/server-bundle.ts +11 -3
  529. package/src/plugins/shims.ts +16 -31
  530. package/src/plugins/static-build.ts +10 -10
  531. package/src/routing/codegen-shared.ts +1 -1
  532. package/src/routing/codegen-write.ts +3 -3
  533. package/src/routing/codegen.ts +14 -5
  534. package/src/routing/collision-probe.ts +3 -3
  535. package/src/routing/collision-spaces.ts +3 -3
  536. package/src/routing/convention-lint.ts +136 -6
  537. package/src/routing/export-detect.ts +1 -1
  538. package/src/routing/index.ts +13 -13
  539. package/src/routing/interception.ts +41 -4
  540. package/src/routing/link-codegen.ts +3 -3
  541. package/src/routing/manifest-codegen.ts +2 -2
  542. package/src/routing/scanner.ts +33 -9
  543. package/src/routing/schema-validation.ts +4 -4
  544. package/src/routing/segment-classify.ts +2 -2
  545. package/src/routing/segment-codegen.ts +1 -1
  546. package/src/routing/segment-keys.ts +1 -1
  547. package/src/routing/slot-placement.ts +1 -1
  548. package/src/routing/walkers.ts +1 -1
  549. package/src/rsc-runtime/transforms.ts +13 -0
  550. package/src/rsc-runtime/vendor-types.d.ts +12 -0
  551. package/src/schema-bridge.ts +1 -1
  552. package/src/search-params/define.ts +8 -8
  553. package/src/search-params/index.ts +3 -3
  554. package/src/search-params/wrappers.ts +3 -3
  555. package/src/server/access-gate.tsx +6 -6
  556. package/src/server/action-client.ts +5 -5
  557. package/src/server/action-handler.ts +16 -16
  558. package/src/server/actions.ts +5 -5
  559. package/src/server/als-registry.ts +8 -8
  560. package/src/server/asset-headers.ts +2 -2
  561. package/src/server/chain-url-parts.ts +5 -5
  562. package/src/server/children-interception.ts +4 -4
  563. package/src/server/compress.ts +1 -1
  564. package/src/server/cookie-context.ts +4 -4
  565. package/src/server/cookie-parsing.ts +2 -2
  566. package/src/server/default-logger.ts +3 -3
  567. package/src/server/deny-boundary.ts +10 -10
  568. package/src/server/deny-renderer.ts +38 -25
  569. package/src/server/early-hints-sender.ts +2 -2
  570. package/src/server/early-hints.ts +2 -2
  571. package/src/server/error-boundary-wrapper.ts +4 -12
  572. package/src/server/fallback-error.ts +13 -13
  573. package/src/server/flight-injection-state.ts +1 -1
  574. package/src/server/form-flash.ts +2 -2
  575. package/src/server/html-injector-core.ts +4 -4
  576. package/src/server/html-injectors.ts +5 -5
  577. package/src/server/index.ts +18 -18
  578. package/src/server/instrumentation.ts +1 -1
  579. package/src/server/internal.ts +50 -50
  580. package/src/server/logger.ts +4 -4
  581. package/src/server/metadata-collector.ts +7 -7
  582. package/src/server/metadata-platform.ts +2 -2
  583. package/src/server/metadata-render.ts +4 -4
  584. package/src/server/metadata-routes.ts +3 -3
  585. package/src/server/metadata-social.ts +2 -2
  586. package/src/server/metadata.ts +2 -2
  587. package/src/server/middleware-runner.ts +1 -1
  588. package/src/server/node-stream-transforms.ts +4 -4
  589. package/src/server/param-coercion.ts +8 -8
  590. package/src/server/pipeline-helpers.ts +7 -7
  591. package/src/server/pipeline-interception.ts +2 -2
  592. package/src/server/pipeline-metadata.ts +1 -1
  593. package/src/server/pipeline-outcome.ts +8 -8
  594. package/src/server/pipeline-phases.ts +24 -28
  595. package/src/server/pipeline.ts +22 -22
  596. package/src/server/prebuilt/cache-key.ts +1 -1
  597. package/src/server/prebuilt/capture-state.ts +1 -1
  598. package/src/server/prebuilt/key-discipline.ts +1 -1
  599. package/src/server/prebuilt/manifest-tag-index.ts +1 -1
  600. package/src/server/prebuilt/overlay.ts +6 -6
  601. package/src/server/prebuilt/payload-source.ts +2 -2
  602. package/src/server/prebuilt/slots.ts +5 -5
  603. package/src/server/prebuilt/synthetic-store.ts +2 -2
  604. package/src/server/prebuilt-builder.ts +16 -16
  605. package/src/server/prebuilt-runtime.ts +12 -12
  606. package/src/server/primitives.ts +7 -7
  607. package/src/server/publish-params.ts +3 -3
  608. package/src/server/request-context.ts +7 -7
  609. package/src/server/route-element-builder.ts +108 -50
  610. package/src/server/route-handler.ts +4 -4
  611. package/src/server/route-matcher.ts +5 -5
  612. package/src/server/rsc-cache-key-guard.ts +3 -5
  613. package/src/server/rsc-entry/action-middleware-runner.ts +7 -7
  614. package/src/server/rsc-entry/api-handler.ts +18 -9
  615. package/src/server/rsc-entry/deny-fallback.ts +10 -10
  616. package/src/server/rsc-entry/error-renderer.ts +27 -27
  617. package/src/server/rsc-entry/helpers.ts +10 -10
  618. package/src/server/rsc-entry/index.ts +51 -47
  619. package/src/server/rsc-entry/render-route.ts +20 -20
  620. package/src/server/rsc-entry/revalidate-renderer.ts +12 -12
  621. package/src/server/rsc-entry/rsc-payload.ts +19 -15
  622. package/src/server/rsc-entry/rsc-stream.ts +8 -8
  623. package/src/server/rsc-entry/ssr-bridge.ts +3 -3
  624. package/src/server/rsc-entry/ssr-renderer.ts +23 -23
  625. package/src/server/rsc-entry/wrap-action-dispatch.ts +9 -9
  626. package/src/server/rsc-prop-warnings.ts +1 -1
  627. package/src/server/sensitive-fields.ts +1 -1
  628. package/src/server/server-timing.ts +1 -1
  629. package/src/server/sitemap-generator.ts +3 -3
  630. package/src/server/sitemap-handler.ts +3 -3
  631. package/src/server/skippable-prefix.ts +7 -7
  632. package/src/server/slot-interception.ts +5 -5
  633. package/src/server/slot-resolver.ts +20 -28
  634. package/src/server/ssr-bridge-types.ts +2 -2
  635. package/src/server/ssr-entry.ts +18 -18
  636. package/src/server/ssr-render.ts +4 -4
  637. package/src/server/ssr-wrappers.tsx +1 -1
  638. package/src/server/state-tree-diff.ts +1 -1
  639. package/src/server/static-generator.ts +6 -6
  640. package/src/server/static-not-found.ts +3 -3
  641. package/src/server/status-code-resolver.ts +1 -1
  642. package/src/server/tracing.ts +5 -5
  643. package/src/server/tree-builder.ts +4 -4
  644. package/src/server/tree-match.ts +1 -1
  645. package/src/server/types.ts +2 -2
  646. package/src/server/utils/mdx-file.ts +2 -2
  647. package/src/server/waituntil-bridge.ts +1 -1
  648. package/src/server/workers-cache-bridge.ts +2 -2
  649. package/src/shared/als-slots.ts +1 -1
  650. package/src/shared/payload-root.ts +2 -2
  651. package/src/shared/rsc-media-type.ts +16 -0
  652. package/src/shared/slot-params.ts +1 -1
  653. package/src/shims/font-google.ts +1 -1
  654. package/src/shims/font-local.ts +1 -1
  655. package/src/shims/navigation-client.ts +5 -5
  656. package/src/shims/navigation.ts +2 -2
  657. package/LICENSE +0 -8
  658. package/dist/_chunks/actions-BjbbNRFN.js.map +0 -1
  659. package/dist/_chunks/build-output-helper-C3DrfzZR.js.map +0 -1
  660. package/dist/_chunks/cache-api-DllJ-Lyw.js.map +0 -1
  661. package/dist/_chunks/cli-check-DJZDc22E.js.map +0 -1
  662. package/dist/_chunks/convention-lint-CpteIpTm.js.map +0 -1
  663. package/dist/_chunks/dist-BA3u1z3W.js +0 -423
  664. package/dist/_chunks/dist-BA3u1z3W.js.map +0 -1
  665. package/dist/_chunks/mdx-file-C005ay-P.js.map +0 -1
  666. package/dist/_chunks/plugin-context-rCinWLiE.js.map +0 -1
  667. package/dist/_chunks/scanner-CAietmj4.js.map +0 -1
  668. package/dist/content/index.d.ts +0 -2
  669. package/dist/content/index.d.ts.map +0 -1
  670. package/dist/content/index.js +0 -0
  671. package/src/content/index.ts +0 -5
  672. package/src/shims/server-only-noop.js +0 -6
package/dist/index.js CHANGED
@@ -1,22 +1,25 @@
1
- import { a as __esmMin, o as __exportAll, s as __toCommonJS } from "./_chunks/dist-BA3u1z3W.js";
2
- import { t as RSC_CONTENT_TYPE } from "./_chunks/rsc-media-type-DRqE_lD_.js";
3
- import { a as canonicalize, d as isMetadataRouteServePath, u as isDynamicMetadataExtension } from "./_chunks/segment-keys-BawYuNFO.js";
4
- import { n as collectInterceptionRewrites, r as matchUrlParts, t as scanRoutes } from "./_chunks/scanner-CAietmj4.js";
5
- import { h as swallow } from "./_chunks/logger-CH7IcMmg.js";
6
- import { c as writeRouteCodegen, i as getPrerenderExport, l as buildDirToRouteMap, n as formatConventionWarnings, r as lintConventions, s as flushCodegenWrites, t as checkAppDirExists } from "./_chunks/convention-lint-CpteIpTm.js";
7
- import { c as resolveClientJavascript, i as mergeFileConfig, l as createNoopTimer, o as resolveAppDir, r as loadTimberConfigFile, s as resolveBuildDir, t as createPluginContext } from "./_chunks/plugin-context-rCinWLiE.js";
8
- import { r as validateSchemaAgainstRoutes, t as collectLeafRoutes } from "./_chunks/walkers-BsVLmD1S.js";
1
+ import { l as registerDevDiscovery } from "./_chunks/graph-cache-CP4GEmf9.js";
2
+ import { n as isScannableSourceFile, t as buildSourceExtensions } from "./_chunks/scan-BoP17W3w.js";
3
+ import { t as RSC_CONTENT_TYPE } from "./_chunks/rsc-media-type-DDc7duTD.js";
4
+ import { a as canonicalize, d as isMetadataRouteServePath, u as isDynamicMetadataExtension } from "./_chunks/segment-keys-BhqoHiLc.js";
5
+ import { i as matchUrlParts, n as scanRoutes, r as collectInterceptionRewrites } from "./_chunks/scanner-BRIOmHE2.js";
6
+ import { t as MDX_EXTENSIONS } from "./_chunks/mdx-file-CXyHGUpS.js";
7
+ import { h as swallow } from "./_chunks/logger-pumCm3Il.js";
8
+ import { c as writeRouteCodegen, i as getPrerenderExport, l as buildDirToRouteMap, n as formatConventionWarnings, r as lintConventions, s as flushCodegenWrites, t as checkAppDirExists } from "./_chunks/convention-lint-DO10_pVl.js";
9
+ import { c as resolveClientJavascript, i as mergeFileConfig, l as createNoopTimer, o as resolveAppDir, r as loadTimberConfigFile, s as resolveBuildDir, t as createPluginContext } from "./_chunks/plugin-context-8idfR3UZ.js";
10
+ import { r as validateSchemaAgainstRoutes, t as collectLeafRoutes } from "./_chunks/walkers-uCu3WW6_.js";
11
+ import { i as poisonPillSource, r as markerFor, t as EXPLICIT_MARKERS } from "./_chunks/poison-rules-DoEhbqaY.js";
9
12
  import { i as withBasePath, n as normalizeBasePath, t as isRelativeBase } from "./_chunks/base-path-DaQrzbez.js";
10
13
  import { t as rscPayloadPath } from "./_chunks/rsc-payload-path-B_LBodc2.js";
11
14
  import { a as REDIRECTS_FILE, n as detectFsIdentity, o as RESERVED_OUTPUT_PATHS, r as fsKey, t as EXACT_FS_IDENTITY } from "./_chunks/fs-identity-D7vb6GdI.js";
12
15
  import { t as EMPTY_BUILD_MANIFEST } from "./_chunks/build-manifest-DWppEdLB.js";
13
16
  import { t as fnv1aHash } from "./_chunks/fast-hash-C-tVYrLb.js";
14
- import { t as formatSize } from "./_chunks/format-CfwjgPz9.js";
15
- import { createLogger, parseAst } from "vite";
17
+ import { t as formatSize } from "./_chunks/format-BKclgVbk.js";
18
+ import { createLogger, normalizePath, parseAst } from "vite";
16
19
  import { basename, dirname, extname, isAbsolute, join, normalize, relative, resolve, win32 } from "node:path";
17
20
  import { builtinModules, createRequire } from "node:module";
18
21
  import react, { reactCompilerPreset } from "@vitejs/plugin-react";
19
- import { existsSync, readFileSync, statSync } from "node:fs";
22
+ import { existsSync, readFileSync, realpathSync, statSync } from "node:fs";
20
23
  import nodeHTTP from "node:http";
21
24
  import { Readable, pipeline } from "node:stream";
22
25
  import { pipeline as pipeline$1 } from "node:stream/promises";
@@ -24,9 +27,10 @@ import "node:https";
24
27
  import "node:http2";
25
28
  import { fileURLToPath, pathToFileURL } from "node:url";
26
29
  import { styleText } from "node:util";
27
- import { constants, createGzip, gzipSync } from "node:zlib";
28
30
  import { createHash, randomUUID } from "node:crypto";
29
- import { copyFile, mkdir, readFile, readdir, rename, rm, stat, writeFile } from "node:fs/promises";
31
+ import { copyFile, mkdir, readFile, readdir, realpath, rename, rm, stat, writeFile } from "node:fs/promises";
32
+ import { isIP } from "node:net";
33
+ import { constants, createGzip, gzipSync } from "node:zlib";
30
34
  //#region src/plugins/content.ts
31
35
  var CONFIG_FILE_NAMES$1 = [
32
36
  "content-collections.ts",
@@ -106,13 +110,14 @@ function timberContent(ctx) {
106
110
  return null;
107
111
  },
108
112
  async configureServer(server) {
113
+ if (process.env.TIMBER_ANALYZE === "1") return;
109
114
  if (!innerPlugin) return;
110
115
  if (typeof innerPlugin.configureServer === "function") await innerPlugin.configureServer.call(this, server);
111
116
  }
112
117
  };
113
118
  }
114
119
  //#endregion
115
- //#region ../../node_modules/.pnpm/srvx@0.12.0/node_modules/srvx/dist/adapters/node.mjs
120
+ //#region ../../node_modules/.pnpm/srvx@0.12.5/node_modules/srvx/dist/adapters/node.mjs
116
121
  function sendNodeResponse(nodeRes, webRes) {
117
122
  try {
118
123
  return _sendNodeResponse(nodeRes, webRes, false) || Promise.resolve();
@@ -397,7 +402,8 @@ var _traceMapping = null;
397
402
  */
398
403
  function getTraceMapping() {
399
404
  if (_traceMapping) return _traceMapping;
400
- _traceMapping = createRequire(createRequire(import.meta.url).resolve("vite"))("@jridgewell/trace-mapping");
405
+ const vitePath = createRequire(import.meta.url).resolve("vite");
406
+ _traceMapping = createRequire(vitePath)("@jridgewell/trace-mapping");
401
407
  return _traceMapping;
402
408
  }
403
409
  /** Labels for terminal output. */
@@ -1143,13 +1149,31 @@ var ERROR_CSS = `
1143
1149
  *
1144
1150
  * Design doc: 18-build-system.md
1145
1151
  */
1146
- var config_validation_exports = /* @__PURE__ */ __exportAll({
1147
- addVirtualModuleContext: () => addVirtualModuleContext,
1148
- checkPeerDependencies: () => checkPeerDependencies,
1149
- formatConfigErrors: () => formatConfigErrors,
1150
- formatMissingPeers: () => formatMissingPeers,
1151
- validateConfig: () => validateConfig
1152
- });
1152
+ var knownKeys = new Set(Object.keys({
1153
+ output: true,
1154
+ debug: true,
1155
+ clientJavascript: true,
1156
+ adapter: true,
1157
+ allowedOrigins: true,
1158
+ csrf: true,
1159
+ limits: true,
1160
+ forms: true,
1161
+ pageExtensions: true,
1162
+ slowRequestMs: true,
1163
+ renderTimeoutMs: true,
1164
+ devBrowserLogs: true,
1165
+ dev: true,
1166
+ serverTiming: true,
1167
+ appDir: true,
1168
+ mdx: true,
1169
+ actionEncryption: true,
1170
+ reactCompiler: true,
1171
+ sitemap: true,
1172
+ buildDir: true,
1173
+ clientSegmentCache: true,
1174
+ topLoader: true,
1175
+ budget: true
1176
+ }));
1153
1177
  /**
1154
1178
  * Validate a TimberUserConfig object.
1155
1179
  *
@@ -1164,29 +1188,31 @@ function validateConfig(config) {
1164
1188
  value: config.output,
1165
1189
  suggestion: "Use output: \"server\" (default) or output: \"static\" for static site generation."
1166
1190
  });
1167
- if (config.pageExtensions !== void 0) if (!Array.isArray(config.pageExtensions)) errors.push({
1168
- field: "pageExtensions",
1169
- message: "pageExtensions must be an array of strings.",
1170
- value: config.pageExtensions,
1171
- suggestion: "Example: pageExtensions: [\"tsx\", \"ts\", \"jsx\", \"js\", \"mdx\"]"
1172
- });
1173
- else for (const ext of config.pageExtensions) {
1174
- if (typeof ext !== "string") {
1175
- errors.push({
1176
- field: "pageExtensions",
1177
- message: `pageExtensions contains a non-string value: ${JSON.stringify(ext)}`,
1178
- value: ext
1179
- });
1180
- break;
1181
- }
1182
- if (ext.startsWith(".")) {
1183
- errors.push({
1184
- field: "pageExtensions",
1185
- message: `pageExtensions should not include the leading dot: "${ext}"`,
1186
- value: ext,
1187
- suggestion: `Use "${ext.slice(1)}" instead of "${ext}".`
1188
- });
1189
- break;
1191
+ if (config.pageExtensions !== void 0) {
1192
+ if (!Array.isArray(config.pageExtensions)) errors.push({
1193
+ field: "pageExtensions",
1194
+ message: "pageExtensions must be an array of strings.",
1195
+ value: config.pageExtensions,
1196
+ suggestion: "Example: pageExtensions: [\"tsx\", \"ts\", \"jsx\", \"js\", \"mdx\"]"
1197
+ });
1198
+ else for (const ext of config.pageExtensions) {
1199
+ if (typeof ext !== "string") {
1200
+ errors.push({
1201
+ field: "pageExtensions",
1202
+ message: `pageExtensions contains a non-string value: ${JSON.stringify(ext)}`,
1203
+ value: ext
1204
+ });
1205
+ break;
1206
+ }
1207
+ if (ext.startsWith(".")) {
1208
+ errors.push({
1209
+ field: "pageExtensions",
1210
+ message: `pageExtensions should not include the leading dot: "${ext}"`,
1211
+ value: ext,
1212
+ suggestion: `Use "${ext.slice(1)}" instead of "${ext}".`
1213
+ });
1214
+ break;
1215
+ }
1190
1216
  }
1191
1217
  }
1192
1218
  if (config.slowRequestMs !== void 0) {
@@ -1255,6 +1281,10 @@ function validateConfig(config) {
1255
1281
  });
1256
1282
  return errors;
1257
1283
  }
1284
+ var RED = "\x1B[31m";
1285
+ var BOLD = "\x1B[1m";
1286
+ var DIM = "\x1B[2m";
1287
+ var RESET = "\x1B[0m";
1258
1288
  /**
1259
1289
  * Format config errors for terminal output.
1260
1290
  */
@@ -1269,6 +1299,16 @@ function formatConfigErrors(errors) {
1269
1299
  }
1270
1300
  return lines.join("\n");
1271
1301
  }
1302
+ var VIRTUAL_MODULE_NAMES = {
1303
+ "virtual:timber-rsc-entry": "RSC entry (server component handler)",
1304
+ "virtual:timber-ssr-entry": "SSR entry (HTML renderer)",
1305
+ "virtual:timber-browser-entry": "Browser entry (client hydration)",
1306
+ "virtual:timber-config": "Runtime config (timber.config.ts)",
1307
+ "virtual:timber-route-manifest": "Route manifest (app/ file tree)",
1308
+ "virtual:timber-instrumentation": "Instrumentation (instrumentation.ts)",
1309
+ "virtual:timber-cache-handler": "Cache handler (timber.cache.ts)",
1310
+ "virtual:timber-build-manifest": "Build manifest (asset mapping)"
1311
+ };
1272
1312
  /**
1273
1313
  * Add timber-specific context to an error message that references virtual modules.
1274
1314
  *
@@ -1280,6 +1320,15 @@ function addVirtualModuleContext(errorMessage) {
1280
1320
  return errorMessage;
1281
1321
  }
1282
1322
  /**
1323
+ * Required (non-optional) peer dependencies that must be installed.
1324
+ */
1325
+ var REQUIRED_PEERS = [
1326
+ "react",
1327
+ "react-dom",
1328
+ "@vitejs/plugin-react",
1329
+ "@vitejs/plugin-rsc"
1330
+ ];
1331
+ /**
1283
1332
  * Check that required peer dependencies are installed.
1284
1333
  *
1285
1334
  * Uses require.resolve with a try/catch — no fs scanning.
@@ -1318,57 +1367,325 @@ function formatMissingPeers(results) {
1318
1367
  lines.push(` ${BOLD}pnpm add ${names.join(" ")}${RESET}`);
1319
1368
  return lines.join("\n");
1320
1369
  }
1321
- var knownKeys, RED, BOLD, DIM, RESET, VIRTUAL_MODULE_NAMES, REQUIRED_PEERS;
1322
- var init_config_validation = __esmMin((() => {
1323
- knownKeys = new Set(Object.keys({
1324
- output: true,
1325
- debug: true,
1326
- clientJavascript: true,
1327
- adapter: true,
1328
- allowedOrigins: true,
1329
- csrf: true,
1330
- limits: true,
1331
- forms: true,
1332
- pageExtensions: true,
1333
- slowRequestMs: true,
1334
- renderTimeoutMs: true,
1335
- devBrowserLogs: true,
1336
- dev: true,
1337
- serverTiming: true,
1338
- appDir: true,
1339
- mdx: true,
1340
- actionEncryption: true,
1341
- reactCompiler: true,
1342
- sitemap: true,
1343
- buildDir: true,
1344
- clientSegmentCache: true,
1345
- topLoader: true,
1346
- budget: true
1347
- }));
1348
- RED = "\x1B[31m";
1349
- BOLD = "\x1B[1m";
1350
- DIM = "\x1B[2m";
1351
- RESET = "\x1B[0m";
1352
- VIRTUAL_MODULE_NAMES = {
1353
- "virtual:timber-rsc-entry": "RSC entry (server component handler)",
1354
- "virtual:timber-ssr-entry": "SSR entry (HTML renderer)",
1355
- "virtual:timber-browser-entry": "Browser entry (client hydration)",
1356
- "virtual:timber-config": "Runtime config (timber.config.ts)",
1357
- "virtual:timber-route-manifest": "Route manifest (app/ file tree)",
1358
- "virtual:timber-instrumentation": "Instrumentation (instrumentation.ts)",
1359
- "virtual:timber-cache-handler": "Cache handler (timber.cache.ts)",
1360
- "virtual:timber-build-manifest": "Build manifest (asset mapping)"
1370
+ /** HMR custom event name for graph-affecting file changes. */
1371
+ var GRAPH_UPDATE_EVENT = "timber:graph-update";
1372
+ /**
1373
+ * Host-header allowlist check, ported branch-for-branch from Vite's
1374
+ * host-validation middleware (`isHostAllowedWithoutCache`) so this
1375
+ * endpoint's reachability matches the rest of the dev server:
1376
+ *
1377
+ * - `allowedHosts: true` allows everything
1378
+ * - a MISSING Host header is allowed (Vite parity — HTTP/1.0 probes)
1379
+ * - any IP-literal host is allowed (`vite --host` LAN access sends
1380
+ * `Host: 192.168.x.x:port`; rejecting it would 403 this endpoint
1381
+ * while every other dev route works)
1382
+ * - `localhost` and `*.localhost` are always allowed
1383
+ * - allowedHosts entries: exact match, or `.suffix` subdomain entries
1384
+ */
1385
+ function isAllowedGraphHost(hostHeader, allowedHosts) {
1386
+ if (allowedHosts === true) return true;
1387
+ if (hostHeader === void 0) return true;
1388
+ let host = hostHeader;
1389
+ const bracket = host.match(/^\[([^\]]+)\](?::\d+)?$/);
1390
+ if (bracket) return isIP(bracket[1]) === 6;
1391
+ const colon = host.lastIndexOf(":");
1392
+ if (colon !== -1) host = host.slice(0, colon);
1393
+ host = host.toLowerCase();
1394
+ if (isIP(host) !== 0) return true;
1395
+ if (host === "localhost" || host.endsWith(".localhost")) return true;
1396
+ for (const entry of allowedHosts ?? []) {
1397
+ const allowed = entry.toLowerCase();
1398
+ if (allowed.startsWith(".")) {
1399
+ if (host === allowed.slice(1) || host.endsWith(allowed)) return true;
1400
+ } else if (host === allowed) return true;
1401
+ }
1402
+ return false;
1403
+ }
1404
+ /**
1405
+ * Non-http(s) origins admitted without a host check: Vite's own
1406
+ * `file:` / `*-extension:` set (its host-validation regex), plus
1407
+ * `vscode-webview:` — VS Code webviews fetch with that Origin, and the
1408
+ * extension is this endpoint's primary consumer. Vite itself never
1409
+ * origin-checks plain HTTP GETs (only WebSocket upgrades), so this
1410
+ * layer is strictly additional; the additions keep it from rejecting
1411
+ * consumers Vite would serve.
1412
+ *
1413
+ * NOT admitted: `Origin: null`. Browsers serialize file:// pages'
1414
+ * opaque origin as the literal string `null` — but so do sandboxed
1415
+ * iframes and data: documents, exactly the untrusted embedders the
1416
+ * check exists to stop, and the header offers nothing to tell them
1417
+ * apart. file:// pages therefore cannot use this endpoint from a
1418
+ * browser; the `file:` scheme entry covers non-browser clients that
1419
+ * send a real scheme-form Origin (Vite admits the same set).
1420
+ */
1421
+ var TRUSTED_ORIGIN_SCHEMES = /^(?:file|vscode-webview|.+-extension):/i;
1422
+ /** Origin check: absent is fine (CLI probe); present must pass the host allowlist. */
1423
+ function isAllowedGraphOrigin(originHeader, allowedHosts) {
1424
+ if (originHeader === void 0) return true;
1425
+ if (TRUSTED_ORIGIN_SCHEMES.test(originHeader)) return true;
1426
+ let originUrl;
1427
+ try {
1428
+ originUrl = new URL(originHeader);
1429
+ } catch {
1430
+ return false;
1431
+ }
1432
+ if (originUrl.host === "") return false;
1433
+ const bareHost = originUrl.hostname.replace(/^\[|\]$/g, "");
1434
+ if (isIP(bareHost) !== 0) {
1435
+ if (bareHost === "127.0.0.1" || bareHost === "::1") return true;
1436
+ if (allowedHosts === true) return true;
1437
+ return (allowedHosts ?? []).some((entry) => entry.toLowerCase() === bareHost);
1438
+ }
1439
+ return isAllowedGraphHost(originUrl.host, allowedHosts);
1440
+ }
1441
+ function sendJson(res, status, body) {
1442
+ res.statusCode = status;
1443
+ res.setHeader("content-type", "application/json; charset=utf-8");
1444
+ res.end(JSON.stringify(body));
1445
+ }
1446
+ /**
1447
+ * Echo an ADMITTED origin back as CORS headers. A webview fetch from
1448
+ * `vscode-webview://…` passes the origin check but the browser rejects
1449
+ * the response body without `Access-Control-Allow-Origin` — the exact
1450
+ * transport design/47 specifies for the extension. Only the validated
1451
+ * origin is echoed (never `*`), with `Vary: Origin` for any cache in
1452
+ * between; unadmitted origins were already 403'd and get nothing.
1453
+ */
1454
+ function reflectCors(res, origin) {
1455
+ if (!origin) return;
1456
+ res.setHeader("Access-Control-Allow-Origin", origin);
1457
+ res.setHeader("Vary", "Origin");
1458
+ }
1459
+ /**
1460
+ * Create the Connect middleware handling GET /__timber/graph.
1461
+ *
1462
+ * Query surface: `?file=<path>` (absolute or project-root-relative) or
1463
+ * `?all=1`. Anything else is a 400 — fail loudly, like the CLI.
1464
+ */
1465
+ function createGraphEndpointMiddleware(server, ctx) {
1466
+ const sourceExtensions = buildSourceExtensions(ctx.config.pageExtensions);
1467
+ return async (req, res, next) => {
1468
+ const rawUrl = req.url;
1469
+ if (!rawUrl || !rawUrl.startsWith("/__timber/")) {
1470
+ next();
1471
+ return;
1472
+ }
1473
+ const url = new URL(rawUrl, "http://placeholder.invalid");
1474
+ if (url.pathname !== "/__timber/graph") {
1475
+ sendJson(res, 404, { error: `unknown /__timber/ endpoint: ${url.pathname}` });
1476
+ return;
1477
+ }
1478
+ if (req.method !== "GET") {
1479
+ res.setHeader("Allow", "GET");
1480
+ sendJson(res, 405, { error: "GET only" });
1481
+ return;
1482
+ }
1483
+ const origin = req.headers.origin;
1484
+ const allowedHosts = server.config.server.allowedHosts;
1485
+ if (!server.config.server.https && !isAllowedGraphHost(req.headers.host, allowedHosts)) {
1486
+ sendJson(res, 403, { error: "host not allowed" });
1487
+ return;
1488
+ }
1489
+ if (!isAllowedGraphOrigin(origin, allowedHosts)) {
1490
+ sendJson(res, 403, { error: "origin not allowed" });
1491
+ return;
1492
+ }
1493
+ reflectCors(res, origin);
1494
+ try {
1495
+ const { classifyLiveFile, classifyLiveProject } = await import("./_chunks/live-graph-Bx4HodF1.js");
1496
+ const preserveSymlinks = server.config.resolve.preserveSymlinks;
1497
+ const root = normalizePath(preserveSymlinks ? ctx.root : await realpath(ctx.root));
1498
+ const appDir = normalizePath(preserveSymlinks ? ctx.appDir : await realpath(ctx.appDir).catch(() => join(root, relative(ctx.root, ctx.appDir))));
1499
+ const liveCtx = {
1500
+ rsc: server.environments.rsc.moduleGraph,
1501
+ ssr: server.environments.ssr.moduleGraph,
1502
+ client: server.environments.client.moduleGraph,
1503
+ root,
1504
+ appDir,
1505
+ pageExtensions: ctx.config.pageExtensions
1506
+ };
1507
+ const allParam = url.searchParams.get("all");
1508
+ if (allParam !== null && allParam !== "1") {
1509
+ sendJson(res, 400, { error: `unsupported all value: ${allParam} (use ?all=1)` });
1510
+ return;
1511
+ }
1512
+ if (allParam === "1") {
1513
+ sendJson(res, 200, {
1514
+ version: 1,
1515
+ source: "dev-server",
1516
+ cached: false,
1517
+ ...await classifyLiveProject(liveCtx)
1518
+ });
1519
+ return;
1520
+ }
1521
+ const fileParam = url.searchParams.get("file");
1522
+ if (!fileParam) {
1523
+ sendJson(res, 400, { error: "missing ?file=<path> (or ?all=1)" });
1524
+ return;
1525
+ }
1526
+ const absolute = normalizePath(isAbsolute(fileParam) ? resolve(fileParam) : resolve(root, fileParam));
1527
+ let target;
1528
+ try {
1529
+ const physical = normalizePath(await realpath(absolute));
1530
+ const rootPhysical = preserveSymlinks ? normalizePath(await realpath(root)) : root;
1531
+ if (physical !== rootPhysical && !physical.startsWith(rootPhysical + "/") && !physical.startsWith(rootPhysical + "\\")) {
1532
+ sendJson(res, 404, { error: `not a project file under ${root}` });
1533
+ return;
1534
+ }
1535
+ if (preserveSymlinks) {
1536
+ if (physical !== rootPhysical + absolute.slice(root.length)) {
1537
+ sendJson(res, 404, { error: `not a project source file: ${absolute}` });
1538
+ return;
1539
+ }
1540
+ }
1541
+ target = normalizePath(preserveSymlinks ? absolute : physical);
1542
+ } catch {
1543
+ sendJson(res, 404, { error: `file not found: ${absolute}` });
1544
+ return;
1545
+ }
1546
+ if (target !== root && !target.startsWith(root + "/") && !target.startsWith(root + "\\")) {
1547
+ sendJson(res, 404, { error: `not a project file under ${root}` });
1548
+ return;
1549
+ }
1550
+ if (!(await stat(target).catch(() => null))?.isFile() || !isScannableSourceFile(normalizePath(target), normalizePath(root), sourceExtensions)) {
1551
+ sendJson(res, 404, { error: `not a project source file: ${target}` });
1552
+ return;
1553
+ }
1554
+ const errors = [];
1555
+ const module = await classifyLiveFile(target, liveCtx, void 0, errors);
1556
+ sendJson(res, 200, {
1557
+ version: 1,
1558
+ source: "dev-server",
1559
+ cached: false,
1560
+ target: {
1561
+ input: fileParam,
1562
+ resolved: target
1563
+ },
1564
+ kind: module.kind,
1565
+ pending: module.pending,
1566
+ subtreeUnknown: module.subtreeUnknown,
1567
+ envs: module.envs,
1568
+ boundary: module.boundary,
1569
+ chains: module.chains,
1570
+ poisonings: module.poisonings,
1571
+ errors
1572
+ });
1573
+ } catch (error) {
1574
+ sendJson(res, 500, { error: error instanceof Error ? error.message : String(error) });
1575
+ }
1576
+ };
1577
+ }
1578
+ /**
1579
+ * Build the push channel: `timber:graph-update` custom HMR events per
1580
+ * project-source change. Consumers (the VS Code extension) re-query
1581
+ * and debounce on their side; the channel just emits. Non-source noise
1582
+ * (build output, dotdirs) is filtered by the same extension set the
1583
+ * scanners use.
1584
+ *
1585
+ * Two phases per edit, because one is not enough (codex review, PR
1586
+ * #1057): the `invalidated` event fires from the plugin's `hotUpdate`
1587
+ * hook — after Vite clears the module's transform result, but its
1588
+ * importer EDGES are only rebuilt when the module is next transformed.
1589
+ * The `transformed` event fires for exactly the files with a pending
1590
+ * invalidation, and only once the node's `transformResult` is set
1591
+ * again — the plugin transform hook itself runs BEFORE Vite's trailing
1592
+ * `vite:import-analysis` (which rebuilds the edges), so the hook only
1593
+ * marks the file "settling" and a short bounded timer confirms
1594
+ * completion via `isTransformed` before emitting. (A module nothing
1595
+ * re-requests never re-transforms — its `transformed` event waits for
1596
+ * the next render, which is also when the graph has new information.)
1597
+ */
1598
+ function makeGraphUpdateChannel(ctx, send, isTransformed, canonicalize = (file) => file) {
1599
+ /** Files invalidated but not yet re-transformed, per environment. */
1600
+ const pending = /* @__PURE__ */ new Set();
1601
+ const key = (file, environment) => `${environment}\0${file}`;
1602
+ const root = normalizePath(canonicalize(ctx.root));
1603
+ const extensions = buildSourceExtensions(ctx.config.pageExtensions);
1604
+ const emitTransformed = (file, environment, structural) => {
1605
+ send({
1606
+ type: "custom",
1607
+ event: GRAPH_UPDATE_EVENT,
1608
+ data: structural ? {
1609
+ file,
1610
+ event: "update",
1611
+ environment,
1612
+ phase: "transformed",
1613
+ structural: true
1614
+ } : {
1615
+ file,
1616
+ event: "update",
1617
+ environment,
1618
+ phase: "transformed"
1619
+ }
1620
+ });
1361
1621
  };
1362
- REQUIRED_PEERS = [
1363
- "react",
1364
- "react-dom",
1365
- "@vitejs/plugin-react",
1366
- "@vitejs/plugin-rsc"
1622
+ /**
1623
+ * Confirm the transform request finished (transformResult set again)
1624
+ * before emitting phase `transformed`. If confirmation never arrives
1625
+ * within the bounded schedule below, the pending key is RE-ARMED
1626
+ * rather than emitted — a `transformed` event over a still-stale
1627
+ * graph would be a false all-clear with no corrective event.
1628
+ */
1629
+ /**
1630
+ * Delays between confirmation re-checks: dense while a normal
1631
+ * transform request finishes, then exponential backoff for slow
1632
+ * import-analysis passes (large graphs, cold dep optimizer) — a
1633
+ * completed slow transform is CACHED, so no later transform hook may
1634
+ * ever fire for it and the tail checks are the only chance to emit.
1635
+ * Total window ≈ 16 s, then give up (bounded — the async-safety
1636
+ * rules ban open-ended polling) and re-arm the pending key.
1637
+ */
1638
+ const CONFIRM_DELAYS_MS = [
1639
+ ...Array.from({ length: 25 }, () => 20),
1640
+ 500,
1641
+ 1e3,
1642
+ 2e3,
1643
+ 4e3,
1644
+ 8e3
1367
1645
  ];
1368
- }));
1646
+ const confirmAndEmit = (file, environment, attempt = 0, structural = false) => {
1647
+ if (!isTransformed || isTransformed(file, environment)) {
1648
+ emitTransformed(file, environment, structural);
1649
+ return;
1650
+ }
1651
+ if (attempt >= CONFIRM_DELAYS_MS.length) {
1652
+ if (!structural) pending.add(key(file, environment));
1653
+ return;
1654
+ }
1655
+ setTimeout(() => confirmAndEmit(file, environment, attempt + 1, structural), CONFIRM_DELAYS_MS[attempt]);
1656
+ };
1657
+ return {
1658
+ onHotUpdate(update) {
1659
+ const file = normalizePath(canonicalize(update.file));
1660
+ if (!isScannableSourceFile(file, root, extensions)) return;
1661
+ if (update.type === "delete") pending.delete(key(file, update.environment));
1662
+ else pending.add(key(file, update.environment));
1663
+ send({
1664
+ type: "custom",
1665
+ event: GRAPH_UPDATE_EVENT,
1666
+ data: {
1667
+ file,
1668
+ event: update.type,
1669
+ environment: update.environment,
1670
+ phase: "invalidated"
1671
+ }
1672
+ });
1673
+ },
1674
+ onTransform(id, environment) {
1675
+ const file = normalizePath(id.split("?")[0]);
1676
+ if (file.includes("virtual:timber-route-manifest")) {
1677
+ confirmAndEmit(file, environment, 25, true);
1678
+ return;
1679
+ }
1680
+ const pendingKey = key(file, environment);
1681
+ if (!pending.has(pendingKey)) return;
1682
+ pending.delete(pendingKey);
1683
+ confirmAndEmit(file, environment);
1684
+ }
1685
+ };
1686
+ }
1369
1687
  //#endregion
1370
1688
  //#region src/server/compress.ts
1371
- init_config_validation();
1372
1689
  /**
1373
1690
  * MIME types that benefit from compression.
1374
1691
  * text/* is handled via prefix matching; these are the specific
@@ -1481,7 +1798,8 @@ function compressResponse(request, response) {
1481
1798
  */
1482
1799
  function compressWithGzip(body) {
1483
1800
  const gzip = createGzip({ flush: constants.Z_SYNC_FLUSH });
1484
- pipeline(Readable.fromWeb(body), gzip, () => {});
1801
+ const nodeInput = Readable.fromWeb(body);
1802
+ pipeline(nodeInput, gzip, () => {});
1485
1803
  return Readable.toWeb(gzip);
1486
1804
  }
1487
1805
  //#endregion
@@ -1516,10 +1834,35 @@ var ASSET_EXTENSIONS = /\.(?:js|ts|tsx|jsx|css|map|json|svg|png|jpg|jpeg|gif|web
1516
1834
  * Hook: configureServer (returns post-hook to register after Vite's middleware)
1517
1835
  */
1518
1836
  function timberDevServer(ctx) {
1837
+ let graphChannel = null;
1519
1838
  return {
1520
1839
  name: "timber-dev-server",
1521
1840
  apply: "serve",
1522
1841
  /**
1842
+ * Push channel for the graph endpoint, phase 1: `invalidated`, one
1843
+ * per (file, environment). Emitted from hotUpdate — which runs
1844
+ * AFTER Vite invalidates the environment module graphs — never
1845
+ * from a raw watcher listener, which would race consumers into
1846
+ * querying pre-invalidation memberships (design/47 §"Dev-server
1847
+ * endpoint").
1848
+ */
1849
+ hotUpdate({ file, type }) {
1850
+ graphChannel?.onHotUpdate({
1851
+ file,
1852
+ type,
1853
+ environment: this.environment.name
1854
+ });
1855
+ },
1856
+ /**
1857
+ * Push channel phase 2: `transformed`, when a pending-invalidated
1858
+ * module's import edges are actually rebuilt. A Set lookup for
1859
+ * everything without a pending invalidation — free on the hot
1860
+ * path. Returning nothing leaves the code untouched.
1861
+ */
1862
+ transform(_code, id) {
1863
+ graphChannel?.onTransform(id, this.environment.name);
1864
+ },
1865
+ /**
1523
1866
  * Register the dev server middleware and config file watcher.
1524
1867
  *
1525
1868
  * Registers as a pre-hook (no return value) so our middleware runs
@@ -1532,7 +1875,30 @@ function timberDevServer(ctx) {
1532
1875
  const configPaths = CONFIG_FILE_NAMES.map((name) => join(ctx.root, name));
1533
1876
  server.watcher.add(configPaths);
1534
1877
  listenForClientErrors(server, ctx.root);
1878
+ server.middlewares.use(createGraphEndpointMiddleware(server, ctx));
1879
+ graphChannel = makeGraphUpdateChannel(ctx, (payload) => server.hot.send(payload), (file, environment) => {
1880
+ const graph = server.environments[environment]?.moduleGraph;
1881
+ if (!graph) return false;
1882
+ const nodes = graph.getModulesByFile(file);
1883
+ if (nodes) {
1884
+ for (const node of nodes) if (node.transformResult != null) return true;
1885
+ return false;
1886
+ }
1887
+ return graph.getModuleById(file)?.transformResult != null;
1888
+ }, (file) => {
1889
+ if (server.config?.resolve?.preserveSymlinks || file.includes("virtual:")) return file;
1890
+ try {
1891
+ return realpathSync(file);
1892
+ } catch {
1893
+ try {
1894
+ return join(realpathSync(dirname(file)), basename(file));
1895
+ } catch {
1896
+ return file;
1897
+ }
1898
+ }
1899
+ });
1535
1900
  server.middlewares.use(createTimberMiddleware(server, ctx));
1901
+ registerDevDiscovery(server.httpServer, ctx.root, server.config);
1536
1902
  if (ctx.holdingServer) {
1537
1903
  const originalListen = server.listen.bind(server);
1538
1904
  const holdingRef = ctx.holdingServer;
@@ -2071,7 +2437,7 @@ function timberEntries(ctx) {
2071
2437
  }
2072
2438
  //#endregion
2073
2439
  //#region src/plugins/mdx.ts
2074
- var MDX_EXTENSIONS = ["mdx", "md"];
2440
+ var MDX_EXTENSIONS_UNDOTTED = [...MDX_EXTENSIONS].map((ext) => ext.slice(1));
2075
2441
  /**
2076
2442
  * Check if mdx-components.tsx (or .ts, .jsx, .js) exists at the project root
2077
2443
  * or in src/. Root takes precedence, matching Next.js behavior.
@@ -2094,8 +2460,9 @@ function findMdxComponents(root) {
2094
2460
  * Determine if MDX should be activated based on config and project structure.
2095
2461
  */
2096
2462
  function shouldActivate(ctx) {
2463
+ if (ctx.config.mdx === false) return false;
2097
2464
  const exts = ctx.config.pageExtensions;
2098
- if (exts && exts.some((ext) => MDX_EXTENSIONS.includes(ext))) return true;
2465
+ if (exts && exts.some((ext) => MDX_EXTENSIONS_UNDOTTED.includes(ext))) return true;
2099
2466
  if (existsSync(join(ctx.root, "content"))) return true;
2100
2467
  return false;
2101
2468
  }
@@ -2105,13 +2472,11 @@ function shouldActivate(ctx) {
2105
2472
  *
2106
2473
  * Why this matters: pnpm only hoists declared (peer) dependencies into a
2107
2474
  * package's resolution scope. The MDX integration's optional companions
2108
- * — `remark-frontmatter`, `remark-mdx-frontmatter`, `@mdx-js/rollup` — are
2109
- * installed as direct deps of the consumer (e.g. `packages/website`), not
2110
- * `@timber-js/app`. A bare `import('remark-frontmatter')` from inside this
2111
- * file resolves against `packages/timber-app/node_modules` and silently
2112
- * fails with `ERR_MODULE_NOT_FOUND`, which made `tryImport` return
2113
- * `undefined` and skipped frontmatter parsing entirely — leaving MDX to
2114
- * choke on YAML as JS expressions (TIM-840).
2475
+ * — `vite-plugin-satteri` and `satteri` — are installed as direct deps of
2476
+ * the consumer (e.g. `packages/website`), not `@timber-js/app`. A bare
2477
+ * `import('vite-plugin-satteri')` from inside this file resolves against
2478
+ * `packages/timber-app/node_modules` and silently fails with
2479
+ * `ERR_MODULE_NOT_FOUND` (TIM-840).
2115
2480
  *
2116
2481
  * Resolving relative to `projectRoot` (via `createRequire`) makes the
2117
2482
  * lookup walk the consumer's `node_modules` tree first, which is where
@@ -2122,7 +2487,8 @@ function shouldActivate(ctx) {
2122
2487
  */
2123
2488
  async function tryImport(name, projectRoot) {
2124
2489
  try {
2125
- const mod = await import(pathToFileURL(createRequire(join(projectRoot, "package.json")).resolve(name)).href);
2490
+ const resolved = createRequire(join(projectRoot, "package.json")).resolve(name);
2491
+ const mod = await import(pathToFileURL(resolved).href);
2126
2492
  return mod.default ?? mod;
2127
2493
  } catch {
2128
2494
  try {
@@ -2138,39 +2504,41 @@ async function tryImport(name, projectRoot) {
2138
2504
  * Create the timber-mdx Vite plugin.
2139
2505
  *
2140
2506
  * Uses the transform and resolveId hooks to delegate MDX compilation
2141
- * to @mdx-js/rollup. The inner plugin is loaded lazily on first activation.
2507
+ * to vite-plugin-satteri. The inner plugin is loaded lazily on first
2508
+ * activation.
2142
2509
  *
2143
- * Hooks: buildStart (loads @mdx-js/rollup), resolveId, load, transform
2510
+ * Hooks: buildStart (loads vite-plugin-satteri), resolveId, load, transform
2144
2511
  */
2145
2512
  function timberMdx(ctx) {
2146
2513
  let innerPlugin = null;
2147
2514
  async function activate() {
2148
2515
  if (innerPlugin !== null || !shouldActivate(ctx)) return;
2149
- const createMdxPlugin = await tryImport("@mdx-js/rollup", ctx.root);
2150
- if (!createMdxPlugin) throw new Error([
2151
- "[timber] MDX is enabled but @mdx-js/rollup is not installed.",
2516
+ if (ctx.config.pageExtensions?.includes("md")) throw new Error([
2517
+ "[timber] pageExtensions includes 'md', but .md route pages are not supported:",
2518
+ "Markdown files compile to HTML strings, not components.",
2519
+ "",
2520
+ "Use .mdx for pages (pageExtensions: ['tsx', 'ts', 'mdx']).",
2521
+ ".md files can still be imported as HTML strings — no pageExtensions entry needed."
2522
+ ].join("\n"));
2523
+ const createSatteriPlugin = await tryImport("vite-plugin-satteri", ctx.root);
2524
+ if (!createSatteriPlugin) throw new Error([
2525
+ "[timber] MDX is enabled but vite-plugin-satteri is not installed.",
2152
2526
  "",
2153
2527
  "Install it:",
2154
- " pnpm add -D @mdx-js/rollup remark-frontmatter remark-mdx-frontmatter",
2528
+ " pnpm add -D vite-plugin-satteri satteri",
2155
2529
  "",
2156
2530
  "MDX is activated because pageExtensions includes \"mdx\"/\"md\" or a content/ directory exists."
2157
2531
  ].join("\n"));
2158
- const mdxConfig = ctx.config.mdx ?? {};
2159
- const remarkPlugins = [];
2160
- const remarkFrontmatter = await tryImport("remark-frontmatter", ctx.root);
2161
- const remarkMdxFrontmatter = await tryImport("remark-mdx-frontmatter", ctx.root);
2162
- if (remarkFrontmatter) remarkPlugins.push(remarkFrontmatter);
2163
- if (remarkMdxFrontmatter) remarkPlugins.push(remarkMdxFrontmatter);
2164
- if (mdxConfig.remarkPlugins) remarkPlugins.push(...mdxConfig.remarkPlugins);
2165
- const mdxOptions = {
2166
- remarkPlugins,
2167
- rehypePlugins: mdxConfig.rehypePlugins ?? [],
2168
- recmaPlugins: mdxConfig.recmaPlugins ?? [],
2169
- remarkRehypeOptions: mdxConfig.remarkRehypeOptions
2170
- };
2532
+ const mdxConfig = ctx.config.mdx || {};
2533
+ const mdxOptions = { development: ctx.dev };
2171
2534
  const mdxComponentsPath = findMdxComponents(ctx.root);
2172
2535
  if (mdxComponentsPath) mdxOptions.providerImportSource = mdxComponentsPath;
2173
- innerPlugin = createMdxPlugin(mdxOptions);
2536
+ innerPlugin = createSatteriPlugin({
2537
+ mdx: mdxOptions,
2538
+ ...mdxConfig.mdastPlugins ? { mdastPlugins: mdxConfig.mdastPlugins } : {},
2539
+ ...mdxConfig.hastPlugins ? { hastPlugins: mdxConfig.hastPlugins } : {},
2540
+ ...mdxConfig.features ? { features: mdxConfig.features } : {}
2541
+ });
2174
2542
  }
2175
2543
  return {
2176
2544
  name: "timber-mdx",
@@ -2198,6 +2566,7 @@ function timberMdx(ctx) {
2198
2566
  },
2199
2567
  async transform(code, id) {
2200
2568
  if (!innerPlugin) return null;
2569
+ if (id.includes("?")) return null;
2201
2570
  const envName = this.environment?.name;
2202
2571
  if (envName && envName !== "rsc") return null;
2203
2572
  if (typeof innerPlugin.transform === "function") return innerPlugin.transform.call(this, code, id);
@@ -2380,6 +2749,7 @@ var ROUTE_FILE_PATTERNS = /\/(page|layout|middleware|access|route|error|global-e
2380
2749
  */
2381
2750
  function writeCodegen(ctx) {
2382
2751
  if (!ctx.routeTree) return;
2752
+ if (process.env.TIMBER_ANALYZE === "1") return;
2383
2753
  writeRouteCodegen(ctx.routeTree, ctx.appDir, ctx.root).catch((err) => {
2384
2754
  console.warn("[timber] Failed to write codegen output:", err);
2385
2755
  });
@@ -2607,9 +2977,7 @@ function warnSchemaValidation(ctx) {
2607
2977
  case "bracket-mismatch":
2608
2978
  console.warn(`[timber] ${w.message}`);
2609
2979
  break;
2610
- case "missing-key":
2611
- console.warn(`[timber] ${w.message}`);
2612
- break;
2980
+ case "missing-key": console.warn(`[timber] ${w.message}`);
2613
2981
  }
2614
2982
  }
2615
2983
  }
@@ -2631,14 +2999,13 @@ var __dirname = dirname(fileURLToPath(import.meta.url));
2631
2999
  var PKG_ROOT = __dirname.endsWith("plugins") ? resolve(__dirname, "..", "..") : resolve(__dirname, "..");
2632
3000
  var SHIMS_DIR = resolve(PKG_ROOT, "src", "shims");
2633
3001
  /**
2634
- * Virtual module IDs for server-only and client-only poison pills.
2635
- *
2636
- * These packages cause build errors when imported in the wrong environment:
2637
- * - `server-only` errors when imported in a client component
2638
- * - `client-only` errors when imported in a server component
3002
+ * The server-only marker's virtual ID, needed directly by the
3003
+ * `#server-only-guard` resolution branch below. All poison-pill rules
3004
+ * (specifiers, virtual IDs, error messages, environment policy) live in
3005
+ * analyze/poison-rules.ts — the single source of truth shared with the
3006
+ * `timber graph` reporter (design/47 §3).
2639
3007
  */
2640
- var SERVER_ONLY_VIRTUAL = "\0timber:server-only";
2641
- var CLIENT_ONLY_VIRTUAL = "\0timber:client-only";
3008
+ var SERVER_ONLY_VIRTUAL = markerFor("server-only").virtualId;
2642
3009
  /**
2643
3010
  * Map from @timber-js/app/<subpath> to relative src/ file paths.
2644
3011
  *
@@ -2765,8 +3132,7 @@ function timberShims(_ctx) {
2765
3132
  * the browser.
2766
3133
  */
2767
3134
  resolveId(id) {
2768
- if (id === "server-only") return SERVER_ONLY_VIRTUAL;
2769
- if (id === "client-only") return CLIENT_ONLY_VIRTUAL;
3135
+ for (const marker of EXPLICIT_MARKERS) if (id === marker.specifier) return marker.virtualId;
2770
3136
  const cleanId = stripJsExtension(id);
2771
3137
  if (cleanId in SHIM_MAP) {
2772
3138
  if (envName(this) === "client" && cleanId === "next/navigation") return resolve(SHIMS_DIR, "navigation-client.ts");
@@ -2815,21 +3181,8 @@ function timberShims(_ctx) {
2815
3181
  * clearly identifies the boundary violation.
2816
3182
  */
2817
3183
  load(id) {
2818
- const isClient = envName(this) === "client";
2819
- if (id === SERVER_ONLY_VIRTUAL) {
2820
- if (isClient) return `throw new Error(
2821
- "This module cannot be imported from a Client Component module. " +
2822
- "It should only be used from a Server Component."
2823
- );`;
2824
- return "export {};";
2825
- }
2826
- if (id === CLIENT_ONLY_VIRTUAL) {
2827
- if (!isClient) return `throw new Error(
2828
- "This module cannot be imported from a Server Component module. " +
2829
- "It should only be used from a Client Component."
2830
- );`;
2831
- return "export {};";
2832
- }
3184
+ const env = envName(this);
3185
+ for (const marker of EXPLICIT_MARKERS) if (id === marker.virtualId) return poisonPillSource(marker, env);
2833
3186
  if (id === "\0timber:server-empty") return `
2834
3187
  const msg = "[timber] @timber-js/app/server was imported from client code. " +
2835
3188
  "Server modules (headers, cookies, redirect, deny, etc.) cannot be used in client components. " +
@@ -4446,7 +4799,7 @@ function encodeInteger(builder, num, relative) {
4446
4799
  } while (delta > 0);
4447
4800
  return num;
4448
4801
  }
4449
- var bufLength = 1024 * 16;
4802
+ var bufLength = 16384;
4450
4803
  var td = typeof TextDecoder !== "undefined" ? /* @__PURE__ */ new TextDecoder() : typeof Buffer !== "undefined" ? { decode(buf) {
4451
4804
  return Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength).toString();
4452
4805
  } } : { decode(buf) {
@@ -4499,7 +4852,7 @@ function encode(decoded) {
4499
4852
  return writer.flush();
4500
4853
  }
4501
4854
  //#endregion
4502
- //#region ../../node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.mjs
4855
+ //#region ../../node_modules/.pnpm/magic-string@1.2.0/node_modules/magic-string/dist/index.mjs
4503
4856
  var BitSet = class BitSet {
4504
4857
  constructor(arg) {
4505
4858
  this.bits = arg instanceof BitSet ? arg.bits.slice() : [];
@@ -4543,14 +4896,16 @@ var Chunk = class Chunk {
4543
4896
  return this.start < index && index < this.end;
4544
4897
  }
4545
4898
  eachNext(fn) {
4546
- let chunk = this;
4899
+ fn(this);
4900
+ let chunk = this.next;
4547
4901
  while (chunk) {
4548
4902
  fn(chunk);
4549
4903
  chunk = chunk.next;
4550
4904
  }
4551
4905
  }
4552
4906
  eachPrevious(fn) {
4553
- let chunk = this;
4907
+ fn(this);
4908
+ let chunk = this.previous;
4554
4909
  while (chunk) {
4555
4910
  fn(chunk);
4556
4911
  chunk = chunk.previous;
@@ -4608,10 +4963,8 @@ var Chunk = class Chunk {
4608
4963
  if (this.outro.length) return true;
4609
4964
  const trimmed = this.content.replace(rx, "");
4610
4965
  if (trimmed.length) {
4611
- if (trimmed !== this.content) {
4612
- this.split(this.start + trimmed.length).edit("", void 0, true);
4613
- if (this.edited) this.edit(trimmed, this.storeName, true);
4614
- }
4966
+ if (trimmed !== this.content) if (this.edited) this.edit(trimmed, this.storeName, true);
4967
+ else this.split(this.start + trimmed.length).edit("", void 0, true);
4615
4968
  return true;
4616
4969
  } else {
4617
4970
  this.edit("", void 0, true);
@@ -4624,9 +4977,9 @@ var Chunk = class Chunk {
4624
4977
  if (this.intro.length) return true;
4625
4978
  const trimmed = this.content.replace(rx, "");
4626
4979
  if (trimmed.length) {
4627
- if (trimmed !== this.content) {
4628
- const newChunk = this.split(this.end - trimmed.length);
4629
- if (this.edited) newChunk.edit(trimmed, this.storeName, true);
4980
+ if (trimmed !== this.content) if (this.edited) this.edit(trimmed, this.storeName, true);
4981
+ else {
4982
+ this.split(this.end - trimmed.length);
4630
4983
  this.edit("", void 0, true);
4631
4984
  }
4632
4985
  return true;
@@ -4637,14 +4990,27 @@ var Chunk = class Chunk {
4637
4990
  }
4638
4991
  }
4639
4992
  };
4993
+ /**
4994
+ * The single error type thrown by MagicString.
4995
+ *
4996
+ * Every message is prefixed with `[MagicString]` so its source is obvious at a
4997
+ * glance, and is kept short and consistent in tone.
4998
+ */
4999
+ var MagicStringError = class extends Error {
5000
+ name = "MagicStringError";
5001
+ constructor(message, options) {
5002
+ super(`[MagicString] ${message}`, options);
5003
+ }
5004
+ };
4640
5005
  function getBtoa() {
4641
5006
  if (typeof globalThis !== "undefined" && typeof globalThis.btoa === "function") return (str) => globalThis.btoa(unescape(encodeURIComponent(str)));
4642
- else if (typeof Buffer === "function") return (str) => Buffer.from(str, "utf-8").toString("base64");
4643
- else return () => {
4644
- throw new Error("Unsupported environment: `window.btoa` or `Buffer` should be supported.");
5007
+ const buffer = globalThis["Buffer"];
5008
+ if (buffer) return (str) => buffer.from(str, "utf-8").toString("base64");
5009
+ return () => {
5010
+ throw new MagicStringError("unsupported environment: `btoa` or `Buffer` is required");
4645
5011
  };
4646
5012
  }
4647
- var btoa = /*#__PURE__*/ getBtoa();
5013
+ var btoa = /* #__PURE__ */ getBtoa();
4648
5014
  var SourceMap = class {
4649
5015
  constructor(properties) {
4650
5016
  this.version = 3;
@@ -4656,43 +5022,20 @@ var SourceMap = class {
4656
5022
  if (typeof properties.x_google_ignoreList !== "undefined") this.x_google_ignoreList = properties.x_google_ignoreList;
4657
5023
  if (typeof properties.debugId !== "undefined") this.debugId = properties.debugId;
4658
5024
  }
5025
+ /**
5026
+ * Returns the equivalent of `JSON.stringify(map)`
5027
+ */
4659
5028
  toString() {
4660
5029
  return JSON.stringify(this);
4661
5030
  }
5031
+ /**
5032
+ * Returns a DataURI containing the sourcemap. Useful for doing this sort of thing:
5033
+ * `generateMap(options?: SourceMapOptions): SourceMap;`
5034
+ */
4662
5035
  toUrl() {
4663
- return "data:application/json;charset=utf-8;base64," + btoa(this.toString());
5036
+ return `data:application/json;charset=utf-8;base64,${btoa(this.toString())}`;
4664
5037
  }
4665
5038
  };
4666
- function guessIndent(code) {
4667
- const lines = code.split("\n");
4668
- const tabbed = lines.filter((line) => /^\t+/.test(line));
4669
- const spaced = lines.filter((line) => /^ {2,}/.test(line));
4670
- if (tabbed.length === 0 && spaced.length === 0) return null;
4671
- if (tabbed.length >= spaced.length) return " ";
4672
- const min = spaced.reduce((previous, current) => {
4673
- const numSpaces = /^ +/.exec(current)[0].length;
4674
- return Math.min(numSpaces, previous);
4675
- }, Infinity);
4676
- return new Array(min + 1).join(" ");
4677
- }
4678
- function getRelativePath(from, to) {
4679
- const fromParts = from.split(/[/\\]/);
4680
- const toParts = to.split(/[/\\]/);
4681
- fromParts.pop();
4682
- while (fromParts[0] === toParts[0]) {
4683
- fromParts.shift();
4684
- toParts.shift();
4685
- }
4686
- if (fromParts.length) {
4687
- let i = fromParts.length;
4688
- while (i--) fromParts[i] = "..";
4689
- }
4690
- return fromParts.concat(toParts).join("/");
4691
- }
4692
- var toString = Object.prototype.toString;
4693
- function isObject(thing) {
4694
- return toString.call(thing) === "[object Object]";
4695
- }
4696
5039
  function getLocator(source) {
4697
5040
  const originalLines = source.split("\n");
4698
5041
  const lineOffsets = [];
@@ -4715,6 +5058,36 @@ function getLocator(source) {
4715
5058
  };
4716
5059
  };
4717
5060
  }
5061
+ function getRelativePath(from, to) {
5062
+ const fromParts = from.split(/[/\\]/);
5063
+ const toParts = to.split(/[/\\]/);
5064
+ fromParts.pop();
5065
+ while (fromParts[0] === toParts[0]) {
5066
+ fromParts.shift();
5067
+ toParts.shift();
5068
+ }
5069
+ if (fromParts.length) {
5070
+ let i = fromParts.length;
5071
+ while (i--) fromParts[i] = "..";
5072
+ }
5073
+ return fromParts.concat(toParts).join("/");
5074
+ }
5075
+ function guessIndent(code) {
5076
+ const lines = code.split("\n");
5077
+ const tabbed = lines.filter((line) => /^\t+/.test(line));
5078
+ const spaced = lines.filter((line) => /^ {2,}/.test(line));
5079
+ if (tabbed.length === 0 && spaced.length === 0) return null;
5080
+ if (tabbed.length >= spaced.length) return " ";
5081
+ const min = spaced.reduce((previous, current) => {
5082
+ const numSpaces = /^ +/.exec(current)[0].length;
5083
+ return Math.min(numSpaces, previous);
5084
+ }, Infinity);
5085
+ return " ".repeat(min);
5086
+ }
5087
+ var toString = Object.prototype.toString;
5088
+ function isObject(thing) {
5089
+ return toString.call(thing) === "[object Object]";
5090
+ }
4718
5091
  var wordRegex = /\w/;
4719
5092
  var Mappings = class {
4720
5093
  constructor(hires) {
@@ -4814,6 +5187,8 @@ var Mappings = class {
4814
5187
  }
4815
5188
  };
4816
5189
  var n = "\n";
5190
+ var NEWLINE_CHAR = "\n".charCodeAt(0);
5191
+ var CR_CHAR = "\r".charCodeAt(0);
4817
5192
  var warned = {
4818
5193
  insertLeft: false,
4819
5194
  insertRight: false,
@@ -4849,11 +5224,11 @@ var MagicString = class MagicString {
4849
5224
  },
4850
5225
  byStart: {
4851
5226
  writable: true,
4852
- value: {}
5227
+ value: /* @__PURE__ */ new Map([[0, chunk]])
4853
5228
  },
4854
5229
  byEnd: {
4855
5230
  writable: true,
4856
- value: {}
5231
+ value: /* @__PURE__ */ new Map([[string.length, chunk]])
4857
5232
  },
4858
5233
  filename: {
4859
5234
  writable: true,
@@ -4884,35 +5259,52 @@ var MagicString = class MagicString {
4884
5259
  value: options.offset || 0
4885
5260
  }
4886
5261
  });
4887
- this.byStart[0] = chunk;
4888
- this.byEnd[string.length] = chunk;
4889
5262
  }
5263
+ /**
5264
+ * Adds the specified character index (with respect to the original string) to sourcemap mappings, if `hires` is false.
5265
+ */
4890
5266
  addSourcemapLocation(char) {
4891
5267
  this.sourcemapLocations.add(char);
4892
5268
  }
5269
+ /**
5270
+ * Appends the specified content to the end of the string.
5271
+ */
4893
5272
  append(content) {
4894
- if (typeof content !== "string") throw new TypeError("outro content must be a string");
5273
+ if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
4895
5274
  this.outro += content;
4896
5275
  return this;
4897
5276
  }
5277
+ /**
5278
+ * Appends the specified content at the index in the original string.
5279
+ * If a range *ending* with index is subsequently moved, the insert will be moved with it.
5280
+ * See also `s.prependLeft(...)`.
5281
+ */
4898
5282
  appendLeft(index, content) {
4899
5283
  index = index + this.offset;
4900
- if (typeof content !== "string") throw new TypeError("inserted content must be a string");
5284
+ if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
4901
5285
  this._split(index);
4902
- const chunk = this.byEnd[index];
5286
+ const chunk = this.byEnd.get(index);
4903
5287
  if (chunk) chunk.appendLeft(content);
4904
5288
  else this.intro += content;
4905
5289
  return this;
4906
5290
  }
5291
+ /**
5292
+ * Appends the specified content at the index in the original string.
5293
+ * If a range *starting* with index is subsequently moved, the insert will be moved with it.
5294
+ * See also `s.prependRight(...)`.
5295
+ */
4907
5296
  appendRight(index, content) {
4908
5297
  index = index + this.offset;
4909
- if (typeof content !== "string") throw new TypeError("inserted content must be a string");
5298
+ if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
4910
5299
  this._split(index);
4911
- const chunk = this.byStart[index];
5300
+ const chunk = this.byStart.get(index);
4912
5301
  if (chunk) chunk.appendRight(content);
4913
5302
  else this.outro += content;
4914
5303
  return this;
4915
5304
  }
5305
+ /**
5306
+ * Does what you'd expect.
5307
+ */
4916
5308
  clone() {
4917
5309
  const cloned = new MagicString(this.original, {
4918
5310
  filename: this.filename,
@@ -4921,8 +5313,8 @@ var MagicString = class MagicString {
4921
5313
  let originalChunk = this.firstChunk;
4922
5314
  let clonedChunk = cloned.firstChunk = cloned.lastSearchedChunk = originalChunk.clone();
4923
5315
  while (originalChunk) {
4924
- cloned.byStart[clonedChunk.start] = clonedChunk;
4925
- cloned.byEnd[clonedChunk.end] = clonedChunk;
5316
+ cloned.byStart.set(clonedChunk.start, clonedChunk);
5317
+ cloned.byEnd.set(clonedChunk.end, clonedChunk);
4926
5318
  const nextOriginalChunk = originalChunk.next;
4927
5319
  const nextClonedChunk = nextOriginalChunk && nextOriginalChunk.clone();
4928
5320
  if (nextClonedChunk) {
@@ -4939,6 +5331,10 @@ var MagicString = class MagicString {
4939
5331
  cloned.outro = this.outro;
4940
5332
  return cloned;
4941
5333
  }
5334
+ /**
5335
+ * Generates a sourcemap object with raw mappings in array form, rather than encoded as a string.
5336
+ * Useful if you need to manipulate the sourcemap further, but most of the time you will use `generateMap` instead.
5337
+ */
4942
5338
  generateDecodedMap(options) {
4943
5339
  options = options || {};
4944
5340
  const sourceIndex = 0;
@@ -4963,12 +5359,17 @@ var MagicString = class MagicString {
4963
5359
  x_google_ignoreList: this.ignoreList ? [sourceIndex] : void 0
4964
5360
  };
4965
5361
  }
5362
+ /**
5363
+ * Generates a version 3 sourcemap.
5364
+ */
4966
5365
  generateMap(options) {
4967
5366
  return new SourceMap(this.generateDecodedMap(options));
4968
5367
  }
5368
+ /** @internal */
4969
5369
  _ensureindentStr() {
4970
5370
  if (this.indentStr === void 0) this.indentStr = guessIndent(this.original);
4971
5371
  }
5372
+ /** @internal */
4972
5373
  _getRawIndentString() {
4973
5374
  this._ensureindentStr();
4974
5375
  return this.indentStr;
@@ -4988,6 +5389,7 @@ var MagicString = class MagicString {
4988
5389
  indentStr = this.indentStr || " ";
4989
5390
  }
4990
5391
  if (indentStr === "") return this;
5392
+ const resolvedIndentStr = indentStr;
4991
5393
  options = options || {};
4992
5394
  const isExcluded = {};
4993
5395
  if (options.exclude) (typeof options.exclude[0] === "number" ? [options.exclude] : options.exclude).forEach((exclusion) => {
@@ -4995,13 +5397,22 @@ var MagicString = class MagicString {
4995
5397
  });
4996
5398
  let shouldIndentNextCharacter = options.indentStart !== false;
4997
5399
  const replacer = (match) => {
4998
- if (shouldIndentNextCharacter) return `${indentStr}${match}`;
5400
+ if (shouldIndentNextCharacter) return `${resolvedIndentStr}${match}`;
4999
5401
  shouldIndentNextCharacter = true;
5000
5402
  return match;
5001
5403
  };
5002
5404
  this.intro = this.intro.replace(pattern, replacer);
5003
5405
  let charIndex = 0;
5004
5406
  let chunk = this.firstChunk;
5407
+ const indentAt = (index) => {
5408
+ shouldIndentNextCharacter = false;
5409
+ if (index === chunk.start) chunk.prependRight(resolvedIndentStr);
5410
+ else {
5411
+ this._splitChunk(chunk, index);
5412
+ chunk = chunk.next;
5413
+ chunk.prependRight(resolvedIndentStr);
5414
+ }
5415
+ };
5005
5416
  while (chunk) {
5006
5417
  const end = chunk.end;
5007
5418
  if (chunk.edited) {
@@ -5009,24 +5420,34 @@ var MagicString = class MagicString {
5009
5420
  chunk.content = chunk.content.replace(pattern, replacer);
5010
5421
  if (chunk.content.length) shouldIndentNextCharacter = chunk.content[chunk.content.length - 1] === "\n";
5011
5422
  }
5012
- } else {
5423
+ } else if (options.exclude) {
5013
5424
  charIndex = chunk.start;
5014
5425
  while (charIndex < end) {
5015
5426
  if (!isExcluded[charIndex]) {
5016
- const char = this.original[charIndex];
5017
- if (char === "\n") shouldIndentNextCharacter = true;
5018
- else if (char !== "\r" && shouldIndentNextCharacter) {
5019
- shouldIndentNextCharacter = false;
5020
- if (charIndex === chunk.start) chunk.prependRight(indentStr);
5021
- else {
5022
- this._splitChunk(chunk, charIndex);
5023
- chunk = chunk.next;
5024
- chunk.prependRight(indentStr);
5025
- }
5026
- }
5427
+ const char = this.original.charCodeAt(charIndex);
5428
+ if (char === NEWLINE_CHAR) shouldIndentNextCharacter = true;
5429
+ else if (char !== CR_CHAR && shouldIndentNextCharacter) indentAt(charIndex);
5027
5430
  }
5028
5431
  charIndex += 1;
5029
5432
  }
5433
+ } else {
5434
+ charIndex = chunk.start;
5435
+ while (charIndex < end) {
5436
+ if (!shouldIndentNextCharacter) {
5437
+ const nextLine = this.original.indexOf(n, charIndex);
5438
+ if (nextLine === -1 || nextLine >= end) break;
5439
+ shouldIndentNextCharacter = true;
5440
+ charIndex = nextLine + 1;
5441
+ continue;
5442
+ }
5443
+ const char = this.original.charCodeAt(charIndex);
5444
+ if (char === NEWLINE_CHAR || char === CR_CHAR) {
5445
+ charIndex += 1;
5446
+ continue;
5447
+ }
5448
+ indentAt(charIndex);
5449
+ charIndex += 1;
5450
+ }
5030
5451
  }
5031
5452
  charIndex = chunk.end;
5032
5453
  chunk = chunk.next;
@@ -5034,9 +5455,11 @@ var MagicString = class MagicString {
5034
5455
  this.outro = this.outro.replace(pattern, replacer);
5035
5456
  return this;
5036
5457
  }
5458
+ /** @internal */
5037
5459
  insert() {
5038
- throw new Error("magicString.insert(...) is deprecated. Use prependRight(...) or appendLeft(...)");
5460
+ throw new MagicStringError("insert() is deprecated, use appendLeft() or prependRight()");
5039
5461
  }
5462
+ /** @internal */
5040
5463
  insertLeft(index, content) {
5041
5464
  if (!warned.insertLeft) {
5042
5465
  console.warn("magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead");
@@ -5044,6 +5467,7 @@ var MagicString = class MagicString {
5044
5467
  }
5045
5468
  return this.appendLeft(index, content);
5046
5469
  }
5470
+ /** @internal */
5047
5471
  insertRight(index, content) {
5048
5472
  if (!warned.insertRight) {
5049
5473
  console.warn("magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead");
@@ -5051,19 +5475,23 @@ var MagicString = class MagicString {
5051
5475
  }
5052
5476
  return this.prependRight(index, content);
5053
5477
  }
5478
+ /**
5479
+ * Moves the characters from `start` and `end` to `index`.
5480
+ */
5054
5481
  move(start, end, index) {
5055
5482
  start = start + this.offset;
5056
5483
  end = end + this.offset;
5057
5484
  index = index + this.offset;
5058
- if (index >= start && index <= end) throw new Error("Cannot move a selection inside itself");
5485
+ if (start === end) return this;
5486
+ if (index >= start && index <= end) throw new MagicStringError("cannot move a selection inside itself");
5059
5487
  this._split(start);
5060
5488
  this._split(end);
5061
5489
  this._split(index);
5062
- const first = this.byStart[start];
5063
- const last = this.byEnd[end];
5490
+ const first = this.byStart.get(start);
5491
+ const last = this.byEnd.get(end);
5064
5492
  const oldLeft = first.previous;
5065
5493
  const oldRight = last.next;
5066
- const newRight = this.byStart[index];
5494
+ const newRight = this.byStart.get(index);
5067
5495
  if (!newRight && last === this.lastChunk) return this;
5068
5496
  const newLeft = newRight ? newRight.previous : this.lastChunk;
5069
5497
  if (oldLeft) oldLeft.next = oldRight;
@@ -5081,23 +5509,42 @@ var MagicString = class MagicString {
5081
5509
  if (!newRight) this.lastChunk = last;
5082
5510
  return this;
5083
5511
  }
5512
+ /**
5513
+ * Replaces the characters from `start` to `end` with `content`, along with the appended/prepended content in
5514
+ * that range. The same restrictions as `s.remove()` apply.
5515
+ *
5516
+ * The fourth argument is optional. It can have a storeName property - if true, the original name will be stored
5517
+ * for later inclusion in a sourcemap's names array - and a contentOnly property which determines whether only
5518
+ * the content is overwritten, or anything that was appended/prepended to the range as well.
5519
+ *
5520
+ * It may be preferred to use `s.update(...)` instead if you wish to avoid overwriting the appended/prepended content.
5521
+ */
5084
5522
  overwrite(start, end, content, options) {
5085
- options = options || {};
5523
+ const optionObject = typeof options === "object" && options ? options : {};
5086
5524
  return this.update(start, end, content, {
5087
- ...options,
5088
- overwrite: !options.contentOnly
5525
+ ...optionObject,
5526
+ overwrite: !optionObject.contentOnly
5089
5527
  });
5090
5528
  }
5529
+ /**
5530
+ * Replaces the characters from `start` to `end` with `content`. The same restrictions as `s.remove()` apply.
5531
+ *
5532
+ * The fourth argument is optional. It can have a storeName property - if true, the original name will be stored
5533
+ * for later inclusion in a sourcemap's names array - and an overwrite property which determines whether only
5534
+ * the content is overwritten, or anything that was appended/prepended to the range as well.
5535
+ */
5091
5536
  update(start, end, content, options) {
5092
5537
  start = start + this.offset;
5093
5538
  end = end + this.offset;
5094
- if (typeof content !== "string") throw new TypeError("replacement content must be a string");
5539
+ if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
5095
5540
  if (this.original.length !== 0) {
5096
5541
  while (start < 0) start += this.original.length;
5097
5542
  while (end < 0) end += this.original.length;
5098
5543
  }
5099
- if (end > this.original.length) throw new Error("end is out of bounds");
5100
- if (start === end) throw new Error("Cannot overwrite a zero-length range – use appendLeft or prependRight instead");
5544
+ if (start < 0) throw new MagicStringError(`start ${start} is out of bounds`);
5545
+ if (end > this.original.length) throw new MagicStringError(`end ${end} is out of bounds`);
5546
+ if (start === end) throw new MagicStringError(`cannot overwrite a zero-length range at ${start}, use appendLeft() or prependRight()`);
5547
+ if (start > end) throw new MagicStringError(`end must be greater than start (start: ${start}, end: ${end})`);
5101
5548
  this._split(start);
5102
5549
  this._split(end);
5103
5550
  if (options === true) {
@@ -5107,8 +5554,9 @@ var MagicString = class MagicString {
5107
5554
  }
5108
5555
  options = { storeName: true };
5109
5556
  }
5110
- const storeName = options !== void 0 ? options.storeName : false;
5111
- const overwrite = options !== void 0 ? options.overwrite : false;
5557
+ const optionObject = typeof options === "object" && options ? options : {};
5558
+ const storeName = optionObject.storeName || false;
5559
+ const overwrite = optionObject.overwrite || false;
5112
5560
  if (storeName) {
5113
5561
  const original = this.original.slice(start, end);
5114
5562
  Object.defineProperty(this.storedNames, original, {
@@ -5117,12 +5565,12 @@ var MagicString = class MagicString {
5117
5565
  enumerable: true
5118
5566
  });
5119
5567
  }
5120
- const first = this.byStart[start];
5121
- const last = this.byEnd[end];
5568
+ const first = this.byStart.get(start);
5569
+ const last = this.byEnd.get(end);
5122
5570
  if (first) {
5123
5571
  let chunk = first;
5124
5572
  while (chunk !== last) {
5125
- if (chunk.next !== this.byStart[chunk.end]) throw new Error("Cannot overwrite across a split point");
5573
+ if (chunk.next !== this.byStart.get(chunk.end)) throw new MagicStringError("cannot overwrite across a split point");
5126
5574
  chunk = chunk.next;
5127
5575
  chunk.edit("", false);
5128
5576
  }
@@ -5134,29 +5582,42 @@ var MagicString = class MagicString {
5134
5582
  }
5135
5583
  return this;
5136
5584
  }
5585
+ /**
5586
+ * Prepends the string with the specified content.
5587
+ */
5137
5588
  prepend(content) {
5138
- if (typeof content !== "string") throw new TypeError("outro content must be a string");
5589
+ if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
5139
5590
  this.intro = content + this.intro;
5140
5591
  return this;
5141
5592
  }
5593
+ /**
5594
+ * Same as `s.appendLeft(...)`, except that the inserted content will go *before* any previous appends or prepends at index
5595
+ */
5142
5596
  prependLeft(index, content) {
5143
5597
  index = index + this.offset;
5144
- if (typeof content !== "string") throw new TypeError("inserted content must be a string");
5598
+ if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
5145
5599
  this._split(index);
5146
- const chunk = this.byEnd[index];
5600
+ const chunk = this.byEnd.get(index);
5147
5601
  if (chunk) chunk.prependLeft(content);
5148
5602
  else this.intro = content + this.intro;
5149
5603
  return this;
5150
5604
  }
5605
+ /**
5606
+ * Same as `s.appendRight(...)`, except that the inserted content will go *before* any previous appends or prepends at `index`
5607
+ */
5151
5608
  prependRight(index, content) {
5152
5609
  index = index + this.offset;
5153
- if (typeof content !== "string") throw new TypeError("inserted content must be a string");
5610
+ if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
5154
5611
  this._split(index);
5155
- const chunk = this.byStart[index];
5612
+ const chunk = this.byStart.get(index);
5156
5613
  if (chunk) chunk.prependRight(content);
5157
5614
  else this.outro = content + this.outro;
5158
5615
  return this;
5159
5616
  }
5617
+ /**
5618
+ * Removes the characters from `start` to `end` (of the original string, **not** the generated string).
5619
+ * Removing the same content twice, or making removals that partially overlap, will cause an error.
5620
+ */
5160
5621
  remove(start, end) {
5161
5622
  start = start + this.offset;
5162
5623
  end = end + this.offset;
@@ -5165,19 +5626,22 @@ var MagicString = class MagicString {
5165
5626
  while (end < 0) end += this.original.length;
5166
5627
  }
5167
5628
  if (start === end) return this;
5168
- if (start < 0 || end > this.original.length) throw new Error("Character is out of bounds");
5169
- if (start > end) throw new Error("end must be greater than start");
5629
+ if (start < 0 || end > this.original.length) throw new MagicStringError(`range ${start}–${end} is out of bounds`);
5630
+ if (start > end) throw new MagicStringError(`end must be greater than start (start: ${start}, end: ${end})`);
5170
5631
  this._split(start);
5171
5632
  this._split(end);
5172
- let chunk = this.byStart[start];
5633
+ let chunk = this.byStart.get(start);
5173
5634
  while (chunk) {
5174
5635
  chunk.intro = "";
5175
5636
  chunk.outro = "";
5176
5637
  chunk.edit("");
5177
- chunk = end > chunk.end ? this.byStart[chunk.end] : null;
5638
+ chunk = end > chunk.end ? this.byStart.get(chunk.end) : null;
5178
5639
  }
5179
5640
  return this;
5180
5641
  }
5642
+ /**
5643
+ * Reset the modified characters from `start` to `end` (of the original string, **not** the generated string).
5644
+ */
5181
5645
  reset(start, end) {
5182
5646
  start = start + this.offset;
5183
5647
  end = end + this.offset;
@@ -5186,25 +5650,26 @@ var MagicString = class MagicString {
5186
5650
  while (end < 0) end += this.original.length;
5187
5651
  }
5188
5652
  if (start === end) return this;
5189
- if (start < 0 || end > this.original.length) throw new Error("Character is out of bounds");
5190
- if (start > end) throw new Error("end must be greater than start");
5653
+ if (start < 0 || end > this.original.length) throw new MagicStringError(`range ${start}–${end} is out of bounds`);
5654
+ if (start > end) throw new MagicStringError(`end must be greater than start (start: ${start}, end: ${end})`);
5191
5655
  this._split(start);
5192
5656
  this._split(end);
5193
- let chunk = this.byStart[start];
5657
+ let chunk = this.byStart.get(start);
5194
5658
  while (chunk) {
5195
5659
  chunk.reset();
5196
- chunk = end > chunk.end ? this.byStart[chunk.end] : null;
5660
+ chunk = end > chunk.end ? this.byStart.get(chunk.end) : null;
5197
5661
  }
5198
5662
  return this;
5199
5663
  }
5200
5664
  lastChar() {
5201
5665
  if (this.outro.length) return this.outro[this.outro.length - 1];
5202
5666
  let chunk = this.lastChunk;
5203
- do {
5667
+ while (chunk) {
5204
5668
  if (chunk.outro.length) return chunk.outro[chunk.outro.length - 1];
5205
5669
  if (chunk.content.length) return chunk.content[chunk.content.length - 1];
5206
5670
  if (chunk.intro.length) return chunk.intro[chunk.intro.length - 1];
5207
- } while (chunk = chunk.previous);
5671
+ chunk = chunk.previous;
5672
+ }
5208
5673
  if (this.intro.length) return this.intro[this.intro.length - 1];
5209
5674
  return "";
5210
5675
  }
@@ -5213,7 +5678,7 @@ var MagicString = class MagicString {
5213
5678
  if (lineIndex !== -1) return this.outro.substr(lineIndex + 1);
5214
5679
  let lineStr = this.outro;
5215
5680
  let chunk = this.lastChunk;
5216
- do {
5681
+ while (chunk) {
5217
5682
  if (chunk.outro.length > 0) {
5218
5683
  lineIndex = chunk.outro.lastIndexOf(n);
5219
5684
  if (lineIndex !== -1) return chunk.outro.substr(lineIndex + 1) + lineStr;
@@ -5229,11 +5694,16 @@ var MagicString = class MagicString {
5229
5694
  if (lineIndex !== -1) return chunk.intro.substr(lineIndex + 1) + lineStr;
5230
5695
  lineStr = chunk.intro + lineStr;
5231
5696
  }
5232
- } while (chunk = chunk.previous);
5697
+ chunk = chunk.previous;
5698
+ }
5233
5699
  lineIndex = this.intro.lastIndexOf(n);
5234
5700
  if (lineIndex !== -1) return this.intro.substr(lineIndex + 1) + lineStr;
5235
5701
  return this.intro + lineStr;
5236
5702
  }
5703
+ /**
5704
+ * Returns the content of the generated string that corresponds to the slice between `start` and `end` of the original string.
5705
+ * Throws error if the indices are for characters that were already removed.
5706
+ */
5237
5707
  slice(start = 0, end = this.original.length - this.offset) {
5238
5708
  start = start + this.offset;
5239
5709
  end = end + this.offset;
@@ -5247,12 +5717,12 @@ var MagicString = class MagicString {
5247
5717
  if (chunk.start < end && chunk.end >= end) return result;
5248
5718
  chunk = chunk.next;
5249
5719
  }
5250
- if (chunk && chunk.edited && chunk.start !== start) throw new Error(`Cannot use replaced character ${start} as slice start anchor.`);
5720
+ if (chunk && chunk.edited && chunk.start !== start) throw new MagicStringError(`cannot use edited character ${start} as slice start anchor`);
5251
5721
  const startChunk = chunk;
5252
5722
  while (chunk) {
5253
5723
  if (chunk.intro && (startChunk !== chunk || chunk.start === start)) result += chunk.intro;
5254
5724
  const containsEnd = chunk.start < end && chunk.end >= end;
5255
- if (containsEnd && chunk.edited && chunk.end !== end) throw new Error(`Cannot use replaced character ${end} as slice end anchor.`);
5725
+ if (containsEnd && chunk.edited && chunk.end !== end) throw new MagicStringError(`cannot use edited character ${end} as slice end anchor`);
5256
5726
  const sliceStart = startChunk === chunk ? start - chunk.start : 0;
5257
5727
  const sliceEnd = containsEnd ? chunk.content.length + end - chunk.end : chunk.content.length;
5258
5728
  result += chunk.content.slice(sliceStart, sliceEnd);
@@ -5262,37 +5732,45 @@ var MagicString = class MagicString {
5262
5732
  }
5263
5733
  return result;
5264
5734
  }
5735
+ /**
5736
+ * Returns a clone of `s`, with all content before the `start` and `end` characters of the original string removed.
5737
+ */
5265
5738
  snip(start, end) {
5266
5739
  const clone = this.clone();
5267
5740
  clone.remove(0, start);
5268
5741
  clone.remove(end, clone.original.length);
5269
5742
  return clone;
5270
5743
  }
5744
+ /** @internal */
5271
5745
  _split(index) {
5272
- if (this.byStart[index] || this.byEnd[index]) return;
5746
+ if (this.byStart.get(index) || this.byEnd.get(index)) return;
5273
5747
  let chunk = this.lastSearchedChunk;
5274
5748
  let previousChunk = chunk;
5275
5749
  const searchForward = index > chunk.end;
5276
5750
  while (chunk) {
5277
5751
  if (chunk.contains(index)) return this._splitChunk(chunk, index);
5278
- chunk = searchForward ? this.byStart[chunk.end] : this.byEnd[chunk.start];
5752
+ chunk = searchForward ? this.byStart.get(chunk.end) : this.byEnd.get(chunk.start);
5279
5753
  if (chunk === previousChunk) return;
5280
5754
  previousChunk = chunk;
5281
5755
  }
5282
5756
  }
5757
+ /** @internal */
5283
5758
  _splitChunk(chunk, index) {
5284
5759
  if (chunk.edited && chunk.content.length) {
5285
5760
  const loc = getLocator(this.original)(index);
5286
- throw new Error(`Cannot split a chunk that has already been edited (${loc.line}:${loc.column} – "${chunk.original}")`);
5761
+ throw new MagicStringError(`cannot split a chunk that has already been edited (${loc.line}:${loc.column} – "${chunk.original}")`);
5287
5762
  }
5288
5763
  const newChunk = chunk.split(index);
5289
- this.byEnd[index] = chunk;
5290
- this.byStart[index] = newChunk;
5291
- this.byEnd[newChunk.end] = newChunk;
5764
+ this.byEnd.set(index, chunk);
5765
+ this.byStart.set(index, newChunk);
5766
+ this.byEnd.set(newChunk.end, newChunk);
5292
5767
  if (chunk === this.lastChunk) this.lastChunk = newChunk;
5293
5768
  this.lastSearchedChunk = chunk;
5294
5769
  return true;
5295
5770
  }
5771
+ /**
5772
+ * Returns the generated string.
5773
+ */
5296
5774
  toString() {
5297
5775
  let str = this.intro;
5298
5776
  let chunk = this.firstChunk;
@@ -5302,29 +5780,41 @@ var MagicString = class MagicString {
5302
5780
  }
5303
5781
  return str + this.outro;
5304
5782
  }
5783
+ /**
5784
+ * Returns true if the resulting source is empty (disregarding white space).
5785
+ */
5305
5786
  isEmpty() {
5306
5787
  let chunk = this.firstChunk;
5307
- do
5788
+ while (chunk) {
5308
5789
  if (chunk.intro.length && chunk.intro.trim() || chunk.content.length && chunk.content.trim() || chunk.outro.length && chunk.outro.trim()) return false;
5309
- while (chunk = chunk.next);
5790
+ chunk = chunk.next;
5791
+ }
5310
5792
  return true;
5311
5793
  }
5312
5794
  length() {
5313
5795
  let chunk = this.firstChunk;
5314
5796
  let length = 0;
5315
- do
5797
+ while (chunk) {
5316
5798
  length += chunk.intro.length + chunk.content.length + chunk.outro.length;
5317
- while (chunk = chunk.next);
5799
+ chunk = chunk.next;
5800
+ }
5318
5801
  return length;
5319
5802
  }
5803
+ /**
5804
+ * Removes empty lines from the start and end.
5805
+ */
5320
5806
  trimLines() {
5321
5807
  return this.trim("[\\r\\n]");
5322
5808
  }
5809
+ /**
5810
+ * Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the start and end.
5811
+ */
5323
5812
  trim(charType) {
5324
5813
  return this.trimStart(charType).trimEnd(charType);
5325
5814
  }
5815
+ /** @internal */
5326
5816
  trimEndAborted(charType) {
5327
- const rx = new RegExp((charType || "\\s") + "+$");
5817
+ const rx = new RegExp(`${charType || "\\s"}+$`);
5328
5818
  this.outro = this.outro.replace(rx, "");
5329
5819
  if (this.outro.length) return true;
5330
5820
  let chunk = this.lastChunk;
@@ -5333,21 +5823,25 @@ var MagicString = class MagicString {
5333
5823
  const aborted = chunk.trimEnd(rx);
5334
5824
  if (chunk.end !== end) {
5335
5825
  if (this.lastChunk === chunk) this.lastChunk = chunk.next;
5336
- this.byEnd[chunk.end] = chunk;
5337
- this.byStart[chunk.next.start] = chunk.next;
5338
- this.byEnd[chunk.next.end] = chunk.next;
5826
+ this.byEnd.set(chunk.end, chunk);
5827
+ this.byStart.set(chunk.next.start, chunk.next);
5828
+ this.byEnd.set(chunk.next.end, chunk.next);
5339
5829
  }
5340
5830
  if (aborted) return true;
5341
5831
  chunk = chunk.previous;
5342
5832
  } while (chunk);
5343
5833
  return false;
5344
5834
  }
5835
+ /**
5836
+ * Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the end.
5837
+ */
5345
5838
  trimEnd(charType) {
5346
5839
  this.trimEndAborted(charType);
5347
5840
  return this;
5348
5841
  }
5842
+ /** @internal */
5349
5843
  trimStartAborted(charType) {
5350
- const rx = new RegExp("^" + (charType || "\\s") + "+");
5844
+ const rx = new RegExp(`^${charType || "\\s"}+`);
5351
5845
  this.intro = this.intro.replace(rx, "");
5352
5846
  if (this.intro.length) return true;
5353
5847
  let chunk = this.firstChunk;
@@ -5356,22 +5850,29 @@ var MagicString = class MagicString {
5356
5850
  const aborted = chunk.trimStart(rx);
5357
5851
  if (chunk.end !== end) {
5358
5852
  if (chunk === this.lastChunk) this.lastChunk = chunk.next;
5359
- this.byEnd[chunk.end] = chunk;
5360
- this.byStart[chunk.next.start] = chunk.next;
5361
- this.byEnd[chunk.next.end] = chunk.next;
5853
+ this.byEnd.set(chunk.end, chunk);
5854
+ this.byStart.set(chunk.next.start, chunk.next);
5855
+ this.byEnd.set(chunk.next.end, chunk.next);
5362
5856
  }
5363
5857
  if (aborted) return true;
5364
5858
  chunk = chunk.next;
5365
5859
  } while (chunk);
5366
5860
  return false;
5367
5861
  }
5862
+ /**
5863
+ * Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the start.
5864
+ */
5368
5865
  trimStart(charType) {
5369
5866
  this.trimStartAborted(charType);
5370
5867
  return this;
5371
5868
  }
5869
+ /**
5870
+ * Indicates if the string has been changed.
5871
+ */
5372
5872
  hasChanged() {
5373
5873
  return this.original !== this.toString();
5374
5874
  }
5875
+ /** @internal */
5375
5876
  _replaceRegexp(searchValue, replacement) {
5376
5877
  function getReplacement(match, str) {
5377
5878
  if (typeof replacement === "string") return replacement.replace(/\$(\$|&|\d+)/g, (_, i) => {
@@ -5380,12 +5881,15 @@ var MagicString = class MagicString {
5380
5881
  if (+i < match.length) return match[+i];
5381
5882
  return `$${i}`;
5382
5883
  });
5383
- else return replacement(...match, match.index, str, match.groups);
5884
+ else return replacement(match[0], ...match.slice(1), match.index, str, match.groups);
5384
5885
  }
5385
5886
  function matchAll(re, str) {
5386
- let match;
5387
5887
  const matches = [];
5388
- while (match = re.exec(str)) matches.push(match);
5888
+ while (true) {
5889
+ const match = re.exec(str);
5890
+ if (!match) break;
5891
+ matches.push(match);
5892
+ }
5389
5893
  return matches;
5390
5894
  }
5391
5895
  if (searchValue.global) matchAll(searchValue, this.original).forEach((match) => {
@@ -5403,6 +5907,7 @@ var MagicString = class MagicString {
5403
5907
  }
5404
5908
  return this;
5405
5909
  }
5910
+ /** @internal */
5406
5911
  _replaceString(string, replacement) {
5407
5912
  const { original } = this;
5408
5913
  const index = original.indexOf(string);
@@ -5412,24 +5917,30 @@ var MagicString = class MagicString {
5412
5917
  }
5413
5918
  return this;
5414
5919
  }
5920
+ /**
5921
+ * String replacement with RegExp or string.
5922
+ */
5415
5923
  replace(searchValue, replacement) {
5416
5924
  if (typeof searchValue === "string") return this._replaceString(searchValue, replacement);
5417
5925
  return this._replaceRegexp(searchValue, replacement);
5418
5926
  }
5927
+ /** @internal */
5419
5928
  _replaceAllString(string, replacement) {
5420
5929
  const { original } = this;
5421
5930
  const stringLength = string.length;
5422
5931
  for (let index = original.indexOf(string); index !== -1; index = original.indexOf(string, index + stringLength)) {
5423
5932
  const previous = original.slice(index, index + stringLength);
5424
- let _replacement = replacement;
5425
- if (typeof replacement === "function") _replacement = replacement(previous, index, original);
5933
+ const _replacement = typeof replacement === "function" ? replacement(previous, index, original) : replacement;
5426
5934
  if (previous !== _replacement) this.overwrite(index, index + stringLength, _replacement);
5427
5935
  }
5428
5936
  return this;
5429
5937
  }
5938
+ /**
5939
+ * Same as `s.replace`, but replace all matched strings instead of just one.
5940
+ */
5430
5941
  replaceAll(searchValue, replacement) {
5431
5942
  if (typeof searchValue === "string") return this._replaceAllString(searchValue, replacement);
5432
- if (!searchValue.global) throw new TypeError("MagicString.prototype.replaceAll called with a non-global RegExp argument");
5943
+ if (!searchValue.global) throw new MagicStringError("replaceAll() requires a global RegExp");
5433
5944
  return this._replaceRegexp(searchValue, replacement);
5434
5945
  }
5435
5946
  };
@@ -5830,6 +6341,7 @@ function timberFonts(ctx) {
5830
6341
  if (pipeline.cssIdMap.matches(id)) {
5831
6342
  const importer = pipeline.cssIdMap.importerFor(id);
5832
6343
  if (!importer) return "";
6344
+ if (process.env.TIMBER_ANALYZE === "1") return "";
5833
6345
  const skipFonts = process.env.TIMBER_SKIP_FONTS === "1";
5834
6346
  for (const font of pipeline.googleFonts()) {
5835
6347
  if (font.importer !== importer) continue;
@@ -7337,8 +7849,10 @@ function lookupFacades(id, sharedModuleFacades) {
7337
7849
  if (!isBareSpecifier(id)) return void 0;
7338
7850
  const needle = `/node_modules/${id}/`;
7339
7851
  let merged;
7340
- for (const [key, facades] of sharedModuleFacades) if (key.includes(needle)) if (!merged) merged = [...facades];
7341
- else merged.push(...facades);
7852
+ for (const [key, facades] of sharedModuleFacades) if (key.includes(needle)) {
7853
+ if (!merged) merged = [...facades];
7854
+ else merged.push(...facades);
7855
+ }
7342
7856
  return merged;
7343
7857
  }
7344
7858
  /**
@@ -7413,6 +7927,7 @@ function clientChunkGroup(meta, appDir, root, sharedModuleFacades) {
7413
7927
  *
7414
7928
  * Design docs: design/11-platform.md, design/25-production-deployments.md
7415
7929
  */
7930
+ var POISON_MARKER_SPECIFIERS = EXPLICIT_MARKERS.map((m) => m.specifier);
7416
7931
  var NODE_BUILTINS = builtinModules.flatMap((m) => [m, `node:${m}`]);
7417
7932
  var CLOUDFLARE_BUILTINS = [
7418
7933
  "cloudflare:workers",
@@ -7426,7 +7941,8 @@ var BUILD_ONLY_EXTERNALS = [
7426
7941
  "vite",
7427
7942
  "nitro",
7428
7943
  "rollup",
7429
- "@mdx-js/rollup",
7944
+ "vite-plugin-satteri",
7945
+ "satteri",
7430
7946
  "fsevents",
7431
7947
  "chokidar"
7432
7948
  ];
@@ -7436,12 +7952,8 @@ function timberServerBundle() {
7436
7952
  name: "timber-server-bundle",
7437
7953
  config(_cfg, { command }) {
7438
7954
  if (command === "serve") return { environments: {
7439
- rsc: { resolve: { noExternal: ["server-only", "client-only"] } },
7440
- ssr: { resolve: { noExternal: [
7441
- "server-only",
7442
- "client-only",
7443
- "nuqs"
7444
- ] } }
7955
+ rsc: { resolve: { noExternal: [...POISON_MARKER_SPECIFIERS] } },
7956
+ ssr: { resolve: { noExternal: [...POISON_MARKER_SPECIFIERS, "nuqs"] } }
7445
7957
  } };
7446
7958
  const serverDefine = { "process.env.NODE_ENV": JSON.stringify("production") };
7447
7959
  return {
@@ -7569,9 +8081,7 @@ function collectPatternNames(node, out) {
7569
8081
  for (const prop of node.properties ?? []) if (prop.type === "RestElement") collectPatternNames(prop, out);
7570
8082
  else collectPatternNames(prop.value, out);
7571
8083
  break;
7572
- case "TSParameterProperty":
7573
- if (node.parameter) collectPatternNames(node.parameter, out);
7574
- break;
8084
+ case "TSParameterProperty": if (node.parameter) collectPatternNames(node.parameter, out);
7575
8085
  }
7576
8086
  }
7577
8087
  /** Return the intersection of param names with `tracked`, or null if none. */
@@ -7943,7 +8453,8 @@ function timberCacheTransform(ctx) {
7943
8453
  }
7944
8454
  if (callSites.length === 0) return;
7945
8455
  callSites.sort((a, b) => a.call.start - b.call.start);
7946
- const relPath = relative(ctx.root || process.cwd(), id);
8456
+ const root = ctx.root || process.cwd();
8457
+ const relPath = relative(root, id);
7947
8458
  const s = new MagicString(code);
7948
8459
  const occurrences = /* @__PURE__ */ new Map();
7949
8460
  for (const { call, stmt } of callSites) {
@@ -8268,9 +8779,7 @@ function analyzeModule(program) {
8268
8779
  case "ExportAllDeclaration":
8269
8780
  collectExportAll(stmt, facts);
8270
8781
  break;
8271
- case "ExportDefaultDeclaration":
8272
- collectExportDefault(stmt, facts);
8273
- break;
8782
+ case "ExportDefaultDeclaration": collectExportDefault(stmt, facts);
8274
8783
  }
8275
8784
  walk(program, facts);
8276
8785
  return facts;
@@ -9351,7 +9860,8 @@ function timberPrebuilt(ctx) {
9351
9860
  if (bindings.named.size === 0 && bindings.namespaces.size === 0) return;
9352
9861
  const callSites = collectModuleScopeSites(program, bindings);
9353
9862
  if (callSites.length === 0) return;
9354
- const relPath = relative(ctx.root || process.cwd(), id);
9863
+ const root = ctx.root || process.cwd();
9864
+ const relPath = relative(root, id);
9355
9865
  const s = new MagicString(code);
9356
9866
  const occurrences = /* @__PURE__ */ new Map();
9357
9867
  const wrapperName = ctx.dev ? "__prebuiltDev" : "__prebuilt";
@@ -9511,27 +10021,24 @@ function timberPrebuilt(ctx) {
9511
10021
  * `export const prerender` to descendant pages via most-specific-wins:
9512
10022
  * walk the segment tree from leaf to root, first explicit value wins.
9513
10023
  *
9514
- * A layout that declares `export const prerender` is ALSO wrapped — the
9515
- * layout's flight payload is its own static shell (`children` is a
9516
- * separate component boundary), so caching it is natural (nav, sidebar,
9517
- * footer benefit from build-time rendering). See design/45 §Layout
9518
- * Propagation.
10024
+ * Layout declarations are propagation policy only. Layouts receive the real
10025
+ * descendant React element as `children` to preserve the server-layout
10026
+ * containment boundary, so their props are not cache-keyable and the layout
10027
+ * itself must not be registered for capture.
9519
10028
  *
9520
10029
  * This transform runs BEFORE timber-prebuilt so the generated
9521
10030
  * `cache.component(...)` call is picked up by the callsite rewrite.
9522
10031
  */
9523
10032
  /**
9524
10033
  * Walk the segment tree and resolve the effective prerender value for
9525
- * every page and layout. Returns a map from file path to resolved value.
10034
+ * every page. Returns a map from page file path to resolved value.
9526
10035
  *
9527
10036
  * **Pages:** walk from leaf toward root; first explicit `export const prerender`
9528
10037
  * wins (page > nearest layout > ... > root layout). If none, dynamic.
9529
10038
  *
9530
- * **Layouts:** a layout that declares `export const prerender` is wrapped
9531
- * directly (its own shell is a separate component boundary from `children`).
9532
- * Layouts without their own declaration are NOT wrapped — they don't
9533
- * inherit from ancestors, because wrapping a layout's shell without the
9534
- * author's explicit opt-in would cache content they may expect to be dynamic.
10039
+ * **Layouts:** declarations propagate to descendant pages but layouts are not
10040
+ * included in the result. Their real React-element `children` preserve secure
10041
+ * containment and deliberately make child-independent layout caching invalid.
9535
10042
  */
9536
10043
  function resolvePagePrerender(root) {
9537
10044
  const result = /* @__PURE__ */ new Map();
@@ -9539,7 +10046,6 @@ function resolvePagePrerender(root) {
9539
10046
  if (node.segmentType === "intercepting" || node.segmentType === "private") return;
9540
10047
  const layoutValue = node.layout ? getPrerenderExport(node.layout.filePath) : void 0;
9541
10048
  const stack = layoutValue !== void 0 ? [layoutValue, ...ancestorStack] : ancestorStack;
9542
- if (node.layout && layoutValue !== void 0 && layoutValue !== false) result.set(node.layout.filePath, layoutValue);
9543
10049
  if (node.page) {
9544
10050
  const pageValue = getPrerenderExport(node.page.filePath);
9545
10051
  const resolved = pageValue !== void 0 ? pageValue : stack[0];
@@ -10622,7 +11128,8 @@ function timber(config) {
10622
11128
  }
10623
11129
  let resolvedDevPort = null;
10624
11130
  let resolvedDevPortExplicit = false;
10625
- if (command === "serve" && !isPreview) {
11131
+ const isMiddlewareMode = Boolean(userConfig.server?.middlewareMode);
11132
+ if (command === "serve" && !isPreview && !isMiddlewareMode) {
10626
11133
  ctx.holdingServer = createHoldingServer();
10627
11134
  const holdingRef = ctx.holdingServer;
10628
11135
  const result = await startDevServerPort({
@@ -10703,7 +11210,6 @@ function timber(config) {
10703
11210
  ctx.buildDir = resolve(resolved.root, resolved.build.outDir);
10704
11211
  if (!ctx.dev) ctx.timer = createNoopTimer();
10705
11212
  else ctx.timer.start("dev-server-setup");
10706
- const { validateConfig, formatConfigErrors, checkPeerDependencies, formatMissingPeers } = (init_config_validation(), __toCommonJS(config_validation_exports));
10707
11213
  const configErrors = validateConfig(ctx.config);
10708
11214
  if (configErrors.length > 0) process.stderr.write(`${formatConfigErrors(configErrors)}\n\n`);
10709
11215
  const peerWarning = formatMissingPeers(checkPeerDependencies(ctx.root));