@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
@@ -1,41 +1,45 @@
1
- /**
2
- * Router Manifest Loading
3
- *
4
- * Handles lazy loading and validation of route manifests.
5
- */
6
-
7
1
  import { invariant, RouteNotFoundError } from "../errors";
8
2
  import { createRouteHelpers } from "../route-definition";
9
3
  import {
10
4
  getContext,
11
5
  runWithPrefixes,
6
+ getIsolatedLazyParent,
12
7
  type EntryData,
13
8
  type MetricsStore,
14
9
  } from "../server/context";
15
10
  import MapRootLayout from "../server/root-layout";
11
+ import { joinPrefix } from "./pattern-matching.js";
16
12
  import type { RouteEntry } from "../types";
17
13
  import type { UrlPatterns } from "../urls";
14
+ import {
15
+ isIncludeProvider,
16
+ resolveIncludeModule,
17
+ } from "../urls/include-provider.js";
18
18
  import { VERSION } from "@rangojs/router:version";
19
19
 
20
+ // Tags an error thrown while dynamically importing an async include's module
21
+ // (`() => import("./routes")`) so loadManifest's outer catch re-raises it as a
22
+ // server error rather than masking it as a RouteNotFoundError (404).
23
+ const MODULE_LOAD_FAILURE = Symbol.for("rango.moduleLoadFailure");
24
+
20
25
  // Module-level manifest cache: avoids re-executing DSL handler on every request.
21
26
  // Handler execution is deterministic (components, loaders, middleware are module-level
22
27
  // stable references), so the resulting EntryData tree can be safely cached and reused
23
28
  // across requests within the same isolate.
24
29
  //
25
- // Cache is keyed by (VERSION, mountIndex, routeKey, isSSR). VERSION comes from the
30
+ // Cache is keyed by (VERSION, routerId, mountIndex, routeKey, isSSR). routeKey is
31
+ // REQUIRED in the key: loadManifest() runs the handler with forRoute=routeKey, and
32
+ // path-helper.ts prunes (skips registering) every route except forRoute, so the
33
+ // resulting Store.manifest is pruned to the requested route — NOT the full include.
34
+ // Dropping routeKey would make a sibling route miss and overwrite this entry with its
35
+ // own pruned manifest, so alternating sibling requests would thrash (re-run the
36
+ // handler every time). Running the include handler once per isolate instead of once
37
+ // per route is possible but needs an unpruned manifest cache with prune-on-read — see
38
+ // LP1 in docs/internal/matching-and-lazy-discovery.md. VERSION comes from the
26
39
  // @rangojs/router:version virtual module which Vite invalidates on RSC module HMR.
27
40
  // When VERSION changes, this module re-evaluates and the cache is recreated empty.
28
- // Including VERSION in the key is additional defense against stale entries.
29
41
  const manifestModuleCache = new Map<string, Map<string, EntryData>>();
30
42
 
