@rangojs/router 0.0.0-experimental.79 → 0.0.0-experimental.7c7e4327

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 (440) hide show
  1. package/AGENTS.md +8 -4
  2. package/README.md +301 -797
  3. package/dist/bin/rango.js +603 -145
  4. package/dist/testing/vitest.js +82 -0
  5. package/dist/vite/index.js +3750 -1160
  6. package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  7. package/package.json +96 -24
  8. package/skills/api-client/SKILL.md +211 -0
  9. package/skills/breadcrumbs/SKILL.md +85 -6
  10. package/skills/bundle-analysis/SKILL.md +159 -0
  11. package/skills/cache-guide/SKILL.md +228 -33
  12. package/skills/caching/SKILL.md +336 -19
  13. package/skills/catalog.json +271 -0
  14. package/skills/comparison/SKILL.md +50 -0
  15. package/skills/comparison/agents/openai.yaml +4 -0
  16. package/skills/comparison/references/framework-comparison.md +837 -0
  17. package/skills/composability/SKILL.md +110 -4
  18. package/skills/css/SKILL.md +76 -0
  19. package/skills/debug-manifest/SKILL.md +5 -3
  20. package/skills/defer-hydration/SKILL.md +235 -0
  21. package/skills/document-cache/SKILL.md +87 -56
  22. package/skills/fonts/SKILL.md +1 -1
  23. package/skills/handler-use/SKILL.md +12 -10
  24. package/skills/hooks/SKILL.md +73 -691
  25. package/skills/hooks/data.md +273 -0
  26. package/skills/hooks/handle-and-actions.md +103 -0
  27. package/skills/hooks/navigation.md +110 -0
  28. package/skills/hooks/outlets.md +41 -0
  29. package/skills/hooks/state.md +228 -0
  30. package/skills/hooks/urls.md +135 -0
  31. package/skills/host-router/SKILL.md +129 -27
  32. package/skills/i18n/SKILL.md +276 -0
  33. package/skills/intercept/SKILL.md +75 -19
  34. package/skills/layout/SKILL.md +40 -19
  35. package/skills/links/SKILL.md +247 -17
  36. package/skills/loader/SKILL.md +248 -10
  37. package/skills/middleware/SKILL.md +25 -13
  38. package/skills/migrate-nextjs/SKILL.md +205 -20
  39. package/skills/migrate-react-router/SKILL.md +59 -670
  40. package/skills/migrate-react-router/cloudflare-workers.md +129 -0
  41. package/skills/migrate-react-router/component-migration.md +196 -0
  42. package/skills/migrate-react-router/data-and-actions.md +225 -0
  43. package/skills/migrate-react-router/route-mapping.md +271 -0
  44. package/skills/mime-routes/SKILL.md +29 -2
  45. package/skills/observability/SKILL.md +202 -0
  46. package/skills/parallel/SKILL.md +40 -10
  47. package/skills/ppr/SKILL.md +616 -0
  48. package/skills/prerender/SKILL.md +72 -60
  49. package/skills/rango/SKILL.md +318 -26
  50. package/skills/react-compiler/SKILL.md +168 -0
  51. package/skills/response-routes/SKILL.md +138 -49
  52. package/skills/route/SKILL.md +117 -9
  53. package/skills/router-setup/SKILL.md +44 -9
  54. package/skills/scripts/SKILL.md +179 -0
  55. package/skills/server-actions/SKILL.md +776 -0
  56. package/skills/shell-manifest/SKILL.md +185 -0
  57. package/skills/streams-and-websockets/SKILL.md +283 -0
  58. package/skills/tailwind/SKILL.md +28 -4
  59. package/skills/testing/SKILL.md +130 -0
  60. package/skills/testing/bindings.md +103 -0
  61. package/skills/testing/cache-prerender.md +127 -0
  62. package/skills/testing/client-components.md +124 -0
  63. package/skills/testing/e2e-parity.md +125 -0
  64. package/skills/testing/flight.md +91 -0
  65. package/skills/testing/handles.md +131 -0
  66. package/skills/testing/loader.md +128 -0
  67. package/skills/testing/middleware.md +99 -0
  68. package/skills/testing/render-handler.md +122 -0
  69. package/skills/testing/response-routes.md +95 -0
  70. package/skills/testing/reverse-and-types.md +85 -0
  71. package/skills/testing/server-actions.md +107 -0
  72. package/skills/testing/server-tree.md +128 -0
  73. package/skills/testing/setup.md +123 -0
  74. package/skills/theme/SKILL.md +1 -1
  75. package/skills/typesafety/SKILL.md +45 -626
  76. package/skills/typesafety/env-and-bindings.md +254 -0
  77. package/skills/typesafety/generated-files-and-cli.md +335 -0
  78. package/skills/typesafety/params-and-search.md +153 -0
  79. package/skills/typesafety/route-types.md +209 -0
  80. package/skills/use-cache/SKILL.md +74 -15
  81. package/skills/vercel/SKILL.md +128 -0
  82. package/skills/view-transitions/SKILL.md +337 -0
  83. package/src/__augment-tests__/augment.ts +81 -0
  84. package/src/__augment-tests__/augmented.check.ts +116 -0
  85. package/src/__internal.ts +0 -65
  86. package/src/browser/action-coordinator.ts +53 -36
  87. package/src/browser/action-fence.ts +47 -0
  88. package/src/browser/app-shell.ts +39 -0
  89. package/src/browser/connection-warmup.ts +134 -0
  90. package/src/browser/cookie-name.ts +140 -0
  91. package/src/browser/event-controller.ts +252 -158
  92. package/src/browser/history-state.ts +21 -0
  93. package/src/browser/index.ts +3 -3
  94. package/src/browser/invalidate-client-cache.ts +52 -0
  95. package/src/browser/logging.ts +28 -0
  96. package/src/browser/merge-segment-loaders.ts +6 -4
  97. package/src/browser/navigation-bridge.ts +94 -25
  98. package/src/browser/navigation-client.ts +144 -79
  99. package/src/browser/navigation-store-handle.ts +38 -0
  100. package/src/browser/navigation-store.ts +161 -73
  101. package/src/browser/navigation-transaction.ts +9 -59
  102. package/src/browser/network-error-handler.ts +34 -7
  103. package/src/browser/partial-update.ts +183 -144
  104. package/src/browser/prefetch/cache.ts +242 -77
  105. package/src/browser/prefetch/fetch.ts +325 -69
  106. package/src/browser/prefetch/queue.ts +61 -12
  107. package/src/browser/rango-state.ts +158 -76
  108. package/src/browser/react/Link.tsx +58 -20
  109. package/src/browser/react/NavigationProvider.tsx +202 -120
  110. package/src/browser/react/ScrollRestoration.tsx +10 -6
  111. package/src/browser/react/filter-segment-order.ts +66 -7
  112. package/src/browser/react/index.ts +0 -48
  113. package/src/browser/react/location-state-shared.ts +178 -8
  114. package/src/browser/react/location-state.ts +39 -14
  115. package/src/browser/react/use-action.ts +6 -15
  116. package/src/browser/react/use-handle.ts +17 -14
  117. package/src/browser/react/use-href.tsx +8 -1
  118. package/src/browser/react/use-link-status.ts +33 -8
  119. package/src/browser/react/use-navigation.ts +32 -7
  120. package/src/browser/react/use-params.ts +20 -10
  121. package/src/browser/react/use-reverse.ts +106 -0
  122. package/src/browser/react/use-router.ts +25 -3
  123. package/src/browser/react/use-search-params.ts +0 -5
  124. package/src/browser/react/use-segments.ts +11 -21
  125. package/src/browser/response-adapter.ts +99 -8
  126. package/src/browser/rsc-router.tsx +145 -28
  127. package/src/browser/scroll-restoration.ts +37 -22
  128. package/src/browser/segment-reconciler.ts +31 -21
  129. package/src/browser/segment-structure-assert.ts +2 -2
  130. package/src/browser/server-action-bridge.ts +236 -65
  131. package/src/browser/types.ts +102 -9
  132. package/src/browser/validate-redirect-origin.ts +43 -16
  133. package/src/build/collect-fallback-refs.ts +107 -0
  134. package/src/build/generate-manifest.ts +203 -154
  135. package/src/build/generate-route-types.ts +3 -1
  136. package/src/build/index.ts +11 -3
  137. package/src/build/prefix-tree-utils.ts +123 -0
  138. package/src/build/route-trie.ts +152 -21
  139. package/src/build/route-types/ast-route-extraction.ts +15 -8
  140. package/src/build/route-types/codegen.ts +16 -5
  141. package/src/build/route-types/include-resolution.ts +456 -62
  142. package/src/build/route-types/param-extraction.ts +6 -3
  143. package/src/build/route-types/per-module-writer.ts +22 -6
  144. package/src/build/route-types/router-processing.ts +128 -51
  145. package/src/build/route-types/scan-filter.ts +1 -1
  146. package/src/build/route-types/source-scan.ts +216 -0
  147. package/src/build/runtime-discovery.ts +13 -21
  148. package/src/cache/cache-error.ts +104 -0
  149. package/src/cache/cache-key-utils.ts +58 -13
  150. package/src/cache/cache-policy.ts +108 -34
  151. package/src/cache/cache-runtime.ts +421 -58
  152. package/src/cache/cache-scope.ts +187 -96
  153. package/src/cache/cache-tag.ts +149 -0
  154. package/src/cache/cf/cf-base64.ts +33 -0
  155. package/src/cache/cf/cf-cache-constants.ts +127 -0
  156. package/src/cache/cf/cf-cache-store.ts +2202 -372
  157. package/src/cache/cf/cf-cache-types.ts +349 -0
  158. package/src/cache/cf/cf-kv-utils.ts +46 -0
  159. package/src/cache/cf/cf-tag-marker-memo.ts +105 -0
  160. package/src/cache/cf/index.ts +6 -16
  161. package/src/cache/document-cache.ts +126 -41
  162. package/src/cache/handle-snapshot.ts +70 -0
  163. package/src/cache/index.ts +23 -20
  164. package/src/cache/memory-segment-store.ts +243 -37
  165. package/src/cache/profile-registry.ts +46 -31
  166. package/src/cache/read-through-swr.ts +56 -12
  167. package/src/cache/segment-codec.ts +13 -21
  168. package/src/cache/shell-snapshot.ts +417 -0
  169. package/src/cache/tag-invalidation.ts +230 -0
  170. package/src/cache/types.ts +180 -99
  171. package/src/cache/vercel/index.ts +11 -0
  172. package/src/cache/vercel/vercel-cache-store.ts +1127 -0
  173. package/src/client.rsc.tsx +41 -21
  174. package/src/client.tsx +33 -61
  175. package/src/cloudflare/index.ts +11 -0
  176. package/src/cloudflare/tracing.ts +108 -0
  177. package/src/component-utils.ts +19 -0
  178. package/src/components/DefaultDocument.tsx +8 -2
  179. package/src/context-var.ts +18 -6
  180. package/src/decode-loader-results.ts +52 -0
  181. package/src/defer.ts +185 -0
  182. package/src/deps/ssr.ts +0 -1
  183. package/src/encode-kv.ts +49 -0
  184. package/src/errors.ts +30 -4
  185. package/src/escape-script.ts +52 -0
  186. package/src/handle.ts +67 -37
  187. package/src/handles/MetaTags.tsx +24 -53
  188. package/src/handles/Scripts.tsx +183 -0
  189. package/src/handles/breadcrumbs.ts +35 -8
  190. package/src/handles/deferred-resolution.ts +127 -0
  191. package/src/handles/is-thenable.ts +18 -0
  192. package/src/handles/meta.ts +14 -40
  193. package/src/handles/script.ts +244 -0
  194. package/src/host/cookie-handler.ts +9 -60
  195. package/src/host/errors.ts +13 -22
  196. package/src/host/index.ts +9 -2
  197. package/src/host/pattern-matcher.ts +23 -52
  198. package/src/host/router.ts +107 -99
  199. package/src/host/testing.ts +40 -27
  200. package/src/host/types.ts +37 -4
  201. package/src/host/utils.ts +1 -1
  202. package/src/href-client.ts +137 -22
  203. package/src/index.rsc.ts +97 -12
  204. package/src/index.ts +98 -14
  205. package/src/internal-debug.ts +11 -10
  206. package/src/loader-store.ts +500 -0
  207. package/src/loader.rsc.ts +20 -13
  208. package/src/loader.ts +12 -11
  209. package/src/missing-id-error.ts +68 -0
  210. package/src/outlet-context.ts +1 -1
  211. package/src/outlet-provider.tsx +1 -5
  212. package/src/prerender/param-hash.ts +16 -16
  213. package/src/prerender/store.ts +32 -37
  214. package/src/prerender.ts +78 -10
  215. package/src/redirect-origin.ts +114 -0
  216. package/src/regex-escape.ts +8 -0
  217. package/src/render-error-thrower.tsx +20 -0
  218. package/src/response-utils.ts +62 -0
  219. package/src/reverse.ts +65 -39
  220. package/src/root-error-boundary.tsx +1 -19
  221. package/src/route-content-wrapper.tsx +19 -77
  222. package/src/route-definition/dsl-helpers.ts +304 -309
  223. package/src/route-definition/helper-factories.ts +28 -140
  224. package/src/route-definition/helpers-types.ts +87 -59
  225. package/src/route-definition/index.ts +1 -2
  226. package/src/route-definition/redirect.ts +44 -11
  227. package/src/route-definition/resolve-handler-use.ts +12 -1
  228. package/src/route-definition/use-item-types.ts +29 -0
  229. package/src/route-map-builder.ts +41 -20
  230. package/src/route-types.ts +19 -46
  231. package/src/router/basename.ts +14 -0
  232. package/src/router/content-negotiation.ts +73 -25
  233. package/src/router/error-handling.ts +45 -18
  234. package/src/router/find-match.ts +129 -30
  235. package/src/router/handler-context.ts +27 -42
  236. package/src/router/instrument.ts +355 -0
  237. package/src/router/intercept-resolution.ts +39 -20
  238. package/src/router/lazy-includes.ts +82 -59
  239. package/src/router/loader-resolution.ts +167 -72
  240. package/src/router/logging.ts +0 -6
  241. package/src/router/manifest.ts +74 -40
  242. package/src/router/match-api.ts +80 -55
  243. package/src/router/match-context.ts +0 -22
  244. package/src/router/match-handlers.ts +211 -165
  245. package/src/router/match-middleware/background-revalidation.ts +40 -24
  246. package/src/router/match-middleware/cache-lookup.ts +159 -285
  247. package/src/router/match-middleware/cache-store.ts +64 -52
  248. package/src/router/match-middleware/intercept-resolution.ts +0 -22
  249. package/src/router/match-middleware/segment-resolution.ts +0 -22
  250. package/src/router/match-pipelines.ts +1 -42
  251. package/src/router/match-result.ts +69 -79
  252. package/src/router/metrics.ts +0 -34
  253. package/src/router/middleware-types.ts +7 -134
  254. package/src/router/middleware.ts +298 -172
  255. package/src/router/navigation-snapshot.ts +7 -56
  256. package/src/router/params-util.ts +23 -0
  257. package/src/router/parse-pattern.ts +115 -0
  258. package/src/router/pattern-matching.ts +181 -150
  259. package/src/router/prefetch-cache-ttl.ts +51 -0
  260. package/src/router/prefetch-limits.ts +37 -0
  261. package/src/router/prerender-match.ts +112 -67
  262. package/src/router/preview-match.ts +6 -2
  263. package/src/router/request-classification.ts +50 -69
  264. package/src/router/revalidation.ts +123 -73
  265. package/src/router/route-snapshot.ts +14 -3
  266. package/src/router/router-context.ts +6 -29
  267. package/src/router/router-interfaces.ts +115 -36
  268. package/src/router/router-options.ts +166 -5
  269. package/src/router/router-registry.ts +2 -5
  270. package/src/router/segment-resolution/fresh.ts +131 -86
  271. package/src/router/segment-resolution/helpers.ts +86 -6
  272. package/src/router/segment-resolution/loader-cache.ts +139 -39
  273. package/src/router/segment-resolution/loader-mask.ts +67 -0
  274. package/src/router/segment-resolution/loader-snapshot.ts +251 -0
  275. package/src/router/segment-resolution/revalidation.ts +272 -320
  276. package/src/router/segment-resolution/static-store.ts +19 -5
  277. package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
  278. package/src/router/segment-resolution/view-transition-default.ts +56 -0
  279. package/src/router/segment-resolution.ts +5 -1
  280. package/src/router/segment-wrappers.ts +6 -5
  281. package/src/router/state-cookie-name.ts +33 -0
  282. package/src/router/substitute-pattern-params.ts +75 -0
  283. package/src/router/telemetry-otel.ts +160 -200
  284. package/src/router/telemetry.ts +105 -20
  285. package/src/router/timeout.ts +0 -20
  286. package/src/router/tracing.ts +215 -0
  287. package/src/router/trie-matching.ts +171 -59
  288. package/src/router/types.ts +9 -63
  289. package/src/router/url-params.ts +57 -0
  290. package/src/router.ts +157 -71
  291. package/src/rsc/full-payload.ts +70 -0
  292. package/src/rsc/handler-context.ts +3 -2
  293. package/src/rsc/handler.ts +291 -217
  294. package/src/rsc/helpers.ts +168 -46
  295. package/src/rsc/index.ts +2 -5
  296. package/src/rsc/json-route-result.ts +38 -0
  297. package/src/rsc/loader-fetch.ts +114 -38
  298. package/src/rsc/manifest-init.ts +29 -42
  299. package/src/rsc/nonce.ts +10 -1
  300. package/src/rsc/origin-guard.ts +39 -25
  301. package/src/rsc/progressive-enhancement.ts +124 -13
  302. package/src/rsc/redirect-guard.ts +100 -0
  303. package/src/rsc/response-cache-serve.ts +238 -0
  304. package/src/rsc/response-error.ts +79 -12
  305. package/src/rsc/response-route-handler.ts +99 -189
  306. package/src/rsc/rsc-rendering.ts +421 -76
  307. package/src/rsc/runtime-warnings.ts +23 -10
  308. package/src/rsc/server-action.ts +282 -116
  309. package/src/rsc/shell-capture.ts +1158 -0
  310. package/src/rsc/shell-serve.ts +150 -0
  311. package/src/rsc/ssr-setup.ts +16 -0
  312. package/src/rsc/transition-gate.ts +89 -0
  313. package/src/rsc/types.ts +53 -5
  314. package/src/runtime-env.ts +18 -0
  315. package/src/search-params.ts +35 -30
  316. package/src/segment-loader-promise.ts +49 -4
  317. package/src/segment-system.tsx +350 -149
  318. package/src/serialize.ts +243 -0
  319. package/src/server/context.ts +208 -51
  320. package/src/server/cookie-parse.ts +32 -0
  321. package/src/server/cookie-store.ts +152 -5
  322. package/src/server/handle-store.ts +21 -38
  323. package/src/server/loader-registry.ts +33 -42
  324. package/src/server/request-context.ts +395 -176
  325. package/src/ssr/index.tsx +458 -178
  326. package/src/ssr/ssr-root.tsx +228 -0
  327. package/src/static-handler.ts +10 -13
  328. package/src/testing/cache-status.ts +162 -0
  329. package/src/testing/collect-handle.ts +46 -0
  330. package/src/testing/dispatch.ts +813 -0
  331. package/src/testing/dom.entry.ts +22 -0
  332. package/src/testing/e2e/fixture.ts +188 -0
  333. package/src/testing/e2e/index.ts +128 -0
  334. package/src/testing/e2e/matchers.ts +35 -0
  335. package/src/testing/e2e/page-helpers.ts +272 -0
  336. package/src/testing/e2e/parity.ts +387 -0
  337. package/src/testing/e2e/server.ts +195 -0
  338. package/src/testing/flight-matchers.ts +97 -0
  339. package/src/testing/flight-normalize.ts +11 -0
  340. package/src/testing/flight-runtime.d.ts +57 -0
  341. package/src/testing/flight-tree.ts +682 -0
  342. package/src/testing/flight.entry.ts +52 -0
  343. package/src/testing/flight.ts +257 -0
  344. package/src/testing/generated-routes.ts +199 -0
  345. package/src/testing/index.ts +105 -0
  346. package/src/testing/internal/context.ts +371 -0
  347. package/src/testing/internal/flight-client-globals.ts +30 -0
  348. package/src/testing/internal/seed-vars.ts +54 -0
  349. package/src/testing/render-handler.ts +357 -0
  350. package/src/testing/render-route.tsx +584 -0
  351. package/src/testing/run-loader.ts +385 -0
  352. package/src/testing/run-middleware.ts +205 -0
  353. package/src/testing/run-transition-when.ts +164 -0
  354. package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
  355. package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
  356. package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
  357. package/src/testing/vitest-stubs/version.ts +5 -0
  358. package/src/testing/vitest.ts +305 -0
  359. package/src/theme/ThemeProvider.tsx +56 -84
  360. package/src/theme/ThemeScript.tsx +7 -9
  361. package/src/theme/constants.ts +52 -13
  362. package/src/theme/index.ts +0 -7
  363. package/src/theme/theme-context.ts +1 -5
  364. package/src/theme/theme-script.ts +22 -21
  365. package/src/theme/use-theme.ts +0 -3
  366. package/src/types/boundaries.ts +0 -35
  367. package/src/types/cache-types.ts +13 -4
  368. package/src/types/error-types.ts +30 -90
  369. package/src/types/global-namespace.ts +54 -41
  370. package/src/types/handler-context.ts +110 -62
  371. package/src/types/index.ts +3 -10
  372. package/src/types/loader-types.ts +11 -9
  373. package/src/types/request-scope.ts +112 -0
  374. package/src/types/route-config.ts +20 -52
  375. package/src/types/route-entry.ts +0 -6
  376. package/src/types/segments.ts +135 -14
  377. package/src/urls/include-helper.ts +19 -64
  378. package/src/urls/include-provider.ts +71 -0
  379. package/src/urls/index.ts +2 -11
  380. package/src/urls/path-helper-types.ts +63 -17
  381. package/src/urls/path-helper.ts +22 -106
  382. package/src/urls/pattern-types.ts +72 -19
  383. package/src/urls/response-types.ts +22 -29
  384. package/src/urls/type-extraction.ts +98 -154
  385. package/src/urls/urls-function.ts +1 -19
  386. package/src/use-loader.tsx +292 -107
  387. package/src/vercel/index.ts +11 -0
  388. package/src/vercel/tracing.ts +88 -0
  389. package/src/vite/debug.ts +185 -0
  390. package/src/vite/discovery/bundle-postprocess.ts +8 -7
  391. package/src/vite/discovery/dev-prerender-cache.ts +117 -0
  392. package/src/vite/discovery/discover-routers.ts +127 -86
  393. package/src/vite/discovery/discovery-errors.ts +255 -0
  394. package/src/vite/discovery/gate-state.ts +171 -0
  395. package/src/vite/discovery/prerender-collection.ts +96 -68
  396. package/src/vite/discovery/route-types-writer.ts +40 -84
  397. package/src/vite/discovery/self-gen-tracking.ts +27 -1
  398. package/src/vite/discovery/state.ts +45 -1
  399. package/src/vite/discovery/virtual-module-codegen.ts +14 -34
  400. package/src/vite/index.ts +4 -0
  401. package/src/vite/inject-client-debug.ts +88 -0
  402. package/src/vite/plugin-types.ts +210 -10
  403. package/src/vite/plugins/cjs-to-esm.ts +16 -19
  404. package/src/vite/plugins/client-ref-dedup.ts +16 -11
  405. package/src/vite/plugins/client-ref-hashing.ts +28 -15
  406. package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
  407. package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  408. package/src/vite/plugins/cloudflare-protocol-stub.ts +194 -0
  409. package/src/vite/plugins/expose-action-id.ts +48 -95
  410. package/src/vite/plugins/expose-id-utils.ts +88 -55
  411. package/src/vite/plugins/expose-ids/export-analysis.ts +101 -34
  412. package/src/vite/plugins/expose-ids/handler-transform.ts +11 -90
  413. package/src/vite/plugins/expose-ids/loader-transform.ts +14 -24
  414. package/src/vite/plugins/expose-ids/router-transform.ts +118 -29
  415. package/src/vite/plugins/expose-internal-ids.ts +505 -486
  416. package/src/vite/plugins/performance-tracks.ts +26 -25
  417. package/src/vite/plugins/refresh-cmd.ts +1 -1
  418. package/src/vite/plugins/use-cache-transform.ts +73 -83
  419. package/src/vite/plugins/vercel-output.ts +384 -0
  420. package/src/vite/plugins/version-injector.ts +40 -29
  421. package/src/vite/plugins/version-plugin.ts +37 -40
  422. package/src/vite/plugins/virtual-entries.ts +138 -27
  423. package/src/vite/rango.ts +236 -138
  424. package/src/vite/router-discovery.ts +927 -136
  425. package/src/vite/utils/ast-handler-extract.ts +26 -35
  426. package/src/vite/utils/banner.ts +1 -1
  427. package/src/vite/utils/bundle-analysis.ts +10 -15
  428. package/src/vite/utils/client-chunks.ts +184 -0
  429. package/src/vite/utils/directive-prologue.ts +40 -0
  430. package/src/vite/utils/forward-user-plugins.ts +171 -0
  431. package/src/vite/utils/manifest-utils.ts +4 -59
  432. package/src/vite/utils/package-resolution.ts +20 -52
  433. package/src/vite/utils/prerender-utils.ts +71 -43
  434. package/src/vite/utils/shared-utils.ts +142 -43
  435. package/src/browser/action-response-classifier.ts +0 -99
  436. package/src/browser/react/use-client-cache.ts +0 -58
  437. package/src/browser/shallow.ts +0 -40
  438. package/src/handles/index.ts +0 -7
  439. package/src/network-error-thrower.tsx +0 -23
  440. package/src/router/middleware-cookies.ts +0 -55
