@rangojs/router 0.0.0-experimental.14 → 0.0.0-experimental.140

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 (460) hide show
  1. package/AGENTS.md +17 -0
  2. package/README.md +432 -7
  3. package/dist/bin/rango.js +2073 -213
  4. package/dist/testing/vitest.js +82 -0
  5. package/dist/vite/index.js +7258 -2714
  6. package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  7. package/package.json +140 -67
  8. package/skills/api-client/SKILL.md +211 -0
  9. package/skills/breadcrumbs/SKILL.md +329 -0
  10. package/skills/bundle-analysis/SKILL.md +159 -0
  11. package/skills/cache-guide/SKILL.md +487 -0
  12. package/skills/caching/SKILL.md +357 -25
  13. package/skills/comparison/SKILL.md +50 -0
  14. package/skills/comparison/agents/openai.yaml +4 -0
  15. package/skills/comparison/references/framework-comparison.md +837 -0
  16. package/skills/composability/SKILL.md +246 -0
  17. package/skills/css/SKILL.md +76 -0
  18. package/skills/debug-manifest/SKILL.md +16 -10
  19. package/skills/document-cache/SKILL.md +87 -62
  20. package/skills/fonts/SKILL.md +6 -4
  21. package/skills/handler-use/SKILL.md +364 -0
  22. package/skills/hooks/SKILL.md +557 -79
  23. package/skills/host-router/SKILL.md +320 -0
  24. package/skills/i18n/SKILL.md +276 -0
  25. package/skills/intercept/SKILL.md +207 -15
  26. package/skills/layout/SKILL.md +146 -6
  27. package/skills/links/SKILL.md +304 -25
  28. package/skills/loader/SKILL.md +616 -54
  29. package/skills/middleware/SKILL.md +217 -37
  30. package/skills/migrate-nextjs/SKILL.md +611 -0
  31. package/skills/migrate-react-router/SKILL.md +927 -0
  32. package/skills/mime-routes/SKILL.md +42 -11
  33. package/skills/observability/SKILL.md +194 -0
  34. package/skills/parallel/SKILL.md +284 -3
  35. package/skills/ppr/SKILL.md +426 -0
  36. package/skills/prerender/SKILL.md +437 -52
  37. package/skills/rango/SKILL.md +369 -22
  38. package/skills/react-compiler/SKILL.md +168 -0
  39. package/skills/response-routes/SKILL.md +263 -121
  40. package/skills/route/SKILL.md +350 -21
  41. package/skills/router-setup/SKILL.md +246 -33
  42. package/skills/scripts/SKILL.md +179 -0
  43. package/skills/server-actions/SKILL.md +775 -0
  44. package/skills/shell-manifest/SKILL.md +185 -0
  45. package/skills/streams-and-websockets/SKILL.md +283 -0
  46. package/skills/tailwind/SKILL.md +27 -3
  47. package/skills/testing/SKILL.md +126 -222
  48. package/skills/testing/bindings.md +103 -0
  49. package/skills/testing/cache-prerender.md +127 -0
  50. package/skills/testing/client-components.md +124 -0
  51. package/skills/testing/e2e-parity.md +125 -0
  52. package/skills/testing/flight.md +91 -0
  53. package/skills/testing/handles.md +131 -0
  54. package/skills/testing/loader.md +128 -0
  55. package/skills/testing/middleware.md +99 -0
  56. package/skills/testing/render-handler.md +122 -0
  57. package/skills/testing/response-routes.md +95 -0
  58. package/skills/testing/reverse-and-types.md +85 -0
  59. package/skills/testing/server-actions.md +107 -0
  60. package/skills/testing/server-tree.md +128 -0
  61. package/skills/testing/setup.md +123 -0
  62. package/skills/theme/SKILL.md +9 -8
  63. package/skills/typesafety/SKILL.md +532 -103
  64. package/skills/use-cache/SKILL.md +367 -0
  65. package/skills/vercel/SKILL.md +128 -0
  66. package/skills/view-transitions/SKILL.md +337 -0
  67. package/src/__augment-tests__/augment.ts +81 -0
  68. package/src/__augment-tests__/augmented.check.ts +116 -0
  69. package/src/__internal.ts +77 -44
  70. package/src/bin/rango.ts +312 -15
  71. package/src/browser/action-coordinator.ts +114 -0
  72. package/src/browser/action-fence.ts +47 -0
  73. package/src/browser/app-shell.ts +39 -0
  74. package/src/browser/app-version.ts +14 -0
  75. package/src/browser/connection-warmup.ts +134 -0
  76. package/src/browser/cookie-name.ts +140 -0
  77. package/src/browser/event-controller.ts +293 -202
  78. package/src/browser/history-state.ts +101 -0
  79. package/src/browser/index.ts +3 -3
  80. package/src/browser/intercept-utils.ts +52 -0
  81. package/src/browser/invalidate-client-cache.ts +52 -0
  82. package/src/browser/link-interceptor.ts +24 -4
  83. package/src/browser/logging.ts +11 -0
  84. package/src/browser/merge-segment-loaders.ts +20 -12
  85. package/src/browser/navigation-bridge.ts +385 -576
  86. package/src/browser/navigation-client.ts +245 -75
  87. package/src/browser/navigation-store-handle.ts +38 -0
  88. package/src/browser/navigation-store.ts +184 -118
  89. package/src/browser/navigation-transaction.ts +247 -0
  90. package/src/browser/network-error-handler.ts +88 -0
  91. package/src/browser/partial-update.ts +412 -364
  92. package/src/browser/prefetch/cache.ts +359 -0
  93. package/src/browser/prefetch/fetch.ts +452 -0
  94. package/src/browser/prefetch/observer.ts +65 -0
  95. package/src/browser/prefetch/policy.ts +48 -0
  96. package/src/browser/prefetch/queue.ts +209 -0
  97. package/src/browser/prefetch/resource-ready.ts +77 -0
  98. package/src/browser/rango-state.ts +194 -0
  99. package/src/browser/react/Link.tsx +275 -68
  100. package/src/browser/react/NavigationProvider.tsx +265 -109
  101. package/src/browser/react/ScrollRestoration.tsx +10 -6
  102. package/src/browser/react/context.ts +11 -0
  103. package/src/browser/react/filter-segment-order.ts +70 -0
  104. package/src/browser/react/index.ts +0 -48
  105. package/src/browser/react/location-state-shared.ts +272 -60
  106. package/src/browser/react/location-state.ts +90 -20
  107. package/src/browser/react/mount-context.ts +6 -1
  108. package/src/browser/react/nonce-context.ts +23 -0
  109. package/src/browser/react/shallow-equal.ts +27 -0
  110. package/src/browser/react/use-action.ts +35 -66
  111. package/src/browser/react/use-handle.ts +39 -126
  112. package/src/browser/react/use-href.tsx +8 -1
  113. package/src/browser/react/use-link-status.ts +39 -13
  114. package/src/browser/react/use-navigation.ts +53 -69
  115. package/src/browser/react/use-params.ts +75 -0
  116. package/src/browser/react/use-pathname.ts +47 -0
  117. package/src/browser/react/use-reverse.ts +106 -0
  118. package/src/browser/react/use-router.ts +98 -0
  119. package/src/browser/react/use-search-params.ts +51 -0
  120. package/src/browser/react/use-segments.ts +72 -99
  121. package/src/browser/response-adapter.ts +164 -0
  122. package/src/browser/rsc-router.tsx +300 -72
  123. package/src/browser/scroll-restoration.ts +138 -50
  124. package/src/browser/segment-reconciler.ts +243 -0
  125. package/src/browser/segment-structure-assert.ts +17 -1
  126. package/src/browser/server-action-bridge.ts +668 -613
  127. package/src/browser/types.ts +223 -51
  128. package/src/browser/validate-redirect-origin.ts +56 -0
  129. package/src/build/collect-fallback-refs.ts +107 -0
  130. package/src/build/generate-manifest.ts +252 -161
  131. package/src/build/generate-route-types.ts +41 -1038
  132. package/src/build/index.ts +12 -7
  133. package/src/build/prefix-tree-utils.ts +123 -0
  134. package/src/build/route-trie.ts +225 -42
  135. package/src/build/route-types/ast-helpers.ts +25 -0
  136. package/src/build/route-types/ast-route-extraction.ts +105 -0
  137. package/src/build/route-types/codegen.ts +113 -0
  138. package/src/build/route-types/include-resolution.ts +812 -0
  139. package/src/build/route-types/param-extraction.ts +51 -0
  140. package/src/build/route-types/per-module-writer.ts +144 -0
  141. package/src/build/route-types/router-processing.ts +695 -0
  142. package/src/build/route-types/scan-filter.ts +85 -0
  143. package/src/build/route-types/source-scan.ts +216 -0
  144. package/src/build/runtime-discovery.ts +223 -0
  145. package/src/cache/background-task.ts +34 -0
  146. package/src/cache/cache-error.ts +104 -0
  147. package/src/cache/cache-key-utils.ts +60 -0
  148. package/src/cache/cache-policy.ts +199 -0
  149. package/src/cache/cache-runtime.ts +525 -0
  150. package/src/cache/cache-scope.ts +298 -332
  151. package/src/cache/cache-tag.ts +103 -0
  152. package/src/cache/cf/cf-base64.ts +33 -0
  153. package/src/cache/cf/cf-cache-constants.ts +127 -0
  154. package/src/cache/cf/cf-cache-store.ts +2500 -158
  155. package/src/cache/cf/cf-cache-types.ts +349 -0
  156. package/src/cache/cf/cf-kv-utils.ts +46 -0
  157. package/src/cache/cf/cf-tag-marker-memo.ts +105 -0
  158. package/src/cache/cf/index.ts +17 -17
  159. package/src/cache/document-cache.ts +199 -92
  160. package/src/cache/handle-capture.ts +81 -0
  161. package/src/cache/handle-snapshot.ts +111 -0
  162. package/src/cache/index.ts +29 -35
  163. package/src/cache/memory-segment-store.ts +363 -30
  164. package/src/cache/profile-registry.ts +88 -0
  165. package/src/cache/read-through-swr.ts +178 -0
  166. package/src/cache/segment-codec.ts +248 -0
  167. package/src/cache/shell-cache.ts +386 -0
  168. package/src/cache/tag-invalidation.ts +230 -0
  169. package/src/cache/taint.ts +153 -0
  170. package/src/cache/types.ts +156 -211
  171. package/src/cache/vercel/index.ts +11 -0
  172. package/src/cache/vercel/vercel-cache-store.ts +1102 -0
  173. package/src/client.rsc.tsx +43 -21
  174. package/src/client.tsx +131 -347
  175. package/src/cloudflare/index.ts +11 -0
  176. package/src/cloudflare/tracing.ts +109 -0
  177. package/src/component-utils.ts +23 -4
  178. package/src/components/DefaultDocument.tsx +13 -3
  179. package/src/context-var.ts +168 -0
  180. package/src/debug.ts +19 -9
  181. package/src/decode-loader-results.ts +52 -0
  182. package/src/defer.ts +185 -0
  183. package/src/deps/ssr.ts +0 -1
  184. package/src/encode-kv.ts +49 -0
  185. package/src/errors.ts +106 -10
  186. package/src/escape-script.ts +52 -0
  187. package/src/handle.ts +110 -35
  188. package/src/handles/MetaTags.tsx +83 -59
  189. package/src/handles/Scripts.tsx +183 -0
  190. package/src/handles/breadcrumbs.ts +93 -0
  191. package/src/handles/deferred-resolution.ts +127 -0
  192. package/src/handles/is-thenable.ts +18 -0
  193. package/src/handles/meta.ts +44 -53
  194. package/src/handles/script.ts +244 -0
  195. package/src/host/cookie-handler.ts +20 -65
  196. package/src/host/errors.ts +21 -30
  197. package/src/host/index.ts +13 -9
  198. package/src/host/pattern-matcher.ts +50 -79
  199. package/src/host/router.ts +151 -121
  200. package/src/host/testing.ts +45 -32
  201. package/src/host/types.ts +52 -11
  202. package/src/host/utils.ts +2 -2
  203. package/src/href-client.ts +192 -57
  204. package/src/index.rsc.ts +177 -35
  205. package/src/index.ts +255 -71
  206. package/src/internal-debug.ts +9 -2
  207. package/src/loader-store.ts +500 -0
  208. package/src/loader.rsc.ts +31 -99
  209. package/src/loader.ts +30 -12
  210. package/src/missing-id-error.ts +68 -0
  211. package/src/outlet-context.ts +1 -1
  212. package/src/outlet-provider.tsx +41 -0
  213. package/src/prerender/param-hash.ts +16 -14
  214. package/src/prerender/store.ts +121 -21
  215. package/src/prerender.ts +460 -26
  216. package/src/redirect-origin.ts +100 -0
  217. package/src/regex-escape.ts +8 -0
  218. package/src/render-error-thrower.tsx +20 -0
  219. package/src/response-utils.ts +62 -0
  220. package/src/reverse.ts +198 -128
  221. package/src/root-error-boundary.tsx +42 -48
  222. package/src/route-content-wrapper.tsx +22 -77
  223. package/src/route-definition/dsl-helpers.ts +1116 -0
  224. package/src/route-definition/helper-factories.ts +88 -0
  225. package/src/route-definition/helpers-types.ts +505 -0
  226. package/src/route-definition/index.ts +54 -0
  227. package/src/route-definition/redirect.ts +134 -0
  228. package/src/route-definition/resolve-handler-use.ts +160 -0
  229. package/src/route-definition/use-item-types.ts +29 -0
  230. package/src/route-definition.ts +1 -1481
  231. package/src/route-map-builder.ts +82 -144
  232. package/src/route-name.ts +53 -0
  233. package/src/route-types.ts +71 -45
  234. package/src/router/basename.ts +14 -0
  235. package/src/router/content-negotiation.ts +263 -0
  236. package/src/router/debug-manifest.ts +72 -0
  237. package/src/router/error-handling.ts +54 -27
  238. package/src/router/find-match.ts +245 -0
  239. package/src/router/handler-context.ts +377 -125
  240. package/src/router/instrument.ts +350 -0
  241. package/src/router/intercept-resolution.ts +59 -28
  242. package/src/router/lazy-includes.ts +254 -0
  243. package/src/router/loader-resolution.ts +421 -157
  244. package/src/router/logging.ts +106 -6
  245. package/src/router/manifest.ts +131 -57
  246. package/src/router/match-api.ts +167 -246
  247. package/src/router/match-context.ts +4 -24
  248. package/src/router/match-handlers.ts +440 -0
  249. package/src/router/match-middleware/background-revalidation.ts +117 -93
  250. package/src/router/match-middleware/cache-lookup.ts +297 -150
  251. package/src/router/match-middleware/cache-store.ts +123 -51
  252. package/src/router/match-middleware/intercept-resolution.ts +44 -43
  253. package/src/router/match-middleware/segment-resolution.ts +64 -22
  254. package/src/router/match-pipelines.ts +11 -87
  255. package/src/router/match-result.ts +121 -50
  256. package/src/router/metrics.ts +219 -28
  257. package/src/router/middleware-types.ts +93 -0
  258. package/src/router/middleware.ts +505 -441
  259. package/src/router/navigation-snapshot.ts +133 -0
  260. package/src/router/params-util.ts +23 -0
  261. package/src/router/parse-pattern.ts +115 -0
  262. package/src/router/pattern-matching.ts +311 -142
  263. package/src/router/prefetch-cache-ttl.ts +51 -0
  264. package/src/router/prefetch-limits.ts +37 -0
  265. package/src/router/prerender-match.ts +547 -0
  266. package/src/router/preview-match.ts +102 -0
  267. package/src/router/request-classification.ts +278 -0
  268. package/src/router/revalidation.ts +203 -62
  269. package/src/router/route-snapshot.ts +246 -0
  270. package/src/router/router-context.ts +45 -48
  271. package/src/router/router-interfaces.ts +554 -0
  272. package/src/router/router-options.ts +779 -0
  273. package/src/router/router-registry.ts +21 -0
  274. package/src/router/segment-resolution/fresh.ts +772 -0
  275. package/src/router/segment-resolution/helpers.ts +348 -0
  276. package/src/router/segment-resolution/loader-cache.ts +250 -0
  277. package/src/router/segment-resolution/loader-mask.ts +44 -0
  278. package/src/router/segment-resolution/revalidation.ts +1331 -0
  279. package/src/router/segment-resolution/static-store.ts +81 -0
  280. package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
  281. package/src/router/segment-resolution/view-transition-default.ts +56 -0
  282. package/src/router/segment-resolution.ts +25 -1354
  283. package/src/router/segment-wrappers.ts +292 -0
  284. package/src/router/state-cookie-name.ts +33 -0
  285. package/src/router/substitute-pattern-params.ts +75 -0
  286. package/src/router/telemetry-otel.ts +261 -0
  287. package/src/router/telemetry.ts +377 -0
  288. package/src/router/timeout.ts +128 -0
  289. package/src/router/tracing.ts +206 -0
  290. package/src/router/trie-matching.ts +240 -61
  291. package/src/router/types.ts +23 -70
  292. package/src/router/url-params.ts +57 -0
  293. package/src/router.ts +781 -2378
  294. package/src/rsc/full-payload.ts +70 -0
  295. package/src/rsc/handler-context.ts +46 -0
  296. package/src/rsc/handler.ts +905 -1142
  297. package/src/rsc/helpers.ts +275 -19
  298. package/src/rsc/index.ts +2 -25
  299. package/src/rsc/json-route-result.ts +38 -0
  300. package/src/rsc/loader-fetch.ts +305 -0
  301. package/src/rsc/manifest-init.ts +77 -0
  302. package/src/rsc/nonce.ts +14 -0
  303. package/src/rsc/origin-guard.ts +155 -0
  304. package/src/rsc/progressive-enhancement.ts +502 -0
  305. package/src/rsc/redirect-guard.ts +99 -0
  306. package/src/rsc/response-cache-serve.ts +238 -0
  307. package/src/rsc/response-error.ts +104 -0
  308. package/src/rsc/response-route-handler.ts +257 -0
  309. package/src/rsc/rsc-rendering.ts +337 -0
  310. package/src/rsc/runtime-warnings.ts +55 -0
  311. package/src/rsc/server-action.ts +522 -0
  312. package/src/rsc/shell-capture.ts +439 -0
  313. package/src/rsc/ssr-setup.ts +144 -0
  314. package/src/rsc/transition-gate.ts +89 -0
  315. package/src/rsc/types.ts +95 -12
  316. package/src/runtime-env.ts +18 -0
  317. package/src/search-params.ts +99 -82
  318. package/src/segment-content-promise.ts +67 -0
  319. package/src/segment-loader-promise.ts +149 -0
  320. package/src/segment-system.tsx +349 -134
  321. package/src/serialize.ts +243 -0
  322. package/src/server/context.ts +452 -85
  323. package/src/server/cookie-parse.ts +32 -0
  324. package/src/server/cookie-store.ts +310 -0
  325. package/src/server/fetchable-loader-store.ts +11 -6
  326. package/src/server/handle-store.ts +123 -42
  327. package/src/server/live.ts +130 -0
  328. package/src/server/loader-registry.ts +51 -100
  329. package/src/server/request-context.ts +842 -157
  330. package/src/server.ts +15 -8
  331. package/src/ssr/index.tsx +412 -136
  332. package/src/ssr/ssr-root.tsx +228 -0
  333. package/src/static-handler.ts +45 -18
  334. package/src/testing/cache-status.ts +162 -0
  335. package/src/testing/collect-handle.ts +46 -0
  336. package/src/testing/dispatch.ts +701 -0
  337. package/src/testing/dom.entry.ts +22 -0
  338. package/src/testing/e2e/fixture.ts +188 -0
  339. package/src/testing/e2e/index.ts +128 -0
  340. package/src/testing/e2e/matchers.ts +35 -0
  341. package/src/testing/e2e/page-helpers.ts +272 -0
  342. package/src/testing/e2e/parity.ts +387 -0
  343. package/src/testing/e2e/server.ts +195 -0
  344. package/src/testing/flight-matchers.ts +97 -0
  345. package/src/testing/flight-normalize.ts +11 -0
  346. package/src/testing/flight-runtime.d.ts +57 -0
  347. package/src/testing/flight-tree.ts +682 -0
  348. package/src/testing/flight.entry.ts +52 -0
  349. package/src/testing/flight.ts +257 -0
  350. package/src/testing/generated-routes.ts +199 -0
  351. package/src/testing/index.ts +105 -0
  352. package/src/testing/internal/context.ts +371 -0
  353. package/src/testing/internal/flight-client-globals.ts +30 -0
  354. package/src/testing/internal/seed-vars.ts +54 -0
  355. package/src/testing/render-handler.ts +357 -0
  356. package/src/testing/render-route.tsx +584 -0
  357. package/src/testing/run-loader.ts +385 -0
  358. package/src/testing/run-middleware.ts +205 -0
  359. package/src/testing/run-transition-when.ts +164 -0
  360. package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
  361. package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
  362. package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
  363. package/src/testing/vitest-stubs/version.ts +5 -0
  364. package/src/testing/vitest.ts +305 -0
  365. package/src/theme/ThemeProvider.tsx +40 -72
  366. package/src/theme/ThemeScript.tsx +12 -14
  367. package/src/theme/constants.ts +57 -15
  368. package/src/theme/index.ts +3 -20
  369. package/src/theme/theme-context.ts +5 -35
  370. package/src/theme/theme-script.ts +43 -39
  371. package/src/theme/use-theme.ts +0 -3
  372. package/src/types/boundaries.ts +123 -0
  373. package/src/types/cache-types.ts +207 -0
  374. package/src/types/error-types.ts +132 -0
  375. package/src/types/global-namespace.ts +113 -0
  376. package/src/types/handler-context.ts +839 -0
  377. package/src/types/index.ts +81 -0
  378. package/src/types/loader-types.ts +212 -0
  379. package/src/types/request-scope.ts +112 -0
  380. package/src/types/route-config.ts +138 -0
  381. package/src/types/route-entry.ts +114 -0
  382. package/src/types/segments.ts +271 -0
  383. package/src/types.ts +1 -1795
  384. package/src/urls/include-helper.ts +162 -0
  385. package/src/urls/include-provider.ts +71 -0
  386. package/src/urls/index.ts +43 -0
  387. package/src/urls/path-helper-types.ts +413 -0
  388. package/src/urls/path-helper.ts +275 -0
  389. package/src/urls/pattern-types.ts +124 -0
  390. package/src/urls/response-types.ts +109 -0
  391. package/src/urls/type-extraction.ts +316 -0
  392. package/src/urls/urls-function.ts +80 -0
  393. package/src/urls.ts +1 -1341
  394. package/src/use-loader.tsx +406 -141
  395. package/src/vercel/index.ts +11 -0
  396. package/src/vercel/tracing.ts +88 -0
  397. package/src/vite/debug.ts +185 -0
  398. package/src/vite/discovery/bundle-postprocess.ts +182 -0
  399. package/src/vite/discovery/discover-routers.ts +389 -0
  400. package/src/vite/discovery/discovery-errors.ts +255 -0
  401. package/src/vite/discovery/gate-state.ts +171 -0
  402. package/src/vite/discovery/prerender-collection.ts +467 -0
  403. package/src/vite/discovery/route-types-writer.ts +214 -0
  404. package/src/vite/discovery/self-gen-tracking.ts +73 -0
  405. package/src/vite/discovery/state.ts +161 -0
  406. package/src/vite/discovery/virtual-module-codegen.ts +183 -0
  407. package/src/vite/index.ts +23 -2255
  408. package/src/vite/inject-client-debug.ts +36 -0
  409. package/src/vite/plugin-types.ts +303 -0
  410. package/src/vite/plugins/cjs-to-esm.ts +90 -0
  411. package/src/vite/plugins/client-ref-dedup.ts +120 -0
  412. package/src/vite/plugins/client-ref-hashing.ts +118 -0
  413. package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
  414. package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  415. package/src/vite/plugins/cloudflare-protocol-stub.ts +194 -0
  416. package/src/vite/{expose-action-id.ts → plugins/expose-action-id.ts} +88 -110
  417. package/src/vite/{expose-id-utils.ts → plugins/expose-id-utils.ts} +89 -79
  418. package/src/vite/plugins/expose-ids/export-analysis.ts +363 -0
  419. package/src/vite/plugins/expose-ids/handler-transform.ts +130 -0
  420. package/src/vite/plugins/expose-ids/loader-transform.ts +64 -0
  421. package/src/vite/plugins/expose-ids/router-transform.ts +199 -0
  422. package/src/vite/plugins/expose-ids/types.ts +45 -0
  423. package/src/vite/plugins/expose-internal-ids.ts +805 -0
  424. package/src/vite/plugins/performance-tracks.ts +89 -0
  425. package/src/vite/plugins/refresh-cmd.ts +127 -0
  426. package/src/vite/plugins/use-cache-transform.ts +313 -0
  427. package/src/vite/plugins/vercel-output.ts +384 -0
  428. package/src/vite/plugins/version-injector.ts +94 -0
  429. package/src/vite/plugins/version-plugin.ts +263 -0
  430. package/src/vite/plugins/virtual-entries.ts +234 -0
  431. package/src/vite/plugins/virtual-stub-plugin.ts +29 -0
  432. package/src/vite/rango.ts +560 -0
  433. package/src/vite/router-discovery.ts +1638 -0
  434. package/src/vite/{ast-handler-extract.ts → utils/ast-handler-extract.ts} +200 -37
  435. package/src/vite/utils/banner.ts +36 -0
  436. package/src/vite/utils/bundle-analysis.ts +132 -0
  437. package/src/vite/utils/client-chunks.ts +184 -0
  438. package/src/vite/utils/directive-prologue.ts +40 -0
  439. package/src/vite/utils/forward-user-plugins.ts +171 -0
  440. package/src/vite/utils/manifest-utils.ts +15 -0
  441. package/src/vite/utils/package-resolution.ts +89 -0
  442. package/src/vite/utils/prerender-utils.ts +249 -0
  443. package/src/vite/utils/shared-utils.ts +269 -0
  444. package/CLAUDE.md +0 -43
  445. package/dist/vite/index.named-routes.gen.ts +0 -103
  446. package/src/browser/lru-cache.ts +0 -69
  447. package/src/browser/react/use-client-cache.ts +0 -56
  448. package/src/browser/request-controller.ts +0 -164
  449. package/src/browser/shallow.ts +0 -35
  450. package/src/cache/memory-store.ts +0 -253
  451. package/src/handles/index.ts +0 -6
  452. package/src/href-context.ts +0 -33
  453. package/src/network-error-thrower.tsx +0 -21
  454. package/src/router.gen.ts +0 -6
  455. package/src/static-handler.gen.ts +0 -5
  456. package/src/urls.gen.ts +0 -8
  457. package/src/vite/expose-internal-ids.ts +0 -1167
  458. package/src/vite/package-resolution.ts +0 -125
  459. package/src/vite/virtual-entries.ts +0 -114
  460. /package/src/vite/{version.d.ts → plugins/version.d.ts} +0 -0