31
- /**
32
- * Load manifest from route entry with AsyncLocalStorage context
33
- * Handles lazy imports, unwrapping, and validation
34
- *
35
- * Results are cached at module level after first execution. Subsequent calls
36
- * for the same (routeKey, isSSR) within the same isolate return cached data
37
- * without re-executing the DSL handler.
38
- */
39
43
  /**
40
44
  * Clear the module-level manifest cache.
41
45
  * Called on HMR to ensure stale handler references are discarded.
@@ -64,8 +68,12 @@ export async function loadManifest(
64
68
 
65
69
  const mountIndex = entry.mountIndex;
66
70
 
67
- // Check module-level cache (persists across requests within same isolate)
68
- const cacheKey = `${VERSION}:${mountIndex ?? ""}:${routeKey}:${isSSR ? 1 : 0}`;
71
+ // Check module-level cache (persists across requests within same isolate).
72
+ // Include routerId so multi-router setups (host routing) don't share cached
73
+ // EntryData across routers with overlapping mountIndex + routeKey combinations.
74
+ // routeKey is in the key because loadManifest() builds a manifest pruned to
75
+ // forRoute=routeKey (see path-helper.ts) — see the cache comment above.
76
+ const cacheKey = `${VERSION}:${entry.routerId ?? ""}:${mountIndex ?? ""}:${routeKey}:${isSSR ? 1 : 0}`;
69
77
  const cached = manifestModuleCache.get(cacheKey);
70
78
  if (cached) {
71
79
  const cacheStart = performance.now();
@@ -74,10 +82,14 @@ export async function loadManifest(
74
82
  Store.mountIndex = mountIndex;
75
83
  Store.isSSR = isSSR;
76
84
  if (metricsStore) Store.metrics = metricsStore;
77
- // Restore cached manifest into Store
78
- for (const [k, v] of cached) {
79
- Store.manifest.set(k, v);
80
- }
85
+ // Alias the request-scoped Store to the cached Map instead of copying it
86
+ // entry-by-entry. At request time this Store is throwaway (no ambient
87
+ // RangoContext store spans classify->match->render, so getOrCreateStore
88
+ // returns a fresh detached store here), so nothing mutates it in place after
89
+ // loadManifest returns. The fresh path below REASSIGNS Store.manifest rather
90
+ // than clearing it in place, so a later fresh load sharing this Store cannot
91
+ // poison the cached Map.
92
+ Store.manifest = cached;
81
93
  pushMetric?.("manifest:cache-hit", cacheStart);
82
94
  return cached.get(routeKey)!;
83
95
  }
@@ -85,22 +97,21 @@ export async function loadManifest(
85
97
  const storeSetupStart = performance.now();
86
98
  const Store = getContext().getOrCreateStore(routeKey);
87
99
 
88
- // Set mount index in store for unique shortCode prefixes
89
100
  Store.mountIndex = mountIndex;
90
-
91
- // Set isSSR flag so loading() can check if we're in SSR
92
101
  Store.isSSR = isSSR;
93
102
 
94
- // Attach metrics store to context if provided
95
103
  if (metricsStore) {
96
104
  Store.metrics = metricsStore;
97
105
  }
98
106
 
99
107
  pushMetric?.("manifest:store-setup", storeSetupStart);
100
108
 
101
- // Clear manifest before rebuilding to prevent stale entry mutations
102
109
  const clearStart = performance.now();
103
- Store.manifest.clear();
110
+ // Reassign rather than clear() in place: a prior cache-hit may have aliased
111
+ // Store.manifest to a shared module-cache Map (see cache-hit branch above),
112
+ // and clearing it in place would poison that cache. A fresh Map isolates this
113
+ // build; the cache still receives an independent copy at the end.
114
+ Store.manifest = new Map();
104
115
  pushMetric?.("manifest:clear", clearStart);
105
116
 
106
117
  try {
@@ -112,36 +123,48 @@ export async function loadManifest(
112
123
  // This ensures routes are registered under the correct layout hierarchy
113
124
  const lazyContext =
114
125
  entry.lazy && entry.lazyPatterns ? entry.lazyContext : null;
115
- const parentForContext =
116
- (lazyContext?.parent as EntryData | null) ?? Store.parent;
126
+ const parentForContext = lazyContext
127
+ ? getIsolatedLazyParent(
128
+ (lazyContext.parent as EntryData | null) ?? Store.parent,
129
+ )
130
+ : Store.parent;
117
131
 
118
132
  // For lazy entries, merge captured counters from include() so the
119
133
  // handler's entries get shortCode indices after sibling entries that
120
134
  // were created during pattern extraction. This prevents shortCode
121
135
  // collisions between lazy and non-lazy entries under the same parent
122
136
  // (e.g., ArticlesLayout and BlogLayout both under NavLayout).
123
- if (lazyContext && (lazyContext as any).counters) {
124
- const captured = (lazyContext as any).counters as Record<string, number>;
125
- for (const [key, value] of Object.entries(captured)) {
137
+ if (lazyContext?.counters) {
138
+ for (const [key, value] of Object.entries(lazyContext.counters)) {
126
139
  Store.counters[key] = Math.max(Store.counters[key] ?? 0, value);
127
140
  }
128
141
  }
129
142
 
130
143
  // Propagate cache profiles for DSL-time cache("profileName") resolution.
131
144
  // Non-lazy entries carry profiles directly; lazy entries carry them
132
- // in the captured lazyContext from include() time.
133
- const entryProfiles =
134
- entry.cacheProfiles ?? (lazyContext as any)?.cacheProfiles;
135
- if (entryProfiles) {
136
- Store.cacheProfiles = entryProfiles;
137
- }
145
+ // in the captured lazyContext from include() time. Always write
146
+ // (including clearing to undefined) so a prior lazy build's profile
147
+ // map cannot leak into a later non-lazy build on the same ALS-backed
148
+ // Store — which would otherwise let cache("name") resolve a profile
149
+ // from an unrelated entry.
150
+ Store.cacheProfiles = entry.cacheProfiles ?? lazyContext?.cacheProfiles;
138
151
 
139
152
  // Propagate rootScoped from lazyContext so that routes inside
140
153
  // nested { name: "sub" } under { name: "" } keep inherited root scope
141
- // when the manifest is rebuilt on each request.
142
- if (lazyContext && (lazyContext as any).rootScoped !== undefined) {
143
- Store.rootScoped = (lazyContext as any).rootScoped;
144
- }
154
+ // when the manifest is rebuilt on each request. Always write
155
+ // (including clearing to undefined, which makes getRootScoped()
156
+ // return its true default) so a prior lazy build's scope cannot leak
157
+ // into a later non-lazy build on the same ALS-backed Store — which
158
+ // would otherwise mis-register plain routes as non-root-scoped and
159
+ // break dot-local reverse resolution.
160
+ Store.rootScoped = lazyContext?.rootScoped;
161
+
162
+ // Propagate includeScope from lazyContext so that direct-descendant
163
+ // shortCodes of this include use the correct scoped counter namespace
164
+ // on every manifest rebuild. Always write (including clearing to
165
+ // undefined) so a prior lazy build's scope cannot leak into a later
166
+ // non-lazy build on the same ALS-backed Store.
167
+ Store.includeScope = lazyContext?.includeScope;
145
168
 
146
169
  const handlerExecStart = performance.now();
147
170
  const useItems = await getContext().runWithStore(
@@ -159,9 +182,35 @@ export async function loadManifest(
159
182
  // not exist in the non-lazy (root handler) path and would produce
160
183
  // mismatched shortCodes.
161
184
  if (entry.lazy && entry.lazyPatterns) {
185
+ // Resolve an async include provider (`() => import("./routes")`) before
186
+ // running its handler. The match-time precomputed shortcut can skip
187
+ // evaluateLazyEntry's resolution, so render-time must resolve it here;
188
+ // cache the resolved patterns on the entry so later renders reuse them.
189
+ if (isIncludeProvider(entry.lazyPatterns)) {
190
+ try {
191
+ entry.lazyPatterns = resolveIncludeModule(
192
+ await entry.lazyPatterns(),
193
+ entry.staticPrefix,
194
+ ) as unknown as UrlPatterns<any>;
195
+ } catch (err) {
196
+ // A failed dynamic import of a REAL, matched route's module is a
197
+ // server error, not a missing route. Tag it so the outer catch
198
+ // surfaces it as a 5xx instead of masking it as a
199
+ // RouteNotFoundError — which renders the 404 page (monitoring
200
+ // misses the failure and a CDN could cache the 404).
201
+ if (err && typeof err === "object") {
202
+ (err as Record<PropertyKey, unknown>)[MODULE_LOAD_FAILURE] =
203
+ true;
204
+ }
205
+ throw err;
206
+ }
207
+ }
162
208
  const lazyPatterns = entry.lazyPatterns as UrlPatterns<any>;
163
209
  const includePrefix = (entry as any)._lazyPrefix || "";
164
- const fullPrefix = (lazyContext?.urlPrefix || "") + includePrefix;
210
+ // Slash-collapsing join so a trailing-slash parent prefix does not
211
+ // bake a double slash into the registered route patterns (must match
212
+ // the same join in evaluateLazyEntry / the build-time runWithPrefixes).
213
+ const fullPrefix = joinPrefix(lazyContext?.urlPrefix, includePrefix);
165
214
 
166
215
  if (fullPrefix || lazyContext?.namePrefix) {
167
216
  return runWithPrefixes(fullPrefix, lazyContext?.namePrefix, () =>
@@ -171,28 +220,19 @@ export async function loadManifest(
171
220
  return lazyPatterns.handler();
172
221
  }
173
222
 
174
- // Wrap handler execution in root layout so routes get correct parent
175
- // This ensures all routes are registered with the layout as their parent
176
223
  let promiseResult: Promise<any> | null = null;
177
224
  const wrappedItems = helpers.layout(MapRootLayout, () => {
178
225
  const result = entry.handler();
179
226
  if (result instanceof Promise) {
180
- // Lazy handler detected - capture promise for async handling
181
227
  promiseResult = result;
182
- return []; // Return empty, we'll discard this wrapped result
228
+ return [];
183
229
  }
184
230
  return result;
185
231
  });
186
232
 
187
- // Handle lazy (Promise-based) handlers
188
233
  if (promiseResult !== null) {
189
234
  const load = await (promiseResult as Promise<any>);
190
- if (
191
- load &&
192
- load !== null &&
193
- typeof load === "object" &&
194
- "default" in load
195
- ) {
235
+ if (load && typeof load === "object" && "default" in load) {
196
236
  // Promise<{ default: () => Array }> - e.g., dynamic import
197
237
  if (typeof load.default !== "function") {
198
238
  throw new Error(
@@ -218,7 +258,6 @@ export async function loadManifest(
218
258
  );
219
259
  }
220
260
 
221
- // Inline handler - routes were registered with correct parent inside layout
222
261
  return [wrappedItems].flat(3);
223
262
  },
224
263
  );
@@ -251,6 +290,16 @@ export async function loadManifest(
251
290
 
252
291
  return Store.manifest.get(routeKey)!;
253
292
  } catch (e) {
293
+ // A tagged async-include module-load failure is a server error for a REAL
294
+ // matched route — re-raise it unchanged (becomes a 5xx) instead of masking
295
+ // it as a RouteNotFoundError (which renders/caches a 404).
296
+ if (
297
+ e &&
298
+ typeof e === "object" &&
299
+ (e as Record<PropertyKey, unknown>)[MODULE_LOAD_FAILURE]
300
+ ) {
301
+ throw e;
302
+ }
254
303
  throw new RouteNotFoundError(
255
304
  `Failed to load route handlers for ${path}: ${(e as Error).message}`,
256
305
  {