@@ -32,6 +32,10 @@ Common reasons to migrate:
32
32
  - **Build-time rendering** — `Static()` and `Prerender()` provide explicit
33
33
  build-time rendering instead of mixing rendering and caching behind conventions.
34
34
  See: `/prerender`
35
+ - **Partial prerendering, shipped** — the `ppr` path option caches a page's
36
+ HTML shell and resumes only the live holes on each request; loaders stay
37
+ fresh. The equivalent of Next's `experimental_ppr`, stable and per-route.
38
+ See: `/ppr`
35
39
  - **Composable route tree** — layouts, includes, middleware, parallels, and
36
40
  intercepts compose directly in the route definition.
37
41
  See: `/composability`, `/parallel`, `/intercept`
@@ -43,6 +47,34 @@ Common reasons to migrate:
43
47
 
44
48
  Work route-by-route, bottom-up. Start with leaf pages, then layouts, then middleware. Verify each route works before moving to the next.
45
49
 
50
+ ## Replace imports, never shim Next
51
+
52
+ Do NOT create mock `next/*` modules, Vite aliases for `next/*`, or compatibility
53
+ wrapper components (a local `Link` that forwards `href` to `to`, a fake
54
+ `useRouter`, a stubbed `next/headers`). Shims freeze Next semantics into the
55
+ app, hide unsupported behavior until runtime, and keep `next` in the dependency
56
+ graph — the migration looks done but isn't. Replace every `next/*` import at
57
+ its call site with the real Rango API:
58
+
59
+ | Next import | Replace with |
60
+ | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
61
+ | `next/link` `Link` | `Link` from `@rangojs/router/client` — rename `href` to `to` (see §6) |
62
+ | `next/navigation` `useRouter`, `usePathname`, `useSearchParams`, `useParams` | same names from `@rangojs/router/client` |
63
+ | `next/navigation` `redirect`, `notFound` | `redirect`, `notFound` from `@rangojs/router` |
64
+ | `next/headers` `cookies`, `headers` | `cookies()`, `headers()` from `@rangojs/router` (server-only) |
65
+ | `next/cache` `revalidateTag`, `unstable_cache` | `updateTag`/`revalidateTag` from `@rangojs/router`; `"use cache"` (see §3 and `/use-cache`) |
66
+ | `next/server` `NextResponse`, `NextRequest` | web-standard `Response`/`Request`; middleware via `router.use()` (see §4) |
67
+ | `next/image` `Image` | plain `<img>` (keep explicit `width`/`height`) or your CDN's image URL — no built-in optimizer |
68
+ | `next/font` | see `/fonts` |
69
+ | `next/script` `Script` | see `/scripts` |
70
+ | `next-themes` | `theme: true` in `createRouter` (see §10) |
71
+
72
+ If an import has no row here and no obvious Rango equivalent, stop and surface
73
+ it to the user — do not mock it to keep the build green.
74
+
75
+ Done means: `grep -rn "from ['\"]next" src/ app/` returns nothing, and `next`
76
+ is gone from `package.json`.
77
+
46
78
  ## 1. Project Setup
