@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
package/dist/bin/rango.js CHANGED
@@ -1,8 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  var __defProp = Object.defineProperty;
3
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
4
- var __esm = (fn, res) => function __init() {
5
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
4
+ var __esm = (fn, res, err) => function __init() {
5
+ if (err) throw err[0];
6
+ try {
7
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
+ } catch (e) {
9
+ throw err = [e], e;
10
+ }
6
11
  };
7
12
  var __export = (target, all) => {
8
13
  for (var name in all)
@@ -22,10 +27,10 @@ function extractParamsFromPattern(pattern) {
22
27
  function formatRouteEntry(key, pattern, _params, search) {
23
28
  const hasSearch = search && Object.keys(search).length > 0;
24
29
  if (!hasSearch) {
25
- return ` ${key}: "${pattern}",`;
30
+ return ` ${key}: ${JSON.stringify(pattern)},`;
26
31
  }
27
- const searchBody = Object.entries(search).map(([k, v]) => `${k}: "${v}"`).join(", ");
28
- return ` ${key}: { path: "${pattern}", search: { ${searchBody} } },`;
32
+ const searchBody = Object.entries(search).map(([k, v]) => `${k}: ${JSON.stringify(v)}`).join(", ");
33
+ return ` ${key}: { path: ${JSON.stringify(pattern)}, search: { ${searchBody} } },`;
29
34
  }
30
35
  var init_param_extraction = __esm({
31
36
  "src/build/route-types/param-extraction.ts"() {
@@ -59,8 +64,8 @@ var init_ast_helpers = __esm({
59
64
 
60
65
  // src/build/route-types/ast-route-extraction.ts
61
66
  import ts2 from "typescript";
62
- function extractRoutesFromSource(code) {
63
- const sourceFile = ts2.createSourceFile(
67
+ function extractRoutesFromSource(code, sourceFileArg) {
68
+ const sourceFile = sourceFileArg ?? ts2.createSourceFile(
64
69
  "input.tsx",
65
70
  code,
66
71
  ts2.ScriptTarget.Latest,
@@ -139,7 +144,7 @@ function generatePerModuleTypesSource(routes) {
139
144
  const valid = routes.filter(({ name }) => {
140
145
  if (!name || /["'\\`\n\r]/.test(name)) {
141
146
  console.warn(
142
- `[rsc-router] Skipping route with invalid name: ${JSON.stringify(name)}`
147
+ `[rango] Skipping route with invalid name: ${JSON.stringify(name)}`
143
148
  );
144
149
  return false;
145
150
  }
@@ -149,7 +154,7 @@ function generatePerModuleTypesSource(routes) {
149
154
  for (const { name, pattern, params, search } of valid) {
150
155
  if (deduped.has(name)) {
151
156
  console.warn(
152
- `[rsc-router] Duplicate route name "${name}" \u2014 keeping first definition`
157
+ `[rango] Duplicate route name "${name}" \u2014 keeping first definition`
153
158
  );
154
159
  continue;
155
160
  }
@@ -185,9 +190,13 @@ export const NamedRoutes = {
185
190
  ${objectBody}
186
191
  } as const;
187
192
 
193
+ // Aliased so the augmentation below does not pay a homomorphic mapped-type
194
+ // instantiation per route; \`as const\` already makes the members readonly.
195
+ type NamedRoutesShape = typeof NamedRoutes;
196
+
188
197
  declare global {
189
- namespace RSCRouter {
190
- interface GeneratedRouteMap extends Readonly<typeof NamedRoutes> {}
198
+ namespace Rango {
199
+ interface GeneratedRouteMap extends NamedRoutesShape {}
191
200
  }
192
201
  }
193
202
  `;
@@ -211,7 +220,7 @@ function findTsFiles(dir, filter) {
211
220
  entries = readdirSync(dir, { withFileTypes: true });
212
221
  } catch (err) {
213
222
  console.warn(
214
- `[rsc-router] Failed to scan directory ${dir}: ${err.message}`
223
+ `[rango] Failed to scan directory ${dir}: ${err.message}`
215
224
  );
216
225
  return results;
217
226
  }
@@ -238,6 +247,33 @@ var init_scan_filter = __esm({
238
247
  import { readFileSync, existsSync } from "node:fs";
239
248
  import { dirname, resolve } from "node:path";
240
249
  import ts3 from "typescript";
250
+ function createScanMemo() {
251
+ return { files: /* @__PURE__ */ new Map(), blockSourceFiles: /* @__PURE__ */ new Map() };
252
+ }
253
+ function parseBlock(memo, block) {
254
+ if (memo) {
255
+ const cached = memo.blockSourceFiles.get(block);
256
+ if (cached) return cached;
257
+ }
258
+ const sf = ts3.createSourceFile(
259
+ "input.tsx",
260
+ block,
261
+ ts3.ScriptTarget.Latest,
262
+ true,
263
+ ts3.ScriptKind.TSX
264
+ );
265
+ if (memo) memo.blockSourceFiles.set(block, sf);
266
+ return sf;
267
+ }
268
+ function readSourceMemoized(memo, realPath) {
269
+ if (memo) {
270
+ const cached = memo.files.get(realPath);
271
+ if (cached !== void 0) return cached;
272
+ }
273
+ const source = readFileSync(realPath, "utf-8");
274
+ if (memo) memo.files.set(realPath, source);
275
+ return source;
276
+ }
241
277
  function extractNamePrefixFromInclude(node) {
242
278
  if (node.arguments.length >= 3) {
243
279
  const thirdArg = node.arguments[2];
@@ -253,8 +289,98 @@ function extractNamePrefixFromInclude(node) {
253
289
  }
254
290
  return null;
255
291
  }
256
- function extractIncludesWithDiagnostics(code) {
257
- const sourceFile = ts3.createSourceFile(
292
+ function thenSelectsNonDefaultMember(expr) {
293
+ const findThenCall = (e) => {
294
+ if (ts3.isCallExpression(e) && ts3.isPropertyAccessExpression(e.expression) && e.expression.name.text === "then") {
295
+ return e;
296
+ }
297
+ if (ts3.isCallExpression(e) && ts3.isPropertyAccessExpression(e.expression)) {
298
+ return findThenCall(e.expression.expression);
299
+ }
300
+ if (ts3.isPropertyAccessExpression(e)) return findThenCall(e.expression);
301
+ if (ts3.isParenthesizedExpression(e)) return findThenCall(e.expression);
302
+ if (ts3.isAwaitExpression(e)) return findThenCall(e.expression);
303
+ return null;
304
+ };
305
+ const thenCall = findThenCall(expr);
306
+ if (!thenCall || thenCall.arguments.length === 0) return false;
307
+ const cb = thenCall.arguments[0];
308
+ if (!ts3.isArrowFunction(cb) && !ts3.isFunctionExpression(cb)) return false;
309
+ let ret;
310
+ if (ts3.isBlock(cb.body)) {
311
+ for (const stmt of cb.body.statements) {
312
+ if (ts3.isReturnStatement(stmt) && stmt.expression) {
313
+ ret = stmt.expression;
314
+ break;
315
+ }
316
+ }
317
+ } else {
318
+ ret = cb.body;
319
+ }
320
+ if (!ret) return false;
321
+ if (ts3.isPropertyAccessExpression(ret)) {
322
+ return ret.name.text !== "default";
323
+ }
324
+ return false;
325
+ }
326
+ function extractDynamicImportSpecifier(node) {
327
+ let body;
328
+ if (ts3.isArrowFunction(node) || ts3.isFunctionExpression(node)) {
329
+ body = node.body;
330
+ }
331
+ if (!body) return null;
332
+ let expr;
333
+ if (ts3.isBlock(body)) {
334
+ for (const stmt of body.statements) {
335
+ if (ts3.isReturnStatement(stmt) && stmt.expression) {
336
+ expr = stmt.expression;
337
+ break;
338
+ }
339
+ }
340
+ } else {
341
+ expr = body;
342
+ }
343
+ if (!expr) return null;
344
+ const findImportCall = (e) => {
345
+ if (ts3.isCallExpression(e) && e.expression.kind === ts3.SyntaxKind.ImportKeyword) {
346
+ return e;
347
+ }
348
+ if (ts3.isCallExpression(e) && ts3.isPropertyAccessExpression(e.expression)) {
349
+ return findImportCall(e.expression.expression);
350
+ }
351
+ if (ts3.isPropertyAccessExpression(e)) return findImportCall(e.expression);
352
+ if (ts3.isParenthesizedExpression(e)) return findImportCall(e.expression);
353
+ if (ts3.isAwaitExpression(e)) return findImportCall(e.expression);
354
+ return null;
355
+ };
356
+ const importCall = findImportCall(expr);
357
+ if (!importCall || importCall.arguments.length === 0) return null;
358
+ if (thenSelectsNonDefaultMember(expr)) return null;
359
+ return getStringValue(importCall.arguments[0]);
360
+ }
361
+ function resolveDefaultExportTarget(code, sourceFile) {
362
+ let result = null;
363
+ function visit(node) {
364
+ if (result) return;
365
+ if (ts3.isExportAssignment(node) && !node.isExportEquals) {
366
+ const expr = node.expression;
367
+ if (ts3.isIdentifier(expr)) {
368
+ result = { variableName: expr.text };
369
+ } else if (ts3.isCallExpression(expr)) {
370
+ const callee = expr.expression;
371
+ if (ts3.isIdentifier(callee) && callee.text === "urls") {
372
+ result = { inlineBlock: expr.getText(sourceFile) };
373
+ }
374
+ }
375
+ return;
376
+ }
377
+ ts3.forEachChild(node, visit);
378
+ }
379
+ visit(sourceFile);
380
+ return result;
381
+ }
382
+ function extractIncludesWithDiagnostics(code, sourceFileArg) {
383
+ const sourceFile = sourceFileArg ?? ts3.createSourceFile(
258
384
  "input.tsx",
259
385
  code,
260
386
  ts3.ScriptTarget.Latest,
@@ -278,12 +404,19 @@ function extractIncludesWithDiagnostics(code) {
278
404
  }
279
405
  const secondArg = node.arguments[1];
280
406
  const namePrefix = extractNamePrefixFromInclude(node);
407
+ const dynamicImportSpec = extractDynamicImportSpecifier(secondArg);
281
408
  if (ts3.isIdentifier(secondArg)) {
282
409
  resolved.push({
283
410
  pathPrefix,
284
411
  variableName: secondArg.text,
285
412
  namePrefix
286
413
  });
414
+ } else if (dynamicImportSpec !== null) {
415
+ resolved.push({
416
+ pathPrefix,
417
+ moduleSpecifier: dynamicImportSpec,
418
+ namePrefix
419
+ });
287
420
  } else if (ts3.isCallExpression(secondArg)) {
288
421
  const callText = secondArg.expression.getText(sourceFile);
289
422
  unresolvable.push({
@@ -308,7 +441,7 @@ function extractIncludesWithDiagnostics(code) {
308
441
  return { resolved, unresolvable };
309
442
  }
310
443
  function resolveImportedVariable(code, localName) {
311
- const importRegex = /import\s*\{([^}]+)\}\s*from\s*["']([^"']+)["']/g;
444
+ const importRegex = /import\s*(?:[\w$]+\s*,\s*)?\{([^}]+)\}\s*from\s*["']([^"']+)["']/g;
312
445
  let match;
313
446
  while ((match = importRegex.exec(code)) !== null) {
314
447
  const imports = match[1];
@@ -345,8 +478,8 @@ function resolveImportPath(importSpec, fromFile) {
345
478
  }
346
479
  return null;
347
480
  }
348
- function extractUrlsBlockForVariable(code, varName) {
349
- const sourceFile = ts3.createSourceFile(
481
+ function extractUrlsBlockForVariable(code, varName, sourceFileArg) {
482
+ const sourceFile = sourceFileArg ?? ts3.createSourceFile(
350
483
  "input.tsx",
351
484
  code,
352
485
  ts3.ScriptTarget.Latest,
@@ -368,67 +501,113 @@ function extractUrlsBlockForVariable(code, varName) {
368
501
  visit(sourceFile);
369
502
  return result;
370
503
  }
371
- function buildRouteMapFromBlock(block, fullSource, filePath, visited, searchSchemasOut, diagnosticsOut) {
504
+ function buildRouteMapFromBlock(block, fullSource, filePath, visited, searchSchemasOut, diagnosticsOut, memo) {
372
505
  const routeMap = {};
373
- const localRoutes = extractRoutesFromSource(block);
506
+ const blockSourceFile = parseBlock(memo, block);
507
+ const localRoutes = extractRoutesFromSource(block, blockSourceFile);
374
508
  for (const { name, pattern, search } of localRoutes) {
375
509
  routeMap[name] = pattern;
376
510
  if (search && searchSchemasOut) {
377
511
  searchSchemasOut[name] = search;
378
512
  }
379
513
  }
380
- const { resolved: includes, unresolvable } = extractIncludesWithDiagnostics(block);
514
+ const { resolved: includes, unresolvable } = extractIncludesWithDiagnostics(
515
+ block,
516
+ blockSourceFile
517
+ );
381
518
  if (diagnosticsOut) {
382
519
  for (const entry of unresolvable) {
383
520
  diagnosticsOut.push({ ...entry, sourceFile: filePath });
384
521
  }
385
522
  }
386
- for (const { pathPrefix, variableName, namePrefix } of includes) {
523
+ for (const inc of includes) {
524
+ const { pathPrefix, namePrefix } = inc;
387
525
  let childResult;
388
- const imported = resolveImportedVariable(fullSource, variableName);
389
- if (imported) {
390
- const targetFile = resolveImportPath(imported.specifier, filePath);
526
+ if (inc.moduleSpecifier) {
527
+ const targetFile = resolveImportPath(inc.moduleSpecifier, filePath);
391
528
  if (!targetFile) {
392
- if (diagnosticsOut) {
393
- diagnosticsOut.push({
394
- pathPrefix,
395
- namePrefix,
396
- reason: "file-not-found",
397
- sourceFile: filePath,
398
- detail: `import "${imported.specifier}" resolved to no file`
399
- });
400
- }
529
+ diagnosticsOut?.push({
530
+ pathPrefix,
531
+ namePrefix,
532
+ reason: "file-not-found",
533
+ sourceFile: filePath,
534
+ detail: `import("${inc.moduleSpecifier}") resolved to no file`
535
+ });
401
536
  continue;
402
537
  }
403
- childResult = buildCombinedRouteMapWithSearch(
404
- targetFile,
405
- imported.exportedName,
406
- visited,
407
- diagnosticsOut
408
- );
409
- } else {
410
- const sameFileBlock = extractUrlsBlockForVariable(
411
- fullSource,
412
- variableName
538
+ let targetSource;
539
+ try {
540
+ targetSource = readSourceMemoized(memo, resolve(targetFile));
541
+ } catch (err) {
542
+ diagnosticsOut?.push({
543
+ pathPrefix,
544
+ namePrefix,
545
+ reason: "file-not-found",
546
+ sourceFile: filePath,
547
+ detail: `import("${inc.moduleSpecifier}") resolved to "${targetFile}" but reading it failed: ${err?.message ?? String(err)}`
548
+ });
549
+ continue;
550
+ }
551
+ const def = resolveDefaultExportTarget(
552
+ targetSource,
553
+ parseBlock(memo, targetSource)
413
554
  );
414
- if (!sameFileBlock) {
415
- if (diagnosticsOut) {
416
- diagnosticsOut.push({
417
- pathPrefix,
418
- namePrefix,
419
- reason: "unresolvable-import",
420
- sourceFile: filePath,
421
- detail: `variable "${variableName}" not found in imports or same-file scope`
422
- });
423
- }
555
+ if (!def) {
556
+ diagnosticsOut?.push({
557
+ pathPrefix,
558
+ namePrefix,
559
+ reason: "unresolvable-import",
560
+ sourceFile: filePath,
561
+ detail: `import("${inc.moduleSpecifier}") has no resolvable \`export default urls(...)\``
562
+ });
424
563
  continue;
425
564
  }
426
- childResult = buildCombinedRouteMapWithSearch(
427
- filePath,
565
+ if (def.inlineBlock) {
566
+ childResult = buildCombinedRouteMapWithSearch(
567
+ targetFile,
568
+ void 0,
569
+ visited,
570
+ diagnosticsOut,
571
+ def.inlineBlock,
572
+ memo
573
+ );
574
+ } else {
575
+ const variableName = def.variableName;
576
+ const resolved = resolveIncludedVariable({
577
+ variableName,
578
+ resolutionFile: targetFile,
579
+ resolutionSource: targetSource,
580
+ reportFile: filePath,
581
+ memo,
582
+ visited,
583
+ diagnosticsOut,
584
+ pathPrefix,
585
+ namePrefix,
586
+ fileNotFoundDetail: (specifier) => `import("${inc.moduleSpecifier}") default re-exports "${variableName}" from "${specifier}", which resolved to no file`,
587
+ notFoundDetail: () => `import("${inc.moduleSpecifier}") default "${variableName}" not found in its imports or same-file scope`
588
+ });
589
+ if (!resolved) continue;
590
+ childResult = resolved;
591
+ }
592
+ } else if (inc.variableName) {
593
+ const variableName = inc.variableName;
594
+ const resolved = resolveIncludedVariable({
428
595
  variableName,
596
+ resolutionFile: filePath,
597
+ resolutionSource: fullSource,
598
+ reportFile: filePath,
599
+ memo,
429
600
  visited,
430
- diagnosticsOut
431
- );
601
+ diagnosticsOut,
602
+ pathPrefix,
603
+ namePrefix,
604
+ fileNotFoundDetail: (specifier) => `import "${specifier}" resolved to no file`,
605
+ notFoundDetail: () => `variable "${variableName}" not found in imports or same-file scope`
606
+ });
607
+ if (!resolved) continue;
608
+ childResult = resolved;
609
+ } else {
610
+ continue;
432
611
  }
433
612
  if (namePrefix === null) {
434
613
  continue;
@@ -451,18 +630,77 @@ function buildRouteMapFromBlock(block, fullSource, filePath, visited, searchSche
451
630
  }
452
631
  return routeMap;
453
632
  }
454
- function buildCombinedRouteMapWithSearch(filePath, variableName, visited, diagnosticsOut, inlineBlock) {
633
+ function resolveIncludedVariable(opts) {
634
+ const {
635
+ variableName,
636
+ resolutionFile,
637
+ resolutionSource,
638
+ reportFile,
639
+ memo,
640
+ visited,
641
+ diagnosticsOut,
642
+ pathPrefix,
643
+ namePrefix
644
+ } = opts;
645
+ const imported = resolveImportedVariable(resolutionSource, variableName);
646
+ if (imported) {
647
+ const targetFile = resolveImportPath(imported.specifier, resolutionFile);
648
+ if (!targetFile) {
649
+ diagnosticsOut?.push({
650
+ pathPrefix,
651
+ namePrefix,
652
+ reason: "file-not-found",
653
+ sourceFile: reportFile,
654
+ detail: opts.fileNotFoundDetail(imported.specifier)
655
+ });
656
+ return null;
657
+ }
658
+ return buildCombinedRouteMapWithSearch(
659
+ targetFile,
660
+ imported.exportedName,
661
+ visited,
662
+ diagnosticsOut,
663
+ void 0,
664
+ memo
665
+ );
666
+ }
667
+ const sameFileBlock = extractUrlsBlockForVariable(
668
+ resolutionSource,
669
+ variableName,
670
+ parseBlock(memo, resolutionSource)
671
+ );
672
+ if (!sameFileBlock) {
673
+ diagnosticsOut?.push({
674
+ pathPrefix,
675
+ namePrefix,
676
+ reason: "unresolvable-import",
677
+ sourceFile: reportFile,
678
+ detail: opts.notFoundDetail()
679
+ });
680
+ return null;
681
+ }
682
+ return buildCombinedRouteMapWithSearch(
683
+ resolutionFile,
684
+ variableName,
685
+ visited,
686
+ diagnosticsOut,
687
+ void 0,
688
+ memo
689
+ );
690
+ }
691
+ function buildCombinedRouteMapWithSearch(filePath, variableName, visited, diagnosticsOut, inlineBlock, memo) {
455
692
  visited = visited ?? /* @__PURE__ */ new Set();
693
+ memo = memo ?? createScanMemo();
456
694
  const realPath = resolve(filePath);
457
695
  const key = variableName ? `${realPath}:${variableName}` : realPath;
458
696
  if (visited.has(key)) {
459
- console.warn(`[rsc-router] Circular include detected, skipping: ${key}`);
697
+ console.warn(`[rango] Circular include detected, skipping: ${key}`);
460
698
  return { routes: {}, searchSchemas: {} };
461
699
  }
462
700
  visited.add(key);
463
701
  let source;
464
702
  try {
465
- source = readFileSync(realPath, "utf-8");
703
+ source = readSourceMemoized(memo, realPath);
466
704
  } catch {
467
705
  return { routes: {}, searchSchemas: {} };
468
706
  }
@@ -470,7 +708,11 @@ function buildCombinedRouteMapWithSearch(filePath, variableName, visited, diagno
470
708
  if (inlineBlock) {
471
709
  block = inlineBlock;
472
710
  } else if (variableName) {
473
- const extracted = extractUrlsBlockForVariable(source, variableName);
711
+ const extracted = extractUrlsBlockForVariable(
712
+ source,
713
+ variableName,
714
+ parseBlock(memo, source)
715
+ );
474
716
  if (!extracted) return { routes: {}, searchSchemas: {} };
475
717
  block = extracted;
476
718
  } else {
@@ -483,7 +725,8 @@ function buildCombinedRouteMapWithSearch(filePath, variableName, visited, diagno
483
725
  realPath,
484
726
  visited,
485
727
  searchSchemas,
486
- diagnosticsOut
728
+ diagnosticsOut,
729
+ memo
487
730
  );
488
731
  visited.delete(key);
489
732
  return { routes, searchSchemas };
@@ -528,8 +771,16 @@ function writePerModuleRouteTypesForFile(filePath) {
528
771
  let routes;
529
772
  if (varNames.length > 0) {
530
773
  routes = [];
774
+ const memo = createScanMemo();
531
775
  for (const varName of varNames) {
532
- const { routes: routeMap, searchSchemas } = buildCombinedRouteMapWithSearch(filePath, varName);
776
+ const { routes: routeMap, searchSchemas } = buildCombinedRouteMapWithSearch(
777
+ filePath,
778
+ varName,
779
+ void 0,
780
+ void 0,
781
+ void 0,
782
+ memo
783
+ );
533
784
  for (const [name, pattern] of Object.entries(routeMap)) {
534
785
  const params = extractParamsFromPattern(pattern);
535
786
  routes.push({
@@ -543,12 +794,12 @@ function writePerModuleRouteTypesForFile(filePath) {
543
794
  } else {
544
795
  routes = extractRoutesFromSource(source);
545
796
  }
546
- const genPath = filePath.replace(/\.(tsx?)$/, ".gen.ts");
797
+ const genPath = filePath.replace(/\.(tsx?|jsx?)$/, ".gen.ts");
547
798
  if (routes.length === 0) {
548
799
  if (varNames.length > 0 && !existsSync2(genPath)) {
549
800
  writeFileSync(genPath, generatePerModuleTypesSource([]));
550
801
  console.log(
551
- `[rsc-router] Generated route types (placeholder) -> ${genPath}`
802
+ `[rango] Generated route types (placeholder) -> ${genPath}`
552
803
  );
553
804
  }
554
805
  return;
@@ -557,11 +808,11 @@ function writePerModuleRouteTypesForFile(filePath) {
557
808
  const existing = existsSync2(genPath) ? readFileSync2(genPath, "utf-8") : null;
558
809
  if (existing !== genSource) {
559
810
  writeFileSync(genPath, genSource);
560
- console.log(`[rsc-router] Generated route types -> ${genPath}`);
811
+ console.log(`[rango] Generated route types -> ${genPath}`);
561
812
  }
562
813
  } catch (err) {
563
814
  console.warn(
564
- `[rsc-router] Failed to generate route types for ${filePath}: ${err.message}`
815
+ `[rango] Failed to generate route types for ${filePath}: ${err.message}`
565
816
  );
566
817
  }
567
818
  }
@@ -576,6 +827,131 @@ var init_per_module_writer = __esm({
576
827
  }
577
828
  });
578
829
 
830
+ // src/build/route-types/source-scan.ts
831
+ function isLineTerminator(ch) {
832
+ const c = ch.charCodeAt(0);
833
+ return c === 10 || c === 13 || c === 8232 || c === 8233;
834
+ }
835
+ function isRegexPositionAt(code, slashPos, prevChar) {
836
+ if (prevChar === void 0) return true;
837
+ if (prevChar === ")" || prevChar === "]" || prevChar === "}") return false;
838
+ if (!/[\w$]/.test(prevChar)) return true;
839
+ let k = slashPos - 1;
840
+ while (k >= 0 && /\s/.test(code[k])) k--;
841
+ const wordEnd = k + 1;
842
+ while (k >= 0 && /[\w$]/.test(code[k])) k--;
843
+ return REGEX_PRECEDING_KEYWORDS.has(code.slice(k + 1, wordEnd));
844
+ }
845
+ function makeCodeClassifier(code) {
846
+ const n = code.length;
847
+ let i = 0;
848
+ let skipStart = -1;
849
+ let skipEnd = -1;
850
+ let lastSig;
851
+ return (q) => {
852
+ if (q >= skipStart && q < skipEnd) return false;
853
+ while (i < n && i <= q) {
854
+ const c = code[i];
855
+ const d = i + 1 < n ? code[i + 1] : "";
856
+ let end = -1;
857
+ let transparent = false;
858
+ if (c === "/" && d === "/") {
859
+ let j = i + 2;
860
+ while (j < n && !isLineTerminator(code[j])) j++;
861
+ end = j;
862
+ transparent = true;
863
+ } else if (c === "/" && d === "*") {
864
+ let j = i + 2;
865
+ while (j < n && !(code[j] === "*" && code[j + 1] === "/")) j++;
866
+ end = Math.min(n, j + 2);
867
+ transparent = true;
868
+ } else if (c === '"' || c === "'" || c === "`") {
869
+ let j = i + 1;
870
+ while (j < n) {
871
+ if (code[j] === "\\") {
872
+ j += 2;
873
+ continue;
874
+ }
875
+ if (code[j] === c) {
876
+ j++;
877
+ break;
878
+ }
879
+ j++;
880
+ }
881
+ end = j;
882
+ } else if (c === "/" && d !== "/" && d !== "*" && isRegexPositionAt(code, i, lastSig)) {
883
+ let j = i + 1;
884
+ let inClass = false;
885
+ let closed = false;
886
+ while (j < n && !isLineTerminator(code[j])) {
887
+ const r = code[j];
888
+ if (r === "\\") {
889
+ j += 2;
890
+ continue;
891
+ }
892
+ if (r === "[") inClass = true;
893
+ else if (r === "]") inClass = false;
894
+ else if (r === "/" && !inClass) {
895
+ j++;
896
+ closed = true;
897
+ break;
898
+ }
899
+ j++;
900
+ }
901
+ if (closed) {
902
+ while (j < n && /[a-z]/.test(code[j])) j++;
903
+ end = j;
904
+ }
905
+ }
906
+ if (end >= 0) {
907
+ if (q < end) {
908
+ skipStart = i;
909
+ skipEnd = end;
910
+ return false;
911
+ }
912
+ i = end;
913
+ if (!transparent) lastSig = "x";
914
+ } else {
915
+ if (!/\s/.test(c)) lastSig = c;
916
+ i++;
917
+ }
918
+ }
919
+ return true;
920
+ };
921
+ }
922
+ function firstCodeMatchIndex(code, pattern) {
923
+ const inCode = makeCodeClassifier(code);
924
+ pattern.lastIndex = 0;
925
+ let m;
926
+ while ((m = pattern.exec(code)) !== null) {
927
+ if (inCode(m.index)) return m.index;
928
+ if (pattern.lastIndex <= m.index) pattern.lastIndex = m.index + 1;
929
+ }
930
+ return -1;
931
+ }
932
+ var REGEX_PRECEDING_KEYWORDS;
933
+ var init_source_scan = __esm({
934
+ "src/build/route-types/source-scan.ts"() {
935
+ "use strict";
936
+ REGEX_PRECEDING_KEYWORDS = /* @__PURE__ */ new Set([
937
+ "return",
938
+ "typeof",
939
+ "instanceof",
940
+ "in",
941
+ "of",
942
+ "new",
943
+ "delete",
944
+ "void",
945
+ "do",
946
+ "else",
947
+ "yield",
948
+ "await",
949
+ "case",
950
+ "throw"
951
+ ]);
952
+ }
953
+ });
954
+
579
955
  // src/build/route-types/router-processing.ts
580
956
  import {
581
957
  readFileSync as readFileSync3,
@@ -606,43 +982,50 @@ function countPublicRouteEntries(source) {
606
982
  function isRoutableSourceFile(name) {
607
983
  return (name.endsWith(".ts") || name.endsWith(".tsx") || name.endsWith(".js") || name.endsWith(".jsx")) && !name.includes(".gen.") && !name.includes(".test.") && !name.includes(".spec.");
608
984
  }
609
- function findRouterFilesRecursive(dir, filter, results) {
985
+ function isExcludedScanDir(name) {
986
+ return name === "node_modules" || name === "dist" || name === "coverage" || name === "__tests__" || name === "__mocks__" || name.startsWith(".");
987
+ }
988
+ function findCallSiteFilesRecursive(dir, pattern, patternG, stopAtMatchDir, filter, results) {
610
989
  let entries;
611
990
  try {
612
991
  entries = readdirSync2(dir, { withFileTypes: true });
613
992
  } catch (err) {
614
993
  console.warn(
615
- `[rsc-router] Failed to scan directory ${dir}: ${err.message}`
994
+ `[rango] Failed to scan directory ${dir}: ${err.message}`
616
995
  );
617
996
  return;
618
997
  }
619
998
  const childDirs = [];
620
- const routerFilesInDir = [];
999
+ const matchesInDir = [];
621
1000
  for (const entry of entries) {
622
1001
  const fullPath = join2(dir, entry.name);
623
1002
  if (entry.isDirectory()) {
624
- if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "coverage" || entry.name === "__tests__" || entry.name === "__mocks__" || entry.name.startsWith("."))
625
- continue;
626
- childDirs.push(fullPath);
1003
+ if (!isExcludedScanDir(entry.name)) childDirs.push(fullPath);
627
1004
  continue;
628
1005
  }
629
1006
  if (!isRoutableSourceFile(entry.name)) continue;
630
1007
  if (filter && !filter(fullPath)) continue;
631
1008
  try {
632
1009
  const source = readFileSync3(fullPath, "utf-8");
633
- if (ROUTER_CALL_PATTERN.test(source)) {
634
- routerFilesInDir.push(fullPath);
1010
+ if (pattern.test(source) && firstCodeMatchIndex(source, patternG) >= 0) {
1011
+ matchesInDir.push(fullPath);
635
1012
  }
636
1013
  } catch {
637
1014
  continue;
638
1015
  }
639
1016
  }
640
- if (routerFilesInDir.length > 0) {
641
- results.push(...routerFilesInDir);
642
- return;
643
- }
644
- for (const childDir of childDirs) {
645
- findRouterFilesRecursive(childDir, filter, results);
1017
+ results.push(...matchesInDir);
1018
+ if (!stopAtMatchDir || matchesInDir.length === 0) {
1019
+ for (const childDir of childDirs) {
1020
+ findCallSiteFilesRecursive(
1021
+ childDir,
1022
+ pattern,
1023
+ patternG,
1024
+ stopAtMatchDir,
1025
+ filter,
1026
+ results
1027
+ );
1028
+ }
646
1029
  }
647
1030
  }
648
1031
  function findNestedRouterConflict(routerFiles) {
@@ -668,7 +1051,7 @@ function findNestedRouterConflict(routerFiles) {
668
1051
  }
669
1052
  return null;
670
1053
  }
671
- function formatNestedRouterConflictError(conflict, prefix = "[rsc-router]") {
1054
+ function formatNestedRouterConflictError(conflict, prefix = "[rango]") {
672
1055
  return `${prefix} Nested router roots are not supported.
673
1056
  Router root: ${conflict.ancestor}
674
1057
  Nested router: ${conflict.nested}
@@ -764,19 +1147,38 @@ function extractBasenameFromRouter(code) {
764
1147
  visit(sourceFile);
765
1148
  return result;
766
1149
  }
767
- function applyBasenameToRoutes(result, basename2) {
1150
+ function applyBasenameToRoutes(result, basename) {
768
1151
  const prefixed = {};
769
1152
  for (const [name, pattern] of Object.entries(result.routes)) {
770
1153
  if (pattern === "/") {
771
- prefixed[name] = basename2;
772
- } else if (basename2.endsWith("/") && pattern.startsWith("/")) {
773
- prefixed[name] = basename2 + pattern.slice(1);
1154
+ prefixed[name] = basename;
1155
+ } else if (basename.endsWith("/") && pattern.startsWith("/")) {
1156
+ prefixed[name] = basename + pattern.slice(1);
774
1157
  } else {
775
- prefixed[name] = basename2 + pattern;
1158
+ prefixed[name] = basename + pattern;
776
1159
  }
777
1160
  }
778
1161
  return { routes: prefixed, searchSchemas: result.searchSchemas };
779
1162
  }
1163
+ function genFileTsPath(sourceFile) {
1164
+ const base = pathBasename(sourceFile).replace(/\.(tsx?|jsx?)$/, "");
1165
+ return join2(dirname2(sourceFile), `${base}.named-routes.gen.ts`);
1166
+ }
1167
+ function resolveSearchSchemas(publicRouteNames, runtimeSchemas, sourceFile) {
1168
+ if (runtimeSchemas && Object.keys(runtimeSchemas).length > 0) {
1169
+ return runtimeSchemas;
1170
+ }
1171
+ const staticParsed = buildCombinedRouteMapForRouterFile(sourceFile);
1172
+ if (Object.keys(staticParsed.searchSchemas).length === 0) {
1173
+ return runtimeSchemas;
1174
+ }
1175
+ const filtered = {};
1176
+ for (const name of publicRouteNames) {
1177
+ const schema = staticParsed.searchSchemas[name];
1178
+ if (schema) filtered[name] = schema;
1179
+ }
1180
+ return Object.keys(filtered).length > 0 ? filtered : runtimeSchemas;
1181
+ }
780
1182
  function buildCombinedRouteMapForRouterFile(routerFilePath) {
781
1183
  let routerSource;
782
1184
  try {
@@ -789,7 +1191,7 @@ function buildCombinedRouteMapForRouterFile(routerFilePath) {
789
1191
  return { routes: {}, searchSchemas: {} };
790
1192
  }
791
1193
  const rawBasename = extractBasenameFromRouter(routerSource);
792
- const basename2 = rawBasename ? ("/" + rawBasename.replace(/^\/+|\/+$/g, "")).replace(/^\/$/, "") : void 0;
1194
+ const basename = rawBasename ? ("/" + rawBasename.replace(/^\/+|\/+$/g, "")).replace(/^\/$/, "") : void 0;
793
1195
  let result;
794
1196
  if (extraction.kind === "inline") {
795
1197
  result = buildCombinedRouteMapWithSearch(
@@ -814,8 +1216,8 @@ function buildCombinedRouteMapForRouterFile(routerFilePath) {
814
1216
  result = buildCombinedRouteMapWithSearch(routerFilePath, extraction.name);
815
1217
  }
816
1218
  }
817
- if (basename2) {
818
- result = applyBasenameToRoutes(result, basename2);
1219
+ if (basename) {
1220
+ result = applyBasenameToRoutes(result, basename);
819
1221
  }
820
1222
  return result;
821
1223
  }
@@ -888,7 +1290,14 @@ function detectUnresolvableIncludesForUrlsFile(filePath) {
888
1290
  }
889
1291
  function findRouterFiles(root, filter) {
890
1292
  const result = [];
891
- findRouterFilesRecursive(root, filter, result);
1293
+ findCallSiteFilesRecursive(
1294
+ root,
1295
+ ROUTER_CALL_PATTERN,
1296
+ ROUTER_CALL_PATTERN_G,
1297
+ true,
1298
+ filter,
1299
+ result
1300
+ );
892
1301
  return result;
893
1302
  }
894
1303
  function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
@@ -897,7 +1306,7 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
897
1306
  if (existsSync3(oldCombinedPath)) {
898
1307
  unlinkSync(oldCombinedPath);
899
1308
  console.log(
900
- `[rsc-router] Removed stale combined route types: ${oldCombinedPath}`
1309
+ `[rango] Removed stale combined route types: ${oldCombinedPath}`
901
1310
  );
902
1311
  }
903
1312
  } catch {
@@ -919,18 +1328,12 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
919
1328
  }
920
1329
  if (!extractUrlsFromRouter(routerSource)) continue;
921
1330
  }
922
- const routerBasename = pathBasename(routerFilePath).replace(
923
- /\.(tsx?|jsx?)$/,
924
- ""
925
- );
926
- const outPath = join2(
927
- dirname2(routerFilePath),
928
- `${routerBasename}.named-routes.gen.ts`
929
- );
1331
+ const outPath = genFileTsPath(routerFilePath);
930
1332
  const existing = existsSync3(outPath) ? readFileSync3(outPath, "utf-8") : null;
931
1333
  if (Object.keys(result.routes).length === 0) {
932
1334
  if (!existing) {
933
1335
  const emptySource = generateRouteTypesSource({});
1336
+ opts?.onWrite?.(outPath, emptySource);
934
1337
  writeFileSync2(outPath, emptySource);
935
1338
  }
936
1339
  continue;
@@ -950,22 +1353,25 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
950
1353
  continue;
951
1354
  }
952
1355
  }
1356
+ opts?.onWrite?.(outPath, source);
953
1357
  writeFileSync2(outPath, source);
954
1358
  console.log(
955
- `[rsc-router] Generated route types (${Object.keys(result.routes).length} routes) -> ${outPath}`
1359
+ `[rango] Generated route types (${Object.keys(result.routes).length} routes) -> ${outPath}`
956
1360
  );
957
1361
  }
958
1362
  }
959
1363
  }
960
- var ROUTER_CALL_PATTERN;
1364
+ var ROUTER_CALL_PATTERN, ROUTER_CALL_PATTERN_G;
961
1365
  var init_router_processing = __esm({
962
1366
  "src/build/route-types/router-processing.ts"() {
963
1367
  "use strict";
964
1368
  init_codegen();
1369
+ init_source_scan();
965
1370
  init_include_resolution();
966
1371
  init_per_module_writer();
967
1372
  init_route_name();
968
1373
  ROUTER_CALL_PATTERN = /\bcreateRouter\s*[<(]/;
1374
+ ROUTER_CALL_PATTERN_G = /\bcreateRouter\s*[<(]/g;
969
1375
  }
970
1376
  });
971
1377
 
@@ -1003,7 +1409,7 @@ import {
1003
1409
  import { createElement, StrictMode } from "react";
1004
1410
  import { hydrateRoot } from "react-dom/client";
1005
1411
  import { rscStream } from "@rangojs/router/internal/deps/html-stream-client";
1006
- import { initBrowserApp, RSCRouter } from "@rangojs/router/browser";
1412
+ import { initBrowserApp, Rango } from "@rangojs/router/browser";
1007
1413
 
1008
1414
  async function initializeApp() {
1009
1415
  const deps = {
@@ -1014,11 +1420,16 @@ async function initializeApp() {
1014
1420
  createTemporaryReferenceSet,
1015
1421
  };
1016
1422
 
1017
- await initBrowserApp({ rscStream, deps });
1423
+ // initBrowserApp resolves the initial payload and returns the browser app
1424
+ // context, including strictMode (default true) from createRouter. StrictMode
1425
+ // is the default; createRouter({ strictMode: false }) ships the opt-out in the
1426
+ // payload metadata. StrictMode emits no DOM, so toggling never changes markup.
1427
+ const { strictMode } = await initBrowserApp({ rscStream, deps });
1018
1428
 
1429
+ const app = createElement(Rango);
1019
1430
  hydrateRoot(
1020
1431
  document,
1021
- createElement(StrictMode, null, createElement(RSCRouter))
1432
+ strictMode === false ? app : createElement(StrictMode, null, app)
1022
1433
  );
1023
1434
  }
1024
1435
 
@@ -1026,9 +1437,14 @@ initializeApp().catch(console.error);
1026
1437
  `.trim();
1027
1438
  VIRTUAL_ENTRY_SSR = `
1028
1439
  import { createFromReadableStream } from "@rangojs/router/internal/deps/ssr";
1029
- import { renderToReadableStream } from "react-dom/server.edge";
1440
+ import { renderToReadableStream, resume } from "react-dom/server.edge";
1441
+ import { prerender } from "react-dom/static.edge";
1030
1442
  import { injectRSCPayload } from "@rangojs/router/internal/deps/html-stream-server";
1031
- import { createSSRHandler } from "@rangojs/router/ssr";
1443
+ import {
1444
+ createSSRHandler,
1445
+ createShellCaptureHandler,
1446
+ createShellResumeHandler,
1447
+ } from "@rangojs/router/ssr";
1032
1448
 
1033
1449
  export const renderHTML = createSSRHandler({
1034
1450
  createFromReadableStream,
@@ -1037,6 +1453,26 @@ export const renderHTML = createSSRHandler({
1037
1453
  loadBootstrapScriptContent: () =>
1038
1454
  import.meta.viteRsc.loadBootstrapScriptContent("index"),
1039
1455
  });
1456
+
1457
+ export const captureShellHTML = createShellCaptureHandler({
1458
+ createFromReadableStream,
1459
+ renderToReadableStream,
1460
+ injectRSCPayload,
1461
+ prerender,
1462
+ resume,
1463
+ loadBootstrapScriptContent: () =>
1464
+ import.meta.viteRsc.loadBootstrapScriptContent("index"),
1465
+ });
1466
+
1467
+ export const resumeShellHTML = createShellResumeHandler({
1468
+ createFromReadableStream,
1469
+ renderToReadableStream,
1470
+ injectRSCPayload,
1471
+ prerender,
1472
+ resume,
1473
+ loadBootstrapScriptContent: () =>
1474
+ import.meta.viteRsc.loadBootstrapScriptContent("index"),
1475
+ });
1040
1476
  `.trim();
1041
1477
  VIRTUAL_IDS = {
1042
1478
  browser: "virtual:rsc-router/entry.browser.js",
@@ -1047,12 +1483,37 @@ export const renderHTML = createSSRHandler({
1047
1483
  }
1048
1484
  });
1049
1485
 
1486
+ // src/vite/utils/directive-prologue.ts
1487
+ import { parseAst } from "vite";
1488
+ function hasUseClientDirective(source) {
1489
+ let program;
1490
+ try {
1491
+ program = parseAst(source, { lang: "tsx" });
1492
+ } catch {
1493
+ return false;
1494
+ }
1495
+ for (const node of program.body ?? []) {
1496
+ if (node?.type === "ExpressionStatement" && node.expression?.type === "Literal" && typeof node.expression.value === "string") {
1497
+ if (node.expression.value === "use client") return true;
1498
+ continue;
1499
+ }
1500
+ break;
1501
+ }
1502
+ return false;
1503
+ }
1504
+ var init_directive_prologue = __esm({
1505
+ "src/vite/utils/directive-prologue.ts"() {
1506
+ "use strict";
1507
+ }
1508
+ });
1509
+
1050
1510
  // src/vite/plugins/version-plugin.ts
1051
1511
  var version_plugin_exports = {};
1052
1512
  __export(version_plugin_exports, {
1053
- createVersionPlugin: () => createVersionPlugin
1513
+ createVersionPlugin: () => createVersionPlugin,
1514
+ isViteDepCachePath: () => isViteDepCachePath
1054
1515
  });
1055
- import { parseAst } from "vite";
1516
+ import { parseAst as parseAst2 } from "vite";
1056
1517
  function isCodeModule(id) {
1057
1518
  return /\.(tsx?|jsx?)($|\?)/.test(id);
1058
1519
  }
@@ -1060,23 +1521,13 @@ function normalizeModuleId(id) {
1060
1521
  return id.split("?", 1)[0];
1061
1522
  }
1062
1523
  function getClientModuleSignature(source) {
1524
+ if (!hasUseClientDirective(source)) return void 0;
1063
1525
  let program;
1064
1526
  try {
1065
- program = parseAst(source, { jsx: true });
1527
+ program = parseAst2(source, { lang: "tsx" });
1066
1528
  } catch {
1067
1529
  return void 0;
1068
1530
  }
1069
- let isUseClient = false;
1070
- for (const node of program.body ?? []) {
1071
- if (node?.type === "ExpressionStatement" && node.expression?.type === "Literal" && typeof node.expression.value === "string") {
1072
- if (node.expression.value === "use client") {
1073
- isUseClient = true;
1074
- }
1075
- continue;
1076
- }
1077
- break;
1078
- }
1079
- if (!isUseClient) return void 0;
1080
1531
  const exports = /* @__PURE__ */ new Set();
1081
1532
  let hasDefault = false;
1082
1533
  let hasExportAll = false;
@@ -1145,11 +1596,12 @@ function createVersionPlugin() {
1145
1596
  let currentVersion = buildVersion;
1146
1597
  let isDev = false;
1147
1598
  let server = null;
1599
+ let resolvedCacheDir;
1148
1600
  const clientModuleSignatures = /* @__PURE__ */ new Map();
1149
1601
  let versionCounter = 0;
1150
1602
  const bumpVersion = (reason) => {
1151
1603
  currentVersion = Date.now().toString(16) + String(++versionCounter);
1152
- console.log(`[rsc-router] ${reason}, version updated: ${currentVersion}`);
1604
+ console.log(`[rango] ${reason}, version updated: ${currentVersion}`);
1153
1605
  const rscEnv = server?.environments?.rsc;
1154
1606
  const versionMod = rscEnv?.moduleGraph?.getModuleById(
1155
1607
  "\0" + VIRTUAL_IDS.version
@@ -1163,6 +1615,7 @@ function createVersionPlugin() {
1163
1615
  enforce: "pre",
1164
1616
  configResolved(config) {
1165
1617
  isDev = config.command === "serve";
1618
+ resolvedCacheDir = config.cacheDir ? String(config.cacheDir).replace(/\\/g, "/") : void 0;
1166
1619
  },
1167
1620
  configureServer(devServer) {
1168
1621
  server = devServer;
@@ -1199,11 +1652,11 @@ function createVersionPlugin() {
1199
1652
  }
1200
1653
  return null;
1201
1654
  },
1202
- // Track RSC module changes and update version
1203
1655
  async hotUpdate(ctx) {
1204
1656
  if (!isDev) return;
1205
1657
  const isRscModule = this.environment?.name === "rsc";
1206
1658
  if (!isRscModule) return;
1659
+ if (isViteDepCachePath(ctx.file, resolvedCacheDir)) return;
1207
1660
  if (ctx.modules.length === 1 && ctx.modules[0].id === "\0" + VIRTUAL_IDS.version) {
1208
1661
  return;
1209
1662
  }
@@ -1233,10 +1686,22 @@ function createVersionPlugin() {
1233
1686
  }
1234
1687
  };
1235
1688
  }
1689
+ function isViteDepCachePath(filePath, cacheDir) {
1690
+ if (!filePath) return false;
1691
+ const normalized = filePath.replace(/\\/g, "/");
1692
+ if (cacheDir) {
1693
+ const normalizedCacheDir = cacheDir.replace(/\\/g, "/").replace(/\/+$/, "");
1694
+ if (normalized === normalizedCacheDir || normalized.startsWith(normalizedCacheDir + "/")) {
1695
+ return true;
1696
+ }
1697
+ }
1698
+ return /\/node_modules\/\.vite[^/]*\//.test(normalized) || normalized.includes("/.vite-isolated/");
1699
+ }
1236
1700
  var init_version_plugin = __esm({
1237
1701
  "src/vite/plugins/version-plugin.ts"() {
1238
1702
  "use strict";
1239
1703
  init_virtual_entries();
1704
+ init_directive_prologue();
1240
1705
  }
1241
1706
  });
1242
1707
 
@@ -1278,7 +1743,7 @@ var runtime_discovery_exports = {};
1278
1743
  __export(runtime_discovery_exports, {
1279
1744
  discoverAndWriteRouteTypes: () => discoverAndWriteRouteTypes
1280
1745
  });
1281
- import { dirname as dirname3, join as join3, basename, resolve as resolve3 } from "node:path";
1746
+ import { resolve as resolve3 } from "node:path";
1282
1747
  import { existsSync as existsSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
1283
1748
  async function discoverAndWriteRouteTypes(opts) {
1284
1749
  let createViteServer;
@@ -1364,7 +1829,10 @@ async function discoverAndWriteRouteTypes(opts) {
1364
1829
  let routerMountIndex = 0;
1365
1830
  for (const [id, router] of registry) {
1366
1831
  if (!router.urlpatterns) continue;
1367
- const manifest = generateManifest(router.urlpatterns, routerMountIndex);
1832
+ const manifest = await generateManifest(
1833
+ router.urlpatterns,
1834
+ routerMountIndex
1835
+ );
1368
1836
  routerMountIndex++;
1369
1837
  const rawManifest = manifest.routeManifest;
1370
1838
  const routeManifest = {};
@@ -1388,22 +1856,12 @@ This means createRouter() stack trace parsing matched an internal frame.
1388
1856
  Set an explicit \`id\` on createRouter() or check the call site.`
1389
1857
  );
1390
1858
  }
1391
- if (!routeSearchSchemas || Object.keys(routeSearchSchemas).length === 0) {
1392
- const staticParsed = buildCombinedRouteMapForRouterFile(sourceFile);
1393
- if (Object.keys(staticParsed.searchSchemas).length > 0) {
1394
- const filtered = {};
1395
- for (const name of Object.keys(routeManifest)) {
1396
- const schema = staticParsed.searchSchemas[name];
1397
- if (schema) filtered[name] = schema;
1398
- }
1399
- if (Object.keys(filtered).length > 0) {
1400
- routeSearchSchemas = filtered;
1401
- }
1402
- }
1403
- }
1404
- const routerDir = dirname3(sourceFile);
1405
- const routerBasename = basename(sourceFile).replace(/\.(tsx?|jsx?)$/, "");
1406
- const outPath = join3(routerDir, `${routerBasename}.named-routes.gen.ts`);
1859
+ routeSearchSchemas = resolveSearchSchemas(
1860
+ Object.keys(routeManifest),
1861
+ routeSearchSchemas,
1862
+ sourceFile
1863
+ );
1864
+ const outPath = genFileTsPath(sourceFile);
1407
1865
  const source = generateRouteTypesSource(
1408
1866
  routeManifest,
1409
1867
  routeSearchSchemas && Object.keys(routeSearchSchemas).length > 0 ? routeSearchSchemas : void 0
@@ -1440,7 +1898,7 @@ var init_runtime_discovery = __esm({
1440
1898
 
1441
1899
  // src/bin/rango.ts
1442
1900
  init_generate_route_types();
1443
- import { resolve as resolve4, dirname as dirname4 } from "node:path";
1901
+ import { resolve as resolve4, dirname as dirname3 } from "node:path";
1444
1902
  import { readFileSync as readFileSync5, statSync, existsSync as existsSync5 } from "node:fs";
1445
1903
  var [command, ...rawArgs] = process.argv.slice(2);
1446
1904
  if (command === "generate") {
@@ -1511,12 +1969,12 @@ Examples:
1511
1969
  );
1512
1970
  }
1513
1971
  function findProjectRoot(fromPath) {
1514
- let dir = dirname4(resolve4(fromPath));
1515
- while (dir !== dirname4(dir)) {
1972
+ let dir = dirname3(resolve4(fromPath));
1973
+ while (dir !== dirname3(dir)) {
1516
1974
  if (existsSync5(resolve4(dir, "package.json")) || existsSync5(resolve4(dir, "vite.config.ts")) || existsSync5(resolve4(dir, "vite.config.js"))) {
1517
1975
  return dir;
1518
1976
  }
1519
- dir = dirname4(dir);
1977
+ dir = dirname3(dir);
1520
1978
  }
1521
1979
  return process.cwd();
1522
1980
  }