@rangojs/router 0.0.0-experimental.b9cb8739 → 0.0.0-experimental.bdaf10aa

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 (449) hide show
  1. package/AGENTS.md +8 -4
  2. package/README.md +303 -741
  3. package/dist/bin/rango.js +730 -184
  4. package/dist/testing/vitest.js +82 -0
  5. package/dist/vite/index.js +4344 -1335
  6. package/dist/vite/index.js.bak +5448 -0
  7. package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  8. package/package.json +86 -15
  9. package/skills/api-client/SKILL.md +211 -0
  10. package/skills/breadcrumbs/SKILL.md +85 -6
  11. package/skills/bundle-analysis/SKILL.md +159 -0
  12. package/skills/cache-guide/SKILL.md +251 -24
  13. package/skills/caching/SKILL.md +375 -17
  14. package/skills/catalog.json +271 -0
  15. package/skills/comparison/SKILL.md +50 -0
  16. package/skills/comparison/agents/openai.yaml +4 -0
  17. package/skills/comparison/references/framework-comparison.md +837 -0
  18. package/skills/composability/SKILL.md +110 -4
  19. package/skills/css/SKILL.md +76 -0
  20. package/skills/debug-manifest/SKILL.md +5 -3
  21. package/skills/defer-hydration/SKILL.md +235 -0
  22. package/skills/document-cache/SKILL.md +87 -56
  23. package/skills/fonts/SKILL.md +1 -1
  24. package/skills/handler-use/SKILL.md +364 -0
  25. package/skills/hooks/SKILL.md +73 -691
  26. package/skills/hooks/data.md +273 -0
  27. package/skills/hooks/handle-and-actions.md +103 -0
  28. package/skills/hooks/navigation.md +110 -0
  29. package/skills/hooks/outlets.md +41 -0
  30. package/skills/hooks/state.md +228 -0
  31. package/skills/hooks/urls.md +135 -0
  32. package/skills/host-router/SKILL.md +129 -27
  33. package/skills/i18n/SKILL.md +276 -0
  34. package/skills/intercept/SKILL.md +94 -18
  35. package/skills/layout/SKILL.md +62 -19
  36. package/skills/links/SKILL.md +249 -17
  37. package/skills/loader/SKILL.md +302 -54
  38. package/skills/middleware/SKILL.md +59 -16
  39. package/skills/migrate-nextjs/SKILL.md +745 -0
  40. package/skills/migrate-react-router/SKILL.md +153 -0
  41. package/skills/migrate-react-router/cloudflare-workers.md +129 -0
  42. package/skills/migrate-react-router/component-migration.md +196 -0
  43. package/skills/migrate-react-router/data-and-actions.md +225 -0
  44. package/skills/migrate-react-router/route-mapping.md +271 -0
  45. package/skills/mime-routes/SKILL.md +29 -2
  46. package/skills/observability/SKILL.md +202 -0
  47. package/skills/parallel/SKILL.md +225 -10
  48. package/skills/ppr/SKILL.md +622 -0
  49. package/skills/prerender/SKILL.md +178 -124
  50. package/skills/rango/SKILL.md +318 -24
  51. package/skills/react-compiler/SKILL.md +168 -0
  52. package/skills/response-routes/SKILL.md +138 -49
  53. package/skills/route/SKILL.md +172 -9
  54. package/skills/router-setup/SKILL.md +131 -11
  55. package/skills/scripts/SKILL.md +179 -0
  56. package/skills/server-actions/SKILL.md +776 -0
  57. package/skills/shell-manifest/SKILL.md +185 -0
  58. package/skills/streams-and-websockets/SKILL.md +283 -0
  59. package/skills/tailwind/SKILL.md +28 -4
  60. package/skills/testing/SKILL.md +130 -0
  61. package/skills/testing/bindings.md +103 -0
  62. package/skills/testing/cache-prerender.md +127 -0
  63. package/skills/testing/client-components.md +124 -0
  64. package/skills/testing/e2e-parity.md +125 -0
  65. package/skills/testing/flight.md +91 -0
  66. package/skills/testing/handles.md +131 -0
  67. package/skills/testing/loader.md +128 -0
  68. package/skills/testing/middleware.md +99 -0
  69. package/skills/testing/render-handler.md +122 -0
  70. package/skills/testing/response-routes.md +95 -0
  71. package/skills/testing/reverse-and-types.md +85 -0
  72. package/skills/testing/server-actions.md +107 -0
  73. package/skills/testing/server-tree.md +128 -0
  74. package/skills/testing/setup.md +123 -0
  75. package/skills/theme/SKILL.md +1 -1
  76. package/skills/typesafety/SKILL.md +45 -616
  77. package/skills/typesafety/env-and-bindings.md +254 -0
  78. package/skills/typesafety/generated-files-and-cli.md +335 -0
  79. package/skills/typesafety/params-and-search.md +153 -0
  80. package/skills/typesafety/route-types.md +209 -0
  81. package/skills/use-cache/SKILL.md +74 -15
  82. package/skills/vercel/SKILL.md +128 -0
  83. package/skills/view-transitions/SKILL.md +337 -0
  84. package/src/__augment-tests__/augment.ts +81 -0
  85. package/src/__augment-tests__/augmented.check.ts +116 -0
  86. package/src/__internal.ts +1 -66
  87. package/src/browser/action-coordinator.ts +53 -36
  88. package/src/browser/action-fence.ts +47 -0
  89. package/src/browser/app-shell.ts +39 -0
  90. package/src/browser/app-version.ts +14 -0
  91. package/src/browser/connection-warmup.ts +134 -0
  92. package/src/browser/cookie-name.ts +140 -0
  93. package/src/browser/event-controller.ts +257 -158
  94. package/src/browser/history-state.ts +21 -0
  95. package/src/browser/index.ts +3 -3
  96. package/src/browser/invalidate-client-cache.ts +52 -0
  97. package/src/browser/logging.ts +28 -0
  98. package/src/browser/merge-segment-loaders.ts +6 -4
  99. package/src/browser/navigation-bridge.ts +132 -33
  100. package/src/browser/navigation-client.ts +218 -68
  101. package/src/browser/navigation-store-handle.ts +38 -0
  102. package/src/browser/navigation-store.ts +203 -80
  103. package/src/browser/navigation-transaction.ts +18 -66
  104. package/src/browser/network-error-handler.ts +34 -7
  105. package/src/browser/partial-update.ts +241 -127
  106. package/src/browser/prefetch/cache.ts +271 -44
  107. package/src/browser/prefetch/fetch.ts +367 -40
  108. package/src/browser/prefetch/queue.ts +144 -23
  109. package/src/browser/prefetch/resource-ready.ts +77 -0
  110. package/src/browser/rango-state.ts +158 -76
  111. package/src/browser/react/Link.tsx +121 -16
  112. package/src/browser/react/NavigationProvider.tsx +240 -122
  113. package/src/browser/react/ScrollRestoration.tsx +10 -6
  114. package/src/browser/react/context.ts +7 -2
  115. package/src/browser/react/filter-segment-order.ts +66 -7
  116. package/src/browser/react/index.ts +0 -48
  117. package/src/browser/react/location-state-shared.ts +178 -8
  118. package/src/browser/react/location-state.ts +39 -14
  119. package/src/browser/react/use-action.ts +6 -15
  120. package/src/browser/react/use-handle.ts +23 -69
  121. package/src/browser/react/use-href.tsx +8 -1
  122. package/src/browser/react/use-link-status.ts +33 -8
  123. package/src/browser/react/use-navigation.ts +32 -7
  124. package/src/browser/react/use-params.ts +20 -10
  125. package/src/browser/react/use-reverse.ts +106 -0
  126. package/src/browser/react/use-router.ts +46 -11
  127. package/src/browser/react/use-search-params.ts +0 -5
  128. package/src/browser/react/use-segments.ts +11 -21
  129. package/src/browser/response-adapter.ts +99 -8
  130. package/src/browser/rsc-router.tsx +272 -80
  131. package/src/browser/scroll-restoration.ts +56 -22
  132. package/src/browser/segment-reconciler.ts +44 -7
  133. package/src/browser/segment-structure-assert.ts +2 -2
  134. package/src/browser/server-action-bridge.ts +244 -71
  135. package/src/browser/types.ts +136 -12
  136. package/src/browser/validate-redirect-origin.ts +43 -16
  137. package/src/build/collect-fallback-refs.ts +107 -0
  138. package/src/build/generate-manifest.ts +207 -158
  139. package/src/build/generate-route-types.ts +6 -1
  140. package/src/build/index.ts +11 -3
  141. package/src/build/prefix-tree-utils.ts +123 -0
  142. package/src/build/route-trie.ts +198 -41
  143. package/src/build/route-types/ast-route-extraction.ts +15 -8
  144. package/src/build/route-types/codegen.ts +16 -5
  145. package/src/build/route-types/include-resolution.ts +464 -63
  146. package/src/build/route-types/param-extraction.ts +6 -3
  147. package/src/build/route-types/per-module-writer.ts +22 -6
  148. package/src/build/route-types/router-processing.ts +336 -110
  149. package/src/build/route-types/scan-filter.ts +9 -2
  150. package/src/build/route-types/source-scan.ts +216 -0
  151. package/src/build/runtime-discovery.ts +13 -21
  152. package/src/cache/cache-error.ts +104 -0
  153. package/src/cache/cache-key-utils.ts +58 -13
  154. package/src/cache/cache-policy.ts +108 -34
  155. package/src/cache/cache-runtime.ts +454 -97
  156. package/src/cache/cache-scope.ts +235 -103
  157. package/src/cache/cache-tag.ts +149 -0
  158. package/src/cache/cf/cf-base64.ts +33 -0
  159. package/src/cache/cf/cf-cache-constants.ts +127 -0
  160. package/src/cache/cf/cf-cache-store.ts +2446 -170
  161. package/src/cache/cf/cf-cache-types.ts +349 -0
  162. package/src/cache/cf/cf-kv-utils.ts +46 -0
  163. package/src/cache/cf/cf-tag-marker-memo.ts +105 -0
  164. package/src/cache/cf/index.ts +11 -17
  165. package/src/cache/document-cache.ts +144 -49
  166. package/src/cache/handle-snapshot.ts +70 -0
  167. package/src/cache/index.ts +24 -20
  168. package/src/cache/memory-segment-store.ts +243 -37
  169. package/src/cache/profile-registry.ts +46 -31
  170. package/src/cache/read-through-swr.ts +56 -12
  171. package/src/cache/segment-codec.ts +13 -21
  172. package/src/cache/shell-snapshot.ts +417 -0
  173. package/src/cache/tag-invalidation.ts +230 -0
  174. package/src/cache/taint.ts +55 -0
  175. package/src/cache/types.ts +194 -99
  176. package/src/cache/vercel/index.ts +11 -0
  177. package/src/cache/vercel/vercel-cache-store.ts +1132 -0
  178. package/src/client.rsc.tsx +41 -21
  179. package/src/client.tsx +116 -290
  180. package/src/cloudflare/index.ts +11 -0
  181. package/src/cloudflare/tracing.ts +108 -0
  182. package/src/component-utils.ts +19 -0
  183. package/src/components/DefaultDocument.tsx +8 -2
  184. package/src/context-var.ts +84 -2
  185. package/src/debug.ts +2 -2
  186. package/src/decode-loader-results.ts +52 -0
  187. package/src/defer.ts +185 -0
  188. package/src/deps/ssr.ts +0 -1
  189. package/src/encode-kv.ts +49 -0
  190. package/src/errors.ts +30 -4
  191. package/src/escape-script.ts +52 -0
  192. package/src/handle.ts +104 -34
  193. package/src/handles/MetaTags.tsx +24 -53
  194. package/src/handles/Scripts.tsx +183 -0
  195. package/src/handles/breadcrumbs.ts +35 -8
  196. package/src/handles/deferred-resolution.ts +127 -0
  197. package/src/handles/is-thenable.ts +18 -0
  198. package/src/handles/meta.ts +14 -40
  199. package/src/handles/script.ts +244 -0
  200. package/src/host/cookie-handler.ts +9 -60
  201. package/src/host/errors.ts +13 -22
  202. package/src/host/index.ts +9 -2
  203. package/src/host/pattern-matcher.ts +23 -52
  204. package/src/host/router.ts +107 -99
  205. package/src/host/testing.ts +40 -27
  206. package/src/host/types.ts +37 -4
  207. package/src/host/utils.ts +1 -1
  208. package/src/href-client.ts +137 -22
  209. package/src/index.rsc.ts +100 -13
  210. package/src/index.ts +143 -19
  211. package/src/internal-debug.ts +11 -10
  212. package/src/loader-store.ts +500 -0
  213. package/src/loader.rsc.ts +20 -13
  214. package/src/loader.ts +12 -11
  215. package/src/missing-id-error.ts +68 -0
  216. package/src/outlet-context.ts +1 -1
  217. package/src/outlet-provider.tsx +1 -5
  218. package/src/prerender/param-hash.ts +16 -16
  219. package/src/prerender/store.ts +37 -41
  220. package/src/prerender.ts +215 -86
  221. package/src/redirect-origin.ts +114 -0
  222. package/src/regex-escape.ts +8 -0
  223. package/src/render-error-thrower.tsx +20 -0
  224. package/src/response-utils.ts +62 -0
  225. package/src/reverse.ts +65 -15
  226. package/src/root-error-boundary.tsx +1 -19
  227. package/src/route-content-wrapper.tsx +19 -77
  228. package/src/route-definition/dsl-helpers.ts +485 -303
  229. package/src/route-definition/helper-factories.ts +28 -140
  230. package/src/route-definition/helpers-types.ts +153 -77
  231. package/src/route-definition/index.ts +4 -2
  232. package/src/route-definition/redirect.ts +53 -12
  233. package/src/route-definition/resolve-handler-use.ts +160 -0
  234. package/src/route-definition/use-item-types.ts +29 -0
  235. package/src/route-map-builder.ts +48 -21
  236. package/src/route-types.ts +37 -46
  237. package/src/router/basename.ts +14 -0
  238. package/src/router/content-negotiation.ts +164 -17
  239. package/src/router/error-handling.ts +45 -18
  240. package/src/router/find-match.ts +130 -29
  241. package/src/router/handler-context.ts +83 -39
  242. package/src/router/instrument.ts +355 -0
  243. package/src/router/intercept-resolution.ts +50 -24
  244. package/src/router/lazy-includes.ts +89 -63
  245. package/src/router/loader-resolution.ts +286 -56
  246. package/src/router/logging.ts +5 -8
  247. package/src/router/manifest.ts +105 -56
  248. package/src/router/match-api.ts +178 -218
  249. package/src/router/match-context.ts +0 -22
  250. package/src/router/match-handlers.ts +211 -165
  251. package/src/router/match-middleware/background-revalidation.ts +66 -22
  252. package/src/router/match-middleware/cache-lookup.ts +214 -263
  253. package/src/router/match-middleware/cache-store.ts +105 -50
  254. package/src/router/match-middleware/intercept-resolution.ts +8 -28
  255. package/src/router/match-middleware/segment-resolution.ts +52 -18
  256. package/src/router/match-pipelines.ts +1 -42
  257. package/src/router/match-result.ts +128 -44
  258. package/src/router/metrics.ts +5 -34
  259. package/src/router/middleware-types.ts +13 -142
  260. package/src/router/middleware.ts +301 -177
  261. package/src/router/navigation-snapshot.ts +133 -0
  262. package/src/router/params-util.ts +23 -0
  263. package/src/router/parse-pattern.ts +115 -0
  264. package/src/router/pattern-matching.ts +181 -150
  265. package/src/router/prefetch-cache-ttl.ts +51 -0
  266. package/src/router/prefetch-limits.ts +37 -0
  267. package/src/router/prerender-match.ts +203 -58
  268. package/src/router/preview-match.ts +35 -103
  269. package/src/router/request-classification.ts +291 -0
  270. package/src/router/revalidation.ts +123 -73
  271. package/src/router/route-snapshot.ts +256 -0
  272. package/src/router/router-context.ts +11 -29
  273. package/src/router/router-interfaces.ts +146 -35
  274. package/src/router/router-options.ts +202 -15
  275. package/src/router/router-registry.ts +2 -5
  276. package/src/router/segment-resolution/fresh.ts +301 -78
  277. package/src/router/segment-resolution/helpers.ts +115 -30
  278. package/src/router/segment-resolution/loader-cache.ts +156 -39
  279. package/src/router/segment-resolution/loader-mask.ts +60 -0
  280. package/src/router/segment-resolution/loader-snapshot.ts +259 -0
  281. package/src/router/segment-resolution/mask-nested.ts +83 -0
  282. package/src/router/segment-resolution/revalidation.ts +477 -385
  283. package/src/router/segment-resolution/static-store.ts +19 -5
  284. package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
  285. package/src/router/segment-resolution/view-transition-default.ts +56 -0
  286. package/src/router/segment-resolution.ts +5 -1
  287. package/src/router/segment-wrappers.ts +8 -5
  288. package/src/router/state-cookie-name.ts +33 -0
  289. package/src/router/substitute-pattern-params.ts +75 -0
  290. package/src/router/telemetry-otel.ts +160 -200
  291. package/src/router/telemetry.ts +105 -20
  292. package/src/router/timeout.ts +0 -20
  293. package/src/router/tracing.ts +215 -0
  294. package/src/router/trie-matching.ts +171 -59
  295. package/src/router/types.ts +10 -63
  296. package/src/router/url-params.ts +57 -0
  297. package/src/router.ts +210 -71
  298. package/src/rsc/full-payload.ts +70 -0
  299. package/src/rsc/handler-context.ts +3 -2
  300. package/src/rsc/handler.ts +682 -508
  301. package/src/rsc/helpers.ts +168 -46
  302. package/src/rsc/index.ts +2 -5
  303. package/src/rsc/json-route-result.ts +38 -0
  304. package/src/rsc/loader-fetch.ts +127 -31
  305. package/src/rsc/manifest-init.ts +33 -42
  306. package/src/rsc/nonce.ts +10 -1
  307. package/src/rsc/origin-guard.ts +39 -25
  308. package/src/rsc/progressive-enhancement.ts +138 -15
  309. package/src/rsc/redirect-guard.ts +100 -0
  310. package/src/rsc/response-cache-serve.ts +238 -0
  311. package/src/rsc/response-error.ts +79 -12
  312. package/src/rsc/response-route-handler.ts +99 -189
  313. package/src/rsc/rsc-rendering.ts +509 -73
  314. package/src/rsc/runtime-warnings.ts +23 -10
  315. package/src/rsc/server-action.ts +287 -113
  316. package/src/rsc/shell-capture.ts +1190 -0
  317. package/src/rsc/shell-serve.ts +181 -0
  318. package/src/rsc/ssr-setup.ts +18 -2
  319. package/src/rsc/transition-gate.ts +89 -0
  320. package/src/rsc/types.ts +62 -6
  321. package/src/runtime-env.ts +18 -0
  322. package/src/search-params.ts +35 -30
  323. package/src/segment-content-promise.ts +67 -0
  324. package/src/segment-loader-promise.ts +167 -0
  325. package/src/segment-system.tsx +449 -132
  326. package/src/serialize.ts +243 -0
  327. package/src/server/context.ts +367 -61
  328. package/src/server/cookie-parse.ts +32 -0
  329. package/src/server/cookie-store.ts +152 -5
  330. package/src/server/handle-store.ts +40 -38
  331. package/src/server/loader-registry.ts +38 -46
  332. package/src/server/request-context.ts +558 -173
  333. package/src/ssr/index.tsx +491 -174
  334. package/src/ssr/inject-rsc-eager.ts +167 -0
  335. package/src/ssr/ssr-root.tsx +228 -0
  336. package/src/static-handler.ts +27 -18
  337. package/src/testing/cache-status.ts +162 -0
  338. package/src/testing/collect-handle.ts +46 -0
  339. package/src/testing/dispatch.ts +813 -0
  340. package/src/testing/dom.entry.ts +22 -0
  341. package/src/testing/e2e/fixture.ts +188 -0
  342. package/src/testing/e2e/index.ts +128 -0
  343. package/src/testing/e2e/matchers.ts +35 -0
  344. package/src/testing/e2e/page-helpers.ts +272 -0
  345. package/src/testing/e2e/parity.ts +387 -0
  346. package/src/testing/e2e/server.ts +195 -0
  347. package/src/testing/flight-matchers.ts +97 -0
  348. package/src/testing/flight-normalize.ts +11 -0
  349. package/src/testing/flight-runtime.d.ts +57 -0
  350. package/src/testing/flight-tree.ts +682 -0
  351. package/src/testing/flight.entry.ts +52 -0
  352. package/src/testing/flight.ts +257 -0
  353. package/src/testing/generated-routes.ts +199 -0
  354. package/src/testing/index.ts +105 -0
  355. package/src/testing/internal/context.ts +371 -0
  356. package/src/testing/internal/flight-client-globals.ts +30 -0
  357. package/src/testing/internal/seed-vars.ts +54 -0
  358. package/src/testing/render-handler.ts +357 -0
  359. package/src/testing/render-route.tsx +584 -0
  360. package/src/testing/run-loader.ts +385 -0
  361. package/src/testing/run-middleware.ts +205 -0
  362. package/src/testing/run-transition-when.ts +164 -0
  363. package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
  364. package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
  365. package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
  366. package/src/testing/vitest-stubs/version.ts +5 -0
  367. package/src/testing/vitest.ts +305 -0
  368. package/src/theme/ThemeProvider.tsx +56 -84
  369. package/src/theme/ThemeScript.tsx +7 -9
  370. package/src/theme/constants.ts +52 -13
  371. package/src/theme/index.ts +0 -7
  372. package/src/theme/theme-context.ts +1 -5
  373. package/src/theme/theme-script.ts +22 -21
  374. package/src/theme/use-theme.ts +0 -3
  375. package/src/types/boundaries.ts +0 -35
  376. package/src/types/cache-types.ts +17 -8
  377. package/src/types/error-types.ts +30 -90
  378. package/src/types/global-namespace.ts +54 -41
  379. package/src/types/handler-context.ts +234 -82
  380. package/src/types/index.ts +3 -10
  381. package/src/types/loader-types.ts +44 -15
  382. package/src/types/request-scope.ts +112 -0
  383. package/src/types/route-config.ts +20 -52
  384. package/src/types/route-entry.ts +19 -7
  385. package/src/types/segments.ts +137 -14
  386. package/src/urls/include-helper.ts +40 -75
  387. package/src/urls/include-provider.ts +71 -0
  388. package/src/urls/index.ts +2 -11
  389. package/src/urls/path-helper-types.ts +102 -23
  390. package/src/urls/path-helper.ts +62 -111
  391. package/src/urls/pattern-types.ts +84 -19
  392. package/src/urls/response-types.ts +25 -22
  393. package/src/urls/type-extraction.ts +98 -154
  394. package/src/urls/urls-function.ts +1 -19
  395. package/src/use-loader.tsx +346 -89
  396. package/src/vercel/index.ts +11 -0
  397. package/src/vercel/tracing.ts +88 -0
  398. package/src/vite/debug.ts +185 -0
  399. package/src/vite/discovery/bundle-postprocess.ts +36 -38
  400. package/src/vite/discovery/dev-prerender-cache.ts +117 -0
  401. package/src/vite/discovery/discover-routers.ts +130 -85
  402. package/src/vite/discovery/discovery-errors.ts +255 -0
  403. package/src/vite/discovery/gate-state.ts +171 -0
  404. package/src/vite/discovery/prerender-collection.ts +214 -132
  405. package/src/vite/discovery/route-types-writer.ts +40 -84
  406. package/src/vite/discovery/self-gen-tracking.ts +27 -1
  407. package/src/vite/discovery/state.ts +57 -6
  408. package/src/vite/discovery/virtual-module-codegen.ts +14 -34
  409. package/src/vite/index.ts +15 -0
  410. package/src/vite/inject-client-debug.ts +88 -0
  411. package/src/vite/plugin-types.ts +234 -62
  412. package/src/vite/plugins/cjs-to-esm.ts +16 -19
  413. package/src/vite/plugins/client-ref-dedup.ts +16 -11
  414. package/src/vite/plugins/client-ref-hashing.ts +28 -15
  415. package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
  416. package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  417. package/src/vite/plugins/cloudflare-protocol-stub.ts +194 -0
  418. package/src/vite/plugins/expose-action-id.ts +49 -98
  419. package/src/vite/plugins/expose-id-utils.ts +96 -51
  420. package/src/vite/plugins/expose-ids/export-analysis.ts +101 -34
  421. package/src/vite/plugins/expose-ids/handler-transform.ts +15 -64
  422. package/src/vite/plugins/expose-ids/loader-transform.ts +14 -24
  423. package/src/vite/plugins/expose-ids/router-transform.ts +118 -29
  424. package/src/vite/plugins/expose-internal-ids.ts +553 -317
  425. package/src/vite/plugins/performance-tracks.ts +89 -0
  426. package/src/vite/plugins/refresh-cmd.ts +89 -27
  427. package/src/vite/plugins/use-cache-transform.ts +73 -83
  428. package/src/vite/plugins/vercel-output.ts +384 -0
  429. package/src/vite/plugins/version-injector.ts +40 -29
  430. package/src/vite/plugins/version-plugin.ts +46 -37
  431. package/src/vite/plugins/virtual-entries.ts +138 -27
  432. package/src/vite/rango.ts +353 -303
  433. package/src/vite/router-discovery.ts +1090 -166
  434. package/src/vite/utils/ast-handler-extract.ts +26 -35
  435. package/src/vite/utils/banner.ts +4 -4
  436. package/src/vite/utils/bundle-analysis.ts +10 -15
  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 +4 -59
  441. package/src/vite/utils/package-resolution.ts +20 -52
  442. package/src/vite/utils/prerender-utils.ts +98 -38
  443. package/src/vite/utils/shared-utils.ts +144 -44
  444. package/src/browser/action-response-classifier.ts +0 -99
  445. package/src/browser/react/use-client-cache.ts +0 -58
  446. package/src/browser/shallow.ts +0 -40
  447. package/src/handles/index.ts +0 -7
  448. package/src/network-error-thrower.tsx +0 -23
  449. package/src/router/middleware-cookies.ts +0 -55