47
79
 
48
80
  Replace Next.js tooling with Vite + Rango:
@@ -88,6 +120,21 @@ The Document component replaces `app/layout.tsx`'s `<html>` wrapper. See `/route
88
120
  | `app/shop/[...path]/page.tsx` | `path("/shop/:path+", CatchAll, { name: "shopCatchAll" })` |
89
121
  | `app/docs/[[...slug]]/page.tsx` | `path("/docs/:slug*", Docs, { name: "docs" })` |
90
122
 
123
+ The catch-all remainder is a single string at `ctx.params.<name>` with the `/`
124
+ separators preserved — split it to recover the array Next gives you:
125
+
126
+ ```typescript
127
+ // app/docs/[[...slug]]/page.tsx -> params.slug is string[] | undefined in Next
128
+ path("/docs/:slug*", (ctx) => {
129
+ // "" for /docs, "a/b/c" for /docs/a/b/c
130
+ const slug = ctx.params.slug === "" ? [] : ctx.params.slug.split("/");
131
+ return <Docs slug={slug} />;
132
+ }, { name: "docs" });
133
+ ```
134
+
135
+ `[...path]` (required, ≥1 segment) maps to `:path+`; `[[...slug]]` (optional,
136
+ matches the bare parent too) maps to `:slug*` — which binds `""` at `/docs`.
137
+
91
138
  ### Layouts
