@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,209 @@
1
+ /**
2
+ * Prefetch Queue
3
+ *
4
+ * Concurrency-limited FIFO queue for speculative prefetches (viewport/render).
5
+ * Hover prefetches bypass this queue — they fire directly for immediate response
6
+ * to user intent.
7
+ *
8
+ * Draining waits for an idle main-thread moment and for viewport images to
9
+ * finish loading, so prefetch fetch() calls never compete with critical
10
+ * resources for the browser's connection pool.
11
+ *
12
+ * When a navigation starts, queued prefetches are cancelled but executing ones
13
+ * are left running. Navigation can reuse their in-flight responses via the
14
+ * prefetch cache's inflight promise map, avoiding duplicate requests.
15
+ */
16
+
17
+ import { wait, waitForIdle, waitForViewportImages } from "./resource-ready.js";
18
+
19
+ // Max prefetches executing at once. Mirrors DEFAULT_PREFETCH_CONCURRENCY
20
+ // (router/prefetch-limits.ts); kept as a local literal so the client bundle
21
+ // doesn't pull in router-layer code. Overridden at startup by
22
+ // setPrefetchConcurrency from server metadata.
23
+ let maxConcurrent = 2;
24
+ const IMAGE_WAIT_TIMEOUT = 2000;
25
+
26
+ /**
27
+ * Set the max number of concurrently-executing speculative prefetches.
28
+ * Called once at app startup with the value from server metadata. A value
29
+ * below 1 (or non-finite) is ignored, keeping the default.
30
+ */
31
+ export function setPrefetchConcurrency(n: number): void {
32
+ if (Number.isFinite(n) && n >= 1) {
33
+ maxConcurrent = Math.floor(n);
34
+ }
35
+ }
36
+
37
+ let active = 0;
38
+ const queue: Array<{
39
+ key: string;
40
+ execute: (signal: AbortSignal) => Promise<void>;
41
+ }> = [];
42
+ const queued = new Set<string>();
43
+ const executing = new Set<string>();
44
+ const abortControllers = new Map<string, AbortController>();
45
+ let drainScheduled = false;
46
+ let drainGeneration = 0;
47
+
48
+ function startExecution(
49
+ key: string,
50
+ execute: (signal: AbortSignal) => Promise<void>,
51
+ ): void {
52
+ active++;
53
+ executing.add(key);
54
+ const ac = new AbortController();
55
+ abortControllers.set(key, ac);
56
+ execute(ac.signal).finally(() => {
57
+ abortControllers.delete(key);
58
+ // Only decrement if this key wasn't already cleared by cancelAllPrefetches.
59
+ // Without this guard, cancelled tasks' .finally() would underflow active
60
+ // below zero, breaking the maxConcurrent guarantee.
61
+ if (executing.delete(key)) {
62
+ active--;
63
+ }
64
+ scheduleDrain();
65
+ });
66
+ }
67
+
68
+ /**
69
+ * Schedule a drain after the browser is idle and viewport images are loaded.
70
+ * Coalesces multiple drain requests into a single deferred callback so
71
+ * batch completion doesn't schedule redundant waits.
72
+ *
73
+ * The two-step wait ensures prefetch fetch() calls don't compete with
74
+ * images for the browser's connection pool:
75
+ * 1. waitForIdle — yield until the main thread has a quiet moment
76
+ * 2. waitForViewportImages OR 2s timeout — yield until visible images
77
+ * finish loading, but don't let slow/broken images block indefinitely
78
+ */
79
+ function scheduleDrain(): void {
80
+ if (drainScheduled) return;
81
+ if (active >= maxConcurrent || queue.length === 0) return;
82
+ drainScheduled = true;
83
+ const gen = drainGeneration;
84
+ waitForIdle()
85
+ .then(() =>
86
+ Promise.race([waitForViewportImages(), wait(IMAGE_WAIT_TIMEOUT)]),
87
+ )
88
+ .then(() => {
89
+ // Stale drain: a cancel/abort happened while we were waiting, and a fresh
90
+ // scheduleDrain may already own drainScheduled for the new generation.
91
+ // Bail WITHOUT clearing the flag so we don't clobber the live wait's
92
+ // single-in-flight-drain coalescing (clearing it here would let the next
93
+ // enqueue start a third overlapping wait).
94
+ if (gen !== drainGeneration) return;
95
+ drainScheduled = false;
96
+ if (queue.length > 0) drain();
97
+ });
98
+ }
99
+
100
+ function drain(): void {
101
+ while (active < maxConcurrent && queue.length > 0) {
102
+ const item = queue.shift()!;
103
+ queued.delete(item.key);
104
+ startExecution(item.key, item.execute);
105
+ }
106
+ }
107
+
108
+ /**
109
+ * Enqueue a prefetch for concurrency-limited execution.
110
+ * Execution is deferred until the browser is idle and viewport images
111
+ * have finished loading, so prefetches never compete with critical
112
+ * resources. Deduplicates by key — items already queued or executing
113
+ * are skipped.
114
+ *
115
+ * The executor receives an AbortSignal that is aborted when
116
+ * cancelAllPrefetches() is called (e.g. on navigation start).
117
+ */
118
+ export function enqueuePrefetch(
119
+ key: string,
120
+ execute: (signal: AbortSignal) => Promise<void>,
121
+ ): void {
122
+ if (queued.has(key) || executing.has(key)) return;
123
+
124
+ queued.add(key);
125
+ queue.push({ key, execute });
126
+ scheduleDrain();
127
+ }
128
+
129
+ /**
130
+ * Normalize a URL-like string for keep-alive matching: parse against a
131
+ * placeholder origin and strip internal `_rsc_*` query params. Returns
132
+ * `pathname + search` so comparisons ignore hash and the internal params
133
+ * that prefetch appends to targets (`_rsc_partial`, `_rsc_segments`,
134
+ * `_rsc_v`, `_rsc_rid`, `_rsc_stale`).
135
+ */
136
+ function normalizeForMatch(urlish: string): string {
137
+ try {
138
+ const u = new URL(urlish, "http://placeholder");
139
+ for (const k of [...u.searchParams.keys()]) {
140
+ if (k.startsWith("_rsc_")) u.searchParams.delete(k);
141
+ }
142
+ return u.pathname + u.search;
143
+ } catch {
144
+ return urlish;
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Cancel queued prefetches and abort in-flight ones that don't match
150
+ * the current navigation target. If `keepUrl` is provided, the
151
+ * executing prefetch whose key targets that URL is kept alive so
152
+ * navigation can reuse its response via consumeInflightPrefetch.
153
+ *
154
+ * Called when a navigation starts via the NavigationProvider's
155
+ * event controller subscription.
156
+ */
157
+ export function cancelAllPrefetches(keepUrl?: string | null): void {
158
+ queue.length = 0;
159
+ queued.clear();
160
+ drainScheduled = false;
161
+ drainGeneration++;
162
+
163
+ // Abort in-flight prefetches that aren't for the navigation target.
164
+ // Key shapes (see prefetch/cache.ts buildPrefetchKey):
165
+ // wildcard: "rangoState\0/target?..."
166
+ // source-scoped: "rangoState\0sourceHref\0/target?..."
167
+ // The target portion is always the final \0-delimited segment and
168
+ // includes internal `_rsc_*` params (from buildPrefetchUrl); keepUrl
169
+ // comes from NavigationProvider's pendingUrl which is the bare
170
+ // navigation target. Normalize both sides before comparing.
171
+ const normalizedKeep = keepUrl ? normalizeForMatch(keepUrl) : null;
172
+ for (const [key, ac] of abortControllers) {
173
+ const lastNul = key.lastIndexOf("\0");
174
+ const target = lastNul >= 0 ? key.substring(lastNul + 1) : "";
175
+ if (
176
+ normalizedKeep &&
177
+ target &&
178
+ normalizeForMatch(target) === normalizedKeep
179
+ )
180
+ continue;
181
+ ac.abort();
182
+ abortControllers.delete(key);
183
+ if (executing.delete(key)) {
184
+ active--;
185
+ }
186
+ }
187
+ }
188
+
189
+ /**
190
+ * Hard-cancel everything including in-flight prefetches.
191
+ * Used by clearPrefetchCache (server action invalidation) where
192
+ * in-flight responses would be stale.
193
+ */
194
+ export function abortAllPrefetches(): void {
195
+ for (const ac of abortControllers.values()) {
196
+ ac.abort();
197
+ }
198
+ abortControllers.clear();
199
+
200
+ queue.length = 0;
201
+ queued.clear();
202
+ // Clear executing before resetting active. In-flight .finally() callbacks
203
+ // check executing.delete(key) — if the key is gone, they skip decrementing,
204
+ // so active settles at 0 without underflow.
205
+ executing.clear();
206
+ active = 0;
207
+ drainScheduled = false;
208
+ drainGeneration++;
209
+ }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Resource Readiness
3
+ *
4
+ * Utilities to defer speculative prefetches until critical resources
5
+ * (viewport images) have finished loading. Prevents prefetch fetch()
6
+ * calls from competing with images for the browser's connection pool.
7
+ */
8
+
9
+ /**
10
+ * Resolve when all in-viewport images have finished loading.
11
+ * Returns immediately if no images are pending.
12
+ *
13
+ * Only checks images that exist at call time — does not observe
14
+ * dynamically added images. For SPA navigations where new images
15
+ * appear after render, call this after the navigation settles.
16
+ */
17
+ export function waitForViewportImages(): Promise<void> {
18
+ if (typeof document === "undefined") return Promise.resolve();
19
+
20
+ const pending = Array.from(document.querySelectorAll("img")).filter((img) => {
21
+ if (img.complete) return false;
22
+ const rect = img.getBoundingClientRect();
23
+ return (
24
+ rect.bottom > 0 &&
25
+ rect.right > 0 &&
26
+ rect.top < window.innerHeight &&
27
+ rect.left < window.innerWidth
28
+ );
29
+ });
30
+
31
+ if (pending.length === 0) return Promise.resolve();
32
+
33
+ return new Promise((resolve) => {
34
+ const settled = new Set<HTMLImageElement>();
35
+
36
+ const settle = (img: HTMLImageElement) => {
37
+ if (settled.has(img)) return;
38
+ settled.add(img);
39
+ if (settled.size >= pending.length) resolve();
40
+ };
41
+
42
+ for (const img of pending) {
43
+ img.addEventListener("load", () => settle(img), { once: true });
44
+ img.addEventListener("error", () => settle(img), { once: true });
45
+ // Re-check: image may have completed between the initial filter
46
+ // and listener attachment. settle() is idempotent per image, so
47
+ // a queued load event firing afterward is harmless.
48
+ if (img.complete) settle(img);
49
+ }
50
+ });
51
+ }
52
+
53
+ /**
54
+ * Resolve after the given number of milliseconds.
55
+ */
56
+ export function wait(ms: number): Promise<void> {
57
+ return new Promise((resolve) => setTimeout(resolve, ms));
58
+ }
59
+
60
+ /**
61
+ * Resolve when the browser has an idle main-thread moment.
62
+ * Uses requestIdleCallback where available, falls back to setTimeout.
63
+ *
64
+ * This is a scheduling hint, not an asset-loaded detector — combine
65
+ * with waitForViewportImages() for full resource readiness.
66
+ */
67
+ export function waitForIdle(timeout = 200): Promise<void> {
68
+ if (typeof window !== "undefined" && "requestIdleCallback" in window) {
69
+ return new Promise((resolve) => {
70
+ window.requestIdleCallback(() => resolve(), { timeout });
71
+ });
72
+ }
73
+
74
+ return new Promise((resolve) => {
75
+ setTimeout(resolve, 0);
76
+ });
77
+ }
@@ -0,0 +1,194 @@
1
+ /**
2
+ * Rango State
3
+ *
4
+ * Manages a session-cookie-based state value for HTTP cache invalidation. The
5
+ * value is sent as the `X-Rango-State` header on prefetch and navigation
6
+ * requests; the server responds with `Vary: X-Rango-State`, so the browser HTTP
7
+ * cache keys responses by (URL, X-Rango-State value).
8
+ *
9
+ * Value format: `{buildVersion}:{invalidationTimestamp}`
10
+ * - Build version changes on deploy, busting all cached prefetches at boot.
11
+ * - Timestamp rotates on invalidation (server action, invalidateClientCache).
12
+ *
13
+ * Storage is a session cookie named by the server-resolved name passed to
14
+ * initRangoState (`{prefix}_{routerId}`, default prefix `rango-state`). The
15
+ * cookie jar is shared across tabs, so a per-request read IS the cross-tab
16
+ * value sync — no `storage` event is needed. An in-memory mirror is a
17
+ * write-through copy that is authoritative only when the cookie is unreadable
18
+ * (e.g. a sandboxed frame, or site data blocked wholesale): the failure
19
+ * direction is always toward freshness.
20
+ *
21
+ * Precedence is load-bearing: when `document.cookie` is readable, the
22
+ * per-request read wins; the mirror is a fallback, never a cache of the read.
23
+ * Caching the read across requests would reintroduce the staleness this
24
+ * mechanism removes.
25
+ */
26
+
27
+ import {
28
+ DEFAULT_STATE_COOKIE_PREFIX,
29
+ decodeStateValue,
30
+ getRawCookieValue,
31
+ mintStateValue,
32
+ serializeStateCookie,
33
+ } from "./cookie-name.js";
34
+
35
+ let cookieName: string = DEFAULT_STATE_COOKIE_PREFIX;
36
+
37
+ let currentVersion = "0";
38
+
39
+ let mirror: string | null = null;
40
+ let cookieBacked = false;
41
+
42
+ let externalRotationObserver: ((value: string) => void) | null = null;
43
+
44
+ /**
45
+ * Register the observer invoked when a read detects an EXTERNAL rotation (a
46
+ * sibling tab, a server `Set-Cookie`, or a cookie clear). Self-rotations
47
+ * (invalidateRangoState) update the mirror synchronously and never fire it.
48
+ */
49
+ export function setRangoStateObserver(
50
+ observer: ((value: string) => void) | null,
51
+ ): void {
52
+ externalRotationObserver = observer;
53
+ }
54
+
55
+ function notifyExternalRotation(value: string): void {
56
+ externalRotationObserver?.(value);
57
+ }
58
+
59
+ interface CookieRead {
60
+ /** False when there is no document or the read threw (sandboxed frame). */
61
+ readable: boolean;
62
+ /** The cookie value, or null when readable but absent. */
63
+ value: string | null;
64
+ }
65
+
66
+ function readCookie(name: string): CookieRead {
67
+ if (typeof document === "undefined") return { readable: false, value: null };
68
+ let raw: string;
69
+ try {
70
+ raw = document.cookie;
71
+ } catch {
72
+ return { readable: false, value: null };
73
+ }
74
+ return { readable: true, value: getRawCookieValue(raw, name) };
75
+ }
76
+
77
+ function writeCookie(name: string, value: string): void {
78
+ if (typeof document === "undefined") return;
79
+ const secure =
80
+ typeof location !== "undefined" && location.protocol === "https:";
81
+ try {
82
+ document.cookie = serializeStateCookie(name, value, secure);
83
+ } catch {}
84
+ }
85
+
86
+ function mintValue(): string {
87
+ return mintStateValue(currentVersion, mirror);
88
+ }
89
+
90
+ /**
91
+ * Initialize the Rango state cookie at app startup. `version` is the build
92
+ * version; `stateCookieName` is the server-resolved cookie name from payload
93
+ * metadata (falls back to the bare default prefix when a payload arrives
94
+ * without it). Keeps an existing matching-version cookie (preserves the cache
95
+ * key across reloads); mints fresh on a version change or a missing cookie.
96
+ */
97
+ export function initRangoState(
98
+ version: string,
99
+ stateCookieName?: string,
100
+ ): void {
101
+ currentVersion = version;
102
+ cookieName = stateCookieName || DEFAULT_STATE_COOKIE_PREFIX;
103
+ cleanupLegacyStorage();
104
+
105
+ const read = readCookie(cookieName);
106
+ if (!read.readable) {
107
+ // Cookies unreadable: the mirror is the source of truth for this session.
108
+ mirror = mintValue();
109
+ cookieBacked = false;
110
+ return;
111
+ }
112
+ if (read.value !== null) {
113
+ const decoded = decodeStateValue(read.value);
114
+ if (decoded && decoded.version === version) {
115
+ // Keep: a matching-version cookie survives the reload warm.
116
+ mirror = read.value;
117
+ cookieBacked = true;
118
+ return;
119
+ }
120
+ }
121
+ // Absent, malformed, or a version change (deploy): mint fresh and write.
122
+ mirror = mintValue();
123
+ cookieBacked = false;
124
+ writeCookie(cookieName, mirror);
125
+ }
126
+
127
+ /**
128
+ * Get the current Rango state value, used as the `X-Rango-State` header on
129
+ * prefetch and navigation requests. Reads the cookie every call (the read is
130
+ * the cross-tab sync channel) and reconciles the mirror.
131
+ */
132
+ export function getRangoState(): string {
133
+ const read = readCookie(cookieName);
134
+
135
+ if (!read.readable) {
136
+ // Mirror authoritative when the jar is unreadable.
137
+ return mirror ?? "0:0";
138
+ }
139
+
140
+ if (read.value !== null) {
141
+ if (read.value !== mirror) {
142
+ // External rotation (sibling tab / server Set-Cookie): adopt it. The
143
+ // mirror update makes this idempotent across a burst of reads.
144
+ mirror = read.value;
145
+ cookieBacked = true;
146
+ notifyExternalRotation(read.value);
147
+ } else {
148
+ cookieBacked = true;
149
+ }
150
+ return read.value;
151
+ }
152
+
153
+ // Readable but absent.
154
+ if (cookieBacked) {
155
+ // present -> absent: an external clear. Mint fresh, write back, and notify
156
+ // once (cookieBacked flips to false so we don't re-fire on the next read).
157
+ mirror = mintValue();
158
+ cookieBacked = false;
159
+ writeCookie(cookieName, mirror);
160
+ notifyExternalRotation(mirror);
161
+ } else if (mirror === null) {
162
+ // First access with no cookie yet (pre-boot): mint silently — there is
163
+ // nothing to invalidate.
164
+ mirror = mintValue();
165
+ writeCookie(cookieName, mirror);
166
+ }
167
+ return mirror;
168
+ }
169
+
170
+ /**
171
+ * Invalidate the Rango state (self-rotation). Called when the client clears its
172
+ * prefetch caches (e.g. via the server-action bridge). Rotates the timestamp,
173
+ * keeps the version, writes the cookie, and updates the mirror synchronously so
174
+ * the external-rotation observer is NOT triggered by our own write.
175
+ */
176
+ export function invalidateRangoState(): void {
177
+ mirror = mintValue();
178
+ cookieBacked = false;
179
+ writeCookie(cookieName, mirror);
180
+ }
181
+
182
+ function cleanupLegacyStorage(): void {
183
+ if (typeof localStorage === "undefined") return;
184
+ try {
185
+ const toRemove: string[] = [];
186
+ for (let i = 0; i < localStorage.length; i++) {
187
+ const key = localStorage.key(i);
188
+ if (key === "rango-state" || (key && key.startsWith("rango-state:"))) {
189
+ toRemove.push(key);
190
+ }
191
+ }
192
+ for (const key of toRemove) localStorage.removeItem(key);
193
+ } catch {}
194
+ }