@@ -11,15 +11,24 @@ import type {
11
11
  InterceptEntry,
12
12
  InterceptSelectorContext,
13
13
  } from "../server/context";
14
- import type { HandlerContext, ResolvedSegment } from "../types";
14
+ import type {
15
+ HandlerContext,
16
+ InternalHandlerContext,
17
+ ResolvedSegment,
18
+ } from "../types";
15
19
  import { evaluateRevalidation } from "./revalidation.js";
16
20
  import { getRequestContext } from "../server/request-context.js";
17
21
  import { executeInterceptMiddleware } from "./middleware.js";
18
22
  import { createReverseFunction } from "./handler-context.js";
19
23
  import { getGlobalRouteMap } from "../route-map-builder.js";
20
- import { handleHandlerResult } from "./segment-resolution.js";
24
+ import {
25
+ handleHandlerResult,
26
+ warnOnStreamedResponse,
27
+ buildLoaderErrorContext,
28
+ } from "./segment-resolution.js";
21
29
  import type { SegmentResolutionDeps } from "./types.js";
22
30
  import { debugLog } from "./logging.js";
31
+ import { runInsideLoaderScope } from "../server/context.js";
23
32
 
24
33
  /**
25
34
  * Check if an intercept's when conditions are satisfied.
@@ -61,28 +70,14 @@ export function findInterceptForRoute(
61
70
  let current: EntryData | null = fromEntry;
62
71
 
63
72
  while (current) {
64
- if (current.intercept && current.intercept.length > 0) {
65
- for (const intercept of current.intercept) {
73
+ // current first, then its sibling layouts — same order as before.
74
+ for (const source of [current, ...current.layout]) {
75
+ for (const intercept of source.intercept) {
66
76
  if (
67
77
  intercept.routeName === targetRouteKey &&
68
78
  evaluateInterceptWhen(intercept, selectorContext, isAction)
69
79
  ) {
70
- return { intercept, entry: current };
71
- }
72
- }
73
- }
74
-
75
- if (current.layout && current.layout.length > 0) {
76
- for (const siblingLayout of current.layout) {
77
- if (siblingLayout.intercept && siblingLayout.intercept.length > 0) {
78
- for (const intercept of siblingLayout.intercept) {
79
- if (
80
- intercept.routeName === targetRouteKey &&
81
- evaluateInterceptWhen(intercept, selectorContext, isAction)
82
- ) {
83
- return { intercept, entry: siblingLayout };
84
- }
85
- }
80
+ return { intercept, entry: source };
86
81
  }
87
82
  }
88
83
  }
@@ -118,10 +113,25 @@ export async function resolveInterceptEntry<TEnv>(
118
113
  };
119
114
  stale?: boolean;
120
115
  },
116
+ options?: {
117
+ /**
118
+ * Skip the intercept's middleware execution. Set ONLY by the post-response
119
+ * background re-render paths (proactive caching, stale background
120
+ * revalidation), whose sole purpose is to re-render the segment tree to
121
+ * populate the cache. The foreground request already ran the intercept
122
+ * middleware before the response was sent — it validated auth, set cookies,
123
+ * and wrote context vars into the request context's shared `_variables`,
124
+ * which the background render reuses. Re-running middleware here would fire
125
+ * its side effects a SECOND time, and a middleware that short-circuits with
126
+ * a Response would `throw` and silently abort the cache write. Never set on
127
+ * the foreground path.
128
+ */
129
+ skipMiddleware?: boolean;
130
+ },
121
131
  ): Promise<ResolvedSegment[]> {
122
132
  const segments: ResolvedSegment[] = [];
123
133
 
124
- if (interceptEntry.middleware.length > 0) {
134
+ if (!options?.skipMiddleware && interceptEntry.middleware.length > 0) {
125
135
  const requestCtx = getRequestContext();
126
136
  if (!requestCtx?.res) {
127
137
  throw new Error(
@@ -133,7 +143,7 @@ export async function resolveInterceptEntry<TEnv>(
133
143
  context.request,
134
144
  context.env,
135
145
  params,
136
- context.var as Record<string, any>,
146
+ (context as InternalHandlerContext<any, TEnv>)._variables,
137
147
  requestCtx.res,
138
148
  createReverseFunction(getGlobalRouteMap()),
139
149
  );
@@ -188,6 +198,7 @@ export async function resolveInterceptEntry<TEnv>(
188
198
  context,
189
199
  actionContext,
190
200
  stale,
201
+ traceSource: "intercept-loader",
191
202
  });
192
203
 
193
204
  if (!shouldRevalidate) {
@@ -206,10 +217,13 @@ export async function resolveInterceptEntry<TEnv>(
206
217
  loaderIds.push(loader.$$id);
207
218
  loaderPromises.push(
208
219
  deps.wrapLoaderPromise(
209
- context.use(loader),
220
+ runInsideLoaderScope(() => context.use(loader)),
210
221
  parentEntry,
211
222
  segmentId,
212
223
  context.pathname,
224
+ // Report a throwing intercept loader to onError + loader.error telemetry,
225
+ // matching the fresh/revalidation paths.
226
+ buildLoaderErrorContext(context),
213
227
  ),
214
228
  );
215
229
  }
@@ -236,6 +250,12 @@ export async function resolveInterceptEntry<TEnv>(
236
250
  let loaderDataPromise: Promise<any[]> | any[] | undefined;
237
251
 
238
252
  if (interceptEntry.loading && loaderPromises.length > 0) {
253
+ if (handlerResult instanceof Promise) {
254
+ warnOnStreamedResponse(
255
+ handlerResult,
256
+ `intercept ${interceptEntry.slotName}`,
257
+ );
258
+ }
239
259
  component =
240
260
  handlerResult instanceof Promise
241
261
  ? handlerResult
@@ -355,6 +375,7 @@ export async function resolveInterceptLoadersOnly<TEnv>(
355
375
  context,
356
376
  actionContext,
357
377
  stale,
378
+ traceSource: "intercept-loader",
358
379
  });
359
380
 
360
381
  if (!shouldRevalidate) {
@@ -372,10 +393,15 @@ export async function resolveInterceptLoadersOnly<TEnv>(
372
393
  loaderIds.push(loader.$$id);
373
394
  loaderPromises.push(
374
395
  deps.wrapLoaderPromise(
375
- context.use(loader),
396
+ runInsideLoaderScope(() => context.use(loader)),
376
397
  parentEntry,
377
398
  segmentId,
378
399
  context.pathname,
400
+ // Report a throwing intercept loader to onError + loader.error telemetry,
401
+ // matching the fresh/revalidation paths. resolveInterceptLoadersOnly is
402
+ // only called on the cache-hit partial-update path (handleCacheHitIntercept),
403
+ // so flag isPartial:true exactly like revalidation.ts's partial path.
404
+ { ...buildLoaderErrorContext(context), isPartial: true },
379
405
  ),
380
406
  );
381
407
  }
@@ -1,24 +1,27 @@
1
1
  import { registerRouteMap } from "../route-map-builder.js";
2
- import { extractStaticPrefix } from "./pattern-matching.js";
2
+ import { extractStaticPrefix, joinPrefix } from "./pattern-matching.js";
3
3
  import {
4
- EntryData,
5
- RSCRouterContext,
4
+ type EntryData,
5
+ RangoContext,
6
6
  runWithPrefixes,
7
+ getIsolatedLazyParent,
7
8
  } from "../server/context";
8
9
  import type { UrlPatterns } from "../urls.js";
9
10
  import type { AllUseItems, IncludeItem } from "../route-types.js";
10
11
  import type { ResolvedRouteMap, RouteEntry, TrailingSlashMode } from "../types";
12
+ import {
13
+ isIncludeProvider,
14
+ resolveIncludeModule,
15
+ } from "../urls/include-provider.js";
11
16
 
12
17
  export interface LazyEvalDeps<TEnv = any> {
13
18
  routesEntries: RouteEntry<TEnv>[];
14
19
  mergedRouteMap: Record<string, string>;
15
20
  nextMountIndex: () => number;
16
21
  getPrecomputedByPrefix: () => Map<string, Record<string, string>> | null;
22
+ routerId?: string;
17
23
  }
18
24
 
19
- // Detect lazy includes in handler result and create placeholder entries
20
- // Lazy includes are IncludeItem with lazy: true and _lazyContext
21
- // Moved to outer scope so it can be reused by evaluateLazyEntry for nested includes
22
25
  export function findLazyIncludes<TEnv = any>(
23
26
  items: AllUseItems[],
24
27
  ): Array<{
@@ -54,7 +57,6 @@ export function findLazyIncludes<TEnv = any>(
54
57
  });
55
58
  }
56
59
  }
57
- // Recursively check nested items (in layouts, etc.)
58
60
  if ((item as any).uses && Array.isArray((item as any).uses)) {
59
61
  lazyItems.push(...findLazyIncludes((item as any).uses));
60
62
  }
@@ -71,19 +73,11 @@ export function findLazyIncludes<TEnv = any>(
71
73
  export function evaluateLazyEntry<TEnv = any>(
72
74
  entry: RouteEntry<TEnv>,
73
75
  deps: LazyEvalDeps<TEnv>,
74
- ): void {
76
+ ): void | Promise<void> {
75
77
  if (!entry.lazy || entry.lazyEvaluated || !entry.lazyPatterns) {
76
78
  return;
77
79
  }
78
80
 
79
- // Check for pre-computed routes from build-time data.
80
- // Only leaf nodes (no nested includes) are precomputed, so entries with
81
- // nested lazy includes fall through to the handler below.
82
- // When multiple entries share the same staticPrefix (e.g., several
83
- // include("/", ...) calls), the precomputed data merges all their routes
84
- // into one entry. Assigning that merged set to the first matching entry
85
- // causes findMatch to pick the wrong handler for routes belonging to a
86
- // different include. Skip the shortcut when the prefix is shared.
87
81
  const currentPrecomputed = deps.getPrecomputedByPrefix();
88
82
  if (currentPrecomputed) {
89
83
  const routes = currentPrecomputed.get(entry.staticPrefix);
@@ -97,56 +91,91 @@ export function evaluateLazyEntry<TEnv = any>(
97
91
  for (const [name, pattern] of Object.entries(routes)) {
98
92
  deps.mergedRouteMap[name] = pattern;
99
93
  }
100
- registerRouteMap(deps.mergedRouteMap);
94
+ // Register only this entry's routes (the delta): the full
95
+ // mergedRouteMap is seeded from the generated manifest at
96
+ // createRouter() time and already registered there — re-passing it
97
+ // made this request-path call O(total routes) (issue #666).
98
+ registerRouteMap(routes);
101
99
  return;
102
100
  }
103
101
  }
104
102
  }
105
103
 
106
- // Mark as evaluated immediately to prevent concurrent evaluation.
107
- // JS is single-threaded but handlers.handler() could theoretically yield,
108
- // and the while-loop in findMatch retries after evaluation.
109
- entry.lazyEvaluated = true;
104
+ // Async provider (`() => import("./routes")`): the route module is evaluated
105
+ // off the startup path, on the first request reaching this prefix. Concurrent
106
+ // first-hits share one in-flight promise so the import + expansion run exactly
107
+ // once. The eager path below stays fully synchronous (no Promise), so the
108
+ // per-entry match loop pays no microtask for normal includes.
109
+ const lazyPatterns = entry.lazyPatterns;
110
+ if (isIncludeProvider(lazyPatterns)) {
111
+ const inflight = (entry as { _lazyInflight?: Promise<void> })._lazyInflight;
112
+ if (inflight) return inflight;
113
+ const work = (async () => {
114
+ const resolved = resolveIncludeModule(
115
+ await lazyPatterns(),
116
+ entry.staticPrefix,
117
+ );
118
+ // Cache the resolved patterns: any later re-entry expands synchronously.
119
+ entry.lazyPatterns = resolved as unknown as UrlPatterns<TEnv>;
120
+ runExpansion(entry, deps, resolved as UrlPatterns<TEnv>);
121
+ })();
122
+ (entry as { _lazyInflight?: Promise<void> })._lazyInflight = work;
123
+ const clear = () => {
124
+ (entry as { _lazyInflight?: Promise<void> })._lazyInflight = undefined;
125
+ };
126
+ // On failure, clear the flag (lazyEvaluated stays false) so a later request
127
+ // can retry the import rather than wedging the route permanently.
128
+ work.then(clear, clear);
129
+ return work;
130
+ }
131
+
132
+ runExpansion(entry, deps, lazyPatterns as UrlPatterns<TEnv>);
133
+ }
110
134
 
111
- const lazyPatterns = entry.lazyPatterns as UrlPatterns<TEnv>;
135
+ /**
136
+ * Synchronously expand a lazy entry's (already-resolved) patterns into routes
137
+ * and splice any nested lazy includes as new entries. Runs once per entry.
138
+ */
139
+ function runExpansion<TEnv = any>(
140
+ entry: RouteEntry<TEnv>,
141
+ deps: LazyEvalDeps<TEnv>,
142
+ lazyPatterns: UrlPatterns<TEnv>,
143
+ ): void {
144
+ // lazyEvaluated is set at the END, only after the handler ran and the routes
145
+ // (and any nested includes) were spliced. Setting it up-front would mark the
146
+ // entry done even if the handler throws mid-expansion: the async provider
147
+ // path clears _lazyInflight on rejection so a later request can retry, but a
148
+ // premature lazyEvaluated=true would make evaluateLazyEntry short-circuit
149
+ // (line ~77) forever, wedging the route at 404 until the isolate restarts.
112
150
  const lazyContext = entry.lazyContext;
113
151
 
114
- // Create a new context for evaluating the lazy patterns
115
152
  const manifest = new Map<string, EntryData>();
116
153
  const patterns = new Map<string, string>();
117
154
  const patternsByPrefix = new Map<string, Map<string, string>>();
118
155
  const trailingSlashMap = new Map<string, TrailingSlashMode>();
119
156
 
120
- // Capture the handler result to detect nested lazy includes
121
157
  let handlerResult: AllUseItems[] = [];
122
158
 
123
- // Merge captured counters from include() to maintain consistent
124
- // shortCode indices with sibling entries from pattern extraction
125
- const lazyCounters: Record<string, number> = {};
126
- if (lazyContext && (lazyContext as any).counters) {
127
- const captured = (lazyContext as any).counters as Record<string, number>;
128
- for (const [key, value] of Object.entries(captured)) {
129
- lazyCounters[key] = value;
130
- }
131
- }
159
+ const lazyCounters: Record<string, number> = lazyContext?.counters
160
+ ? { ...lazyContext.counters }
161
+ : {};
132
162
 
133
- RSCRouterContext.run(
163
+ RangoContext.run(
134
164
  {
135
165
  manifest,
136
166
  patterns,
137
167
  patternsByPrefix,
138
168
  trailingSlash: trailingSlashMap,
139
169
  namespace: "lazy",
140
- parent: (lazyContext?.parent as EntryData | null) ?? null,
170
+ parent: getIsolatedLazyParent(lazyContext?.parent as EntryData | null),
141
171
  counters: lazyCounters,
142
- cacheProfiles: (lazyContext as any)?.cacheProfiles,
143
- rootScoped: (lazyContext as any)?.rootScoped,
172
+ cacheProfiles: lazyContext?.cacheProfiles,
173
+ rootScoped: lazyContext?.rootScoped,
174
+ includeScope: lazyContext?.includeScope,
144
175
  },
145
176
  () => {
146
- // Run the lazy patterns handler with the original context prefixes
147
- // The prefix comes from the IncludeItem stored in lazyPatterns
148
177
  const includePrefix = (entry as any)._lazyPrefix || "";
149
- const fullPrefix = (lazyContext?.urlPrefix || "") + includePrefix;
178
+ const fullPrefix = joinPrefix(lazyContext?.urlPrefix, includePrefix);
150
179
 
151
180
  if (fullPrefix || lazyContext?.namePrefix) {
152
181
  runWithPrefixes(fullPrefix, lazyContext?.namePrefix, () => {
@@ -158,11 +187,9 @@ export function evaluateLazyEntry<TEnv = any>(
158
187
  },
159
188
  );
160
189
 
161
- // Populate the entry's routes from the patterns
162
190
  const routesObject: Record<string, string> = {};
163
191
  for (const [name, pattern] of patterns.entries()) {
164
192
  routesObject[name] = pattern;
165
- // Also add to merged route map for reverse() support
166
193
  const existingPattern = deps.mergedRouteMap[name];
167
194
  if (existingPattern !== undefined && existingPattern !== pattern) {
168
195
  console.warn(
@@ -173,45 +200,38 @@ export function evaluateLazyEntry<TEnv = any>(
173
200
  deps.mergedRouteMap[name] = pattern;
174
201
  }
175
202
 
176
- // Update the entry in-place
177
203
  entry.routes = routesObject as ResolvedRouteMap<any>;
178
204
 
179
- // Note: Do NOT clear lazyPatterns/lazyContext here.
180
- // loadManifest() needs them on every request to re-run the handler
181
- // in the correct AsyncLocalStorage context (Store.manifest).
182
-
183
- // Update trailing slash config if available
184
205
  if (trailingSlashMap.size > 0) {
185
206
  entry.trailingSlash = Object.fromEntries(trailingSlashMap);
186
207
  }
187
208
 
188
- // Detect nested lazy includes and register them as new entries
189
209
  const nestedLazyIncludes = findLazyIncludes(handlerResult);
190
210
  for (const lazyInclude of nestedLazyIncludes) {
191
- // Compute the full URL prefix (combining parent prefix if any)
192
- const fullPrefix = lazyInclude.context.urlPrefix
193
- ? lazyInclude.context.urlPrefix + lazyInclude.prefix
194
- : lazyInclude.prefix;
211
+ const fullPrefix = joinPrefix(
212
+ lazyInclude.context.urlPrefix,
213
+ lazyInclude.prefix,
214
+ );
195
215
 
196
216
  const nestedEntry: RouteEntry<TEnv> & { _lazyPrefix?: string } = {
197
217
  prefix: "",
198
218
  staticPrefix: extractStaticPrefix(fullPrefix),
199
- routes: {} as ResolvedRouteMap<any>, // Empty until first match
219
+ routes: {} as ResolvedRouteMap<any>,
200
220
  trailingSlash: entry.trailingSlash,
201
- handler: (lazyInclude.patterns as UrlPatterns<TEnv>).handler,
221
+ // include entries don't invoke their own handler (real handlers come from
222
+ // the expanded routes); use the parent's placeholder. A provider has no
223
+ // `.handler` until resolved, so never read it here.
224
+ handler: isIncludeProvider(lazyInclude.patterns)
225
+ ? entry.handler
226
+ : (lazyInclude.patterns as UrlPatterns<TEnv>).handler,
202
227
  mountIndex: deps.nextMountIndex(),
203
- // Lazy evaluation fields
228
+ routerId: deps.routerId,
204
229
  lazy: true,
205
230
  lazyPatterns: lazyInclude.patterns,
206
231
  lazyContext: lazyInclude.context,
207
232
  lazyEvaluated: false,
208
- // Store the include prefix for evaluation
209
233
  _lazyPrefix: lazyInclude.prefix,
210
234
  };
211
- // Insert nested lazy entry before any entry whose staticPrefix is a
212
- // prefix of (but shorter than) this lazy entry's staticPrefix.
213
- // This ensures more specific lazy includes are matched before
214
- // less specific eager entries (e.g., "/href/nested" before "/href/:id").
215
235
  const nestedPrefix = nestedEntry.staticPrefix;
216
236
  let insertIndex = deps.routesEntries.length;
217
237
  if (nestedPrefix) {
@@ -229,6 +249,12 @@ export function evaluateLazyEntry<TEnv = any>(
229
249
  deps.routesEntries.splice(insertIndex, 0, nestedEntry);
230
250
  }
231
251
 
232
- // Re-register route map for runtime reverse() usage
233
- registerRouteMap(deps.mergedRouteMap);
252
+ // Delta only see the matching comment on the precomputed branch above and
253
+ // the WHY block on registerRouteMap (issue #666).
254
+ registerRouteMap(routesObject);
255
+
256
+ // Expansion fully succeeded (handler ran, routes + nested includes spliced) —
257
+ // mark done now so a mid-expansion throw above leaves lazyEvaluated=false and
258
+ // the entry retriable.
259
+ entry.lazyEvaluated = true;
234
260
  }