@@ -0,0 +1,560 @@
1
+ import { type PluginOption } from "vite";
2
+ import { readFileSync, existsSync } from "node:fs";
3
+ import { resolve } from "node:path";
4
+ import { exposeActionId } from "./plugins/expose-action-id.js";
5
+ import {
6
+ exposeInternalIds,
7
+ exposeRouterId,
8
+ } from "./plugins/expose-internal-ids.js";
9
+ import { useCacheTransform } from "./plugins/use-cache-transform.js";
10
+ import { clientRefDedup } from "./plugins/client-ref-dedup.js";
11
+ import { VIRTUAL_IDS } from "./plugins/virtual-entries.js";
12
+ import {
13
+ getExcludeDeps,
14
+ getPackageAliases,
15
+ getPublishedPackageName,
16
+ getVendorAliases,
17
+ } from "./utils/package-resolution.js";
18
+ import {
19
+ findRouterFiles,
20
+ findHostRouterFiles,
21
+ } from "../build/generate-route-types.js";
22
+ import { createVersionPlugin } from "./plugins/version-plugin.js";
23
+ import {
24
+ sharedRolldownOptions,
25
+ createVirtualEntriesPlugin,
26
+ normalizeHostRouterEntry,
27
+ onwarn,
28
+ getManualChunks,
29
+ } from "./utils/shared-utils.js";
30
+ import {
31
+ resolveClientChunks,
32
+ type ClientChunkContext,
33
+ } from "./utils/client-chunks.js";
34
+ import type {
35
+ RangoOptions,
36
+ RangoNodeOptions,
37
+ RangoVercelOptions,
38
+ } from "./plugin-types.js";
39
+ import { createVercelOutputPlugin } from "./plugins/vercel-output.js";
40
+ import { printBanner, rangoVersion } from "./utils/banner.js";
41
+ import { createVersionInjectorPlugin } from "./plugins/version-injector.js";
42
+ import { createCjsToEsmPlugin } from "./plugins/cjs-to-esm.js";
43
+ import { createRouterDiscoveryPlugin } from "./router-discovery.js";
44
+ import { performanceTracksPlugin } from "./plugins/performance-tracks.js";
45
+ import { createRangoDebugger, NS } from "./debug.js";
46
+
47
+ const debugConfig = createRangoDebugger(NS.config);
48
+
49
+ // The leading-directive 'use client' sniff is shared with version-plugin's
50
+ // getClientModuleSignature so the two cannot drift. Imported for local use by the
51
+ // HMR transform below and re-exported because the E8 sniff test imports it from
52
+ // this module.
53
+ import { hasUseClientDirective } from "./utils/directive-prologue.js";
54
+ export { hasUseClientDirective };
55
+
56
+ /**
57
+ * Vite plugin for @rangojs/router.
58
+ *
59
+ * Includes @vitejs/plugin-rsc and all necessary transforms for the router
60
+ * to function correctly with React Server Components.
61
+ *
62
+ * @example Node.js (default)
63
+ * ```ts
64
+ * export default defineConfig({
65
+ * plugins: [react(), rango()],
66
+ * });
67
+ * ```
68
+ *
69
+ * @example Cloudflare Workers
70
+ * ```ts
71
+ * export default defineConfig({
72
+ * plugins: [
73
+ * react(),
74
+ * rango({ preset: 'cloudflare' }),
75
+ * cloudflare({ viteEnvironment: { name: 'rsc' } }),
76
+ * ],
77
+ * });
78
+ * ```
79
+ */
80
+ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
81
+ const rangoStart = performance.now();
82
+ const resolvedOptions: RangoOptions = options ?? { preset: "node" };
83
+ const preset = resolvedOptions.preset ?? "node";
84
+ const showBanner = resolvedOptions.banner ?? true;
85
+ const clientChunksOption = resolvedOptions.clientChunks ?? true;
86
+ const useBuiltInClientChunks = clientChunksOption === true;
87
+ const clientChunkCtx: ClientChunkContext | undefined = useBuiltInClientChunks
88
+ ? { fallbackRefs: new Set<string>() }
89
+ : undefined;
90
+ const clientChunks = resolveClientChunks(clientChunksOption, clientChunkCtx);
91
+ debugConfig?.("rango(%s) setup start", preset);
92
+
93
+ const plugins: PluginOption[] = [];
94
+
95
+ // Get package resolution info (workspace vs npm install).
96
+ // Vendor aliases redirect the bare plugin-rsc vendor specs (which plugin-rsc
97
+ // itself injects into optimizeDeps.include) to absolute paths resolved from
98
+ // this package — so strict-pnpm consumers don't hit "Failed to resolve
99
+ // dependency" warnings when those deps aren't hoisted to their app root.
100
+ const rangoAliases = { ...getPackageAliases(), ...getVendorAliases() };
101
+ const excludeDeps = [
102
+ ...getExcludeDeps(),
103
+ // plugin-rsc itself injects these into the client env's
104
+ // optimizeDeps.include, which overrides exclude for the dep's own
105
+ // pre-bundle entry. What exclude still controls is how *other*
106
+ // pre-bundled deps treat imports of these specs (external vs inlined)
107
+ // via esbuildCjsExternalPlugin. The cjs-to-esm transform in
108
+ // plugins/cjs-to-esm.ts is the fallback for strict-pnpm consumers,
109
+ // where client.browser's bare include fails to resolve and Vite ends up
110
+ // serving the raw CJS file at dev-serve time.
111
+ "@vitejs/plugin-rsc/browser",
112
+ "@vitejs/plugin-rsc/vendor/react-server-dom/client.browser",
113
+ ];
114
+
115
+ // Vite supports a nested `A > B` syntax in optimizeDeps.include that resolves
116
+ // B from A's location. We anchor transitive deps (rsc-html-stream,
117
+ // @vitejs/plugin-rsc/vendor/*) to @rangojs/router so pnpm consumers — where
118
+ // these aren't visible at the app root — can still pre-bundle them.
119
+ const pkg = getPublishedPackageName();
120
+ const nested = (spec: string) => `${pkg} > ${spec}`;
121
+
122
+ // Mutable ref for the served entry path (node/vercel presets only). Populated
123
+ // by the auto-discover config() hook using Vite's resolved root. `kind` selects
124
+ // the RSC entry template: "router" wraps a single createRouter() app in
125
+ // createRSCHandler; "host" wraps a createHostRouter() instance and serves it
126
+ // via hostRouter.match().
127
+ const routerRef: { path: string | undefined; kind: "router" | "host" } = {
128
+ path: undefined,
129
+ kind: "router",
130
+ };
131
+ // Explicit host-router entry (node/vercel `hostRouter` option), root-relative.
132
+ const explicitHostRouter =
133
+ preset !== "cloudflare"
134
+ ? (resolvedOptions as RangoNodeOptions | RangoVercelOptions).hostRouter
135
+ : undefined;
136
+
137
+ // Build-time prerendering is enabled for both presets.
138
+ // Collection runs in-process via the RSC dev environment runner during discoverRouters().
139
+ const prerenderEnabled = true;
140
+
141
+ if (preset === "cloudflare") {
142
+ const { default: rsc } = await import("@vitejs/plugin-rsc");
143
+
144
+ const finalEntries: { client: string; ssr: string } = {
145
+ client: VIRTUAL_IDS.browser,
146
+ ssr: VIRTUAL_IDS.ssr,
147
+ };
148
+
149
+ plugins.push({
150
+ name: "@rangojs/router:cloudflare-integration",
151
+ enforce: "pre",
152
+
153
+ config() {
154
+ return {
155
+ optimizeDeps: {
156
+ exclude: excludeDeps,
157
+ rolldownOptions: sharedRolldownOptions,
158
+ },
159
+ resolve: {
160
+ alias: rangoAliases,
161
+ // Force a single React/React-DOM copy across all three RSC
162
+ // environments. RSC requires exactly one react/react-dom instance
163
+ // per environment runtime; consumer install topologies (pnpm
164
+ // strict layout, experimental React pins, third-party "use client"
165
+ // packages) can otherwise resolve duplicate copies, causing
166
+ // "Invalid hook call" / lost context. Child environments inherit
167
+ // this root dedupe, and Vite merges it with any consumer dedupe.
168
+ dedupe: ["react", "react-dom"],
169
+ },
170
+ build: {
171
+ rollupOptions: { onwarn },
172
+ },
173
+ environments: {
174
+ client: {
175
+ build: {
176
+ rollupOptions: {
177
+ onwarn,
178
+ output: {
179
+ manualChunks: getManualChunks,
180
+ },
181
+ },
182
+ },
183
+ optimizeDeps: {
184
+ include: [nested("rsc-html-stream/client")],
185
+ exclude: excludeDeps,
186
+ rolldownOptions: sharedRolldownOptions,
187
+ },
188
+ },
189
+ ssr: {
190
+ build: {
191
+ outDir: "./dist/rsc/ssr",
192
+ },
193
+ optimizeDeps: {
194
+ entries: [finalEntries.ssr],
195
+ include: [
196
+ "react",
197
+ "react-dom",
198
+ "react-dom/server.edge",
199
+ "react-dom/static.edge",
200
+ "react/jsx-runtime",
201
+ "react/jsx-dev-runtime",
202
+ nested("rsc-html-stream/server"),
203
+ nested(
204
+ "@vitejs/plugin-rsc/vendor/react-server-dom/client.edge",
205
+ ),
206
+ ],
207
+ exclude: excludeDeps,
208
+ rolldownOptions: sharedRolldownOptions,
209
+ },
210
+ },
211
+ rsc: {
212
+ optimizeDeps: {
213
+ include: [
214
+ "react",
215
+ "react/jsx-runtime",
216
+ "react/jsx-dev-runtime",
217
+ nested(
218
+ "@vitejs/plugin-rsc/vendor/react-server-dom/server.edge",
219
+ ),
220
+ ],
221
+ exclude: excludeDeps,
222
+ rolldownOptions: sharedRolldownOptions,
223
+ },
224
+ },
225
+ },
226
+ };
227
+ },
228
+
229
+ configResolved(config) {
230
+ if (showBanner) {
231
+ const mode =
232
+ config.command === "serve"
233
+ ? process.argv.includes("preview")
234
+ ? "preview"
235
+ : "dev"
236
+ : "build";
237
+ printBanner(mode, "cloudflare", rangoVersion);
238
+ }
239
+ },
240
+ });
241
+
242
+ plugins.push(createVirtualEntriesPlugin(finalEntries));
243
+ plugins.push(performanceTracksPlugin());
244
+ plugins.push(
245
+ rsc({
246
+ entries: finalEntries,
247
+ serverHandler: false,
248
+ clientChunks,
249
+ }) as PluginOption,
250
+ );
251
+ plugins.push(clientRefDedup());
252
+ } else {
253
+ plugins.push({
254
+ name: "@rangojs/router:auto-discover",
255
+ config(userConfig) {
256
+ if (routerRef.path) return;
257
+ const root = userConfig.root
258
+ ? resolve(process.cwd(), userConfig.root)
259
+ : process.cwd();
260
+ const toRootRelative = (abs: string) =>
261
+ (abs.startsWith(root)
262
+ ? "./" + abs.slice(root.length + 1)
263
+ : abs
264
+ ).replaceAll("\\", "/");
265
+ const bulletList = (files: string[]) =>
266
+ files.map((f) => " - " + toRootRelative(f)).join("\n");
267
+
268
+ // 1. Explicit host entry wins: serve the createHostRouter() instance.
269
+ if (explicitHostRouter) {
270
+ routerRef.path = normalizeHostRouterEntry(
271
+ explicitHostRouter,
272
+ root,
273
+ existsSync,
274
+ );
275
+ routerRef.kind = "host";
276
+ return;
277
+ }
278
+
279
+ // 2. A createHostRouter() file means this is a multi-app host deploy:
280
+ // serve it via the host entry. Checked BEFORE single-router discovery,
281
+ // because a host app may compose just one createRouter() sub-app plus
282
+ // host middleware / domain rules / inline .map() routes -- and a lone
283
+ // sub-app must not shadow the host entry (it would bypass
284
+ // hostRouter.match()).
285
+ const hostCandidates = findHostRouterFiles(root);
286
+ if (hostCandidates.length === 1) {
287
+ const hostPath = toRootRelative(hostCandidates[0]);
288
+ // Auto-detection preempts single-router discovery, so name the winning
289
+ // file: a stale prototype still containing `createHostRouter(` would
290
+ // otherwise silently become the served entry in place of the app.
291
+ // eslint-disable-next-line no-console
292
+ console.info(
293
+ `[rango] Serving host router entry ${hostPath} (auto-detected). ` +
294
+ `Set the \`hostRouter\` option to override.`,
295
+ );
296
+ routerRef.path = hostPath;
297
+ routerRef.kind = "host";
298
+ return;
299
+ }
300
+ if (hostCandidates.length > 1) {
301
+ throw new Error(
302
+ `[rango] Multiple host routers found:\n${bulletList(hostCandidates)}\n\n` +
303
+ `Set the \`hostRouter\` option to the entry to serve, e.g. rango({ preset: "${preset}", hostRouter: "./src/worker.rsc.tsx" }).`,
304
+ );
305
+ }
306
+
307
+ // 3. No host entry: single createRouter() app.
308
+ const candidates = findRouterFiles(root);
309
+ if (candidates.length === 1) {
310
+ routerRef.path = toRootRelative(candidates[0]);
311
+ routerRef.kind = "router";
312
+ return;
313
+ }
314
+ if (candidates.length > 1) {
315
+ throw new Error(
316
+ `[rango] Multiple routers found:\n${bulletList(candidates)}\n\n` +
317
+ `If this is a multi-app host router, export a createHostRouter() instance and set the \`hostRouter\` option (e.g. rango({ preset: "${preset}", hostRouter: "./src/worker.rsc.tsx" })), or use preset: "cloudflare" where you own the worker entry.`,
318
+ );
319
+ }
320
+ },
321
+ });
322
+
323
+ const finalEntries = {
324
+ client: VIRTUAL_IDS.browser,
325
+ ssr: VIRTUAL_IDS.ssr,
326
+ rsc: VIRTUAL_IDS.rsc,
327
+ };
328
+
329
+ const { default: rsc } = await import("@vitejs/plugin-rsc");
330
+
331
+ let hasWarnedDuplicate = false;
332
+
333
+ plugins.push({
334
+ name: "@rangojs/router:rsc-integration",
335
+ enforce: "pre",
336
+
337
+ config(_userConfig, configEnv) {
338
+ // Fold NODE_ENV for the vercel preset's build. The cloudflare plugin
339
+ // does this automatically and node apps do it themselves; vercel has no
340
+ // platform plugin, so without this React's CJS dev branch survives and
341
+ // doubles the SSR/RSC bundle (Bundle Hygiene rule #2). Only the exact
342
+ // `process.env.NODE_ENV` token is replaced.
343
+ const vercelDefine =
344
+ preset === "vercel" && configEnv.command === "build"
345
+ ? { "process.env.NODE_ENV": JSON.stringify("production") }
346
+ : undefined;
347
+ // The vercel preset's deployed function has no node_modules, so the
348
+ // server bundles must be fully self-contained. Bundle every dependency
349
+ // into the rsc + ssr builds instead of externalizing them (the node
350
+ // default, which only works because `vite preview` runs where
351
+ // node_modules exists). node: builtins stay external automatically.
352
+ //
353
+ // BUILD ONLY. In `vite dev` this must NOT apply: noExternal forces every
354
+ // server dependency through the RSC/SSR dev module runners, which cannot
355
+ // load many CJS packages (pg, mysql2, most SDKs, @vercel/functions) and
356
+ // crashes the dev server -- while the same app runs fine under
357
+ // preset: "node" and in the production build. Gating on `build` restores
358
+ // node-preset dev semantics (deps externalized to Node's require).
359
+ const vercelServerEnv =
360
+ preset === "vercel" && configEnv.command === "build"
361
+ ? { resolve: { noExternal: true as const } }
362
+ : undefined;
363
+ return {
364
+ ...(vercelDefine ? { define: vercelDefine } : {}),
365
+ optimizeDeps: {
366
+ exclude: excludeDeps,
367
+ rolldownOptions: sharedRolldownOptions,
368
+ },
369
+ build: {
370
+ rollupOptions: { onwarn },
371
+ },
372
+ resolve: {
373
+ alias: rangoAliases,
374
+ // Force a single React/React-DOM copy across all three RSC
375
+ // environments. RSC requires exactly one react/react-dom instance
376
+ // per environment runtime; consumer install topologies (pnpm
377
+ // strict layout, experimental React pins, third-party "use client"
378
+ // packages) can otherwise resolve duplicate copies, causing
379
+ // "Invalid hook call" / lost context. Child environments inherit
380
+ // this root dedupe, and Vite merges it with any consumer dedupe.
381
+ dedupe: ["react", "react-dom"],
382
+ },
383
+ environments: {
384
+ client: {
385
+ build: {
386
+ rollupOptions: {
387
+ onwarn,
388
+ output: {
389
+ manualChunks: getManualChunks,
390
+ },
391
+ },
392
+ },
393
+ optimizeDeps: {
394
+ include: [
395
+ "react",
396
+ "react-dom",
397
+ "react/jsx-runtime",
398
+ "react/jsx-dev-runtime",
399
+ nested("rsc-html-stream/client"),
400
+ ],
401
+ exclude: excludeDeps,
402
+ rolldownOptions: sharedRolldownOptions,
403
+ entries: [VIRTUAL_IDS.browser],
404
+ },
405
+ },
406
+ ssr: {
407
+ ...(vercelServerEnv ?? {}),
408
+ optimizeDeps: {
409
+ entries: [VIRTUAL_IDS.ssr],
410
+ include: [
411
+ "react",
412
+ "react-dom",
413
+ "react-dom/server.edge",
414
+ "react-dom/static.edge",
415
+ "react/jsx-runtime",
416
+ "react/jsx-dev-runtime",
417
+ nested(
418
+ "@vitejs/plugin-rsc/vendor/react-server-dom/client.edge",
419
+ ),
420
+ ],
421
+ exclude: excludeDeps,
422
+ rolldownOptions: sharedRolldownOptions,
423
+ },
424
+ },
425
+ rsc: {
426
+ ...(vercelServerEnv ?? {}),
427
+ optimizeDeps: {
428
+ entries: [VIRTUAL_IDS.rsc],
429
+ include: [
430
+ "react",
431
+ "react/jsx-runtime",
432
+ "react/jsx-dev-runtime",
433
+ nested(
434
+ "@vitejs/plugin-rsc/vendor/react-server-dom/server.edge",
435
+ ),
436
+ ],
437
+ // Vite 8 does not propagate the top-level optimizeDeps.exclude
438
+ // (set in config()) to non-client envs, so the rsc env must set
439
+ // it explicitly — mirroring the node ssr env and the cloudflare
440
+ // rsc env. Without it a strict-pnpm npm-installed app can try to
441
+ // pre-bundle the router's own subpath entries and fail.
442
+ exclude: excludeDeps,
443
+ rolldownOptions: sharedRolldownOptions,
444
+ },
445
+ },
446
+ },
447
+ };
448
+ },
449
+
450
+ configResolved(config) {
451
+ if (showBanner) {
452
+ const mode =
453
+ config.command === "serve"
454
+ ? process.argv.includes("preview")
455
+ ? "preview"
456
+ : "dev"
457
+ : "build";
458
+ printBanner(
459
+ mode,
460
+ preset === "vercel" ? "vercel" : "node",
461
+ rangoVersion,
462
+ );
463
+ }
464
+
465
+ const rscMinimalCount = config.plugins.filter(
466
+ (p) => p.name === "rsc:minimal",
467
+ ).length;
468
+
469
+ if (rscMinimalCount > 1 && !hasWarnedDuplicate) {
470
+ hasWarnedDuplicate = true;
471
+ console.warn(
472
+ "[rango] Duplicate @vitejs/plugin-rsc detected. " +
473
+ "Remove rsc() from your vite config — rango() includes it automatically.",
474
+ );
475
+ }
476
+ },
477
+ });
478
+
479
+ plugins.push(createVirtualEntriesPlugin(finalEntries, routerRef));
480
+ plugins.push(performanceTracksPlugin());
481
+ plugins.push(
482
+ rsc({
483
+ entries: finalEntries,
484
+ clientChunks,
485
+ }) as PluginOption,
486
+ );
487
+ plugins.push(clientRefDedup());
488
+ }
489
+
490
+ plugins.push({
491
+ name: "@rangojs/router:client-component-hmr",
492
+ hotUpdate(ctx) {
493
+ const envName = this.environment?.name;
494
+ if (envName !== "rsc" && envName !== "ssr") return;
495
+
496
+ // Check if the changed file is a "use client" module
497
+ const file = ctx.file;
498
+ if (
499
+ !file.endsWith(".tsx") &&
500
+ !file.endsWith(".ts") &&
501
+ !file.endsWith(".jsx") &&
502
+ !file.endsWith(".js")
503
+ )
504
+ return;
505
+
506
+ try {
507
+ const source = readFileSync(file, "utf-8");
508
+ if (hasUseClientDirective(source)) {
509
+ return [];
510
+ }
511
+ } catch {}
512
+ },
513
+ });
514
+
515
+ plugins.push(exposeActionId());
516
+ plugins.push(useCacheTransform());
517
+ plugins.push(exposeInternalIds());
518
+ plugins.push(exposeRouterId());
519
+ plugins.push(createVersionPlugin());
520
+
521
+ const discoveryEntryPath =
522
+ preset !== "cloudflare" ? routerRef.path : undefined;
523
+ const discoveryRouterRef = preset !== "cloudflare" ? routerRef : undefined;
524
+
525
+ if (preset === "cloudflare") {
526
+ plugins.push(createVersionInjectorPlugin(undefined));
527
+ }
528
+
529
+ plugins.push(createCjsToEsmPlugin());
530
+ plugins.push(
531
+ createRouterDiscoveryPlugin(discoveryEntryPath, {
532
+ routerPathRef: discoveryRouterRef,
533
+ enableBuildPrerender: prerenderEnabled,
534
+ buildEnv: options?.buildEnv,
535
+ preset,
536
+ prerenderOnError: options?.prerender?.onError,
537
+ discovery: options?.discovery,
538
+ clientChunkCtx,
539
+ }),
540
+ );
541
+
542
+ // Vercel preset: assemble .vercel/output from dist/ after the build. Pushed
543
+ // last so its buildApp (order "post") hook runs after the discovery plugin's
544
+ // rsc-env postprocess. buildApp fires once after the whole multi-environment
545
+ // build, so dist/ is complete (closeBundle is unusable here -- it fires per
546
+ // environment, twice for ssr; see the plugin's own note).
547
+ if (preset === "vercel") {
548
+ plugins.push(
549
+ createVercelOutputPlugin(resolvedOptions as RangoVercelOptions),
550
+ );
551
+ }
552
+
553
+ debugConfig?.(
554
+ "rango(%s) setup done: %d plugin(s) (%sms)",
555
+ preset,
556
+ plugins.length,
557
+ (performance.now() - rangoStart).toFixed(1),
558
+ );
559
+ return plugins;
560
+ }