@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,359 @@
1
+ /**
2
+ * Prefetch Cache
3
+ *
4
+ * In-memory cache storing eagerly-decoded prefetch payloads for instant,
5
+ * already-warm cache hits on subsequent navigation. A prefetch fetches the
6
+ * RSC partial AND decodes it (createFromFetch) up front — decoding the Flight
7
+ * stream resolves the route's client references, so the route's JS chunks are
8
+ * imported during prefetch rather than on click. The decoded payload is reused
9
+ * verbatim by navigation, so a prefetched click loads no new code. Two key
10
+ * scopes are in play:
11
+ * - Wildcard (default): built by `buildPrefetchKey(rangoState, target)` —
12
+ * shape `rangoState\0/target?...`. Shared across all source pages and
13
+ * invalidated automatically when Rango state bumps (deploy or
14
+ * server-action invalidation).
15
+ * - Source-scoped: built by `buildSourceKey(rangoState, sourceHref, target)`
16
+ * — shape `rangoState\0sourceHref\0/target?...`. Embeds the Rango state
17
+ * (so rotation invalidates source-scoped entries too) plus the source
18
+ * href (so each originating page gets its own slot). Populated when the
19
+ * server tags a response with `X-RSC-Prefetch-Scope: source` (intercept
20
+ * modals etc.), OR when a Link opts in with `prefetchKey=":source"` — in
21
+ * both cases so source-sensitive responses cannot bleed into navigations
22
+ * from other pages.
23
+ *
24
+ * Also tracks in-flight prefetch promises. Each promise resolves to the
25
+ * decoded prefetch entry (or null), letting navigation adopt a
26
+ * still-downloading prefetch without issuing a duplicate request. A
27
+ * single promise can be registered under multiple alias keys (see
28
+ * `setInflightPromiseWithAliases`) so same-source navigations adopt via
29
+ * their source key while cross-source ones fall through to the wildcard
30
+ * alias — with consume/clear atomically removing every alias.
31
+ *
32
+ * Replaces the previous browser HTTP cache approach which was unreliable
33
+ * due to response draining race conditions and browser inconsistencies.
34
+ *
35
+ * State here lives in module-level singletons (cache, inflight, generation,
36
+ * cacheTTL, etc.) rather than a per-instance factory. This is correct because
37
+ * exactly one router is live per document — an SPA navigation crossing a
38
+ * host-router boundary forces a full document reload — so the singletons are
39
+ * effectively per-document. Unit tests reset them via clearPrefetchCache().
40
+ */
41
+
42
+ import { abortAllPrefetches } from "./queue.js";
43
+ import { invalidateRangoState } from "../rango-state.js";
44
+ import type { RscPayload } from "../types.js";
45
+
46
+ /**
47
+ * A prefetch that has been fetched AND eagerly decoded. Storing the decoded
48
+ * payload (not the raw Response) is what makes a prefetched navigation "warm":
49
+ * decoding the Flight stream during prefetch pulls the route's client chunks,
50
+ * so the click reuses ready elements and loads no new JS.
51
+ */
52
+ export interface DecodedPrefetch {
53
+ /** The eagerly-decoded RSC payload. Reused verbatim by navigation. */
54
+ payload: Promise<RscPayload>;
55
+ /**
56
+ * Resolves when the underlying RSC stream finishes draining. Navigation
57
+ * forwards this as its streamComplete so scroll/revalidation gating is
58
+ * unchanged from the fresh-fetch path.
59
+ */
60
+ streamComplete: Promise<void>;
61
+ /**
62
+ * Prefetch scope as tagged by the server via `X-RSC-Prefetch-Scope`.
63
+ * `"source"` means the response is source-page-sensitive and must not be
64
+ * reused by a navigation from a different page — navigation enforces this
65
+ * when it adopted an inflight entry through the wildcard key.
66
+ */
67
+ scope: "source" | "wildcard";
68
+ /**
69
+ * Synchronously-readable flag, flipped to true when `streamComplete` resolves
70
+ * (the entire RSC stream has drained). Navigation reads this at click time to
71
+ * tell a FULLY warmed prefetch (payload commits without suspending → safe to
72
+ * commit in a startTransition, no fallback flash) from a partially-warmed one
73
+ * (still streaming → stream its fallbacks like a cold load). Starts false.
74
+ */
75
+ complete: boolean;
76
+ }
77
+
78
+ let cacheTTL = 300_000;
79
+
80
+ // Max stored entries before FIFO eviction. Mirrors DEFAULT_PREFETCH_CACHE_SIZE
81
+ // (router/prefetch-limits.ts); kept as a local literal so the client bundle
82
+ // doesn't pull in router-layer code, matching the cacheTTL default above.
83
+ // Overridden at startup by initPrefetchCache from server metadata.
84
+ let maxPrefetchCacheSize = 100;
85
+
86
+ /**
87
+ * Initialize the prefetch cache with the configured TTL and max size.
88
+ * Called once at app startup with the values from server metadata. Each
89
+ * argument is applied only when provided, so a caller can set just the TTL.
90
+ * A TTL of 0 disables the in-memory cache and all prefetching. A size below 1
91
+ * is ignored (the default is kept) — disabling prefetch is the TTL's job.
92
+ */
93
+ export function initPrefetchCache(ttlMs?: number, maxSize?: number): void {
94
+ if (ttlMs !== undefined) cacheTTL = ttlMs;
95
+ if (maxSize !== undefined && Number.isFinite(maxSize) && maxSize >= 1) {
96
+ maxPrefetchCacheSize = Math.floor(maxSize);
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Check if the prefetch cache is disabled (TTL <= 0).
102
+ * When disabled, no prefetch requests should be issued.
103
+ */
104
+ export function isPrefetchCacheDisabled(): boolean {
105
+ return cacheTTL <= 0;
106
+ }
107
+
108
+ interface PrefetchCacheEntry {
109
+ entry: DecodedPrefetch;
110
+ timestamp: number;
111
+ }
112
+
113
+ const cache = new Map<string, PrefetchCacheEntry>();
114
+ const inflight = new Set<string>();
115
+
116
+ const inflightPromises = new Map<string, Promise<DecodedPrefetch | null>>();
117
+
118
+ const inflightAliases = new Map<string, string[]>();
119
+
120
+ const adoptedKeys = new Set<string>();
121
+
122
+ let generation = 0;
123
+
124
+ /**
125
+ * Build a cache key by combining a scope prefix with the target URL.
126
+ *
127
+ * Low-level primitive — callers that want a specific scope should use
128
+ * one of:
129
+ * - Wildcard (source-agnostic): prefix is the Rango state value from
130
+ * `getRangoState()`. Shared across all source pages. Invalidated
131
+ * automatically when Rango state bumps (deploy or server-action).
132
+ * Key shape: `rangoState\0/target?...`.
133
+ * - Source-scoped: use `buildSourceKey()`. Key shape:
134
+ * `rangoState\0sourceHref\0/target?...` — embeds the Rango state so
135
+ * rotation invalidates source-scoped entries alongside wildcard ones,
136
+ * plus the source page href so the key is unique per originating page.
137
+ * Populated either when the server tags a response with
138
+ * `X-RSC-Prefetch-Scope: source` (intercept modals, etc.) or when a
139
+ * Link opts in via `prefetchKey=":source"`.
140
+ *
141
+ * The `_rsc_segments` query param that travels in the target URL means
142
+ * clients with different mounted segment trees naturally get different
143
+ * keys — so segment-level diffs remain consistent across both scopes.
144
+ */
145
+ export function buildPrefetchKey(prefix: string, targetUrl: URL): string {
146
+ return prefix + "\0" + targetUrl.pathname + targetUrl.search;
147
+ }
148
+
149
+ /**
150
+ * Build a source-scoped cache key. Key shape:
151
+ * `rangoState\0sourceHref\0/target?...`.
152
+ *
153
+ * - `rangoState` is included so state rotation invalidates source-scoped
154
+ * entries alongside wildcard ones.
155
+ * - `sourceHref` makes the key unique per originating page.
156
+ */
157
+ export function buildSourceKey(
158
+ rangoState: string,
159
+ sourceHref: string,
160
+ targetUrl: URL,
161
+ ): string {
162
+ return buildPrefetchKey(rangoState + "\0" + sourceHref, targetUrl);
163
+ }
164
+
165
+ /**
166
+ * Walk an inflight key plus any sibling aliases registered via
167
+ * `setInflightPromiseWithAliases`, invoking `fn` for each.
168
+ */
169
+ function forEachAlias(key: string, fn: (k: string) => void): void {
170
+ const aliases = inflightAliases.get(key);
171
+ if (aliases) {
172
+ for (const k of aliases) fn(k);
173
+ } else {
174
+ fn(key);
175
+ }
176
+ }
177
+
178
+ /**
179
+ * Check if a prefetch is already cached, in-flight, or queued for the given key.
180
+ */
181
+ export function hasPrefetch(key: string): boolean {
182
+ if (inflight.has(key)) return true;
183
+ if (cacheTTL <= 0) return false;
184
+ const entry = cache.get(key);
185
+ if (!entry) return false;
186
+ if (Date.now() - entry.timestamp > cacheTTL) {
187
+ cache.delete(key);
188
+ return false;
189
+ }
190
+ return true;
191
+ }
192
+
193
+ /**
194
+ * Consume a cached, eagerly-decoded prefetch. Returns null if not found or
195
+ * expired. One-time consumption: the entry is deleted after retrieval.
196
+ * Returns null when caching is disabled (TTL <= 0).
197
+ *
198
+ * Does NOT check in-flight prefetches — use consumeInflightPrefetch()
199
+ * for that (returns a Promise instead of a resolved entry).
200
+ */
201
+ export function consumePrefetch(key: string): DecodedPrefetch | null {
202
+ if (cacheTTL <= 0) return null;
203
+ const entry = cache.get(key);
204
+ if (!entry) return null;
205
+ if (Date.now() - entry.timestamp > cacheTTL) {
206
+ cache.delete(key);
207
+ return null;
208
+ }
209
+ cache.delete(key);
210
+ return entry.entry;
211
+ }
212
+
213
+ /**
214
+ * Consume an in-flight prefetch promise. Returns null if no prefetch is
215
+ * in-flight for this key. The returned Promise resolves to the decoded
216
+ * prefetch entry (or null if the fetch failed/was aborted, or carried a
217
+ * control header the navigation must re-fetch to honor).
218
+ *
219
+ * One-time consumption: the promise entry is removed (along with any
220
+ * sibling aliases registered via `setInflightPromiseWithAliases`) so a
221
+ * second call on any alias returns null — only one caller can adopt the
222
+ * shared Response stream. The `inflight` set entry is intentionally
223
+ * kept so that `hasPrefetch()` continues to return true while the
224
+ * underlying fetch is still downloading — this prevents
225
+ * `prefetchDirect()` or other callers from starting a duplicate request
226
+ * during the handoff window. The inflight flag is cleaned up naturally
227
+ * by `clearPrefetchInflight()` in the fetch's `.finally()`.
228
+ */
229
+ export function consumeInflightPrefetch(
230
+ key: string,
231
+ ): Promise<DecodedPrefetch | null> | null {
232
+ const promise = inflightPromises.get(key);
233
+ if (!promise) return null;
234
+ // Remove the promise under every alias so a second consumer cannot
235
+ // adopt the same stream and race on the body, and mark every alias as
236
+ // adopted so the pending `storePrefetch` (which resolves later, after this
237
+ // adoption) does not leave the now-owned, single-use entry in the cache map.
238
+ // `inflightAliases` is intentionally preserved — `clearPrefetchInflight()` in
239
+ // the fetch's `.finally()` still needs it to clear every inflight flag and
240
+ // adopted marker; deleting here would strand the sibling's flag forever.
241
+ forEachAlias(key, (k) => {
242
+ inflightPromises.delete(k);
243
+ adoptedKeys.add(k);
244
+ });
245
+ return promise;
246
+ }
247
+
248
+ /**
249
+ * Store an eagerly-decoded prefetch in the in-memory cache.
250
+ *
251
+ * Skips storage if the generation has changed since the fetch started
252
+ * (a server action invalidated the cache mid-flight).
253
+ */
254
+ export function storePrefetch(
255
+ key: string,
256
+ entry: DecodedPrefetch,
257
+ fetchGeneration: number,
258
+ ): void {
259
+ if (cacheTTL <= 0) return;
260
+ if (fetchGeneration !== generation) return;
261
+
262
+ // If a navigation already adopted this prefetch's in-flight promise, it owns
263
+ // the single-use entry (and has drained its handle generator). Do NOT also
264
+ // publish it to the cache map, or a later navigation would be served the
265
+ // exhausted entry and lose that route's handles. Clear the marker (under all
266
+ // aliases) now that the decision is made.
267
+ if (adoptedKeys.has(key)) {
268
+ forEachAlias(key, (k) => adoptedKeys.delete(k));
269
+ return;
270
+ }
271
+
272
+ // Evict expired entries
273
+ const now = Date.now();
274
+ for (const [k, cached] of cache) {
275
+ if (now - cached.timestamp > cacheTTL) {
276
+ cache.delete(k);
277
+ }
278
+ }
279
+
280
+ // FIFO eviction if at capacity
281
+ if (cache.size >= maxPrefetchCacheSize) {
282
+ const oldest = cache.keys().next().value;
283
+ if (oldest) cache.delete(oldest);
284
+ }
285
+
286
+ cache.set(key, { entry, timestamp: now });
287
+ }
288
+
289
+ /**
290
+ * Remove a single stored prefetch entry. Used to evict an entry whose body
291
+ * stream stalled after headers arrived (its payload / streamComplete never
292
+ * settle), so future prefetches and navigation refetch instead of dedupe-ing
293
+ * against — and awaiting — a stuck entry.
294
+ *
295
+ * Identity-guarded: only evicts when the entry CURRENTLY stored under `key` is
296
+ * the exact `entry` we published. A generation check alone is insufficient —
297
+ * after this entry is consumed (consumePrefetch) and a fresh prefetch
298
+ * republishes under the SAME key in the SAME generation, a gen-only guard would
299
+ * delete that valid newer entry. Reference identity drops only our own stalled
300
+ * entry.
301
+ */
302
+ export function removePrefetch(key: string, entry: DecodedPrefetch): void {
303
+ if (cache.get(key)?.entry === entry) cache.delete(key);
304
+ }
305
+
306
+ /**
307
+ * Capture the current generation. The returned value is passed to
308
+ * storePrefetch so it can detect stale completions.
309
+ */
310
+ export function currentGeneration(): number {
311
+ return generation;
312
+ }
313
+
314
+ export function markPrefetchInflight(key: string): void {
315
+ inflight.add(key);
316
+ }
317
+
318
+ export function setInflightPromise(
319
+ key: string,
320
+ promise: Promise<DecodedPrefetch | null>,
321
+ ): void {
322
+ inflightPromises.set(key, promise);
323
+ }
324
+
325
+ /**
326
+ * Store the same in-flight Promise under multiple keys, recording them
327
+ * as sibling aliases. Consuming or clearing any one alias atomically
328
+ * removes every entry, guaranteeing the shared Response stream has a
329
+ * single consumer even when navigation looks up either key.
330
+ */
331
+ export function setInflightPromiseWithAliases(
332
+ keys: string[],
333
+ promise: Promise<DecodedPrefetch | null>,
334
+ ): void {
335
+ for (const k of keys) {
336
+ inflightPromises.set(k, promise);
337
+ inflightAliases.set(k, keys);
338
+ }
339
+ }
340
+
341
+ export function clearPrefetchInflight(key: string): void {
342
+ forEachAlias(key, (k) => {
343
+ inflight.delete(k);
344
+ inflightPromises.delete(k);
345
+ inflightAliases.delete(k);
346
+ adoptedKeys.delete(k);
347
+ });
348
+ }
349
+
350
+ export function clearPrefetchCache(): void {
351
+ generation++;
352
+ inflight.clear();
353
+ inflightPromises.clear();
354
+ inflightAliases.clear();
355
+ adoptedKeys.clear();
356
+ cache.clear();
357
+ abortAllPrefetches();
358
+ invalidateRangoState();
359
+ }