92
139
 
93
140
  ```typescript
@@ -153,6 +200,18 @@ export const marketingPatterns = urls(({ path }) => [
153
200
  include("/", marketingPatterns, { name: "marketing" }),
154
201
  ```
155
202
 
203
+ Next.js code-splits each route segment automatically. Rango's eager `include()`
204
+ bundles the group into the entry chunk; to get Next-style per-section splitting,
205
+ pass an async provider so the group loads on the first request under its prefix:
206
+
207
+ ```typescript
208
+ // urls/admin.tsx: `export default adminPatterns` — loads on first /admin request
209
+ include("/admin", () => import("./urls/admin"), { name: "admin" }),
210
+ ```
211
+
212
+ Route types, `href()`, and prerender still see every route in the split group.
213
+ See `/composability`.
214
+
156
215
  ### Parallel routes
157
216
 
158
217
  In Next.js, `@sidebar` and `@main` are both named slots. In Rango, the main content
@@ -193,9 +252,9 @@ The main content always goes through `<Outlet />` via the `path()` handler.
193
252
  // Rango: explicit intercept in layout
194
253
  layout(<ShopLayout />, () => [
195
254
  path("/product/:id", ProductPage, { name: "product" }),
196
- intercept("@modal", ".product", <ProductModal />, () => [
197
- when(({ from }) => from.pathname.startsWith("/shop")),
198
- ]),
255
+ intercept("@modal", ".product", <ProductModal />, {
256
+ when: ({ from }) => from.pathname.startsWith("/shop"),
257
+ }),
199
258
  ])
