@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,357 @@
1
+ /// <reference path="./flight-runtime.d.ts" />
2
+ /**
3
+ * renderHandler — run a REAL route handler and assert what it renders.
4
+ *
5
+ * A Rango route handler is a pure function `(ctx) => RSC` (what you pass to
6
+ * `path("/p/:slug", ProductPage)`), NOT a component. To test one faithfully you
7
+ * must give it the HandlerContext the router builds at runtime, so `ctx.params`,
8
+ * `ctx.use(Loader)`, `ctx.use(Meta)` / `ctx.use(Breadcrumbs)` (handles),
9
+ * `ctx.reverse`, `ctx.get`/`ctx.header`/`cookies()` all work. renderHandler does
10
+ * exactly that, then serializes the handler's returned RSC and deserializes it
11
+ * to an inspectable tree (same serialize/deserialize core as renderServerTree).
12
+ *
13
+ * Loaders are SEEDED (no real loader execution) the same way `runLoader` seeds
14
+ * them — pass `loaders: [[ProductLoader, data]]`. Handle pushes
15
+ * (`ctx.use(Meta)({...})`) are captured on `result.handles`. The handler's
16
+ * cookie/header/flash effects and a thrown/returned redirect are surfaced too
17
+ * (like `runInRequestContext`). If the handler returns/throws a `Response`
18
+ * (a response route / `throw redirect()`), there is no RSC `tree`.
19
+ *
20
+ * Must run under the `react-server` export condition (the rsc Vitest project).
21
+ * Wire `rangoUseClientTransform()` so `"use client"` islands in the handler's RSC
22
+ * auto-register (or pass `clientComponents`).
23
+ */
24
+ import type { ReactNode } from "react";
25
+ import {
26
+ createRequestContext,
27
+ runWithRequestContext,
28
+ setRequestContextParams,
29
+ type RequestContext,
30
+ } from "../server/request-context.js";
31
+ import { createHandlerContext } from "../router/handler-context.js";
32
+ import { resolveLocationStateEntries } from "../browser/react/location-state-shared.js";
33
+ import { isHandle, type Handle } from "../handle.js";
34
+ import { withDefer } from "../defer.js";
35
+ import type { HandlerContext } from "../types/handler-context.js";
36
+ import type { LoaderDefinition } from "../types.js";
37
+ import {
38
+ seedVariables,
39
+ resolveSeededStateCookieName,
40
+ type VarsInit,
41
+ type StateCookieSeed,
42
+ } from "./internal/seed-vars.js";
43
+
44
+ export type { StateCookieSeed } from "./internal/seed-vars.js";
45
+ import {
46
+ assertNoLegacyUrlOption,
47
+ serializeNodeToFlight,
48
+ isServerOnlyStubError,
49
+ } from "./flight.js";
50
+ import type { SegmentCacheStore } from "../cache/types.js";
51
+ import type { CacheProfile } from "../cache/profile-registry.js";
52
+ import type { ThemeConfig } from "../theme/types.js";
53
+ import { resolveThemeConfig } from "../theme/constants.js";
54
+ import {
55
+ deserializeFlight,
56
+ makeClientManifest,
57
+ registerClientComponents,
58
+ } from "./flight-tree.js";
59
+
60
+ const DEFAULT_URL = "http://localhost/";
61
+
62
+ /** A route handler under test: the `(ctx) => RSC | Response` function you pass to `path(...)`. */
63
+ export type TestableHandler<TEnv = any> = (
64
+ ctx: HandlerContext<any, TEnv>,
65
+ ) => ReactNode | Promise<ReactNode> | Response | Promise<Response>;
66
+
67
+ /** Options for {@link renderHandler}. */
68
+ export interface RenderHandlerOptions<TEnv = any> {
69
+ /** Route params surfaced as `ctx.params`. */
70
+ params?: Record<string, string>;
71
+ /** Environment bindings surfaced as `ctx.env`. */
72
+ env?: TEnv;
73
+ /** Backing Request (string or Request); defaults to a localhost GET. */
74
+ request?: Request | string;
75
+ /** Request headers (e.g. Cookie) the handler reads via `cookies()`. */
76
+ headers?: HeadersInit;
77
+ /** Variables a prior middleware set, read via `ctx.get(...)`. Object or tuples. */
78
+ vars?: VarsInit;
79
+ /** Matched route name (drives `ctx.routeName` and scoped reverse). */
80
+ routeName?: string;
81
+ /** Route name -> pattern map enabling `ctx.reverse()`. */
82
+ routeMap?: Record<string, string>;
83
+ /**
84
+ * Seed the data `ctx.use(SomeLoader)` returns — NO real loader runs (same model
85
+ * as `runLoader`'s `loaders`). Matched by loader reference, so a real
86
+ * `createLoader()` handle resolves regardless of its build-injected `$$id`.
87
+ */
88
+ loaders?: ReadonlyArray<readonly [LoaderDefinition<any, any>, unknown]>;
89
+ /**
90
+ * `"use client"` components in the handler's RSC, so they serialize as real
91
+ * boundaries when `rangoUseClientTransform()` is not wired. Keyed by name; see
92
+ * renderServerTree's `clientComponents`.
93
+ */
94
+ clientComponents?: Record<string, unknown>;
95
+ /**
96
+ * Customize the rango state cookie a handler that calls
97
+ * `invalidateClientCache()` rotates. The name is ALWAYS seeded (default
98
+ * `rango-state_router_0`) so the rotation `Set-Cookie` is emitted like
99
+ * production rather than no-opping; override `prefix`/`routerId` to match your
100
+ * `createRouter({ stateCookiePrefix, id })`, or `version` (the build
101
+ * identifier prefixed to the rotated `{version}:{timestamp}` value, default
102
+ * `"0"`). Assert via `result.response.headers.getSetCookie()` against
103
+ * `result.stateCookieName`.
104
+ */
105
+ stateCookie?: StateCookieSeed;
106
+ /**
107
+ * Segment cache store backing a `"use cache"` function the handler invokes
108
+ * (e.g. `new MemorySegmentCacheStore()`). Without it, `registerCachedFunction`
109
+ * takes the uncached bypass and the cached path is NOT exercised (the runtime
110
+ * emits a one-time warning under the test runner). Pair with `cacheProfiles`
111
+ * so the profile the directive names resolves.
112
+ */
113
+ cacheStore?: SegmentCacheStore;
114
+ /**
115
+ * Cache profiles in the `createRouter({ cacheProfiles })` shape, required for
116
+ * `"use cache: profileName"` resolution once a `cacheStore` is wired.
117
+ */
118
+ cacheProfiles?: Record<string, CacheProfile>;
119
+ /**
120
+ * Render as if inside a server action's revalidation render (production sets
121
+ * this in revalidateAfterAction). A stale `"use cache"` entry whose profile
122
+ * opts into `foregroundOnAction` then re-executes in the FOREGROUND (fresh
123
+ * result in this render) instead of being served stale + revalidated in the
124
+ * background. Without it, a stale entry keeps SWR. Pair with `cacheStore` +
125
+ * `cacheProfiles` to exercise the `foregroundOnAction` opt-in.
126
+ */
127
+ inActionRevalidation?: boolean;
128
+ /**
129
+ * Theme config in the same shape `createRouter({ theme })` takes (e.g. `true`
130
+ * or `{ themes: [...] }`). Without it `ctx.theme`/`ctx.setTheme` are inert,
131
+ * mirroring an app with no theme configured. Pass one to exercise a handler
132
+ * that reads `ctx.theme` or writes the theme cookie via `ctx.setTheme(...)`.
133
+ */
134
+ theme?: ThemeConfig | true;
135
+ }
136
+
137
+ /** Result of {@link renderHandler}. */
138
+ export interface RenderHandlerResult {
139
+ /**
140
+ * The deserialized RSC the handler returned, as an inspectable React element
141
+ * tree — `undefined` when the handler returned or threw a `Response`. Use
142
+ * `findClientBoundaries` (from testing/flight) to locate client islands.
143
+ */
144
+ tree: unknown;
145
+ /** The raw Flight wire string; `undefined` when the handler produced a `Response`. */
146
+ flight: string | undefined;
147
+ /** The value the handler THREW (a `redirect()`/`notFound()` Response), captured not re-thrown. */
148
+ thrown: unknown;
149
+ /** The merged Response (status + headers + Set-Cookie); a thrown/returned redirect merged with accumulated effects. */
150
+ response: Response;
151
+ /** Effective cookie view after the handler ran, as `{ name: value }`. */
152
+ cookies: Record<string, string>;
153
+ /** Response headers as `{ name: value }` (excludes set-cookie; includes a redirect Location). */
154
+ headers: Record<string, string>;
155
+ /**
156
+ * The resolved rango state cookie name this run seeded (default
157
+ * `rango-state_router_0`, or composed from `opts.stateCookie`). Assert the
158
+ * `invalidateClientCache()` rotation against it without recomputing:
159
+ * `response.headers.getSetCookie().some((c) => c.startsWith(stateCookieName + "="))`.
160
+ */
161
+ stateCookieName: string;
162
+ /** Location state the handler set (`ctx.setLocationState`/`redirect({ state })`), as `{ key: value }`. */
163
+ locationState: Record<string, unknown>;
164
+ /** What the handler pushed via `ctx.use(Handle)(...)` (e.g. Meta, Breadcrumbs), keyed by handle. */
165
+ handles: Map<Handle<any, any>, unknown[]>;
166
+ }
167
+
168
+ /**
169
+ * A renderHandler MISCONFIGURATION (e.g. an unseeded loader) — distinct from a
170
+ * value the handler intentionally threw (a redirect). Setup errors REJECT;
171
+ * handler throws are captured on `result.thrown`.
172
+ */
173
+ class RenderHandlerSetupError extends Error {}
174
+
175
+ function headersToObject(headers: Headers): Record<string, string> {
176
+ const out: Record<string, string> = {};
177
+ headers.forEach((value, name) => {
178
+ if (name.toLowerCase() !== "set-cookie") out[name] = value;
179
+ });
180
+ return out;
181
+ }
182
+
183
+ function toRequest(
184
+ request: Request | string | undefined,
185
+ headers?: HeadersInit,
186
+ ): Request {
187
+ if (request instanceof Request) return request;
188
+ if (typeof request === "string") {
189
+ return new Request(new URL(request, DEFAULT_URL), { headers });
190
+ }
191
+ return new Request(DEFAULT_URL, { headers });
192
+ }
193
+
194
+ function buildResponse(reqCtx: RequestContext<any>, source: unknown): Response {
195
+ const stub = reqCtx.res;
196
+ if (source instanceof Response) {
197
+ const merged = new Headers(source.headers);
198
+ for (const cookie of stub.headers.getSetCookie()) {
199
+ merged.append("set-cookie", cookie);
200
+ }
201
+ stub.headers.forEach((value, name) => {
202
+ if (name.toLowerCase() === "set-cookie") return;
203
+ if (!merged.has(name)) merged.set(name, value);
204
+ });
205
+ return new Response(source.body, {
206
+ status: source.status,
207
+ headers: merged,
208
+ });
209
+ }
210
+ return new Response(null, { status: stub.status, headers: stub.headers });
211
+ }
212
+
213
+ /**
214
+ * Run a route handler with a seeded HandlerContext and return its rendered RSC
215
+ * (deserialized tree) plus the effects it produced. See the module header.
216
+ *
217
+ * @example
218
+ * ```ts
219
+ * // ProductPage is the real handler: (ctx) => <main>{ctx.params.slug}...</main>
220
+ * const { tree, handles } = await renderHandler(ProductPage, {
221
+ * params: { slug: "wine" },
222
+ * loaders: [[ProductLoader, { name: "Wine", price: 9 }]],
223
+ * vars: [[Tenant, tenant]],
224
+ * routeMap: { product: "/p/:slug" },
225
+ * });
226
+ * ```
227
+ */
228
+ export async function renderHandler<TEnv = any>(
229
+ handler: TestableHandler<TEnv>,
230
+ opts: RenderHandlerOptions<TEnv> = {},
231
+ ): Promise<RenderHandlerResult> {
232
+ assertNoLegacyUrlOption(opts, "renderHandler");
233
+ if (opts.clientComponents) registerClientComponents(opts.clientComponents);
234
+ const request = toRequest(opts.request, opts.headers);
235
+ const url = new URL(request.url);
236
+ const stateCookieName = resolveSeededStateCookieName(opts.stateCookie);
237
+ const reqCtx = createRequestContext<TEnv>({
238
+ env: (opts.env ?? {}) as TEnv,
239
+ request,
240
+ url,
241
+ variables: seedVariables({}, opts.vars),
242
+ stateCookieName,
243
+ version: opts.stateCookie?.version,
244
+ cacheStore: opts.cacheStore,
245
+ cacheProfiles: opts.cacheProfiles,
246
+ themeConfig:
247
+ opts.theme === undefined ? undefined : resolveThemeConfig(opts.theme),
248
+ });
249
+
250
+ // Simulate an action revalidation render (production sets this in
251
+ // revalidateAfterAction) so a `foregroundOnAction` cache profile foregrounds a
252
+ // stale entry. See the foregroundOnAction option doc.
253
+ if (opts.inActionRevalidation) reqCtx._inActionRevalidation = true;
254
+
255
+ const loaderSeeds = new Map<unknown, unknown>(opts.loaders ?? []);
256
+ const handlePushes = new Map<Handle<any, any>, unknown[]>();
257
+
258
+ let out: ReactNode | Response | undefined;
259
+ let flight: string | undefined;
260
+ let thrown: unknown;
261
+ let didThrow = false;
262
+
263
+ await runWithRequestContext(reqCtx as RequestContext<TEnv>, async () => {
264
+ // Scope the request-context reverse to opts.routeMap too (not just the
265
+ // handler context built below), so a nested server component reading
266
+ // getRequestContext().reverse() resolves against the same map as the
267
+ // handler's ctx.reverse -- matching renderToFlightString/renderServerTree.
268
+ setRequestContextParams(opts.params ?? {}, opts.routeName, opts.routeMap);
269
+ const hctx = createHandlerContext<TEnv>(
270
+ opts.params ?? {},
271
+ reqCtx.request,
272
+ reqCtx.searchParams,
273
+ reqCtx.pathname,
274
+ reqCtx.url,
275
+ reqCtx.env,
276
+ opts.routeMap ?? {},
277
+ opts.routeName,
278
+ );
279
+ (hctx as { use: unknown }).use = (item: unknown) => {
280
+ if (isHandle(item)) {
281
+ const handle = item as Handle<any, any>;
282
+ // withDefer attaches .defer() so the harness mirrors production's push.
283
+ return withDefer((dataOrFn: unknown) => {
284
+ const value =
285
+ typeof dataOrFn === "function"
286
+ ? (dataOrFn as () => unknown)()
287
+ : dataOrFn;
288
+ const pushed = handlePushes.get(handle) ?? [];
289
+ pushed.push(value);
290
+ handlePushes.set(handle, pushed);
291
+ });
292
+ }
293
+ // Production ctx.use(Loader) ALWAYS returns a Promise (the cached loader
294
+ // promise); wrap the seed so a handler composing on the result matches.
295
+ if (loaderSeeds.has(item)) return Promise.resolve(loaderSeeds.get(item));
296
+ throw new RenderHandlerSetupError(
297
+ `renderHandler: ctx.use(loader) was not seeded. Pass ` +
298
+ `{ loaders: [[YourLoader, data]] } for each loader the handler reads.`,
299
+ );
300
+ };
301
+ (hctx as { _currentSegmentId?: string })._currentSegmentId = "test.segment";
302
+
303
+ try {
304
+ out = await handler(hctx as HandlerContext<any, TEnv>);
305
+ if (out !== undefined && !(out instanceof Response)) {
306
+ flight = await serializeNodeToFlight(
307
+ out as ReactNode,
308
+ makeClientManifest(),
309
+ url.pathname,
310
+ );
311
+ }
312
+ } catch (error) {
313
+ if (error instanceof RenderHandlerSetupError) throw error;
314
+ if (isServerOnlyStubError(error)) {
315
+ throw new RenderHandlerSetupError(
316
+ `renderHandler: the handler called a server-only API (getRequestContext/cookies/...) ` +
317
+ `but "@rangojs/router" resolved to the out-of-react-server stub. Add ` +
318
+ `rangoTestAliases({ preset }) to your vitest.rsc.config.ts \`resolve.alias\` so the ` +
319
+ `bare specifier maps to index.rsc.ts (the real react-server implementations). ` +
320
+ `Original: ${(error as Error).message}`,
321
+ );
322
+ }
323
+ didThrow = true;
324
+ thrown = error;
325
+ }
326
+ });
327
+
328
+ const cookies = { ...reqCtx.cookies() };
329
+ const responseSource = didThrow
330
+ ? thrown
331
+ : out instanceof Response
332
+ ? out
333
+ : undefined;
334
+ const response = buildResponse(reqCtx as RequestContext<any>, responseSource);
335
+ const headers = headersToObject(response.headers);
336
+ const locationState = resolveLocationStateEntries(
337
+ (
338
+ reqCtx as {
339
+ _locationState?: Parameters<typeof resolveLocationStateEntries>[0];
340
+ }
341
+ )._locationState ?? [],
342
+ );
343
+ const tree =
344
+ flight !== undefined ? await deserializeFlight(flight) : undefined;
345
+
346
+ return {
347
+ tree,
348
+ flight,
349
+ thrown,
350
+ response,
351
+ cookies,
352
+ headers,
353
+ stateCookieName,
354
+ locationState,
355
+ handles: handlePushes,
356
+ };
357
+ }