@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
@@ -4,7 +4,96 @@
4
4
  * Utility functions for RSC request handling.
5
5
  */
6
6
 
7
- import { getRequestContext } from "../server/request-context.js";
7
+ import {
8
+ _getRequestContext,
9
+ getLocationState,
10
+ } from "../server/request-context.js";
11
+ import type { RequestContext } from "../server/request-context.js";
12
+ import { resolveLocationStateEntries } from "../browser/react/location-state-shared.js";
13
+ import { isRedirectResponse } from "../response-utils.js";
14
+ import {
15
+ EXTERNAL_REDIRECT_MARKER,
16
+ isExternalRedirect,
17
+ markExternalRedirect,
18
+ } from "../redirect-origin.js";
19
+ import type { MiddlewareEntry, MiddlewareFn } from "../router/middleware.js";
20
+ import { formatCacheSignalHeader } from "../router/telemetry.js";
21
+ import type { RscPayload } from "./types.js";
22
+
23
+ /**
24
+ * DEVELOPMENT/TEST ONLY. When the debug cache signal gate is on,
25
+ * match/matchPartial populate ctx._cacheSignal. Emit it as the X-Rango-Cache
26
+ * header. When the gate is off, ctx._cacheSignal is undefined and NOTHING is
27
+ * attached — output is byte-identical to the default. Header mutation failures
28
+ * are swallowed so immutable Response headers (e.g. protocol-switch) are safe.
29
+ */
30
+ function applyCacheSignalHeader(target: Headers, ctx: RequestContext): void {
31
+ const signal = ctx._cacheSignal;
32
+ if (!signal || signal.length === 0) return;
33
+ try {
34
+ target.set("X-Rango-Cache", formatCacheSignalHeader(signal));
35
+ } catch {
36
+ // Headers immutable — skip.
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Copy stub headers from the request context onto a target Headers instance:
42
+ * append Set-Cookie entries, set everything else only if absent. Header
43
+ * mutation failures are swallowed so the same logic works against Response
44
+ * headers that may be immutable (e.g. Cloudflare protocol-switch responses).
45
+ */
46
+ function applyStubHeaders(target: Headers, stub: Headers): void {
47
+ stub.forEach((value, name) => {
48
+ try {
49
+ // The reserved external-redirect marker is internal and never a trust
50
+ // signal; never copy a stub value (e.g. a stray ctx.header() call) onto a
51
+ // browser-facing response. The opt-in is the out-of-band brand.
52
+ if (name.toLowerCase() === EXTERNAL_REDIRECT_MARKER) return;
53
+ if (name.toLowerCase() === "set-cookie") {
54
+ target.append(name, value);
55
+ } else if (!target.has(name)) {
56
+ target.set(name, value);
57
+ }
58
+ } catch {
59
+ // Headers immutable — skip.
60
+ }
61
+ });
62
+ }
63
+
64
+ /**
65
+ * Drain ctx._onResponseCallbacks onto a response. Swapping the array before
66
+ * iteration prevents re-entrant registrations from double-firing and matches
67
+ * the contract that each callback runs at most once per request.
68
+ *
69
+ * Exported so the testing primitives' buildRunResponse can reuse the exact
70
+ * production drain (swap-before-iterate + external-redirect brand preservation)
71
+ * rather than maintain a hand-synced copy. This module is plugin-rsc-free on its
72
+ * eager graph (dispatch.ts already statically imports from here in the same
73
+ * testing barrel), so importing it adds nothing to the unit runner's graph.
74
+ */
75
+ export function drainOnResponseCallbacks(
76
+ ctx: RequestContext,
77
+ response: Response,
78
+ ): Response {
79
+ const callbacks = ctx._onResponseCallbacks;
80
+ if (callbacks.length === 0) return response;
81
+ ctx._onResponseCallbacks = [];
82
+ // An onResponse callback may return a NEW Response (e.g. to add a header),
83
+ // which drops the out-of-band external-redirect brand (brand is keyed on
84
+ // Response object identity). Preserve a redirect(url, { external: true })
85
+ // opt-in across that rebuild so a callback can't silently neutralize the
86
+ // off-host redirect at the guard chokepoint.
87
+ const wasExternal = isExternalRedirect(response);
88
+ let result = response;
89
+ for (const callback of callbacks) {
90
+ result = callback(result) ?? result;
91
+ }
92
+ if (wasExternal && !isExternalRedirect(result)) {
93
+ markExternalRedirect(result);
94
+ }
95
+ return result;
96
+ }
8
97
 
9
98
  /**
10
99
  * Check if a request body has content to decode
@@ -27,38 +116,205 @@ export function hasBodyContent(body: FormData | string): boolean {
27
116
  */
28
117
  export function createResponseWithMergedHeaders(
29
118
  body: BodyInit | null,
30
- init: ResponseInit
119
+ init: ResponseInit,
31
120
  ): Response {
32
- const ctx = getRequestContext();
121
+ const ctx = _getRequestContext();
33
122
  if (!ctx) {
34
123
  return new Response(body, init);
35
124
  }
36
125
 
37
- // Merge headers from stub response into the new response
126
+ // Delete Set-Cookie from the stub after consuming so downstream merge
127
+ // points (e.g. executeMiddleware) don't duplicate them.
38
128
  const mergedHeaders = new Headers(init.headers);
39
- ctx.res.headers.forEach((value, name) => {
40
- if (name.toLowerCase() === "set-cookie") {
41
- mergedHeaders.append(name, value);
42
- } else if (!mergedHeaders.has(name)) {
43
- // Only set if not already present in init.headers
44
- mergedHeaders.set(name, value);
45
- }
46
- });
129
+ applyStubHeaders(mergedHeaders, ctx.res.headers);
130
+ ctx.res.headers.delete("set-cookie");
131
+ applyCacheSignalHeader(mergedHeaders, ctx);
47
132
 
48
- // Use ctx.res.status if it was set (e.g., 404 for notFound, 500 for error)
49
- // Otherwise use the status from init
133
+ // ctx.res.status overrides init.status when explicitly set (e.g. 404 for
134
+ // notFound, 500 for error). Default ctx.res.status is 200.
50
135
  const status = ctx.res.status !== 200 ? ctx.res.status : init.status;
51
136
 
52
- let response = new Response(body, {
137
+ const response = new Response(body, {
53
138
  ...init,
54
139
  status,
55
140
  headers: mergedHeaders,
56
141
  });
57
142
 
58
- // Run onResponse callbacks - each can inspect/modify the response
59
- for (const callback of ctx._onResponseCallbacks) {
60
- response = callback(response) ?? response;
143
+ return drainOnResponseCallbacks(ctx, response);
144
+ }
145
+
146
+ /**
147
+ * Create a 204 response with X-RSC-Redirect header for stateless redirects.
148
+ * Used during partial/action requests where fetch would auto-follow a raw
149
+ * 3xx to a URL that renders full HTML instead of Flight data. The 204 status
150
+ * prevents auto-follow; the client reads the header and re-navigates via
151
+ * the router.
152
+ */
153
+ export function createSimpleRedirectResponse(redirectUrl: string): Response {
154
+ return createResponseWithMergedHeaders(null, {
155
+ status: 204,
156
+ headers: { "X-RSC-Redirect": redirectUrl },
157
+ });
158
+ }
159
+
160
+ /**
161
+ * Carry over headers from a source redirect Response to a wrapper Response.
162
+ * Skips Location and X-RSC-Redirect (intentionally replaced by the wrapper) and
163
+ * appends Set-Cookie to avoid clobbering multiple cookie headers.
164
+ *
165
+ * This is a GENERIC copier used by every redirect-rebuild path (PE
166
+ * extractRedirectResponse, the SPA intercept below, the guard's neutralize
167
+ * rebuild), so it has two redirect-specific jobs:
168
+ *
169
+ * 1. NEVER copy the reserved external-redirect header: it is no longer a trust
170
+ * signal (the opt-in is the out-of-band brand), and a forged value from a
171
+ * proxied upstream must not ride a rebuilt response to the browser.
172
+ * 2. Transfer the out-of-band external brand: a rebuilt document-native redirect
173
+ * has to carry the opt-in to the guard chokepoint, which reads and clears it.
174
+ * Without this transfer, redirect(url, { external: true }) would be silently
175
+ * neutralized on any rebuild path (fail-closed, but a feature regression).
176
+ */
177
+ export function carryOverRedirectHeaders(
178
+ source: Response,
179
+ target: Response,
180
+ ): void {
181
+ source.headers.forEach((value, name) => {
182
+ const lower = name.toLowerCase();
183
+ if (lower === "location" || lower === "x-rsc-redirect") return;
184
+ if (lower === EXTERNAL_REDIRECT_MARKER) return;
185
+ if (lower === "set-cookie") {
186
+ target.headers.append(name, value);
187
+ } else if (!target.headers.has(name)) {
188
+ target.headers.set(name, value);
189
+ }
190
+ });
191
+ if (isExternalRedirect(source)) {
192
+ markExternalRedirect(target);
193
+ }
194
+ }
195
+
196
+ /**
197
+ * If a response is a 3xx redirect during a partial (client-side) request,
198
+ * intercept it and return a Flight-compatible redirect instead.
199
+ * fetch() auto-follows 3xx which would hit a URL that renders full HTML
200
+ * the client can't parse. Returns null if the response is not a redirect.
201
+ */
202
+ export function interceptRedirectForPartial(
203
+ response: Response,
204
+ createRedirectFlightResponse: (
205
+ redirectUrl: string,
206
+ locationState?: Record<string, unknown>,
207
+ external?: boolean,
208
+ ) => Response,
209
+ ): Response | null {
210
+ if (!isRedirectResponse(response)) {
211
+ return null;
212
+ }
213
+ const redirectUrl = response.headers.get("Location")!;
214
+ // redirect(url, { external: true }) marks an explicit off-host redirect via
215
+ // the out-of-band brand (not a wire header). On the SPA/action channel the
216
+ // intent must travel as a Flight payload (metadata.redirect.external) so the
217
+ // client does a scheme-validated hard navigation (location.assign) rather than
218
+ // a partial fetch. The client re-validates the scheme; see partial-update.ts.
219
+ const external = isExternalRedirect(response);
220
+ const locationState = getLocationState();
221
+ let intercepted: Response;
222
+ if (locationState) {
223
+ intercepted = createRedirectFlightResponse(
224
+ redirectUrl,
225
+ resolveLocationStateEntries(locationState),
226
+ external,
227
+ );
228
+ } else if (external) {
229
+ intercepted = createRedirectFlightResponse(redirectUrl, undefined, true);
230
+ } else {
231
+ intercepted = createSimpleRedirectResponse(redirectUrl);
232
+ }
233
+
234
+ carryOverRedirectHeaders(response, intercepted);
235
+ // Defense-in-depth at the SPA browser-facing exit: carryOverRedirectHeaders
236
+ // already refuses to copy the reserved marker, but strip any value that might
237
+ // exist on `intercepted` so a forged header can never ride the 200/204 to the
238
+ // browser. The external intent travels in metadata.redirect.external (Flight),
239
+ // where the client re-validates the scheme.
240
+ try {
241
+ intercepted.headers.delete(EXTERNAL_REDIRECT_MARKER);
242
+ } catch {
243
+ // Immutable headers: the marker was never copied here, so this is inert.
244
+ }
245
+
246
+ return intercepted;
247
+ }
248
+
249
+ /**
250
+ * Attach location state set during a request to a payload's metadata.
251
+ * No-op if no location state was set. Callers must ensure payload.metadata
252
+ * is populated (the non-null assertion holds for the partial/action payloads
253
+ * that reach this helper).
254
+ */
255
+ export function attachLocationStateIfPresent(payload: RscPayload): void {
256
+ const locationState = getLocationState();
257
+ if (locationState) {
258
+ payload.metadata!.locationState =
259
+ resolveLocationStateEntries(locationState);
61
260
  }
261
+ }
62
262
 
63
- return response;
263
+ /**
264
+ * Only cache successful responses. Non-200 statuses (errors, redirects) are
265
+ * not cached -- notFound() produces 500 in response routes, and explicit
266
+ * non-200 Responses are rare enough that caching them would be surprising.
267
+ */
268
+ export function isCacheableStatus(status: number): boolean {
269
+ return status === 200;
270
+ }
271
+
272
+ /**
273
+ * Convert route-level middleware entries to the format expected by
274
+ * executeMiddleware. Route middleware from previewMatch carries just
275
+ * { handler, params }; this wraps them in the full MiddlewareEntry shape.
276
+ */
277
+ export function buildRouteMiddlewareEntries<TEnv>(
278
+ routeMiddleware: Array<{
279
+ handler: MiddlewareFn;
280
+ params: Record<string, string>;
281
+ }>,
282
+ ): Array<{ entry: MiddlewareEntry<TEnv>; params: Record<string, string> }> {
283
+ return routeMiddleware.map((mw) => ({
284
+ entry: {
285
+ pattern: null,
286
+ regex: null,
287
+ paramNames: [],
288
+ handler: mw.handler,
289
+ } as MiddlewareEntry<TEnv>,
290
+ params: mw.params,
291
+ }));
292
+ }
293
+
294
+ /**
295
+ * Merge stub headers from the request context onto an existing Response in
296
+ * place, then drain onResponse callbacks. Used when a Response cannot flow
297
+ * through `new Response()` — status 101 is outside the constructor's
298
+ * 200-599 range, and the Cloudflare-specific `webSocket` property would be
299
+ * lost on reconstruction.
300
+ */
301
+ export function mergeStubHeadersAndFinalize(response: Response): Response {
302
+ const ctx = _getRequestContext();
303
+ if (!ctx) return response;
304
+
305
+ applyStubHeaders(response.headers, ctx.res.headers);
306
+ ctx.res.headers.delete("set-cookie");
307
+
308
+ return drainOnResponseCallbacks(ctx, response);
309
+ }
310
+
311
+ /**
312
+ * Run onResponse callbacks on an existing Response. Used by code paths that
313
+ * bypass createResponseWithMergedHeaders (e.g. middleware short-circuits)
314
+ * but still need ctx.onResponse() callbacks to fire.
315
+ */
316
+ export function finalizeResponse(response: Response): Response {
317
+ const ctx = _getRequestContext();
318
+ if (!ctx) return response;
319
+ return drainOnResponseCallbacks(ctx, response);
64
320
  }
package/src/rsc/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * RSC Router - RSC Entry Point
2
+ * Rango - RSC Entry Point
3
3
  *
4
4
  * This module provides RSC utilities for server-side rendering,
5
5
  * server actions, loader fetching, and progressive enhancement.
@@ -29,28 +29,5 @@ export type {
29
29
  NonceProvider,
30
30
  } from "./types.js";
31
31
 
32
- // Re-export HandleStore types for consumers who need custom handling
33
- export {
34
- createHandleStore,
35
- type HandleStore,
36
- type HandleData,
37
- } from "../server/handle-store.js";
38
-
39
32
  // Re-export request context utilities for server-side access to env/request/params
40
- export {
41
- getRequestContext,
42
- requireRequestContext,
43
- setRequestContextParams,
44
- } from "../server/request-context.js";
45
-
46
- // Re-export cache store types and implementations
47
- export type {
48
- SegmentCacheStore,
49
- CachedEntryData,
50
- CachedEntryResult,
51
- SegmentCacheProvider,
52
- SegmentHandleData,
53
- } from "../cache/types.js";
54
-
55
- export { MemorySegmentCacheStore } from "../cache/memory-segment-store.js";
56
- export { CFCacheStore, type CFCacheStoreOptions } from "../cache/cf/index.js";
33
+ export { getRequestContext } from "../server/request-context.js";
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Shared serialization for `json()` response-route results.
3
+ *
4
+ * Kept in its own lightweight module (depends only on `errors.js`) so the
5
+ * `dispatch()` testing primitive can import it WITHOUT dragging in
6
+ * `response-route-handler.ts`'s heavy runtime graph, which transitively reaches
7
+ * a Vite virtual module and breaks a plain (non-Vite) vitest import.
8
+ */
9
+
10
+ import { RouterError } from "../errors.js";
11
+
12
+ /**
13
+ * Serialize a `json()` response-route result, rejecting a nested unresolved
14
+ * Promise (the forgotten-await footgun: `() => ({ data: fetchSomething() })`).
15
+ * `JSON.stringify` would silently emit `{}` for a Promise, shipping empty data;
16
+ * the RSC pipeline awaits nested promises but this path does not. Throwing
17
+ * `RESPONSE_NOT_SERIALIZABLE` makes the failure loud.
18
+ *
19
+ * Shared by the production response-route handler and the `dispatch()` testing
20
+ * primitive so a `dispatch` json test of a forgotten await fails exactly where
21
+ * production 500s, instead of going green.
22
+ */
23
+ export function stringifyJsonRouteResult(result: unknown): string {
24
+ return JSON.stringify(result, (_key, value) => {
25
+ if (
26
+ value != null &&
27
+ typeof (value as { then?: unknown }).then === "function"
28
+ ) {
29
+ throw new RouterError(
30
+ "RESPONSE_NOT_SERIALIZABLE",
31
+ "A json() response route returned a Promise (likely a forgotten " +
32
+ "await). Await async values before returning so they serialize, " +
33
+ "instead of emitting an empty {}.",
34
+ );
35
+ }
36
+ return value;
37
+ });
38
+ }