200
259
  ```
201
260
 
@@ -225,7 +284,7 @@ Loaders are Rango's live data layer. Use them when you need:
225
284
 
226
285
  - **Client-side data refresh** — `useLoader()` in client components for reactive data
227
286
  - **Per-loader caching** — opt in with `loader(MyLoader, () => [cache({ ttl: 60 })])`; loaders stay live by default
228
- - **Revalidation control** — `revalidate()` targets specific loaders after actions
287
+ - **Revalidation control** — `revalidate()` targets specific segments and loaders after actions
229
288
  - **Loading skeletons** — `loading()` shows a Suspense fallback while loaders resolve
230
289
 
231
290
  ```typescript
@@ -288,21 +347,136 @@ export const Product = Passthrough(ProductDef, async (ctx) => {
288
347
  Use `Passthrough()` whenever the Next.js route has `dynamicParams: true` (the
289
348
  default) or serves an open-ended param space. See `/prerender` for full API.
290
349
 
291
- ### Revalidation: different model
350
+ ### Rendering-mode segment config
351
+
352
+ Next.js route segment config maps onto Rango's explicit primitives:
353
+
354
+ | Next.js segment config | Rango |
355
+ | --------------------------------------------------- | ------------------------------------------------------------ |
356
+ | `dynamic = "force-static"` + `generateStaticParams` | `Static()` / `Prerender()` (see `/prerender`) |
357
+ | `revalidate = 60` (ISR) | `cache({ ttl: 60, swr: ... })` on the route (see `/caching`) |
358
+ | `dynamic = "force-dynamic"` | the default — routes are dynamic unless you cache them |
359
+ | `dynamicParams = true` | `Passthrough()` (above) |
360
+ | `experimental_ppr = true` | the `ppr` path option (below, and `/ppr`) |
361
+
362
+ ### Partial prerendering → the `ppr` path option
363
+
364
+ Next.js PPR statically prerenders a shell at build time and streams the parts
365
+ inside `<Suspense>` at request time. Rango ships the same model as a path
366
+ option — the shell is captured at runtime into the app cache store and resumed
367
+ on later requests, with the holes rendered fresh per request:
368
+
369
+ ```typescript
370
+ // Next.js: app/products/[id]/page.tsx
371
+ export const experimental_ppr = true;
372
+ export default async function Page({ params }) {
373
+ return (
374
+ <ProductShell>
375
+ <Suspense fallback={<PriceSkeleton />}>
376
+ <LivePrice id={params.id} />
377
+ </Suspense>
378
+ </ProductShell>
379
+ );
380
+ }
381
+
382
+ // Rango, step 1 — direct carry-over. Your Suspense tree IS the hole model:
383
+ // hand the un-awaited promise down, keep the boundary, add the ppr option.
384
+ // No loader, no loading(), no restructuring.
385
+ function ProductPage(ctx: HandlerContext) {
386
+ const price = fetchPrice(ctx.params.id); // pending promise — NOT awaited
387
+ return (
388
+ <ProductShell>
389
+ <Suspense fallback={<PriceSkeleton />}>
390
+ <LivePrice price={price} /> {/* use(price) inside */}
391
+ </Suspense>
392
+ </ProductShell>
393
+ );
394
+ }
395
+ path("/products/:id", ProductPage, {
396
+ name: "product",
397
+ ppr: { ttl: 600, swr: 120 }, // or ppr: true (default ttl 300s)
398
+ });
399
+
400
+ // Rango, step 2 (optional refinement) — promote the fetch to a loader for a
401
+ // GUARANTEED hole: loaders are masked at capture and fresh on every serve,
402
+ // even when the value resolves instantly (a raw promise that settles fast
403
+ // would bake into the shell). loading() is the loader's hole boundary.
404
+ path(
405
+ "/products/:id",
406
+ ProductPage,
407
+ { name: "product", ppr: { ttl: 600, swr: 120 } },
408
+ () => [loader(LivePriceLoader), loading(<PriceSkeleton />)],
409
+ ),
410
+ ```
411
+
412
+ Differences that matter during migration:
413
+
414
+ - **The Suspense/promise model carries over.** As in Next, a still-pending
415
+ promise handed to a component that suspends under its own `<Suspense>`
416
+ postpones at capture and becomes a hole — existing Next PPR trees keep
417
+ working as-is, no `loading()` required. One container rule everywhere
418
+ (handlers, handles, loaders): awaited/settled data bakes into the shell; a
419
+ promise nested inside your data stays a live hole. For loaders, `loading()`
420
+ selects the lane: present = guaranteed live (masked at capture, fresh every
421
+ serve, immune to fast resolution — prefer it for per-request data); absent =
422
+ the bake lane (the settled container bakes and is snapshot-pinned per shell,
423
+ nested promises stay live). Identity reads (`cookies()`/`headers()`) where
424
+ the value would bake refuse the capture by construction.
425
+ - **Shell freshness is explicit.** Next's PPR shell is fixed until the next
426
+ build; Rango's has `ttl`/`swr`/`tags` per route, and `updateTag()` /
427
+ `revalidateTag()` drop the shell (`revalidate()` does not — it is a data
428
+ lever and never touches shell HTML).
429
+ - **`cookies()`/`headers()` in shell material THROW during capture** (in Next
430
+ they silently force dynamic rendering). Per-user reads must move behind a
431
+ `loading()` boundary (the live loader lane) or into a nested promise — the
432
+ refusal surfaces at migration time, which is the point.
433
+ - **A store is required.** PPR needs the app-level `createRouter({ cache })`
434
+ store to implement the shell family (`MemorySegmentCacheStore`,
435
+ `CFCacheStore`, `VercelCacheStore`). Without one the route quietly stays
436
+ fully dynamic with a once-per-key warning.
437
+ - **Middleware still guards every serve.** Auth middleware (global or route
438
+ DSL) runs before any shell byte on HIT and MISS alike — no Next-style "PPR
439
+ bypasses middleware" caveats to migrate around.
440
+
441
+ A route without `ppr` pays zero cost. See `/ppr` for the full execution matrix,
442
+ hole rules, and pitfalls.
443
+
444
+ ### Revalidation: two distinct axes
445
+
446
+ Next.js conflates two things under "revalidation." Rango separates them — and
447
+ tag-based cache invalidation now maps directly.
448
+
449
+ **1. Cache invalidation (bust cached values) — direct equivalent.** Tag entries
450
+ with `cache({ tags })` or runtime `cacheTag(...tags)`. `cacheTag()` works inside a
451
+ `"use cache"` function (tags that entry) AND render-callable in a plain server
452
+ component (no `"use cache"` needed — it tags the document / PPR shell the component
453
+ renders into). Then invalidate by tag:
292
454
 
293
- Next.js uses path/tag-based cache invalidation (`revalidatePath`, `revalidateTag`)
294
- to bust cached responses. Rango does not currently have a direct equivalent.
455
+ ```typescript
456
+ // Next.js Rango
457
+ // revalidateTag("products") → await updateTag("products") // in a server action: awaitable,
458
+ // // read-your-own-writes (next render is fresh)
459
+ // or revalidateTag("products") // in a route handler / webhook:
460
+ // // background, non-blocking (hard-purge)
461
+ ```
295
462
 
296
- In Rango, separate these two concepts:
463
+ `updateTag` is awaitable and immediate; `revalidateTag` is fire-and-forget. Both
464
+ hard-purge (the next read re-renders fresh); the only difference is awaitability —
465
+ despite the Next.js name, `revalidateTag` here is NOT stale-while-revalidate.
466
+ Built-in stores (`MemorySegmentCacheStore`, `CFCacheStore`) index by tag. Next's
467
+ `revalidatePath` has no path-based equivalent — tag the relevant entries instead.
297
468
 
298
- **Partial rendering revalidation** `revalidate()` controls which segments
299
- (layouts, paths, loaders, parallels) should re-run during partial action
300
- re-rendering. This is about the segment tree, not cache invalidation:
469
+ **2. Partial-render selection (which segments re-run after an action).** This is
470
+ NOT cache invalidation it is `revalidate()`, controlling which segments
471
+ (layouts, paths, loaders, parallels) recompute during partial action
472
+ re-rendering:
301
473
 
302
474
  ```typescript
475
+ import { updateBlog } from "./actions/blog";
476
+
303
477
  // Re-run this layout when a blog action fires
304
478
  layout(BlogLayout, () => [
305
- revalidate(({ actionId }) => actionId?.includes("updateBlog") ?? false),
479
+ revalidate((ctx) => ctx.isAction(updateBlog) || undefined),
306
480
  path("/blog/:slug", BlogPost, { name: "blogPost" }),
307
481
  ]);
308
482
 
@@ -323,15 +497,18 @@ cache({ ttl: 60, swr: 300 }, () => [
323
497
  ]);
324
498
  ```
325
499
 
326
- The key shift is:
500
+ The two axes compose: `updateTag()` / `revalidateTag()` bust cached values;
501
+ `revalidate()` selects which segments re-render and stream to the client after an
502
+ action.
327
503
 
328
- - Next.js asks "which cached path or tag should I invalidate?"
329
- - Rango asks "which segments should re-run after this action?"
504
+ When migrating:
330
505
 
331
- When migrating `revalidatePath()` / `revalidateTag()` usage, the Rango version
332
- usually is not a 1:1 API replacement. Instead, decide which layouts, routes,
333
- loaders, or parallels should recompute after an action and declare
334
- `revalidate()` at those segment boundaries.
506
+ - `revalidateTag(tag)` `await updateTag(tag)` (in a server action) or
507
+ `revalidateTag(tag)` (in a route handler / webhook). Effectively 1:1.
508
+ - `revalidatePath(path)` no path-based equivalent; tag the entries on that
509
+ route (`cache({ tags })` / `cacheTag(...)`) and invalidate by tag.
510
+ - To also force specific segments to re-render after the action (independent of
511
+ cache busting), attach a `revalidate()` rule at those segment boundaries.
335
512
 
336
513
  ## 4. Middleware
337
514
 
@@ -463,6 +640,8 @@ Server actions work the same way — `"use server"` directive, `useActionState`,
463
640
 
464
641
  Key difference: in Rango, route middleware does NOT wrap action execution. Actions only see global middleware context. Use `getRequestContext()` in actions to access `ctx.set()`/`ctx.get()`.
465
642
 
643
+ Next.js's `revalidateTag()` maps directly: tag entries via `cache({ tags })` / `cacheTag(...)`, then invalidate. **In a server action use `await updateTag(tag)`** — it is read-your-own-writes, so the action's own re-render sees fresh data; `revalidateTag(tag)` is a background (non-blocking) hard-purge and is NOT read-your-own-writes, so reserve it for route handlers / webhooks (calling it from an action can leave that action's re-render stale). `revalidatePath()` has no path-based equivalent — tag the route's entries instead. Separately, to force specific matched segments (path/layout/parallel/intercept) and their loaders to re-render after an action, attach a `revalidate(({ actionId }) => ...)` rule to that segment or loader registration. See `/server-actions` for the full pattern (validation, error handling, file uploads), `/caching` for tag invalidation, and `/loader` for revalidation rule semantics.
644
+
466
645
  ## 8. Metadata / Head
467
646
 
468
647
  Rango uses the `Meta` handle + `<MetaTags />` client component:
@@ -557,4 +736,10 @@ See `/theme` for full API including system detection and cookie persistence.
557
736
  10. [ ] Migrate API routes to `path.json()` / `path.text()`
558
737
  11. [ ] Update metadata to use `Meta` handle + `<MetaTags />` in document head
559
738
  12. [ ] Replace `next-themes` with `theme: true` in createRouter (see `/theme`)
560
- 13. [ ] Run `npx rango generate src/` to generate route types
739
+ 13. [ ] Map rendering-mode segment config: `revalidate = N` `cache({ ttl })`,
740
+ `force-static` → `Static()`/`Prerender()`, `experimental_ppr` → the
741
+ `ppr` path option (loader + `loading()` as the hole)
742
+ 14. [ ] Run `npx rango generate src/` to generate route types
743
+ 15. [ ] Verify no shims: `grep -rn "from ['\"]next" src/ app/` returns nothing,
744
+ no mock `next/*` modules or aliases exist, and `next` is out of
745
+ `package.json`