@rangojs/router 0.0.0-experimental.dfa55db4 → 0.0.0-experimental.e16b7c00

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 (1041) hide show
  1. package/README.md +120 -25
  2. package/dist/bin/rango.js +147 -57
  3. package/dist/vite/index.js +2108 -829
  4. package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  5. package/package.json +13 -8
  6. package/skills/breadcrumbs/SKILL.md +3 -1
  7. package/skills/bundle-analysis/SKILL.md +159 -0
  8. package/skills/cache-guide/SKILL.md +222 -30
  9. package/skills/caching/SKILL.md +188 -8
  10. package/skills/composability/SKILL.md +27 -2
  11. package/skills/document-cache/SKILL.md +78 -55
  12. package/skills/handler-use/SKILL.md +364 -0
  13. package/skills/hooks/SKILL.md +229 -20
  14. package/skills/host-router/SKILL.md +45 -20
  15. package/skills/i18n/SKILL.md +276 -0
  16. package/skills/intercept/SKILL.md +46 -4
  17. package/skills/layout/SKILL.md +28 -7
  18. package/skills/links/SKILL.md +247 -17
  19. package/skills/loader/SKILL.md +219 -9
  20. package/skills/middleware/SKILL.md +47 -12
  21. package/skills/migrate-nextjs/SKILL.md +582 -0
  22. package/skills/migrate-react-router/SKILL.md +769 -0
  23. package/skills/mime-routes/SKILL.md +27 -0
  24. package/skills/observability/SKILL.md +137 -0
  25. package/skills/parallel/SKILL.md +71 -6
  26. package/skills/prerender/SKILL.md +14 -33
  27. package/skills/rango/SKILL.md +236 -22
  28. package/skills/react-compiler/SKILL.md +168 -0
  29. package/skills/response-routes/SKILL.md +66 -9
  30. package/skills/route/SKILL.md +57 -4
  31. package/skills/router-setup/SKILL.md +3 -3
  32. package/skills/server-actions/SKILL.md +751 -0
  33. package/skills/streams-and-websockets/SKILL.md +283 -0
  34. package/skills/typesafety/SKILL.md +319 -27
  35. package/skills/use-cache/SKILL.md +36 -5
  36. package/skills/view-transitions/SKILL.md +294 -0
  37. package/src/__augment-tests__/augment.ts +81 -0
  38. package/src/__augment-tests__/augmented.check.ts +117 -0
  39. package/src/browser/action-coordinator.ts +53 -36
  40. package/src/browser/app-shell.ts +52 -0
  41. package/src/browser/event-controller.ts +86 -70
  42. package/src/browser/history-state.ts +21 -0
  43. package/src/browser/index.ts +3 -3
  44. package/src/browser/navigation-bridge.ts +86 -11
  45. package/src/browser/navigation-client.ts +76 -28
  46. package/src/browser/navigation-store.ts +32 -9
  47. package/src/browser/navigation-transaction.ts +10 -28
  48. package/src/browser/partial-update.ts +64 -26
  49. package/src/browser/prefetch/cache.ts +129 -21
  50. package/src/browser/prefetch/fetch.ts +148 -16
  51. package/src/browser/prefetch/queue.ts +36 -5
  52. package/src/browser/rango-state.ts +53 -13
  53. package/src/browser/react/Link.tsx +30 -2
  54. package/src/browser/react/NavigationProvider.tsx +72 -31
  55. package/src/browser/react/filter-segment-order.ts +51 -7
  56. package/src/browser/react/index.ts +3 -0
  57. package/src/browser/react/location-state-shared.ts +175 -4
  58. package/src/browser/react/location-state.ts +39 -13
  59. package/src/browser/react/use-handle.ts +17 -9
  60. package/src/browser/react/use-navigation.ts +22 -2
  61. package/src/browser/react/use-params.ts +20 -8
  62. package/src/browser/react/use-reverse.ts +106 -0
  63. package/src/browser/react/use-router.ts +22 -2
  64. package/src/browser/react/use-segments.ts +11 -8
  65. package/src/browser/response-adapter.ts +25 -0
  66. package/src/browser/rsc-router.tsx +64 -22
  67. package/src/browser/scroll-restoration.ts +22 -14
  68. package/src/browser/segment-reconciler.ts +36 -14
  69. package/src/browser/segment-structure-assert.ts +2 -2
  70. package/src/browser/server-action-bridge.ts +23 -30
  71. package/src/browser/types.ts +21 -0
  72. package/src/build/collect-fallback-refs.ts +107 -0
  73. package/src/build/generate-manifest.ts +60 -35
  74. package/src/build/generate-route-types.ts +2 -0
  75. package/src/build/index.ts +2 -0
  76. package/src/build/route-trie.ts +52 -25
  77. package/src/build/route-types/codegen.ts +4 -4
  78. package/src/build/route-types/include-resolution.ts +1 -1
  79. package/src/build/route-types/per-module-writer.ts +7 -4
  80. package/src/build/route-types/router-processing.ts +55 -14
  81. package/src/build/route-types/scan-filter.ts +1 -1
  82. package/src/build/route-types/source-scan.ts +118 -0
  83. package/src/build/runtime-discovery.ts +9 -20
  84. package/src/cache/cache-error.ts +104 -0
  85. package/src/cache/cache-policy.ts +95 -1
  86. package/src/cache/cache-runtime.ts +79 -13
  87. package/src/cache/cache-scope.ts +77 -46
  88. package/src/cache/cache-tag.ts +135 -0
  89. package/src/cache/cf/cf-cache-store.ts +1067 -176
  90. package/src/cache/cf/index.ts +4 -1
  91. package/src/cache/document-cache.ts +59 -7
  92. package/src/cache/index.ts +6 -0
  93. package/src/cache/memory-segment-store.ts +158 -14
  94. package/src/cache/tag-invalidation.ts +206 -0
  95. package/src/cache/types.ts +27 -0
  96. package/src/client.rsc.tsx +3 -0
  97. package/src/client.tsx +92 -182
  98. package/src/context-var.ts +5 -5
  99. package/src/decode-loader-results.ts +36 -0
  100. package/src/errors.ts +30 -1
  101. package/src/handle.ts +4 -6
  102. package/src/host/index.ts +2 -2
  103. package/src/host/router.ts +129 -57
  104. package/src/host/types.ts +31 -2
  105. package/src/host/utils.ts +1 -1
  106. package/src/href-client.ts +140 -20
  107. package/src/index.rsc.ts +16 -4
  108. package/src/index.ts +65 -15
  109. package/src/loader-store.ts +500 -0
  110. package/src/loader.rsc.ts +2 -5
  111. package/src/loader.ts +3 -10
  112. package/src/missing-id-error.ts +68 -0
  113. package/src/outlet-context.ts +1 -1
  114. package/src/prerender.ts +4 -4
  115. package/src/response-utils.ts +37 -0
  116. package/src/reverse.ts +65 -36
  117. package/src/route-content-wrapper.tsx +6 -28
  118. package/src/route-definition/dsl-helpers.ts +384 -257
  119. package/src/route-definition/helper-factories.ts +29 -139
  120. package/src/route-definition/helpers-types.ts +100 -28
  121. package/src/route-definition/resolve-handler-use.ts +6 -0
  122. package/src/route-definition/use-item-types.ts +32 -0
  123. package/src/route-types.ts +26 -41
  124. package/src/router/content-negotiation.ts +15 -2
  125. package/src/router/error-handling.ts +1 -1
  126. package/src/router/handler-context.ts +21 -38
  127. package/src/router/intercept-resolution.ts +4 -18
  128. package/src/router/lazy-includes.ts +8 -8
  129. package/src/router/loader-resolution.ts +19 -2
  130. package/src/router/manifest.ts +22 -13
  131. package/src/router/match-api.ts +4 -3
  132. package/src/router/match-handlers.ts +1 -0
  133. package/src/router/match-middleware/cache-lookup.ts +46 -92
  134. package/src/router/match-middleware/cache-store.ts +3 -2
  135. package/src/router/match-result.ts +103 -4
  136. package/src/router/metrics.ts +1 -1
  137. package/src/router/middleware-types.ts +15 -26
  138. package/src/router/middleware.ts +99 -84
  139. package/src/router/pattern-matching.ts +101 -17
  140. package/src/router/prerender-match.ts +3 -1
  141. package/src/router/preview-match.ts +3 -1
  142. package/src/router/request-classification.ts +4 -28
  143. package/src/router/revalidation.ts +58 -2
  144. package/src/router/router-interfaces.ts +45 -28
  145. package/src/router/router-options.ts +25 -1
  146. package/src/router/router-registry.ts +2 -5
  147. package/src/router/segment-resolution/fresh.ts +32 -6
  148. package/src/router/segment-resolution/loader-cache.ts +8 -17
  149. package/src/router/segment-resolution/revalidation.ts +154 -107
  150. package/src/router/segment-resolution/view-transition-default.ts +36 -0
  151. package/src/router/substitute-pattern-params.ts +56 -0
  152. package/src/router/trie-matching.ts +18 -13
  153. package/src/router/types.ts +8 -0
  154. package/src/router/url-params.ts +49 -0
  155. package/src/router.ts +23 -18
  156. package/src/rsc/handler-context.ts +2 -2
  157. package/src/rsc/handler.ts +46 -74
  158. package/src/rsc/helpers.ts +72 -43
  159. package/src/rsc/index.ts +1 -1
  160. package/src/rsc/origin-guard.ts +28 -10
  161. package/src/rsc/progressive-enhancement.ts +4 -0
  162. package/src/rsc/response-route-handler.ts +54 -54
  163. package/src/rsc/rsc-rendering.ts +35 -51
  164. package/src/rsc/runtime-warnings.ts +9 -10
  165. package/src/rsc/server-action.ts +17 -37
  166. package/src/rsc/ssr-setup.ts +16 -0
  167. package/src/rsc/types.ts +8 -2
  168. package/src/search-params.ts +4 -4
  169. package/src/segment-content-promise.ts +67 -0
  170. package/src/segment-loader-promise.ts +122 -0
  171. package/src/segment-system.tsx +132 -116
  172. package/src/serialize.ts +243 -0
  173. package/src/server/context.ts +143 -53
  174. package/src/server/cookie-store.ts +28 -4
  175. package/src/server/request-context.ts +46 -44
  176. package/src/ssr/index.tsx +5 -1
  177. package/src/static-handler.ts +1 -1
  178. package/src/types/cache-types.ts +13 -4
  179. package/src/types/error-types.ts +5 -1
  180. package/src/types/global-namespace.ts +39 -26
  181. package/src/types/handler-context.ts +68 -50
  182. package/src/types/index.ts +1 -0
  183. package/src/types/loader-types.ts +5 -6
  184. package/src/types/request-scope.ts +126 -0
  185. package/src/types/route-entry.ts +11 -0
  186. package/src/types/segments.ts +36 -2
  187. package/src/urls/include-helper.ts +34 -67
  188. package/src/urls/index.ts +0 -3
  189. package/src/urls/path-helper-types.ts +41 -7
  190. package/src/urls/path-helper.ts +17 -52
  191. package/src/urls/pattern-types.ts +36 -19
  192. package/src/urls/response-types.ts +22 -29
  193. package/src/urls/type-extraction.ts +26 -116
  194. package/src/urls/urls-function.ts +1 -5
  195. package/src/use-loader.tsx +416 -42
  196. package/src/vite/debug.ts +185 -0
  197. package/src/vite/discovery/bundle-postprocess.ts +6 -6
  198. package/src/vite/discovery/discover-routers.ts +101 -51
  199. package/src/vite/discovery/discovery-errors.ts +194 -0
  200. package/src/vite/discovery/gate-state.ts +171 -0
  201. package/src/vite/discovery/prerender-collection.ts +67 -26
  202. package/src/vite/discovery/route-types-writer.ts +40 -84
  203. package/src/vite/discovery/self-gen-tracking.ts +27 -1
  204. package/src/vite/discovery/state.ts +33 -0
  205. package/src/vite/discovery/virtual-module-codegen.ts +13 -23
  206. package/src/vite/index.ts +2 -0
  207. package/src/vite/plugin-types.ts +67 -0
  208. package/src/vite/plugins/cjs-to-esm.ts +8 -7
  209. package/src/vite/plugins/client-ref-dedup.ts +16 -0
  210. package/src/vite/plugins/client-ref-hashing.ts +28 -5
  211. package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
  212. package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  213. package/src/vite/plugins/cloudflare-protocol-stub.ts +214 -0
  214. package/src/vite/plugins/expose-action-id.ts +54 -30
  215. package/src/vite/plugins/expose-id-utils.ts +24 -8
  216. package/src/vite/plugins/expose-ids/export-analysis.ts +100 -20
  217. package/src/vite/plugins/expose-ids/handler-transform.ts +8 -61
  218. package/src/vite/plugins/expose-ids/loader-transform.ts +3 -5
  219. package/src/vite/plugins/expose-ids/router-transform.ts +20 -3
  220. package/src/vite/plugins/expose-internal-ids.ts +503 -468
  221. package/src/vite/plugins/performance-tracks.ts +29 -25
  222. package/src/vite/plugins/use-cache-transform.ts +65 -50
  223. package/src/vite/plugins/version-injector.ts +39 -23
  224. package/src/vite/plugins/version-plugin.ts +59 -2
  225. package/src/vite/plugins/virtual-entries.ts +2 -2
  226. package/src/vite/rango.ts +116 -29
  227. package/src/vite/router-discovery.ts +750 -100
  228. package/src/vite/utils/ast-handler-extract.ts +15 -15
  229. package/src/vite/utils/banner.ts +1 -1
  230. package/src/vite/utils/bundle-analysis.ts +4 -2
  231. package/src/vite/utils/client-chunks.ts +190 -0
  232. package/src/vite/utils/forward-user-plugins.ts +193 -0
  233. package/src/vite/utils/manifest-utils.ts +21 -5
  234. package/src/vite/utils/package-resolution.ts +41 -1
  235. package/src/vite/utils/prerender-utils.ts +21 -6
  236. package/src/vite/utils/shared-utils.ts +107 -26
  237. package/dist/__internal.d.ts +0 -83
  238. package/dist/__internal.d.ts.map +0 -1
  239. package/dist/__internal.js +0 -19
  240. package/dist/__internal.js.map +0 -1
  241. package/dist/__mocks__/version.d.ts +0 -7
  242. package/dist/__mocks__/version.d.ts.map +0 -1
  243. package/dist/__mocks__/version.js +0 -7
  244. package/dist/__mocks__/version.js.map +0 -1
  245. package/dist/__tests__/client-href.test.d.ts +0 -2
  246. package/dist/__tests__/client-href.test.d.ts.map +0 -1
  247. package/dist/__tests__/client-href.test.js +0 -74
  248. package/dist/__tests__/client-href.test.js.map +0 -1
  249. package/dist/__tests__/component-utils.test.d.ts +0 -2
  250. package/dist/__tests__/component-utils.test.d.ts.map +0 -1
  251. package/dist/__tests__/component-utils.test.js +0 -51
  252. package/dist/__tests__/component-utils.test.js.map +0 -1
  253. package/dist/__tests__/event-controller.test.d.ts +0 -2
  254. package/dist/__tests__/event-controller.test.d.ts.map +0 -1
  255. package/dist/__tests__/event-controller.test.js +0 -538
  256. package/dist/__tests__/event-controller.test.js.map +0 -1
  257. package/dist/__tests__/helpers/route-tree.d.ts +0 -118
  258. package/dist/__tests__/helpers/route-tree.d.ts.map +0 -1
  259. package/dist/__tests__/helpers/route-tree.js +0 -374
  260. package/dist/__tests__/helpers/route-tree.js.map +0 -1
  261. package/dist/__tests__/match-result.test.d.ts +0 -2
  262. package/dist/__tests__/match-result.test.d.ts.map +0 -1
  263. package/dist/__tests__/match-result.test.js +0 -154
  264. package/dist/__tests__/match-result.test.js.map +0 -1
  265. package/dist/__tests__/navigation-store.test.d.ts +0 -2
  266. package/dist/__tests__/navigation-store.test.d.ts.map +0 -1
  267. package/dist/__tests__/navigation-store.test.js +0 -440
  268. package/dist/__tests__/navigation-store.test.js.map +0 -1
  269. package/dist/__tests__/partial-update.test.d.ts +0 -2
  270. package/dist/__tests__/partial-update.test.d.ts.map +0 -1
  271. package/dist/__tests__/partial-update.test.js +0 -1009
  272. package/dist/__tests__/partial-update.test.js.map +0 -1
  273. package/dist/__tests__/reverse-types.test.d.ts +0 -8
  274. package/dist/__tests__/reverse-types.test.d.ts.map +0 -1
  275. package/dist/__tests__/reverse-types.test.js +0 -656
  276. package/dist/__tests__/reverse-types.test.js.map +0 -1
  277. package/dist/__tests__/route-definition.test.d.ts +0 -2
  278. package/dist/__tests__/route-definition.test.d.ts.map +0 -1
  279. package/dist/__tests__/route-definition.test.js +0 -55
  280. package/dist/__tests__/route-definition.test.js.map +0 -1
  281. package/dist/__tests__/router-helpers.test.d.ts +0 -2
  282. package/dist/__tests__/router-helpers.test.d.ts.map +0 -1
  283. package/dist/__tests__/router-helpers.test.js +0 -377
  284. package/dist/__tests__/router-helpers.test.js.map +0 -1
  285. package/dist/__tests__/router-integration-2.test.d.ts +0 -2
  286. package/dist/__tests__/router-integration-2.test.d.ts.map +0 -1
  287. package/dist/__tests__/router-integration-2.test.js +0 -426
  288. package/dist/__tests__/router-integration-2.test.js.map +0 -1
  289. package/dist/__tests__/router-integration.test.d.ts +0 -2
  290. package/dist/__tests__/router-integration.test.d.ts.map +0 -1
  291. package/dist/__tests__/router-integration.test.js +0 -1051
  292. package/dist/__tests__/router-integration.test.js.map +0 -1
  293. package/dist/__tests__/search-params.test.d.ts +0 -5
  294. package/dist/__tests__/search-params.test.d.ts.map +0 -1
  295. package/dist/__tests__/search-params.test.js +0 -306
  296. package/dist/__tests__/search-params.test.js.map +0 -1
  297. package/dist/__tests__/segment-system.test.d.ts +0 -2
  298. package/dist/__tests__/segment-system.test.d.ts.map +0 -1
  299. package/dist/__tests__/segment-system.test.js +0 -627
  300. package/dist/__tests__/segment-system.test.js.map +0 -1
  301. package/dist/__tests__/static-handler-types.test.d.ts +0 -8
  302. package/dist/__tests__/static-handler-types.test.d.ts.map +0 -1
  303. package/dist/__tests__/static-handler-types.test.js +0 -63
  304. package/dist/__tests__/static-handler-types.test.js.map +0 -1
  305. package/dist/__tests__/urls.test.d.ts +0 -2
  306. package/dist/__tests__/urls.test.d.ts.map +0 -1
  307. package/dist/__tests__/urls.test.js +0 -421
  308. package/dist/__tests__/urls.test.js.map +0 -1
  309. package/dist/__tests__/use-mount.test.d.ts +0 -2
  310. package/dist/__tests__/use-mount.test.d.ts.map +0 -1
  311. package/dist/__tests__/use-mount.test.js +0 -35
  312. package/dist/__tests__/use-mount.test.js.map +0 -1
  313. package/dist/bin/rango.d.ts +0 -2
  314. package/dist/bin/rango.d.ts.map +0 -1
  315. package/dist/bin/rango.js.map +0 -1
  316. package/dist/browser/event-controller.d.ts +0 -191
  317. package/dist/browser/event-controller.d.ts.map +0 -1
  318. package/dist/browser/event-controller.js +0 -559
  319. package/dist/browser/event-controller.js.map +0 -1
  320. package/dist/browser/index.d.ts +0 -2
  321. package/dist/browser/index.d.ts.map +0 -1
  322. package/dist/browser/index.js +0 -14
  323. package/dist/browser/index.js.map +0 -1
  324. package/dist/browser/link-interceptor.d.ts +0 -38
  325. package/dist/browser/link-interceptor.d.ts.map +0 -1
  326. package/dist/browser/link-interceptor.js +0 -99
  327. package/dist/browser/link-interceptor.js.map +0 -1
  328. package/dist/browser/logging.d.ts +0 -10
  329. package/dist/browser/logging.d.ts.map +0 -1
  330. package/dist/browser/logging.js +0 -29
  331. package/dist/browser/logging.js.map +0 -1
  332. package/dist/browser/lru-cache.d.ts +0 -17
  333. package/dist/browser/lru-cache.d.ts.map +0 -1
  334. package/dist/browser/lru-cache.js +0 -50
  335. package/dist/browser/lru-cache.js.map +0 -1
  336. package/dist/browser/merge-segment-loaders.d.ts +0 -39
  337. package/dist/browser/merge-segment-loaders.d.ts.map +0 -1
  338. package/dist/browser/merge-segment-loaders.js +0 -102
  339. package/dist/browser/merge-segment-loaders.js.map +0 -1
  340. package/dist/browser/navigation-bridge.d.ts +0 -102
  341. package/dist/browser/navigation-bridge.d.ts.map +0 -1
  342. package/dist/browser/navigation-bridge.js +0 -708
  343. package/dist/browser/navigation-bridge.js.map +0 -1
  344. package/dist/browser/navigation-client.d.ts +0 -25
  345. package/dist/browser/navigation-client.d.ts.map +0 -1
  346. package/dist/browser/navigation-client.js +0 -157
  347. package/dist/browser/navigation-client.js.map +0 -1
  348. package/dist/browser/navigation-store.d.ts +0 -101
  349. package/dist/browser/navigation-store.d.ts.map +0 -1
  350. package/dist/browser/navigation-store.js +0 -625
  351. package/dist/browser/navigation-store.js.map +0 -1
  352. package/dist/browser/partial-update.d.ts +0 -75
  353. package/dist/browser/partial-update.d.ts.map +0 -1
  354. package/dist/browser/partial-update.js +0 -426
  355. package/dist/browser/partial-update.js.map +0 -1
  356. package/dist/browser/react/Link.d.ts +0 -86
  357. package/dist/browser/react/Link.d.ts.map +0 -1
  358. package/dist/browser/react/Link.js +0 -128
  359. package/dist/browser/react/Link.js.map +0 -1
  360. package/dist/browser/react/NavigationProvider.d.ts +0 -63
  361. package/dist/browser/react/NavigationProvider.d.ts.map +0 -1
  362. package/dist/browser/react/NavigationProvider.js +0 -216
  363. package/dist/browser/react/NavigationProvider.js.map +0 -1
  364. package/dist/browser/react/ScrollRestoration.d.ts +0 -75
  365. package/dist/browser/react/ScrollRestoration.d.ts.map +0 -1
  366. package/dist/browser/react/ScrollRestoration.js +0 -57
  367. package/dist/browser/react/ScrollRestoration.js.map +0 -1
  368. package/dist/browser/react/context.d.ts +0 -46
  369. package/dist/browser/react/context.d.ts.map +0 -1
  370. package/dist/browser/react/context.js +0 -10
  371. package/dist/browser/react/context.js.map +0 -1
  372. package/dist/browser/react/index.d.ts +0 -11
  373. package/dist/browser/react/index.d.ts.map +0 -1
  374. package/dist/browser/react/index.js +0 -22
  375. package/dist/browser/react/index.js.map +0 -1
  376. package/dist/browser/react/location-state-shared.d.ts +0 -63
  377. package/dist/browser/react/location-state-shared.d.ts.map +0 -1
  378. package/dist/browser/react/location-state-shared.js +0 -81
  379. package/dist/browser/react/location-state-shared.js.map +0 -1
  380. package/dist/browser/react/location-state.d.ts +0 -23
  381. package/dist/browser/react/location-state.d.ts.map +0 -1
  382. package/dist/browser/react/location-state.js +0 -29
  383. package/dist/browser/react/location-state.js.map +0 -1
  384. package/dist/browser/react/mount-context.d.ts +0 -24
  385. package/dist/browser/react/mount-context.d.ts.map +0 -1
  386. package/dist/browser/react/mount-context.js +0 -24
  387. package/dist/browser/react/mount-context.js.map +0 -1
  388. package/dist/browser/react/use-action.d.ts +0 -64
  389. package/dist/browser/react/use-action.d.ts.map +0 -1
  390. package/dist/browser/react/use-action.js +0 -134
  391. package/dist/browser/react/use-action.js.map +0 -1
  392. package/dist/browser/react/use-client-cache.d.ts +0 -41
  393. package/dist/browser/react/use-client-cache.d.ts.map +0 -1
  394. package/dist/browser/react/use-client-cache.js +0 -39
  395. package/dist/browser/react/use-client-cache.js.map +0 -1
  396. package/dist/browser/react/use-handle.d.ts +0 -31
  397. package/dist/browser/react/use-handle.d.ts.map +0 -1
  398. package/dist/browser/react/use-handle.js +0 -144
  399. package/dist/browser/react/use-handle.js.map +0 -1
  400. package/dist/browser/react/use-href.d.ts +0 -33
  401. package/dist/browser/react/use-href.d.ts.map +0 -1
  402. package/dist/browser/react/use-href.js +0 -39
  403. package/dist/browser/react/use-href.js.map +0 -1
  404. package/dist/browser/react/use-link-status.d.ts +0 -37
  405. package/dist/browser/react/use-link-status.d.ts.map +0 -1
  406. package/dist/browser/react/use-link-status.js +0 -99
  407. package/dist/browser/react/use-link-status.js.map +0 -1
  408. package/dist/browser/react/use-mount.d.ts +0 -25
  409. package/dist/browser/react/use-mount.d.ts.map +0 -1
  410. package/dist/browser/react/use-mount.js +0 -30
  411. package/dist/browser/react/use-mount.js.map +0 -1
  412. package/dist/browser/react/use-navigation.d.ts +0 -27
  413. package/dist/browser/react/use-navigation.d.ts.map +0 -1
  414. package/dist/browser/react/use-navigation.js +0 -87
  415. package/dist/browser/react/use-navigation.js.map +0 -1
  416. package/dist/browser/react/use-segments.d.ts +0 -38
  417. package/dist/browser/react/use-segments.d.ts.map +0 -1
  418. package/dist/browser/react/use-segments.js +0 -130
  419. package/dist/browser/react/use-segments.js.map +0 -1
  420. package/dist/browser/request-controller.d.ts +0 -26
  421. package/dist/browser/request-controller.d.ts.map +0 -1
  422. package/dist/browser/request-controller.js +0 -147
  423. package/dist/browser/request-controller.js.map +0 -1
  424. package/dist/browser/rsc-router.d.ts +0 -129
  425. package/dist/browser/rsc-router.d.ts.map +0 -1
  426. package/dist/browser/rsc-router.js +0 -195
  427. package/dist/browser/rsc-router.js.map +0 -1
  428. package/dist/browser/scroll-restoration.d.ts +0 -93
  429. package/dist/browser/scroll-restoration.d.ts.map +0 -1
  430. package/dist/browser/scroll-restoration.js +0 -321
  431. package/dist/browser/scroll-restoration.js.map +0 -1
  432. package/dist/browser/segment-structure-assert.d.ts +0 -17
  433. package/dist/browser/segment-structure-assert.d.ts.map +0 -1
  434. package/dist/browser/segment-structure-assert.js +0 -59
  435. package/dist/browser/segment-structure-assert.js.map +0 -1
  436. package/dist/browser/server-action-bridge.d.ts +0 -26
  437. package/dist/browser/server-action-bridge.d.ts.map +0 -1
  438. package/dist/browser/server-action-bridge.js +0 -668
  439. package/dist/browser/server-action-bridge.js.map +0 -1
  440. package/dist/browser/shallow.d.ts +0 -12
  441. package/dist/browser/shallow.d.ts.map +0 -1
  442. package/dist/browser/shallow.js +0 -34
  443. package/dist/browser/shallow.js.map +0 -1
  444. package/dist/browser/types.d.ts +0 -369
  445. package/dist/browser/types.d.ts.map +0 -1
  446. package/dist/browser/types.js +0 -2
  447. package/dist/browser/types.js.map +0 -1
  448. package/dist/build/__tests__/generate-cli.test.d.ts +0 -2
  449. package/dist/build/__tests__/generate-cli.test.d.ts.map +0 -1
  450. package/dist/build/__tests__/generate-cli.test.js +0 -237
  451. package/dist/build/__tests__/generate-cli.test.js.map +0 -1
  452. package/dist/build/__tests__/generate-manifest.test.d.ts +0 -2
  453. package/dist/build/__tests__/generate-manifest.test.d.ts.map +0 -1
  454. package/dist/build/__tests__/generate-manifest.test.js +0 -119
  455. package/dist/build/__tests__/generate-manifest.test.js.map +0 -1
  456. package/dist/build/__tests__/generate-route-types.test.d.ts +0 -2
  457. package/dist/build/__tests__/generate-route-types.test.d.ts.map +0 -1
  458. package/dist/build/__tests__/generate-route-types.test.js +0 -620
  459. package/dist/build/__tests__/generate-route-types.test.js.map +0 -1
  460. package/dist/build/__tests__/per-router-manifest.test.d.ts +0 -2
  461. package/dist/build/__tests__/per-router-manifest.test.d.ts.map +0 -1
  462. package/dist/build/__tests__/per-router-manifest.test.js +0 -308
  463. package/dist/build/__tests__/per-router-manifest.test.js.map +0 -1
  464. package/dist/build/generate-manifest.d.ts +0 -81
  465. package/dist/build/generate-manifest.d.ts.map +0 -1
  466. package/dist/build/generate-manifest.js +0 -276
  467. package/dist/build/generate-manifest.js.map +0 -1
  468. package/dist/build/generate-route-types.d.ts +0 -115
  469. package/dist/build/generate-route-types.d.ts.map +0 -1
  470. package/dist/build/generate-route-types.js +0 -740
  471. package/dist/build/generate-route-types.js.map +0 -1
  472. package/dist/build/index.d.ts +0 -21
  473. package/dist/build/index.d.ts.map +0 -1
  474. package/dist/build/index.js +0 -21
  475. package/dist/build/index.js.map +0 -1
  476. package/dist/build/route-trie.d.ts +0 -71
  477. package/dist/build/route-trie.d.ts.map +0 -1
  478. package/dist/build/route-trie.js +0 -175
  479. package/dist/build/route-trie.js.map +0 -1
  480. package/dist/cache/__tests__/cache-scope.test.d.ts +0 -2
  481. package/dist/cache/__tests__/cache-scope.test.d.ts.map +0 -1
  482. package/dist/cache/__tests__/cache-scope.test.js +0 -208
  483. package/dist/cache/__tests__/cache-scope.test.js.map +0 -1
  484. package/dist/cache/__tests__/document-cache.test.d.ts +0 -2
  485. package/dist/cache/__tests__/document-cache.test.d.ts.map +0 -1
  486. package/dist/cache/__tests__/document-cache.test.js +0 -345
  487. package/dist/cache/__tests__/document-cache.test.js.map +0 -1
  488. package/dist/cache/__tests__/memory-segment-store.test.d.ts +0 -2
  489. package/dist/cache/__tests__/memory-segment-store.test.d.ts.map +0 -1
  490. package/dist/cache/__tests__/memory-segment-store.test.js +0 -425
  491. package/dist/cache/__tests__/memory-segment-store.test.js.map +0 -1
  492. package/dist/cache/__tests__/memory-store.test.d.ts +0 -2
  493. package/dist/cache/__tests__/memory-store.test.d.ts.map +0 -1
  494. package/dist/cache/__tests__/memory-store.test.js +0 -367
  495. package/dist/cache/__tests__/memory-store.test.js.map +0 -1
  496. package/dist/cache/cache-scope.d.ts +0 -102
  497. package/dist/cache/cache-scope.d.ts.map +0 -1
  498. package/dist/cache/cache-scope.js +0 -440
  499. package/dist/cache/cache-scope.js.map +0 -1
  500. package/dist/cache/cf/__tests__/cf-cache-store.test.d.ts +0 -2
  501. package/dist/cache/cf/__tests__/cf-cache-store.test.d.ts.map +0 -1
  502. package/dist/cache/cf/__tests__/cf-cache-store.test.js +0 -330
  503. package/dist/cache/cf/__tests__/cf-cache-store.test.js.map +0 -1
  504. package/dist/cache/cf/cf-cache-store.d.ts +0 -165
  505. package/dist/cache/cf/cf-cache-store.d.ts.map +0 -1
  506. package/dist/cache/cf/cf-cache-store.js +0 -242
  507. package/dist/cache/cf/cf-cache-store.js.map +0 -1
  508. package/dist/cache/cf/index.d.ts +0 -14
  509. package/dist/cache/cf/index.d.ts.map +0 -1
  510. package/dist/cache/cf/index.js +0 -17
  511. package/dist/cache/cf/index.js.map +0 -1
  512. package/dist/cache/document-cache.d.ts +0 -64
  513. package/dist/cache/document-cache.d.ts.map +0 -1
  514. package/dist/cache/document-cache.js +0 -228
  515. package/dist/cache/document-cache.js.map +0 -1
  516. package/dist/cache/index.d.ts +0 -19
  517. package/dist/cache/index.d.ts.map +0 -1
  518. package/dist/cache/index.js +0 -21
  519. package/dist/cache/index.js.map +0 -1
  520. package/dist/cache/memory-segment-store.d.ts +0 -110
  521. package/dist/cache/memory-segment-store.d.ts.map +0 -1
  522. package/dist/cache/memory-segment-store.js +0 -117
  523. package/dist/cache/memory-segment-store.js.map +0 -1
  524. package/dist/cache/memory-store.d.ts +0 -41
  525. package/dist/cache/memory-store.d.ts.map +0 -1
  526. package/dist/cache/memory-store.js +0 -191
  527. package/dist/cache/memory-store.js.map +0 -1
  528. package/dist/cache/types.d.ts +0 -317
  529. package/dist/cache/types.d.ts.map +0 -1
  530. package/dist/cache/types.js +0 -12
  531. package/dist/cache/types.js.map +0 -1
  532. package/dist/client.d.ts +0 -248
  533. package/dist/client.d.ts.map +0 -1
  534. package/dist/client.js +0 -367
  535. package/dist/client.js.map +0 -1
  536. package/dist/client.rsc.d.ts +0 -26
  537. package/dist/client.rsc.d.ts.map +0 -1
  538. package/dist/client.rsc.js +0 -46
  539. package/dist/client.rsc.js.map +0 -1
  540. package/dist/component-utils.d.ts +0 -36
  541. package/dist/component-utils.d.ts.map +0 -1
  542. package/dist/component-utils.js +0 -61
  543. package/dist/component-utils.js.map +0 -1
  544. package/dist/components/DefaultDocument.d.ts +0 -13
  545. package/dist/components/DefaultDocument.d.ts.map +0 -1
  546. package/dist/components/DefaultDocument.js +0 -15
  547. package/dist/components/DefaultDocument.js.map +0 -1
  548. package/dist/debug.d.ts +0 -58
  549. package/dist/debug.d.ts.map +0 -1
  550. package/dist/debug.js +0 -157
  551. package/dist/debug.js.map +0 -1
  552. package/dist/default-error-boundary.d.ts +0 -11
  553. package/dist/default-error-boundary.d.ts.map +0 -1
  554. package/dist/default-error-boundary.js +0 -45
  555. package/dist/default-error-boundary.js.map +0 -1
  556. package/dist/deps/browser.d.ts +0 -2
  557. package/dist/deps/browser.d.ts.map +0 -1
  558. package/dist/deps/browser.js +0 -3
  559. package/dist/deps/browser.js.map +0 -1
  560. package/dist/deps/html-stream-client.d.ts +0 -2
  561. package/dist/deps/html-stream-client.d.ts.map +0 -1
  562. package/dist/deps/html-stream-client.js +0 -3
  563. package/dist/deps/html-stream-client.js.map +0 -1
  564. package/dist/deps/html-stream-server.d.ts +0 -2
  565. package/dist/deps/html-stream-server.d.ts.map +0 -1
  566. package/dist/deps/html-stream-server.js +0 -3
  567. package/dist/deps/html-stream-server.js.map +0 -1
  568. package/dist/deps/rsc.d.ts +0 -2
  569. package/dist/deps/rsc.d.ts.map +0 -1
  570. package/dist/deps/rsc.js +0 -4
  571. package/dist/deps/rsc.js.map +0 -1
  572. package/dist/deps/ssr.d.ts +0 -2
  573. package/dist/deps/ssr.d.ts.map +0 -1
  574. package/dist/deps/ssr.js +0 -3
  575. package/dist/deps/ssr.js.map +0 -1
  576. package/dist/errors.d.ts +0 -174
  577. package/dist/errors.d.ts.map +0 -1
  578. package/dist/errors.js +0 -241
  579. package/dist/errors.js.map +0 -1
  580. package/dist/handle.d.ts +0 -78
  581. package/dist/handle.d.ts.map +0 -1
  582. package/dist/handle.js +0 -82
  583. package/dist/handle.js.map +0 -1
  584. package/dist/handles/MetaTags.d.ts +0 -14
  585. package/dist/handles/MetaTags.d.ts.map +0 -1
  586. package/dist/handles/MetaTags.js +0 -136
  587. package/dist/handles/MetaTags.js.map +0 -1
  588. package/dist/handles/index.d.ts +0 -6
  589. package/dist/handles/index.d.ts.map +0 -1
  590. package/dist/handles/index.js +0 -6
  591. package/dist/handles/index.js.map +0 -1
  592. package/dist/handles/meta.d.ts +0 -39
  593. package/dist/handles/meta.d.ts.map +0 -1
  594. package/dist/handles/meta.js +0 -202
  595. package/dist/handles/meta.js.map +0 -1
  596. package/dist/host/__tests__/errors.test.d.ts +0 -2
  597. package/dist/host/__tests__/errors.test.d.ts.map +0 -1
  598. package/dist/host/__tests__/errors.test.js +0 -76
  599. package/dist/host/__tests__/errors.test.js.map +0 -1
  600. package/dist/host/__tests__/pattern-comprehensive.test.d.ts +0 -2
  601. package/dist/host/__tests__/pattern-comprehensive.test.d.ts.map +0 -1
  602. package/dist/host/__tests__/pattern-comprehensive.test.js +0 -732
  603. package/dist/host/__tests__/pattern-comprehensive.test.js.map +0 -1
  604. package/dist/host/__tests__/pattern-matcher.test.d.ts +0 -2
  605. package/dist/host/__tests__/pattern-matcher.test.d.ts.map +0 -1
  606. package/dist/host/__tests__/pattern-matcher.test.js +0 -251
  607. package/dist/host/__tests__/pattern-matcher.test.js.map +0 -1
  608. package/dist/host/__tests__/router.test.d.ts +0 -2
  609. package/dist/host/__tests__/router.test.d.ts.map +0 -1
  610. package/dist/host/__tests__/router.test.js +0 -241
  611. package/dist/host/__tests__/router.test.js.map +0 -1
  612. package/dist/host/__tests__/testing.test.d.ts +0 -2
  613. package/dist/host/__tests__/testing.test.d.ts.map +0 -1
  614. package/dist/host/__tests__/testing.test.js +0 -64
  615. package/dist/host/__tests__/testing.test.js.map +0 -1
  616. package/dist/host/__tests__/utils.test.d.ts +0 -2
  617. package/dist/host/__tests__/utils.test.d.ts.map +0 -1
  618. package/dist/host/__tests__/utils.test.js +0 -29
  619. package/dist/host/__tests__/utils.test.js.map +0 -1
  620. package/dist/host/cookie-handler.d.ts +0 -34
  621. package/dist/host/cookie-handler.d.ts.map +0 -1
  622. package/dist/host/cookie-handler.js +0 -124
  623. package/dist/host/cookie-handler.js.map +0 -1
  624. package/dist/host/errors.d.ts +0 -56
  625. package/dist/host/errors.d.ts.map +0 -1
  626. package/dist/host/errors.js +0 -79
  627. package/dist/host/errors.js.map +0 -1
  628. package/dist/host/index.d.ts +0 -29
  629. package/dist/host/index.d.ts.map +0 -1
  630. package/dist/host/index.js +0 -32
  631. package/dist/host/index.js.map +0 -1
  632. package/dist/host/pattern-matcher.d.ts +0 -36
  633. package/dist/host/pattern-matcher.d.ts.map +0 -1
  634. package/dist/host/pattern-matcher.js +0 -172
  635. package/dist/host/pattern-matcher.js.map +0 -1
  636. package/dist/host/router.d.ts +0 -26
  637. package/dist/host/router.d.ts.map +0 -1
  638. package/dist/host/router.js +0 -218
  639. package/dist/host/router.js.map +0 -1
  640. package/dist/host/testing.d.ts +0 -36
  641. package/dist/host/testing.d.ts.map +0 -1
  642. package/dist/host/testing.js +0 -55
  643. package/dist/host/testing.js.map +0 -1
  644. package/dist/host/types.d.ts +0 -115
  645. package/dist/host/types.d.ts.map +0 -1
  646. package/dist/host/types.js +0 -7
  647. package/dist/host/types.js.map +0 -1
  648. package/dist/host/utils.d.ts +0 -21
  649. package/dist/host/utils.d.ts.map +0 -1
  650. package/dist/host/utils.js +0 -23
  651. package/dist/host/utils.js.map +0 -1
  652. package/dist/href-client.d.ts +0 -131
  653. package/dist/href-client.d.ts.map +0 -1
  654. package/dist/href-client.js +0 -64
  655. package/dist/href-client.js.map +0 -1
  656. package/dist/href-context.d.ts +0 -29
  657. package/dist/href-context.d.ts.map +0 -1
  658. package/dist/href-context.js +0 -21
  659. package/dist/href-context.js.map +0 -1
  660. package/dist/index.d.ts +0 -73
  661. package/dist/index.d.ts.map +0 -1
  662. package/dist/index.js +0 -91
  663. package/dist/index.js.map +0 -1
  664. package/dist/index.rsc.d.ts +0 -32
  665. package/dist/index.rsc.d.ts.map +0 -1
  666. package/dist/index.rsc.js +0 -40
  667. package/dist/index.rsc.js.map +0 -1
  668. package/dist/internal-debug.d.ts +0 -2
  669. package/dist/internal-debug.d.ts.map +0 -1
  670. package/dist/internal-debug.js +0 -5
  671. package/dist/internal-debug.js.map +0 -1
  672. package/dist/loader.d.ts +0 -14
  673. package/dist/loader.d.ts.map +0 -1
  674. package/dist/loader.js +0 -20
  675. package/dist/loader.js.map +0 -1
  676. package/dist/loader.rsc.d.ts +0 -19
  677. package/dist/loader.rsc.d.ts.map +0 -1
  678. package/dist/loader.rsc.js +0 -99
  679. package/dist/loader.rsc.js.map +0 -1
  680. package/dist/network-error-thrower.d.ts +0 -17
  681. package/dist/network-error-thrower.d.ts.map +0 -1
  682. package/dist/network-error-thrower.js +0 -14
  683. package/dist/network-error-thrower.js.map +0 -1
  684. package/dist/outlet-context.d.ts +0 -13
  685. package/dist/outlet-context.d.ts.map +0 -1
  686. package/dist/outlet-context.js +0 -3
  687. package/dist/outlet-context.js.map +0 -1
  688. package/dist/prerender/__tests__/param-hash.test.d.ts +0 -2
  689. package/dist/prerender/__tests__/param-hash.test.d.ts.map +0 -1
  690. package/dist/prerender/__tests__/param-hash.test.js +0 -148
  691. package/dist/prerender/__tests__/param-hash.test.js.map +0 -1
  692. package/dist/prerender/param-hash.d.ts +0 -16
  693. package/dist/prerender/param-hash.d.ts.map +0 -1
  694. package/dist/prerender/param-hash.js +0 -36
  695. package/dist/prerender/param-hash.js.map +0 -1
  696. package/dist/prerender/store.d.ts +0 -38
  697. package/dist/prerender/store.d.ts.map +0 -1
  698. package/dist/prerender/store.js +0 -61
  699. package/dist/prerender/store.js.map +0 -1
  700. package/dist/prerender.d.ts +0 -66
  701. package/dist/prerender.d.ts.map +0 -1
  702. package/dist/prerender.js +0 -57
  703. package/dist/prerender.js.map +0 -1
  704. package/dist/reverse.d.ts +0 -196
  705. package/dist/reverse.d.ts.map +0 -1
  706. package/dist/reverse.js +0 -78
  707. package/dist/reverse.js.map +0 -1
  708. package/dist/root-error-boundary.d.ts +0 -33
  709. package/dist/root-error-boundary.d.ts.map +0 -1
  710. package/dist/root-error-boundary.js +0 -165
  711. package/dist/root-error-boundary.js.map +0 -1
  712. package/dist/route-content-wrapper.d.ts +0 -46
  713. package/dist/route-content-wrapper.d.ts.map +0 -1
  714. package/dist/route-content-wrapper.js +0 -77
  715. package/dist/route-content-wrapper.js.map +0 -1
  716. package/dist/route-definition.d.ts +0 -421
  717. package/dist/route-definition.d.ts.map +0 -1
  718. package/dist/route-definition.js +0 -868
  719. package/dist/route-definition.js.map +0 -1
  720. package/dist/route-map-builder.d.ts +0 -155
  721. package/dist/route-map-builder.d.ts.map +0 -1
  722. package/dist/route-map-builder.js +0 -237
  723. package/dist/route-map-builder.js.map +0 -1
  724. package/dist/route-types.d.ts +0 -165
  725. package/dist/route-types.d.ts.map +0 -1
  726. package/dist/route-types.js +0 -7
  727. package/dist/route-types.js.map +0 -1
  728. package/dist/router/__tests__/handler-context.test.d.ts +0 -2
  729. package/dist/router/__tests__/handler-context.test.d.ts.map +0 -1
  730. package/dist/router/__tests__/handler-context.test.js +0 -65
  731. package/dist/router/__tests__/handler-context.test.js.map +0 -1
  732. package/dist/router/__tests__/loader-cycle-detection.test.d.ts +0 -2
  733. package/dist/router/__tests__/loader-cycle-detection.test.d.ts.map +0 -1
  734. package/dist/router/__tests__/loader-cycle-detection.test.js +0 -221
  735. package/dist/router/__tests__/loader-cycle-detection.test.js.map +0 -1
  736. package/dist/router/__tests__/match-context.test.d.ts +0 -2
  737. package/dist/router/__tests__/match-context.test.d.ts.map +0 -1
  738. package/dist/router/__tests__/match-context.test.js +0 -92
  739. package/dist/router/__tests__/match-context.test.js.map +0 -1
  740. package/dist/router/__tests__/match-pipelines.test.d.ts +0 -2
  741. package/dist/router/__tests__/match-pipelines.test.d.ts.map +0 -1
  742. package/dist/router/__tests__/match-pipelines.test.js +0 -417
  743. package/dist/router/__tests__/match-pipelines.test.js.map +0 -1
  744. package/dist/router/__tests__/match-result.test.d.ts +0 -2
  745. package/dist/router/__tests__/match-result.test.d.ts.map +0 -1
  746. package/dist/router/__tests__/match-result.test.js +0 -457
  747. package/dist/router/__tests__/match-result.test.js.map +0 -1
  748. package/dist/router/__tests__/on-error.test.d.ts +0 -2
  749. package/dist/router/__tests__/on-error.test.d.ts.map +0 -1
  750. package/dist/router/__tests__/on-error.test.js +0 -678
  751. package/dist/router/__tests__/on-error.test.js.map +0 -1
  752. package/dist/router/__tests__/pattern-matching.test.d.ts +0 -2
  753. package/dist/router/__tests__/pattern-matching.test.d.ts.map +0 -1
  754. package/dist/router/__tests__/pattern-matching.test.js +0 -629
  755. package/dist/router/__tests__/pattern-matching.test.js.map +0 -1
  756. package/dist/router/__tests__/segment-resolution-parallel-loading.test.d.ts +0 -2
  757. package/dist/router/__tests__/segment-resolution-parallel-loading.test.d.ts.map +0 -1
  758. package/dist/router/__tests__/segment-resolution-parallel-loading.test.js +0 -155
  759. package/dist/router/__tests__/segment-resolution-parallel-loading.test.js.map +0 -1
  760. package/dist/router/error-handling.d.ts +0 -77
  761. package/dist/router/error-handling.d.ts.map +0 -1
  762. package/dist/router/error-handling.js +0 -202
  763. package/dist/router/error-handling.js.map +0 -1
  764. package/dist/router/handler-context.d.ts +0 -20
  765. package/dist/router/handler-context.d.ts.map +0 -1
  766. package/dist/router/handler-context.js +0 -198
  767. package/dist/router/handler-context.js.map +0 -1
  768. package/dist/router/intercept-resolution.d.ts +0 -66
  769. package/dist/router/intercept-resolution.d.ts.map +0 -1
  770. package/dist/router/intercept-resolution.js +0 -246
  771. package/dist/router/intercept-resolution.js.map +0 -1
  772. package/dist/router/loader-resolution.d.ts +0 -64
  773. package/dist/router/loader-resolution.d.ts.map +0 -1
  774. package/dist/router/loader-resolution.js +0 -284
  775. package/dist/router/loader-resolution.js.map +0 -1
  776. package/dist/router/logging.d.ts +0 -15
  777. package/dist/router/logging.d.ts.map +0 -1
  778. package/dist/router/logging.js +0 -99
  779. package/dist/router/logging.js.map +0 -1
  780. package/dist/router/manifest.d.ts +0 -22
  781. package/dist/router/manifest.d.ts.map +0 -1
  782. package/dist/router/manifest.js +0 -181
  783. package/dist/router/manifest.js.map +0 -1
  784. package/dist/router/match-api.d.ts +0 -35
  785. package/dist/router/match-api.d.ts.map +0 -1
  786. package/dist/router/match-api.js +0 -406
  787. package/dist/router/match-api.js.map +0 -1
  788. package/dist/router/match-context.d.ts +0 -206
  789. package/dist/router/match-context.d.ts.map +0 -1
  790. package/dist/router/match-context.js +0 -17
  791. package/dist/router/match-context.js.map +0 -1
  792. package/dist/router/match-middleware/background-revalidation.d.ts +0 -127
  793. package/dist/router/match-middleware/background-revalidation.d.ts.map +0 -1
  794. package/dist/router/match-middleware/background-revalidation.js +0 -75
  795. package/dist/router/match-middleware/background-revalidation.js.map +0 -1
  796. package/dist/router/match-middleware/cache-lookup.d.ts +0 -112
  797. package/dist/router/match-middleware/cache-lookup.d.ts.map +0 -1
  798. package/dist/router/match-middleware/cache-lookup.js +0 -257
  799. package/dist/router/match-middleware/cache-lookup.js.map +0 -1
  800. package/dist/router/match-middleware/cache-store.d.ts +0 -113
  801. package/dist/router/match-middleware/cache-store.d.ts.map +0 -1
  802. package/dist/router/match-middleware/cache-store.js +0 -108
  803. package/dist/router/match-middleware/cache-store.js.map +0 -1
  804. package/dist/router/match-middleware/index.d.ts +0 -81
  805. package/dist/router/match-middleware/index.d.ts.map +0 -1
  806. package/dist/router/match-middleware/index.js +0 -80
  807. package/dist/router/match-middleware/index.js.map +0 -1
  808. package/dist/router/match-middleware/intercept-resolution.d.ts +0 -117
  809. package/dist/router/match-middleware/intercept-resolution.d.ts.map +0 -1
  810. package/dist/router/match-middleware/intercept-resolution.js +0 -134
  811. package/dist/router/match-middleware/intercept-resolution.js.map +0 -1
  812. package/dist/router/match-middleware/segment-resolution.d.ts +0 -99
  813. package/dist/router/match-middleware/segment-resolution.d.ts.map +0 -1
  814. package/dist/router/match-middleware/segment-resolution.js +0 -53
  815. package/dist/router/match-middleware/segment-resolution.js.map +0 -1
  816. package/dist/router/match-pipelines.d.ts +0 -147
  817. package/dist/router/match-pipelines.d.ts.map +0 -1
  818. package/dist/router/match-pipelines.js +0 -82
  819. package/dist/router/match-pipelines.js.map +0 -1
  820. package/dist/router/match-result.d.ts +0 -126
  821. package/dist/router/match-result.d.ts.map +0 -1
  822. package/dist/router/match-result.js +0 -93
  823. package/dist/router/match-result.js.map +0 -1
  824. package/dist/router/metrics.d.ts +0 -20
  825. package/dist/router/metrics.d.ts.map +0 -1
  826. package/dist/router/metrics.js +0 -47
  827. package/dist/router/metrics.js.map +0 -1
  828. package/dist/router/middleware.d.ts +0 -249
  829. package/dist/router/middleware.d.ts.map +0 -1
  830. package/dist/router/middleware.js +0 -434
  831. package/dist/router/middleware.js.map +0 -1
  832. package/dist/router/middleware.test.d.ts +0 -2
  833. package/dist/router/middleware.test.d.ts.map +0 -1
  834. package/dist/router/middleware.test.js +0 -816
  835. package/dist/router/middleware.test.js.map +0 -1
  836. package/dist/router/pattern-matching.d.ts +0 -149
  837. package/dist/router/pattern-matching.d.ts.map +0 -1
  838. package/dist/router/pattern-matching.js +0 -349
  839. package/dist/router/pattern-matching.js.map +0 -1
  840. package/dist/router/revalidation.d.ts +0 -44
  841. package/dist/router/revalidation.d.ts.map +0 -1
  842. package/dist/router/revalidation.js +0 -147
  843. package/dist/router/revalidation.js.map +0 -1
  844. package/dist/router/router-context.d.ts +0 -135
  845. package/dist/router/router-context.d.ts.map +0 -1
  846. package/dist/router/router-context.js +0 -36
  847. package/dist/router/router-context.js.map +0 -1
  848. package/dist/router/segment-resolution.d.ts +0 -127
  849. package/dist/router/segment-resolution.d.ts.map +0 -1
  850. package/dist/router/segment-resolution.js +0 -919
  851. package/dist/router/segment-resolution.js.map +0 -1
  852. package/dist/router/trie-matching.d.ts +0 -40
  853. package/dist/router/trie-matching.d.ts.map +0 -1
  854. package/dist/router/trie-matching.js +0 -127
  855. package/dist/router/trie-matching.js.map +0 -1
  856. package/dist/router/types.d.ts +0 -136
  857. package/dist/router/types.d.ts.map +0 -1
  858. package/dist/router/types.js +0 -7
  859. package/dist/router/types.js.map +0 -1
  860. package/dist/router.d.ts +0 -753
  861. package/dist/router.d.ts.map +0 -1
  862. package/dist/router.gen.d.ts +0 -6
  863. package/dist/router.gen.d.ts.map +0 -1
  864. package/dist/router.gen.js +0 -6
  865. package/dist/router.gen.js.map +0 -1
  866. package/dist/router.js +0 -1304
  867. package/dist/router.js.map +0 -1
  868. package/dist/rsc/__tests__/helpers.test.d.ts +0 -2
  869. package/dist/rsc/__tests__/helpers.test.d.ts.map +0 -1
  870. package/dist/rsc/__tests__/helpers.test.js +0 -140
  871. package/dist/rsc/__tests__/helpers.test.js.map +0 -1
  872. package/dist/rsc/handler.d.ts +0 -45
  873. package/dist/rsc/handler.d.ts.map +0 -1
  874. package/dist/rsc/handler.js +0 -1172
  875. package/dist/rsc/handler.js.map +0 -1
  876. package/dist/rsc/helpers.d.ts +0 -16
  877. package/dist/rsc/helpers.d.ts.map +0 -1
  878. package/dist/rsc/helpers.js +0 -55
  879. package/dist/rsc/helpers.js.map +0 -1
  880. package/dist/rsc/index.d.ts +0 -22
  881. package/dist/rsc/index.d.ts.map +0 -1
  882. package/dist/rsc/index.js +0 -23
  883. package/dist/rsc/index.js.map +0 -1
  884. package/dist/rsc/nonce.d.ts +0 -9
  885. package/dist/rsc/nonce.d.ts.map +0 -1
  886. package/dist/rsc/nonce.js +0 -18
  887. package/dist/rsc/nonce.js.map +0 -1
  888. package/dist/rsc/types.d.ts +0 -206
  889. package/dist/rsc/types.d.ts.map +0 -1
  890. package/dist/rsc/types.js +0 -8
  891. package/dist/rsc/types.js.map +0 -1
  892. package/dist/search-params.d.ts +0 -103
  893. package/dist/search-params.d.ts.map +0 -1
  894. package/dist/search-params.js +0 -74
  895. package/dist/search-params.js.map +0 -1
  896. package/dist/segment-system.d.ts +0 -75
  897. package/dist/segment-system.d.ts.map +0 -1
  898. package/dist/segment-system.js +0 -336
  899. package/dist/segment-system.js.map +0 -1
  900. package/dist/server/context.d.ts +0 -245
  901. package/dist/server/context.d.ts.map +0 -1
  902. package/dist/server/context.js +0 -197
  903. package/dist/server/context.js.map +0 -1
  904. package/dist/server/fetchable-loader-store.d.ts +0 -18
  905. package/dist/server/fetchable-loader-store.d.ts.map +0 -1
  906. package/dist/server/fetchable-loader-store.js +0 -18
  907. package/dist/server/fetchable-loader-store.js.map +0 -1
  908. package/dist/server/handle-store.d.ts +0 -85
  909. package/dist/server/handle-store.d.ts.map +0 -1
  910. package/dist/server/handle-store.js +0 -142
  911. package/dist/server/handle-store.js.map +0 -1
  912. package/dist/server/loader-registry.d.ts +0 -55
  913. package/dist/server/loader-registry.d.ts.map +0 -1
  914. package/dist/server/loader-registry.js +0 -132
  915. package/dist/server/loader-registry.js.map +0 -1
  916. package/dist/server/request-context.d.ts +0 -226
  917. package/dist/server/request-context.d.ts.map +0 -1
  918. package/dist/server/request-context.js +0 -290
  919. package/dist/server/request-context.js.map +0 -1
  920. package/dist/server/root-layout.d.ts +0 -4
  921. package/dist/server/root-layout.d.ts.map +0 -1
  922. package/dist/server/root-layout.js +0 -5
  923. package/dist/server/root-layout.js.map +0 -1
  924. package/dist/server.d.ts +0 -15
  925. package/dist/server.d.ts.map +0 -1
  926. package/dist/server.js +0 -20
  927. package/dist/server.js.map +0 -1
  928. package/dist/ssr/__tests__/ssr-handler.test.d.ts +0 -2
  929. package/dist/ssr/__tests__/ssr-handler.test.d.ts.map +0 -1
  930. package/dist/ssr/__tests__/ssr-handler.test.js +0 -132
  931. package/dist/ssr/__tests__/ssr-handler.test.js.map +0 -1
  932. package/dist/ssr/index.d.ts +0 -98
  933. package/dist/ssr/index.d.ts.map +0 -1
  934. package/dist/ssr/index.js +0 -158
  935. package/dist/ssr/index.js.map +0 -1
  936. package/dist/static-handler.d.ts +0 -50
  937. package/dist/static-handler.d.ts.map +0 -1
  938. package/dist/static-handler.gen.d.ts +0 -5
  939. package/dist/static-handler.gen.d.ts.map +0 -1
  940. package/dist/static-handler.gen.js +0 -5
  941. package/dist/static-handler.gen.js.map +0 -1
  942. package/dist/static-handler.js +0 -29
  943. package/dist/static-handler.js.map +0 -1
  944. package/dist/theme/ThemeProvider.d.ts +0 -20
  945. package/dist/theme/ThemeProvider.d.ts.map +0 -1
  946. package/dist/theme/ThemeProvider.js +0 -240
  947. package/dist/theme/ThemeProvider.js.map +0 -1
  948. package/dist/theme/ThemeScript.d.ts +0 -48
  949. package/dist/theme/ThemeScript.d.ts.map +0 -1
  950. package/dist/theme/ThemeScript.js +0 -13
  951. package/dist/theme/ThemeScript.js.map +0 -1
  952. package/dist/theme/__tests__/theme.test.d.ts +0 -2
  953. package/dist/theme/__tests__/theme.test.d.ts.map +0 -1
  954. package/dist/theme/__tests__/theme.test.js +0 -103
  955. package/dist/theme/__tests__/theme.test.js.map +0 -1
  956. package/dist/theme/constants.d.ts +0 -29
  957. package/dist/theme/constants.d.ts.map +0 -1
  958. package/dist/theme/constants.js +0 -48
  959. package/dist/theme/constants.js.map +0 -1
  960. package/dist/theme/index.d.ts +0 -31
  961. package/dist/theme/index.d.ts.map +0 -1
  962. package/dist/theme/index.js +0 -36
  963. package/dist/theme/index.js.map +0 -1
  964. package/dist/theme/theme-context.d.ts +0 -40
  965. package/dist/theme/theme-context.d.ts.map +0 -1
  966. package/dist/theme/theme-context.js +0 -60
  967. package/dist/theme/theme-context.js.map +0 -1
  968. package/dist/theme/theme-script.d.ts +0 -27
  969. package/dist/theme/theme-script.d.ts.map +0 -1
  970. package/dist/theme/theme-script.js +0 -147
  971. package/dist/theme/theme-script.js.map +0 -1
  972. package/dist/theme/types.d.ts +0 -163
  973. package/dist/theme/types.d.ts.map +0 -1
  974. package/dist/theme/types.js +0 -11
  975. package/dist/theme/types.js.map +0 -1
  976. package/dist/theme/use-theme.d.ts +0 -12
  977. package/dist/theme/use-theme.d.ts.map +0 -1
  978. package/dist/theme/use-theme.js +0 -40
  979. package/dist/theme/use-theme.js.map +0 -1
  980. package/dist/types.d.ts +0 -1479
  981. package/dist/types.d.ts.map +0 -1
  982. package/dist/types.js +0 -10
  983. package/dist/types.js.map +0 -1
  984. package/dist/urls.d.ts +0 -441
  985. package/dist/urls.d.ts.map +0 -1
  986. package/dist/urls.gen.d.ts +0 -8
  987. package/dist/urls.gen.d.ts.map +0 -1
  988. package/dist/urls.gen.js +0 -8
  989. package/dist/urls.gen.js.map +0 -1
  990. package/dist/urls.js +0 -443
  991. package/dist/urls.js.map +0 -1
  992. package/dist/use-loader.d.ts +0 -127
  993. package/dist/use-loader.d.ts.map +0 -1
  994. package/dist/use-loader.js +0 -237
  995. package/dist/use-loader.js.map +0 -1
  996. package/dist/vite/__tests__/ast-handler-extract.test.d.ts +0 -2
  997. package/dist/vite/__tests__/ast-handler-extract.test.d.ts.map +0 -1
  998. package/dist/vite/__tests__/ast-handler-extract.test.js +0 -294
  999. package/dist/vite/__tests__/ast-handler-extract.test.js.map +0 -1
  1000. package/dist/vite/__tests__/expose-id-utils.test.d.ts +0 -2
  1001. package/dist/vite/__tests__/expose-id-utils.test.d.ts.map +0 -1
  1002. package/dist/vite/__tests__/expose-id-utils.test.js +0 -224
  1003. package/dist/vite/__tests__/expose-id-utils.test.js.map +0 -1
  1004. package/dist/vite/__tests__/expose-internal-ids.test.d.ts +0 -2
  1005. package/dist/vite/__tests__/expose-internal-ids.test.d.ts.map +0 -1
  1006. package/dist/vite/__tests__/expose-internal-ids.test.js +0 -647
  1007. package/dist/vite/__tests__/expose-internal-ids.test.js.map +0 -1
  1008. package/dist/vite/__tests__/expose-router-id.test.d.ts +0 -2
  1009. package/dist/vite/__tests__/expose-router-id.test.d.ts.map +0 -1
  1010. package/dist/vite/__tests__/expose-router-id.test.js +0 -39
  1011. package/dist/vite/__tests__/expose-router-id.test.js.map +0 -1
  1012. package/dist/vite/ast-handler-extract.d.ts +0 -49
  1013. package/dist/vite/ast-handler-extract.d.ts.map +0 -1
  1014. package/dist/vite/ast-handler-extract.js +0 -249
  1015. package/dist/vite/ast-handler-extract.js.map +0 -1
  1016. package/dist/vite/expose-action-id.d.ts +0 -19
  1017. package/dist/vite/expose-action-id.d.ts.map +0 -1
  1018. package/dist/vite/expose-action-id.js +0 -250
  1019. package/dist/vite/expose-action-id.js.map +0 -1
  1020. package/dist/vite/expose-id-utils.d.ts +0 -69
  1021. package/dist/vite/expose-id-utils.d.ts.map +0 -1
  1022. package/dist/vite/expose-id-utils.js +0 -289
  1023. package/dist/vite/expose-id-utils.js.map +0 -1
  1024. package/dist/vite/expose-internal-ids.d.ts +0 -22
  1025. package/dist/vite/expose-internal-ids.d.ts.map +0 -1
  1026. package/dist/vite/expose-internal-ids.js +0 -886
  1027. package/dist/vite/expose-internal-ids.js.map +0 -1
  1028. package/dist/vite/index.d.ts +0 -149
  1029. package/dist/vite/index.d.ts.map +0 -1
  1030. package/dist/vite/index.js.bak +0 -5448
  1031. package/dist/vite/index.js.map +0 -1
  1032. package/dist/vite/index.named-routes.gen.ts +0 -103
  1033. package/dist/vite/package-resolution.d.ts +0 -43
  1034. package/dist/vite/package-resolution.d.ts.map +0 -1
  1035. package/dist/vite/package-resolution.js +0 -112
  1036. package/dist/vite/package-resolution.js.map +0 -1
  1037. package/dist/vite/virtual-entries.d.ts +0 -25
  1038. package/dist/vite/virtual-entries.d.ts.map +0 -1
  1039. package/dist/vite/virtual-entries.js +0 -110
  1040. package/dist/vite/virtual-entries.js.map +0 -1
  1041. package/src/browser/action-response-classifier.ts +0 -99
@@ -18,8 +18,11 @@ function hashId(filePath, exportName) {
18
18
  const hash = crypto.createHash("sha256").update(input).digest("hex");
19
19
  return `${hash.slice(0, 8)}#${exportName}`;
20
20
  }
21
- function hashInlineId(filePath, lineNumber, index) {
22
- const input = index !== void 0 && index > 0 ? `${filePath}:${lineNumber}:${index}` : `${filePath}:${lineNumber}`;
21
+ function makeStubId(filePath, exportName, isBuild) {
22
+ return isBuild ? hashId(filePath, exportName) : `${filePath}#${exportName}`;
23
+ }
24
+ function hashInlineId(filePath, fnName, index) {
25
+ const input = `${filePath}:${fnName}:${index}`;
23
26
  return crypto.createHash("sha256").update(input).digest("hex").slice(0, 8);
24
27
  }
25
28
  function buildExportMap(program) {
@@ -188,7 +191,100 @@ function escapeRegExp(input) {
188
191
  return input.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
189
192
  }
190
193
 
194
+ // src/vite/debug.ts
195
+ import debugFactory from "debug";
196
+ var NS = {
197
+ config: "rango:config",
198
+ discovery: "rango:discovery",
199
+ routes: "rango:routes",
200
+ prerender: "rango:prerender",
201
+ build: "rango:build",
202
+ dev: "rango:dev",
203
+ transform: "rango:transform",
204
+ chunks: "rango:chunks"
205
+ };
206
+ if (process.env.INTERNAL_RANGO_DEBUG) {
207
+ const existing = debugFactory.disable();
208
+ debugFactory.enable(existing ? `${existing},rango:*` : "rango:*");
209
+ }
210
+ function createRangoDebugger(namespace) {
211
+ const primary = debugFactory(namespace);
212
+ const shadow = debugFactory(`vite:${namespace}`);
213
+ if (primary.enabled) return primary;
214
+ if (shadow.enabled) return shadow;
215
+ return void 0;
216
+ }
217
+ async function timed(debug11, label, fn) {
218
+ if (!debug11) return await fn();
219
+ const start = performance.now();
220
+ try {
221
+ return await fn();
222
+ } finally {
223
+ debug11("%s (%sms)", label, (performance.now() - start).toFixed(1));
224
+ }
225
+ }
226
+ function timedSync(debug11, label, fn) {
227
+ if (!debug11) return fn();
228
+ const start = performance.now();
229
+ try {
230
+ return fn();
231
+ } finally {
232
+ debug11("%s (%sms)", label, (performance.now() - start).toFixed(1));
233
+ }
234
+ }
235
+ function createCounter(debug11, label) {
236
+ if (!debug11) return void 0;
237
+ let n = 0;
238
+ let totalMs = 0;
239
+ let slowestMs = 0;
240
+ let slowestFile = "";
241
+ const record = (file, ms) => {
242
+ n++;
243
+ totalMs += ms;
244
+ if (ms > slowestMs) {
245
+ slowestMs = ms;
246
+ slowestFile = file;
247
+ }
248
+ };
249
+ return {
250
+ record,
251
+ time(file, fn) {
252
+ const start = performance.now();
253
+ let out;
254
+ try {
255
+ out = fn();
256
+ } catch (err) {
257
+ record(file, performance.now() - start);
258
+ throw err;
259
+ }
260
+ if (out && typeof out.then === "function") {
261
+ return out.finally(
262
+ () => record(file, performance.now() - start)
263
+ );
264
+ }
265
+ record(file, performance.now() - start);
266
+ return out;
267
+ },
268
+ flush() {
269
+ if (n === 0) return;
270
+ debug11(
271
+ "%s: %d files, %sms total, slowest %sms %s",
272
+ label,
273
+ n,
274
+ totalMs.toFixed(1),
275
+ slowestMs.toFixed(1),
276
+ slowestFile
277
+ );
278
+ n = 0;
279
+ totalMs = 0;
280
+ slowestMs = 0;
281
+ slowestFile = "";
282
+ }
283
+ };
284
+ }
285
+
191
286
  // src/vite/plugins/expose-action-id.ts
287
+ var debug = createRangoDebugger(NS.transform);
192
288
  function getRscPluginApi(config) {
193
289
  let plugin = config.plugins.find((p) => p.name === "rsc:minimal");
194
290
  if (!plugin) {
@@ -197,7 +293,7 @@ function getRscPluginApi(config) {
197
293
  );
198
294
  if (plugin) {
199
295
  console.warn(
200
- `[rsc-router:expose-action-id] RSC plugin found by API structure (name: "${plugin.name}"). Consider updating the name lookup if the plugin was renamed.`
296
+ `[rango:expose-action-id] RSC plugin found by API structure (name: "${plugin.name}"). Consider updating the name lookup if the plugin was renamed.`
201
297
  );
202
298
  }
203
299
  }
@@ -277,6 +373,8 @@ function exposeActionId() {
277
373
  let isBuild = false;
278
374
  let hashToFileMap;
279
375
  let rscPluginApi;
376
+ const counterTransform = createCounter(debug, "expose-action-id transform");
377
+ const counterRender = createCounter(debug, "expose-action-id renderChunk");
280
378
  return {
281
379
  name: "@rangojs/router:expose-action-id",
282
380
  // Run after all other plugins (including RSC plugin's transforms)
@@ -286,13 +384,17 @@ function exposeActionId() {
286
384
  isBuild = config.command === "build";
287
385
  rscPluginApi = getRscPluginApi(config);
288
386
  },
387
+ buildEnd() {
388
+ counterTransform?.flush();
389
+ counterRender?.flush();
390
+ },
289
391
  buildStart() {
290
392
  if (!rscPluginApi) {
291
393
  rscPluginApi = getRscPluginApi(config);
292
394
  }
293
395
  if (!rscPluginApi) {
294
396
  throw new Error(
295
- "[rsc-router] Could not find @vitejs/plugin-rsc. @rangojs/router requires the Vite RSC plugin, which is included automatically by rango()."
397
+ "[rango] Could not find @vitejs/plugin-rsc. @rangojs/router requires the Vite RSC plugin, which is included automatically by rango()."
296
398
  );
297
399
  }
298
400
  if (!isBuild) return;
@@ -322,35 +424,49 @@ function exposeActionId() {
322
424
  if (id.includes("/node_modules/")) {
323
425
  return;
324
426
  }
325
- return transformServerReferences(code, id);
427
+ const start = counterTransform ? performance.now() : 0;
428
+ try {
429
+ return transformServerReferences(code, id);
430
+ } finally {
431
+ counterTransform?.record(id, performance.now() - start);
432
+ }
326
433
  },
327
434
  // Build mode: renderChunk runs after all transforms and bundling complete
328
435
  renderChunk(code, chunk) {
329
- const isRscEnv = this.environment?.name === "rsc";
330
- const effectiveMap = isRscEnv ? hashToFileMap : void 0;
331
- if (isRscEnv && hashToFileMap) {
332
- const s = new MagicString(code);
333
- const changed1 = applyServerReferenceWrapping(code, s, effectiveMap);
334
- const changed2 = applyRegisterReferenceWrapping(code, s, hashToFileMap);
335
- if (changed1 || changed2) {
336
- return {
337
- code: s.toString(),
338
- map: s.generateMap({
339
- source: chunk.fileName,
340
- includeContent: true
341
- })
342
- };
436
+ const start = counterRender ? performance.now() : 0;
437
+ try {
438
+ const isRscEnv = this.environment?.name === "rsc";
439
+ const effectiveMap = isRscEnv ? hashToFileMap : void 0;
440
+ if (isRscEnv && hashToFileMap) {
441
+ const s = new MagicString(code);
442
+ const changed1 = applyServerReferenceWrapping(code, s, effectiveMap);
443
+ const changed2 = applyRegisterReferenceWrapping(
444
+ code,
445
+ s,
446
+ hashToFileMap
447
+ );
448
+ if (changed1 || changed2) {
449
+ return {
450
+ code: s.toString(),
451
+ map: s.generateMap({
452
+ source: chunk.fileName,
453
+ includeContent: true
454
+ })
455
+ };
456
+ }
457
+ return null;
343
458
  }
344
- return null;
459
+ return transformServerReferences(code, chunk.fileName, effectiveMap);
460
+ } finally {
461
+ counterRender?.record(chunk.fileName, performance.now() - start);
345
462
  }
346
- return transformServerReferences(code, chunk.fileName, effectiveMap);
347
463
  }
348
464
  };
349
465
  }
350
466
 
351
467
  // src/vite/plugins/expose-internal-ids.ts
352
468
  import { parseAst as parseAst2 } from "vite";
353
- import MagicString4 from "magic-string";
469
+ import MagicString3 from "magic-string";
354
470
  import path4 from "node:path";
355
471
 
356
472
  // src/vite/utils/ast-handler-extract.ts
@@ -360,7 +476,7 @@ function isDirectivePrologueStatement(node) {
360
476
  function findImportInsertionPos(code, parseAst4) {
361
477
  let program;
362
478
  try {
363
- program = parseAst4(code, { jsx: true });
479
+ program = parseAst4(code, { lang: "tsx" });
364
480
  } catch {
365
481
  return 0;
366
482
  }
@@ -400,7 +516,7 @@ function walkNode(node, parent, ancestors, enter) {
400
516
  function findHandlerCalls(code, fnName, parseAst4) {
401
517
  let program;
402
518
  try {
403
- program = parseAst4(code, { jsx: true });
519
+ program = parseAst4(code, { lang: "tsx" });
404
520
  } catch {
405
521
  return [];
406
522
  }
@@ -474,7 +590,7 @@ function getImportedLocalNamesFromProgram(program, importedName) {
474
590
  }
475
591
  function getImportedLocalNames(code, importedName, parseAst4) {
476
592
  try {
477
- const program = parseAst4(code, { jsx: true });
593
+ const program = parseAst4(code, { lang: "tsx" });
478
594
  return getImportedLocalNamesFromProgram(program, importedName);
479
595
  } catch {
480
596
  return /* @__PURE__ */ new Set();
@@ -483,7 +599,7 @@ function getImportedLocalNames(code, importedName, parseAst4) {
483
599
  function extractImportDeclarations(code, parseAst4) {
484
600
  let program;
485
601
  try {
486
- program = parseAst4(code, { jsx: true });
602
+ program = parseAst4(code, { lang: "tsx" });
487
603
  } catch {
488
604
  return [];
489
605
  }
@@ -538,7 +654,7 @@ function isSafeVariableDeclaration(node, handlerNames) {
538
654
  function extractModuleLevelDeclarations(code, parseAst4, handlerNames) {
539
655
  let program;
540
656
  try {
541
- program = parseAst4(code, { jsx: true });
657
+ program = parseAst4(code, { lang: "tsx" });
542
658
  } catch {
543
659
  return [];
544
660
  }
@@ -582,14 +698,12 @@ function transformInlineHandlers(fnName, virtualPrefix, s, code, filePath, virtu
582
698
  parseAst4,
583
699
  handlerNames
584
700
  );
585
- const lineCounts = /* @__PURE__ */ new Map();
586
701
  const importStatements = [];
587
- for (const site of inlineSites) {
588
- const lineCount = lineCounts.get(site.lineNumber) ?? 0;
589
- lineCounts.set(site.lineNumber, lineCount + 1);
590
- const hash = hashInlineId(filePath, site.lineNumber, lineCount);
702
+ for (const [siteIndex, site] of inlineSites.entries()) {
703
+ const hash = hashInlineId(filePath, fnName, siteIndex);
591
704
  const exportName = `__sh_${hash}`;
592
- const virtualId = `\0${virtualPrefix}${filePath}:${site.lineNumber}${lineCount > 0 ? `:${lineCount}` : ""}`;
705
+ const idSuffix = `${filePath}:${fnName}:${siteIndex}`;
706
+ const virtualId = `\0${virtualPrefix}${idSuffix}`;
593
707
  const handlerCode = code.slice(site.callStart, site.callEnd);
594
708
  virtualRegistry.set(virtualId, {
595
709
  originalModuleId: moduleId,
@@ -599,7 +713,7 @@ function transformInlineHandlers(fnName, virtualPrefix, s, code, filePath, virtu
599
713
  exportName
600
714
  });
601
715
  s.overwrite(site.callStart, site.callEnd, exportName);
602
- const importId = `${virtualPrefix}${filePath}:${site.lineNumber}${lineCount > 0 ? `:${lineCount}` : ""}`;
716
+ const importId = `${virtualPrefix}${idSuffix}`;
603
717
  importStatements.push(`import { ${exportName} } from "${importId}";`);
604
718
  }
605
719
  if (importStatements.length > 0) {
@@ -631,6 +745,83 @@ var STRICT_CREATE_CONFIGS = [
631
745
 
632
746
  // src/vite/plugins/expose-ids/export-analysis.ts
633
747
  import { parseAst } from "vite";
748
+
749
+ // src/build/route-types/source-scan.ts
750
+ function isLineTerminator(ch) {
751
+ const c = ch.charCodeAt(0);
752
+ return c === 10 || c === 13 || c === 8232 || c === 8233;
753
+ }
754
+ function makeCodeClassifier(code) {
755
+ const n = code.length;
756
+ let i = 0;
757
+ let skipStart = -1;
758
+ let skipEnd = -1;
759
+ return (q) => {
760
+ if (q >= skipStart && q < skipEnd) return false;
761
+ while (i < n && i <= q) {
762
+ const c = code[i];
763
+ const d = i + 1 < n ? code[i + 1] : "";
764
+ let end = -1;
765
+ if (c === "/" && d === "/") {
766
+ let j = i + 2;
767
+ while (j < n && !isLineTerminator(code[j])) j++;
768
+ end = j;
769
+ } else if (c === "/" && d === "*") {
770
+ let j = i + 2;
771
+ while (j < n && !(code[j] === "*" && code[j + 1] === "/")) j++;
772
+ end = Math.min(n, j + 2);
773
+ } else if (c === '"' || c === "'" || c === "`") {
774
+ let j = i + 1;
775
+ while (j < n) {
776
+ if (code[j] === "\\") {
777
+ j += 2;
778
+ continue;
779
+ }
780
+ if (code[j] === c) {
781
+ j++;
782
+ break;
783
+ }
784
+ j++;
785
+ }
786
+ end = j;
787
+ }
788
+ if (end >= 0) {
789
+ if (q < end) {
790
+ skipStart = i;
791
+ skipEnd = end;
792
+ return false;
793
+ }
794
+ i = end;
795
+ } else {
796
+ i++;
797
+ }
798
+ }
799
+ return true;
800
+ };
801
+ }
802
+ function firstCodeMatchIndex(code, pattern) {
803
+ const inCode = makeCodeClassifier(code);
804
+ pattern.lastIndex = 0;
805
+ let m;
806
+ while ((m = pattern.exec(code)) !== null) {
807
+ if (inCode(m.index)) return m.index;
808
+ if (pattern.lastIndex <= m.index) pattern.lastIndex = m.index + 1;
809
+ }
810
+ return -1;
811
+ }
812
+ function codeMatchIndices(code, pattern) {
813
+ const inCode = makeCodeClassifier(code);
814
+ const indices = [];
815
+ pattern.lastIndex = 0;
816
+ let m;
817
+ while ((m = pattern.exec(code)) !== null) {
818
+ if (inCode(m.index)) indices.push(m.index);
819
+ if (pattern.lastIndex <= m.index) pattern.lastIndex = m.index + 1;
820
+ }
821
+ return indices;
822
+ }
823
+
824
+ // src/vite/plugins/expose-ids/export-analysis.ts
634
825
  function isExportOnlyFile(code, bindings) {
635
826
  if (bindings.length === 0) return false;
636
827
  const knownLocals = /* @__PURE__ */ new Set();
@@ -659,12 +850,30 @@ function isExportOnlyFile(code, bindings) {
659
850
  }
660
851
  return true;
661
852
  }
662
- function countCreateCallsForNames(code, fnNames) {
663
- const pattern = new RegExp(
853
+ function createCallPattern(fnNames) {
854
+ return new RegExp(
664
855
  `\\b(?:${fnNames.map(escapeRegExp).join("|")})\\s*(?:<[^>]*>\\s*)?\\(`,
665
856
  "g"
666
857
  );
667
- return (code.match(pattern) || []).length;
858
+ }
859
+ function countCreateCallsForNames(code, fnNames) {
860
+ return codeMatchIndices(code, createCallPattern(fnNames)).length;
861
+ }
862
+ function offsetToLineColumn(code, index) {
863
+ let line = 1;
864
+ let lineStart = 0;
865
+ const end = Math.min(index, code.length);
866
+ for (let i = 0; i < end; i++) {
867
+ if (code[i] === "\n") {
868
+ line++;
869
+ lineStart = i + 1;
870
+ }
871
+ }
872
+ return { line, column: index - lineStart + 1 };
873
+ }
874
+ function findUnsupportedCreateCallSites(code, fnNames, supportedBindings) {
875
+ const supported = new Set(supportedBindings.map((b) => b.callExprStart));
876
+ return codeMatchIndices(code, createCallPattern(fnNames)).filter((index) => !supported.has(index)).map((index) => offsetToLineColumn(code, index));
668
877
  }
669
878
  function getImportedFnNames(code, importedName) {
670
879
  const importPattern = /import\s*\{([^}]*)\}\s*from\s*["']@rangojs\/router(?:\/[^"']*)?["']/g;
@@ -695,6 +904,17 @@ function getCalledIdentifierFromCall(callExpr) {
695
904
  }
696
905
  return null;
697
906
  }
907
+ function unwrapSignatureWrappedCall(init, fnNameSet) {
908
+ if (init?.type !== "CallExpression") return init;
909
+ const directId = getCalledIdentifierFromCall(init);
910
+ if (directId && fnNameSet.has(directId)) return init;
911
+ const firstArg = init.arguments?.[0];
912
+ if (firstArg?.type === "CallExpression") {
913
+ const innerId = getCalledIdentifierFromCall(firstArg);
914
+ if (innerId && fnNameSet.has(innerId)) return firstArg;
915
+ }
916
+ return init;
917
+ }
698
918
  function collectCreateExportBindingsFallback(code, fnNames) {
699
919
  const alternation = fnNames.map(escapeRegExp).join("|");
700
920
  const exportConstPattern = new RegExp(
@@ -754,7 +974,7 @@ function collectCreateExportBindingsFallback(code, fnNames) {
754
974
  function collectCreateExportBindings(code, fnNames, program) {
755
975
  if (!program) {
756
976
  try {
757
- program = parseAst(code, { jsx: true });
977
+ program = parseAst(code, { lang: "tsx" });
758
978
  } catch {
759
979
  return collectCreateExportBindingsFallback(code, fnNames);
760
980
  }
@@ -767,16 +987,16 @@ function collectCreateExportBindings(code, fnNames, program) {
767
987
  return;
768
988
  }
769
989
  for (const decl of varDecl.declarations ?? []) {
770
- const calledIdentifier = getCalledIdentifierFromCall(decl?.init);
771
- if (decl?.id?.type !== "Identifier" || decl?.init?.type !== "CallExpression" || !calledIdentifier || !fnNameSet.has(calledIdentifier)) {
990
+ const callExpr = unwrapSignatureWrappedCall(decl?.init, fnNameSet);
991
+ const calledIdentifier = getCalledIdentifierFromCall(callExpr);
992
+ if (decl?.id?.type !== "Identifier" || callExpr?.type !== "CallExpression" || !calledIdentifier || !fnNameSet.has(calledIdentifier)) {
772
993
  continue;
773
994
  }
774
995
  const localName = decl.id.name;
775
996
  const exportNames = exportMap.get(localName) ?? [];
776
997
  if (exportNames.length === 0) continue;
777
- const callStart = decl.init.start;
778
- const callEnd = decl.init.end;
779
- const calleeEnd = decl.init.callee.end;
998
+ const callEnd = callExpr.end;
999
+ const calleeEnd = callExpr.callee.end;
780
1000
  let openParenPos = -1;
781
1001
  for (let i = calleeEnd; i < callEnd; i++) {
782
1002
  if (code[i] === "(") {
@@ -790,10 +1010,10 @@ function collectCreateExportBindings(code, fnNames, program) {
790
1010
  bindings.push({
791
1011
  localName,
792
1012
  exportNames,
793
- callExprStart: decl.init.start,
1013
+ callExprStart: callExpr.start,
794
1014
  callOpenParenPos: openParenPos,
795
1015
  callCloseParenPos: closeParenPos,
796
- argCount: decl.init.arguments?.length ?? 0,
1016
+ argCount: callExpr.arguments?.length ?? 0,
797
1017
  statementEnd
798
1018
  });
799
1019
  }
@@ -812,9 +1032,20 @@ function collectCreateExportBindings(code, fnNames, program) {
812
1032
  }
813
1033
  return bindings;
814
1034
  }
815
- function buildUnsupportedShapeWarning(filePath, fnName) {
816
- return [
817
- `[rsc-router] Unsupported ${fnName} shape in "${filePath}".`,
1035
+ function buildUnsupportedShapeWarning(filePath, fnName, sites = []) {
1036
+ const lines = [`[rango] Unsupported ${fnName} shape in "${filePath}".`];
1037
+ if (sites.length === 1) {
1038
+ const s = sites[0];
1039
+ lines.push(
1040
+ `The ${fnName}(...) call at ${filePath}:${s.line}:${s.column} has no stable $$id injected \u2014 it is not in a supported shape.`
1041
+ );
1042
+ } else if (sites.length > 1) {
1043
+ lines.push(
1044
+ `These ${fnName}(...) calls have no stable $$id injected \u2014 they are not in a supported shape:`
1045
+ );
1046
+ for (const s of sites) lines.push(` - ${filePath}:${s.line}:${s.column}`);
1047
+ }
1048
+ lines.push(
818
1049
  `Supported shapes are:`,
819
1050
  ` - export const X = ${fnName}(...)`,
820
1051
  ` - const X = ${fnName}(...); export { X }`,
@@ -822,7 +1053,8 @@ function buildUnsupportedShapeWarning(filePath, fnName) {
822
1053
  `Potentially unsupported forms include:`,
823
1054
  ` - export let/var X = ${fnName}(...)`,
824
1055
  ` - inline ${fnName}(...) calls`
825
- ].join("\n");
1056
+ );
1057
+ return lines.join("\n");
826
1058
  }
827
1059
 
828
1060
  // src/vite/plugins/expose-ids/loader-transform.ts
@@ -836,7 +1068,7 @@ function generateClientLoaderStubs(bindings, code, filePath, isBuild) {
836
1068
  const lines = [];
837
1069
  for (const binding of bindings) {
838
1070
  for (const name of binding.exportNames) {
839
- const loaderId = isBuild ? hashId(filePath, name) : `${filePath}#${name}`;
1071
+ const loaderId = makeStubId(filePath, name, isBuild);
840
1072
  lines.push(
841
1073
  `export const ${name} = { __brand: "loader", $$id: "${loaderId}" };`
842
1074
  );
@@ -848,7 +1080,7 @@ function transformLoaders(bindings, s, filePath, isBuild) {
848
1080
  let hasChanges = false;
849
1081
  for (const binding of bindings) {
850
1082
  const exportName = binding.exportNames[0];
851
- const loaderId = isBuild ? hashId(filePath, exportName) : `${filePath}#${exportName}`;
1083
+ const loaderId = makeStubId(filePath, exportName, isBuild);
852
1084
  const paramInjection = binding.argCount === 1 ? `, undefined, "${loaderId}"` : `, "${loaderId}"`;
853
1085
  s.appendLeft(binding.callCloseParenPos, paramInjection);
854
1086
  const propInjection = `
@@ -860,7 +1092,6 @@ ${binding.localName}.$$id = "${loaderId}";`;
860
1092
  }
861
1093
 
862
1094
  // src/vite/plugins/expose-ids/handler-transform.ts
863
- import MagicString2 from "magic-string";
864
1095
  function analyzeCreateHandleArgs(code, startPos, endPos) {
865
1096
  const content = code.slice(startPos, endPos).trim();
866
1097
  return { hasArgs: content.length > 0 };
@@ -874,7 +1105,7 @@ function transformHandles(bindings, s, code, filePath, isBuild) {
874
1105
  binding.callOpenParenPos + 1,
875
1106
  binding.callCloseParenPos
876
1107
  );
877
- const handleId = isBuild ? hashId(filePath, exportName) : `${filePath}#${exportName}`;
1108
+ const handleId = makeStubId(filePath, exportName, isBuild);
878
1109
  let paramInjection;
879
1110
  if (!args.hasArgs) {
880
1111
  paramInjection = `undefined, "${handleId}"`;
@@ -893,7 +1124,7 @@ function transformLocationState(bindings, s, filePath, isBuild) {
893
1124
  let hasChanges = false;
894
1125
  for (const binding of bindings) {
895
1126
  const exportName = binding.exportNames[0];
896
- const stateKey = isBuild ? hashId(filePath, exportName) : `${filePath}#${exportName}`;
1127
+ const stateKey = makeStubId(filePath, exportName, isBuild);
897
1128
  const propInjection = `
898
1129
  ${binding.localName}.__rsc_ls_key = "__rsc_ls_${stateKey}";`;
899
1130
  s.appendRight(binding.statementEnd, propInjection);
@@ -905,7 +1136,7 @@ function generateWholeFileStubs(cfg, bindings, code, filePath, isBuild) {
905
1136
  if (!isExportOnlyFile(code, bindings)) return null;
906
1137
  const exportNames = bindings.flatMap((b) => b.exportNames);
907
1138
  const stubs = exportNames.map((name) => {
908
- const handlerId = isBuild ? hashId(filePath, name) : `${filePath}#${name}`;
1139
+ const handlerId = makeStubId(filePath, name, isBuild);
909
1140
  return `export const ${name} = { __brand: "${cfg.brand}", $$id: "${handlerId}" };`;
910
1141
  });
911
1142
  return { code: stubs.join("\n") + "\n", map: null };
@@ -914,7 +1145,7 @@ function stubHandlerExprs(cfg, bindings, s, filePath, isBuild) {
914
1145
  let hasChanges = false;
915
1146
  for (const binding of bindings) {
916
1147
  const exportName = binding.exportNames[0];
917
- const handlerId = isBuild ? hashId(filePath, exportName) : `${filePath}#${exportName}`;
1148
+ const handlerId = makeStubId(filePath, exportName, isBuild);
918
1149
  s.overwrite(
919
1150
  binding.callExprStart,
920
1151
  binding.callCloseParenPos + 1,
@@ -928,7 +1159,7 @@ function transformHandlerIds(cfg, bindings, s, filePath, isBuild) {
928
1159
  let hasChanges = false;
929
1160
  for (const binding of bindings) {
930
1161
  const exportName = binding.exportNames[0];
931
- const handlerId = isBuild ? hashId(filePath, exportName) : `${filePath}#${exportName}`;
1162
+ const handlerId = makeStubId(filePath, exportName, isBuild);
932
1163
  let paramInjection;
933
1164
  if (binding.argCount === 0) {
934
1165
  paramInjection = `undefined, "${handlerId}"`;
@@ -947,19 +1178,20 @@ ${binding.localName}.$$id = "${handlerId}";`;
947
1178
  }
948
1179
 
949
1180
  // src/vite/plugins/expose-ids/router-transform.ts
950
- import MagicString3 from "magic-string";
1181
+ import MagicString2 from "magic-string";
951
1182
  import path3 from "node:path";
952
1183
  import { createHash } from "node:crypto";
1184
+ var debug2 = createRangoDebugger(NS.transform);
953
1185
  function transformRouter(code, filePath, routerFnNames, absolutePath) {
954
1186
  const pat = new RegExp(
955
1187
  `\\b(?:${routerFnNames.map((n) => n.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|")})\\s*(?:<[^>]*>)?\\s*\\(`,
956
1188
  "g"
957
1189
  );
958
1190
  let match;
959
- const s = new MagicString3(code);
1191
+ const s = new MagicString2(code);
960
1192
  let changed = false;
961
- const basename3 = path3.basename(filePath).replace(/\.(tsx?|jsx?)$/, "");
962
- const routeNamesImport = `./${basename3}.named-routes.gen.js`;
1193
+ const basename2 = path3.basename(filePath).replace(/\.(tsx?|jsx?)$/, "");
1194
+ const routeNamesImport = `./${basename2}.named-routes.gen.js`;
963
1195
  const routeNamesVar = `__rsc_rn`;
964
1196
  while ((match = pat.exec(code)) !== null) {
965
1197
  const callStart = match.index;
@@ -992,11 +1224,15 @@ function transformRouter(code, filePath, routerFnNames, absolutePath) {
992
1224
  }
993
1225
  function exposeRouterId() {
994
1226
  let projectRoot = "";
1227
+ const counter = createCounter(debug2, "expose-router-id");
995
1228
  return {
996
1229
  name: "@rangojs/router:expose-router-id",
997
1230
  configResolved(config) {
998
1231
  projectRoot = config.root;
999
1232
  },
1233
+ buildEnd() {
1234
+ counter?.flush();
1235
+ },
1000
1236
  transform(code, id) {
1001
1237
  if (!code.includes("createRouter")) return null;
1002
1238
  if (!/import\s*\{[^}]*\bcreateRouter\b[^}]*\}\s*from\s*["']@rangojs\/router(?:\/server)?["']/.test(
@@ -1005,14 +1241,25 @@ function exposeRouterId() {
1005
1241
  return null;
1006
1242
  }
1007
1243
  if (id.includes("node_modules")) return null;
1008
- const filePath = normalizePath(path3.relative(projectRoot, id));
1009
- const routerFnNames = getImportedFnNames(code, "createRouter");
1010
- return transformRouter(code, filePath, routerFnNames, normalizePath(id));
1244
+ const start = counter ? performance.now() : 0;
1245
+ try {
1246
+ const filePath = normalizePath(path3.relative(projectRoot, id));
1247
+ const routerFnNames = getImportedFnNames(code, "createRouter");
1248
+ return transformRouter(
1249
+ code,
1250
+ filePath,
1251
+ routerFnNames,
1252
+ normalizePath(id)
1253
+ );
1254
+ } finally {
1255
+ counter?.record(id, performance.now() - start);
1256
+ }
1011
1257
  }
1012
1258
  };
1013
1259
  }
1014
1260
 
1015
1261
  // src/vite/plugins/expose-internal-ids.ts
1262
+ var debug3 = createRangoDebugger(NS.transform);
1016
1263
  var VIRTUAL_LOADER_MANIFEST = "virtual:rsc-router/loader-manifest";
1017
1264
  var RESOLVED_VIRTUAL_LOADER_MANIFEST = "\0" + VIRTUAL_LOADER_MANIFEST;
1018
1265
  var VIRTUAL_HANDLER_PREFIX = "virtual:handler-extract:";
@@ -1025,9 +1272,13 @@ function exposeInternalIds(options) {
1025
1272
  const staticHandlerModules = /* @__PURE__ */ new Map();
1026
1273
  const virtualHandlers = /* @__PURE__ */ new Map();
1027
1274
  const unsupportedShapeWarnings = /* @__PURE__ */ new Set();
1275
+ const counter = createCounter(debug3, "expose-internal-ids");
1028
1276
  return {
1029
1277
  name: "@rangojs/router:expose-internal-ids",
1030
1278
  enforce: "post",
1279
+ buildEnd() {
1280
+ counter?.flush();
1281
+ },
1031
1282
  api: {
1032
1283
  prerenderHandlerModules,
1033
1284
  staticHandlerModules
@@ -1141,11 +1392,13 @@ ${lazyImports.join(",\n")}
1141
1392
  // --------------- Unified transform ---------------
1142
1393
  transform(code, id) {
1143
1394
  if (id.includes("/node_modules/")) return;
1144
- const filePath = normalizePath(path4.relative(projectRoot, id));
1145
- const isRscEnv = this.environment?.name === "rsc";
1146
- if (id.includes(".named-routes.gen.") && !isRscEnv && this.environment?.name === "client") {
1147
- this.warn(
1148
- `
1395
+ const __t0 = counter ? performance.now() : 0;
1396
+ try {
1397
+ const filePath = normalizePath(path4.relative(projectRoot, id));
1398
+ const isRscEnv = this.environment?.name === "rsc";
1399
+ if (id.includes(".named-routes.gen.") && !isRscEnv && this.environment?.name === "client") {
1400
+ this.warn(
1401
+ `
1149
1402
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1150
1403
  !! !!
1151
1404
  !! WARNING: NamedRoutes imported in a CLIENT component! !!
@@ -1165,355 +1418,363 @@ ${lazyImports.join(",\n")}
1165
1418
  !! !!
1166
1419
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1167
1420
  `
1168
- );
1169
- }
1170
- if (!code.includes("@rangojs/router")) return;
1171
- const has = detectImports(code);
1172
- const hasLoaderCode = has.loader && code.includes("createLoader");
1173
- const hasHandleCode = has.handle && code.includes("createHandle");
1174
- const hasLocationStateCode = has.locationState && code.includes("createLocationState");
1175
- const hasPrerenderHandlerCode = has.prerenderHandler && code.includes("Prerender");
1176
- const hasStaticHandlerCode = has.staticHandler && code.includes("Static");
1177
- if (!hasLoaderCode && !hasHandleCode && !hasLocationStateCode && !hasPrerenderHandlerCode && !hasStaticHandlerCode) {
1178
- return;
1179
- }
1180
- const _fnNamesCache = /* @__PURE__ */ new Map();
1181
- const _bindingsCache = /* @__PURE__ */ new Map();
1182
- let _cachedAst;
1183
- let _astParseFailed = false;
1184
- let _astCodeRef = code;
1185
- const getFnNames = (canonicalName) => {
1186
- let result = _fnNamesCache.get(canonicalName);
1187
- if (!result) {
1188
- result = getImportedFnNames(code, canonicalName);
1189
- _fnNamesCache.set(canonicalName, result);
1421
+ );
1190
1422
  }
1191
- return result;
1192
- };
1193
- const lazyAst = () => {
1194
- if (code !== _astCodeRef) {
1195
- _cachedAst = void 0;
1196
- _astParseFailed = false;
1197
- _astCodeRef = code;
1423
+ if (!code.includes("@rangojs/router")) return;
1424
+ const has = detectImports(code);
1425
+ const hasLoaderCode = has.loader && code.includes("createLoader");
1426
+ const hasHandleCode = has.handle && code.includes("createHandle");
1427
+ const hasLocationStateCode = has.locationState && code.includes("createLocationState");
1428
+ const hasPrerenderHandlerCode = has.prerenderHandler && code.includes("Prerender");
1429
+ const hasStaticHandlerCode = has.staticHandler && code.includes("Static");
1430
+ if (!hasLoaderCode && !hasHandleCode && !hasLocationStateCode && !hasPrerenderHandlerCode && !hasStaticHandlerCode) {
1431
+ return;
1198
1432
  }
1199
- if (_cachedAst !== void 0 || _astParseFailed) return _cachedAst;
1200
- try {
1201
- _cachedAst = parseAst2(code, { jsx: true });
1202
- } catch {
1203
- _astParseFailed = true;
1433
+ const _fnNamesCache = /* @__PURE__ */ new Map();
1434
+ const _bindingsCache = /* @__PURE__ */ new Map();
1435
+ let _cachedAst;
1436
+ let _astParseFailed = false;
1437
+ let _astCodeRef = code;
1438
+ const getFnNames = (canonicalName) => {
1439
+ let result = _fnNamesCache.get(canonicalName);
1440
+ if (!result) {
1441
+ result = getImportedFnNames(code, canonicalName);
1442
+ _fnNamesCache.set(canonicalName, result);
1443
+ }
1444
+ return result;
1445
+ };
1446
+ const lazyAst = () => {
1447
+ if (code !== _astCodeRef) {
1448
+ _cachedAst = void 0;
1449
+ _astParseFailed = false;
1450
+ _astCodeRef = code;
1451
+ }
1452
+ if (_cachedAst !== void 0 || _astParseFailed) return _cachedAst;
1453
+ try {
1454
+ _cachedAst = parseAst2(code, { lang: "tsx" });
1455
+ } catch {
1456
+ _astParseFailed = true;
1457
+ }
1458
+ return _cachedAst;
1459
+ };
1460
+ const getBindings = (currentCode, fnNames) => {
1461
+ const key = fnNames.join("\0");
1462
+ let result = _bindingsCache.get(key);
1463
+ if (!result) {
1464
+ result = collectCreateExportBindings(
1465
+ currentCode,
1466
+ fnNames,
1467
+ lazyAst()
1468
+ );
1469
+ _bindingsCache.set(key, result);
1470
+ }
1471
+ return result;
1472
+ };
1473
+ for (const cfg of STRICT_CREATE_CONFIGS) {
1474
+ const hasCode = cfg.fnName === "createLoader" ? hasLoaderCode : cfg.fnName === "createHandle" ? hasHandleCode : hasLocationStateCode;
1475
+ if (!hasCode) continue;
1476
+ const fnNames = getFnNames(cfg.fnName);
1477
+ const sites = findUnsupportedCreateCallSites(
1478
+ code,
1479
+ fnNames,
1480
+ getBindings(code, fnNames)
1481
+ );
1482
+ if (sites.length === 0) continue;
1483
+ const warnKey = `${id}::${cfg.fnName}`;
1484
+ if (unsupportedShapeWarnings.has(warnKey)) continue;
1485
+ unsupportedShapeWarnings.add(warnKey);
1486
+ this.warn(buildUnsupportedShapeWarning(filePath, cfg.fnName, sites));
1204
1487
  }
1205
- return _cachedAst;
1206
- };
1207
- const getBindings = (currentCode, fnNames) => {
1208
- const key = fnNames.join("\0");
1209
- let result = _bindingsCache.get(key);
1210
- if (!result) {
1211
- result = collectCreateExportBindings(currentCode, fnNames, lazyAst());
1212
- _bindingsCache.set(key, result);
1488
+ if (hasLoaderCode && isRscEnv) {
1489
+ const fnNames = getFnNames("createLoader");
1490
+ const bindings = getBindings(code, fnNames);
1491
+ for (const binding of bindings) {
1492
+ const exportName = binding.exportNames[0];
1493
+ const hashedId = hashId(filePath, exportName);
1494
+ loaderRegistry.set(hashedId, {
1495
+ filePath,
1496
+ exportName
1497
+ });
1498
+ }
1213
1499
  }
1214
- return result;
1215
- };
1216
- for (const cfg of STRICT_CREATE_CONFIGS) {
1217
- const hasCode = cfg.fnName === "createLoader" ? hasLoaderCode : cfg.fnName === "createHandle" ? hasHandleCode : hasLocationStateCode;
1218
- if (!hasCode) continue;
1219
- const fnNames = getFnNames(cfg.fnName);
1220
- const totalCalls = countCreateCallsForNames(code, fnNames);
1221
- const supportedBindings = getBindings(code, fnNames).length;
1222
- if (totalCalls <= supportedBindings) continue;
1223
- const warnKey = `${id}::${cfg.fnName}`;
1224
- if (unsupportedShapeWarnings.has(warnKey)) continue;
1225
- unsupportedShapeWarnings.add(warnKey);
1226
- this.warn(buildUnsupportedShapeWarning(filePath, cfg.fnName));
1227
- }
1228
- if (hasLoaderCode && isRscEnv) {
1229
- const fnNames = getFnNames("createLoader");
1230
- const bindings = getBindings(code, fnNames);
1231
- for (const binding of bindings) {
1232
- const exportName = binding.exportNames[0];
1233
- const hashedId = hashId(filePath, exportName);
1234
- loaderRegistry.set(hashedId, {
1500
+ if (hasLoaderCode && !isRscEnv) {
1501
+ const fnNames = getFnNames("createLoader");
1502
+ const bindings = getBindings(code, fnNames);
1503
+ const stubResult = generateClientLoaderStubs(
1504
+ bindings,
1505
+ code,
1235
1506
  filePath,
1236
- exportName
1237
- });
1238
- }
1239
- }
1240
- if (hasLoaderCode && !isRscEnv) {
1241
- const fnNames = getFnNames("createLoader");
1242
- const bindings = getBindings(code, fnNames);
1243
- const stubResult = generateClientLoaderStubs(
1244
- bindings,
1245
- code,
1246
- filePath,
1247
- isBuild
1248
- );
1249
- if (stubResult) return stubResult;
1250
- }
1251
- if (hasPrerenderHandlerCode && !isRscEnv) {
1252
- const fnNames = getFnNames(PRERENDER_CONFIG.fnName);
1253
- const bindings = getBindings(code, fnNames);
1254
- const wholeFile = generateWholeFileStubs(
1255
- PRERENDER_CONFIG,
1256
- bindings,
1257
- code,
1258
- filePath,
1259
- isBuild
1260
- );
1261
- if (wholeFile) return wholeFile;
1262
- }
1263
- if (hasPrerenderHandlerCode && isRscEnv && isBuild) {
1264
- const fnNames = getFnNames(PRERENDER_CONFIG.fnName);
1265
- const exportNames = getBindings(code, fnNames).map(
1266
- (b) => b.exportNames[0]
1267
- );
1268
- if (exportNames.length > 0) {
1269
- prerenderHandlerModules.set(id, exportNames);
1507
+ isBuild
1508
+ );
1509
+ if (stubResult) return stubResult;
1270
1510
  }
1271
- }
1272
- let changed = false;
1273
- const handlerConfigs = [
1274
- hasStaticHandlerCode && STATIC_CONFIG,
1275
- hasPrerenderHandlerCode && PRERENDER_CONFIG
1276
- ].filter((c) => !!c).map((cfg) => {
1277
- const fnNames = getFnNames(cfg.fnName);
1278
- return { cfg, fnNames };
1279
- });
1280
- for (const { cfg, fnNames } of handlerConfigs) {
1281
- const totalCalls = countCreateCallsForNames(code, fnNames);
1282
- const supportedBindings = getBindings(code, fnNames).length;
1283
- if (totalCalls > supportedBindings) {
1284
- const iterS = new MagicString4(code);
1285
- const result = transformInlineHandlers(
1286
- cfg.fnName,
1287
- VIRTUAL_HANDLER_PREFIX,
1288
- iterS,
1511
+ if (hasPrerenderHandlerCode && !isRscEnv) {
1512
+ const fnNames = getFnNames(PRERENDER_CONFIG.fnName);
1513
+ const bindings = getBindings(code, fnNames);
1514
+ const wholeFile = generateWholeFileStubs(
1515
+ PRERENDER_CONFIG,
1516
+ bindings,
1289
1517
  code,
1290
1518
  filePath,
1291
- virtualHandlers,
1292
- id,
1293
- parseAst2
1519
+ isBuild
1294
1520
  );
1295
- if (result) {
1296
- changed = true;
1297
- code = iterS.toString();
1298
- _bindingsCache.clear();
1299
- }
1521
+ if (wholeFile) return wholeFile;
1300
1522
  }
1301
- }
1302
- if (hasStaticHandlerCode && !isRscEnv) {
1303
- const fnNames = getFnNames(STATIC_CONFIG.fnName);
1304
- const bindings = getBindings(code, fnNames);
1305
- const wholeFile = generateWholeFileStubs(
1306
- STATIC_CONFIG,
1307
- bindings,
1308
- code,
1309
- filePath,
1310
- isBuild
1311
- );
1312
- if (wholeFile) return wholeFile;
1313
- }
1314
- if (!isRscEnv && (hasPrerenderHandlerCode || hasStaticHandlerCode)) {
1315
- const prerenderFnNames = hasPrerenderHandlerCode ? getFnNames(PRERENDER_CONFIG.fnName) : [];
1316
- const staticFnNames = hasStaticHandlerCode ? getFnNames(STATIC_CONFIG.fnName) : [];
1317
- const loaderFnNames = hasLoaderCode ? getFnNames("createLoader") : [];
1318
- const handleFnNames = hasHandleCode ? getFnNames("createHandle") : [];
1319
- const lsFnNames = hasLocationStateCode ? getFnNames("createLocationState") : [];
1320
- const allBindings = [];
1321
- for (const fnNames of [
1322
- prerenderFnNames,
1323
- staticFnNames,
1324
- loaderFnNames,
1325
- handleFnNames,
1326
- lsFnNames
1327
- ]) {
1328
- if (fnNames.length > 0) {
1329
- allBindings.push(...getBindings(code, fnNames));
1523
+ let changed = false;
1524
+ const handlerConfigs = [
1525
+ hasStaticHandlerCode && STATIC_CONFIG,
1526
+ hasPrerenderHandlerCode && PRERENDER_CONFIG
1527
+ ].filter((c) => !!c).map((cfg) => {
1528
+ const fnNames = getFnNames(cfg.fnName);
1529
+ return { cfg, fnNames };
1530
+ });
1531
+ for (const { cfg, fnNames } of handlerConfigs) {
1532
+ const totalCalls = countCreateCallsForNames(code, fnNames);
1533
+ const supportedBindings = getBindings(code, fnNames).length;
1534
+ if (totalCalls > supportedBindings) {
1535
+ const iterS = new MagicString3(code);
1536
+ const result = transformInlineHandlers(
1537
+ cfg.fnName,
1538
+ VIRTUAL_HANDLER_PREFIX,
1539
+ iterS,
1540
+ code,
1541
+ filePath,
1542
+ virtualHandlers,
1543
+ id,
1544
+ parseAst2
1545
+ );
1546
+ if (result) {
1547
+ changed = true;
1548
+ code = iterS.toString();
1549
+ _bindingsCache.clear();
1550
+ }
1330
1551
  }
1331
1552
  }
1332
- let canStubWholeFile = allBindings.length > 0 && isExportOnlyFile(code, allBindings);
1333
- if (canStubWholeFile && (handleFnNames.length > 0 || lsFnNames.length > 0)) {
1334
- const exportedLocals = new Set(allBindings.map((b) => b.localName));
1335
- const strippedBindings = [];
1336
- const localDeclPattern = /(?:^|;|\n)\s*(?:const|let|var|function)\s+(\w+)/g;
1337
- let declMatch;
1338
- while ((declMatch = localDeclPattern.exec(code)) !== null) {
1339
- if (!exportedLocals.has(declMatch[1])) {
1340
- strippedBindings.push(declMatch[1]);
1553
+ if (hasStaticHandlerCode && !isRscEnv) {
1554
+ const fnNames = getFnNames(STATIC_CONFIG.fnName);
1555
+ const bindings = getBindings(code, fnNames);
1556
+ const wholeFile = generateWholeFileStubs(
1557
+ STATIC_CONFIG,
1558
+ bindings,
1559
+ code,
1560
+ filePath,
1561
+ isBuild
1562
+ );
1563
+ if (wholeFile) return wholeFile;
1564
+ }
1565
+ if (!isRscEnv && (hasPrerenderHandlerCode || hasStaticHandlerCode)) {
1566
+ const prerenderFnNames = hasPrerenderHandlerCode ? getFnNames(PRERENDER_CONFIG.fnName) : [];
1567
+ const staticFnNames = hasStaticHandlerCode ? getFnNames(STATIC_CONFIG.fnName) : [];
1568
+ const loaderFnNames = hasLoaderCode ? getFnNames("createLoader") : [];
1569
+ const handleFnNames = hasHandleCode ? getFnNames("createHandle") : [];
1570
+ const lsFnNames = hasLocationStateCode ? getFnNames("createLocationState") : [];
1571
+ const allBindings = [];
1572
+ for (const fnNames of [
1573
+ prerenderFnNames,
1574
+ staticFnNames,
1575
+ loaderFnNames,
1576
+ handleFnNames,
1577
+ lsFnNames
1578
+ ]) {
1579
+ if (fnNames.length > 0) {
1580
+ allBindings.push(...getBindings(code, fnNames));
1341
1581
  }
1342
1582
  }
1343
- const importPattern = /import\s*\{([^}]*)\}\s*from\s*["'](?!@rangojs\/router)[^"']*["']/g;
1344
- let importMatch;
1345
- while ((importMatch = importPattern.exec(code)) !== null) {
1346
- for (const spec of importMatch[1].split(",")) {
1347
- const m = spec.trim().match(/^[A-Za-z_$][\w$]*(?:\s+as\s+([A-Za-z_$][\w$]*))?$/);
1348
- if (m) strippedBindings.push(m[1] || m[0].trim().split(/\s/)[0]);
1583
+ let canStubWholeFile = allBindings.length > 0 && isExportOnlyFile(code, allBindings);
1584
+ if (canStubWholeFile && (handleFnNames.length > 0 || lsFnNames.length > 0)) {
1585
+ const exportedLocals = new Set(allBindings.map((b) => b.localName));
1586
+ const strippedBindings = [];
1587
+ const localDeclPattern = /(?:^|;|\n)\s*(?:const|let|var|function)\s+(\w+)/g;
1588
+ let declMatch;
1589
+ while ((declMatch = localDeclPattern.exec(code)) !== null) {
1590
+ const name = declMatch[1];
1591
+ if (!exportedLocals.has(name) && !/^_c\d*$/.test(name)) {
1592
+ strippedBindings.push(name);
1593
+ }
1349
1594
  }
1350
- }
1351
- const defaultImportPattern = /import\s+([A-Za-z_$][\w$]*)\s+from\s*["'](?!@rangojs\/router)[^"']*["']/g;
1352
- while ((importMatch = defaultImportPattern.exec(code)) !== null) {
1353
- strippedBindings.push(importMatch[1]);
1354
- }
1355
- if (strippedBindings.length > 0) {
1356
- const preservedBindings = allBindings.filter((b) => {
1357
- const fc = code.slice(b.callExprStart, b.callOpenParenPos + 1);
1358
- return handleFnNames.some((n) => fc.includes(n)) || lsFnNames.some((n) => fc.includes(n));
1359
- });
1360
- canStubWholeFile = !preservedBindings.some((b) => {
1361
- const expr = code.slice(b.callExprStart, b.callCloseParenPos + 1);
1362
- return strippedBindings.some(
1363
- (name) => new RegExp(`\\b${name}\\b`).test(expr)
1595
+ const importPattern = /import\s*\{([^}]*)\}\s*from\s*["'](?!@rangojs\/router)[^"']*["']/g;
1596
+ let importMatch;
1597
+ while ((importMatch = importPattern.exec(code)) !== null) {
1598
+ for (const spec of importMatch[1].split(",")) {
1599
+ const m = spec.trim().match(/^[A-Za-z_$][\w$]*(?:\s+as\s+([A-Za-z_$][\w$]*))?$/);
1600
+ if (m)
1601
+ strippedBindings.push(m[1] || m[0].trim().split(/\s/)[0]);
1602
+ }
1603
+ }
1604
+ const defaultImportPattern = /import\s+([A-Za-z_$][\w$]*)\s+from\s*["'](?!@rangojs\/router)[^"']*["']/g;
1605
+ while ((importMatch = defaultImportPattern.exec(code)) !== null) {
1606
+ strippedBindings.push(importMatch[1]);
1607
+ }
1608
+ const nsImportPattern = /import\s+\*\s+as\s+([A-Za-z_$][\w$]*)\s+from\s*["'](?!@rangojs\/router)[^"']*["']/g;
1609
+ while ((importMatch = nsImportPattern.exec(code)) !== null) {
1610
+ strippedBindings.push(importMatch[1]);
1611
+ }
1612
+ if (strippedBindings.length > 0) {
1613
+ const preservedBindings = allBindings.filter((b) => {
1614
+ const fc = code.slice(b.callExprStart, b.callOpenParenPos + 1);
1615
+ return handleFnNames.some((n) => fc.includes(n)) || lsFnNames.some((n) => fc.includes(n));
1616
+ });
1617
+ const strippedRe = new RegExp(
1618
+ `\\b(?:${strippedBindings.join("|")})\\b`
1364
1619
  );
1365
- });
1366
- }
1367
- }
1368
- if (canStubWholeFile) {
1369
- const lines = [];
1370
- const neededImports = [];
1371
- if (handleFnNames.length > 0) neededImports.push("createHandle");
1372
- if (lsFnNames.length > 0) neededImports.push("createLocationState");
1373
- if (neededImports.length > 0) {
1374
- lines.push(
1375
- `import { ${neededImports.join(", ")} } from "@rangojs/router";`
1376
- );
1620
+ canStubWholeFile = !preservedBindings.some((b) => {
1621
+ const expr = code.slice(
1622
+ b.callExprStart,
1623
+ b.callCloseParenPos + 1
1624
+ );
1625
+ return strippedRe.test(expr);
1626
+ });
1627
+ }
1377
1628
  }
1378
- for (const binding of allBindings) {
1379
- const fnCall = code.slice(
1380
- binding.callExprStart,
1381
- binding.callOpenParenPos + 1
1382
- );
1383
- const isHandle = handleFnNames.some((n) => fnCall.includes(n));
1384
- const isLocationState = lsFnNames.some((n) => fnCall.includes(n));
1385
- const primaryName = binding.exportNames[0];
1386
- const stubId = isBuild ? hashId(filePath, primaryName) : `${filePath}#${primaryName}`;
1387
- if (isHandle || isLocationState) {
1388
- const rawCallExpr = code.slice(
1629
+ if (canStubWholeFile) {
1630
+ const lines = [];
1631
+ const neededImports = [];
1632
+ if (handleFnNames.length > 0) neededImports.push("createHandle");
1633
+ if (lsFnNames.length > 0) neededImports.push("createLocationState");
1634
+ if (neededImports.length > 0) {
1635
+ lines.push(
1636
+ `import { ${neededImports.join(", ")} } from "@rangojs/router";`
1637
+ );
1638
+ }
1639
+ for (const binding of allBindings) {
1640
+ const fnCall = code.slice(
1389
1641
  binding.callExprStart,
1390
- binding.callCloseParenPos + 1
1642
+ binding.callOpenParenPos + 1
1391
1643
  );
1392
- const canonicalName = isHandle ? "createHandle" : "createLocationState";
1393
- const activeFnNames = isHandle ? handleFnNames : lsFnNames;
1394
- let callExpr = rawCallExpr;
1395
- for (const alias of activeFnNames) {
1396
- if (alias !== canonicalName && callExpr.startsWith(alias)) {
1397
- callExpr = canonicalName + callExpr.slice(alias.length);
1398
- break;
1644
+ const isHandle = handleFnNames.some((n) => fnCall.includes(n));
1645
+ const isLocationState = lsFnNames.some((n) => fnCall.includes(n));
1646
+ const primaryName = binding.exportNames[0];
1647
+ const stubId = makeStubId(filePath, primaryName, isBuild);
1648
+ if (isHandle || isLocationState) {
1649
+ const rawArgs = code.slice(
1650
+ binding.callOpenParenPos + 1,
1651
+ binding.callCloseParenPos
1652
+ ).replace(/\b_c\d*\s*=\s*/g, "");
1653
+ const canonicalName = isHandle ? "createHandle" : "createLocationState";
1654
+ const activeFnNames = isHandle ? handleFnNames : lsFnNames;
1655
+ let rawCallee = code.slice(
1656
+ binding.callExprStart,
1657
+ binding.callOpenParenPos
1658
+ );
1659
+ for (const alias of activeFnNames) {
1660
+ if (alias !== canonicalName && rawCallee.startsWith(alias)) {
1661
+ rawCallee = canonicalName + rawCallee.slice(alias.length);
1662
+ break;
1663
+ }
1664
+ }
1665
+ if (isHandle) {
1666
+ const idParam = binding.argCount === 0 ? `undefined, "${stubId}"` : `, "${stubId}"`;
1667
+ lines.push(
1668
+ `export const ${primaryName} = ${rawCallee}(${rawArgs}${idParam});`
1669
+ );
1670
+ lines.push(`${primaryName}.$$id = "${stubId}";`);
1671
+ } else {
1672
+ lines.push(
1673
+ `export const ${primaryName} = ${rawCallee}(${rawArgs});`
1674
+ );
1675
+ lines.push(
1676
+ `${primaryName}.__rsc_ls_key = "__rsc_ls_${stubId}";`
1677
+ );
1678
+ }
1679
+ for (const name of binding.exportNames.slice(1)) {
1680
+ lines.push(`export const ${name} = ${primaryName};`);
1399
1681
  }
1400
- }
1401
- lines.push(`export const ${primaryName} = ${callExpr};`);
1402
- if (isHandle) {
1403
- lines.push(`${primaryName}.$$id = "${stubId}";`);
1404
1682
  } else {
1683
+ let brand = "loader";
1684
+ if (prerenderFnNames.some((n) => fnCall.includes(n))) {
1685
+ brand = PRERENDER_CONFIG.brand;
1686
+ } else if (staticFnNames.some((n) => fnCall.includes(n))) {
1687
+ brand = STATIC_CONFIG.brand;
1688
+ }
1405
1689
  lines.push(
1406
- `${primaryName}.__rsc_ls_key = "__rsc_ls_${stubId}";`
1690
+ `export const ${primaryName} = { __brand: "${brand}", $$id: "${stubId}" };`
1407
1691
  );
1408
- }
1409
- for (const name of binding.exportNames.slice(1)) {
1410
- lines.push(`export const ${name} = ${primaryName};`);
1411
- }
1412
- } else {
1413
- let brand = "loader";
1414
- if (prerenderFnNames.some((n) => fnCall.includes(n))) {
1415
- brand = PRERENDER_CONFIG.brand;
1416
- } else if (staticFnNames.some((n) => fnCall.includes(n))) {
1417
- brand = STATIC_CONFIG.brand;
1418
- }
1419
- lines.push(
1420
- `export const ${primaryName} = { __brand: "${brand}", $$id: "${stubId}" };`
1421
- );
1422
- for (const name of binding.exportNames.slice(1)) {
1423
- lines.push(`export const ${name} = ${primaryName};`);
1692
+ for (const name of binding.exportNames.slice(1)) {
1693
+ lines.push(`export const ${name} = ${primaryName};`);
1694
+ }
1424
1695
  }
1425
1696
  }
1697
+ return { code: lines.join("\n") + "\n", map: null };
1426
1698
  }
1427
- return { code: lines.join("\n") + "\n", map: null };
1428
1699
  }
1429
- }
1430
- if (hasStaticHandlerCode && isRscEnv && isBuild) {
1431
- const fnNames = getFnNames(STATIC_CONFIG.fnName);
1432
- const exportNames = getBindings(code, fnNames).map(
1433
- (b) => b.exportNames[0]
1434
- );
1435
- if (exportNames.length > 0) {
1436
- staticHandlerModules.set(id, exportNames);
1700
+ if (isRscEnv && isBuild) {
1701
+ const trackTypes = [
1702
+ [
1703
+ hasPrerenderHandlerCode,
1704
+ PRERENDER_CONFIG,
1705
+ prerenderHandlerModules
1706
+ ],
1707
+ [hasStaticHandlerCode, STATIC_CONFIG, staticHandlerModules]
1708
+ ];
1709
+ for (const [has2, cfg, trackMap] of trackTypes) {
1710
+ if (!has2) continue;
1711
+ const exportNames = getBindings(code, getFnNames(cfg.fnName)).map(
1712
+ (b) => b.exportNames[0]
1713
+ );
1714
+ if (exportNames.length > 0) trackMap.set(id, exportNames);
1715
+ }
1437
1716
  }
1438
- }
1439
- const s = new MagicString4(code);
1440
- if (hasLoaderCode) {
1441
- const fnNames = getFnNames("createLoader");
1442
- changed = transformLoaders(getBindings(code, fnNames), s, filePath, isBuild) || changed;
1443
- }
1444
- if (hasHandleCode) {
1445
- const fnNames = getFnNames("createHandle");
1446
- changed = transformHandles(
1447
- getBindings(code, fnNames),
1448
- s,
1449
- code,
1450
- filePath,
1451
- isBuild
1452
- ) || changed;
1453
- }
1454
- if (hasLocationStateCode) {
1455
- const fnNames = getFnNames("createLocationState");
1456
- changed = transformLocationState(
1457
- getBindings(code, fnNames),
1458
- s,
1459
- filePath,
1460
- isBuild
1461
- ) || changed;
1462
- }
1463
- if (hasPrerenderHandlerCode) {
1464
- const fnNames = getFnNames(PRERENDER_CONFIG.fnName);
1465
- const bindings = getBindings(code, fnNames);
1466
- if (isRscEnv) {
1467
- changed = transformHandlerIds(
1468
- PRERENDER_CONFIG,
1469
- bindings,
1717
+ const s = new MagicString3(code);
1718
+ if (hasLoaderCode) {
1719
+ const fnNames = getFnNames("createLoader");
1720
+ changed = transformLoaders(
1721
+ getBindings(code, fnNames),
1470
1722
  s,
1471
1723
  filePath,
1472
1724
  isBuild
1473
1725
  ) || changed;
1474
- } else {
1475
- changed = stubHandlerExprs(
1476
- PRERENDER_CONFIG,
1477
- bindings,
1726
+ }
1727
+ if (hasHandleCode) {
1728
+ const fnNames = getFnNames("createHandle");
1729
+ changed = transformHandles(
1730
+ getBindings(code, fnNames),
1478
1731
  s,
1732
+ code,
1479
1733
  filePath,
1480
1734
  isBuild
1481
1735
  ) || changed;
1482
1736
  }
1483
- }
1484
- if (hasStaticHandlerCode) {
1485
- const fnNames = getFnNames(STATIC_CONFIG.fnName);
1486
- const bindings = getBindings(code, fnNames);
1487
- if (isRscEnv) {
1488
- changed = transformHandlerIds(
1489
- STATIC_CONFIG,
1490
- bindings,
1737
+ if (hasLocationStateCode) {
1738
+ const fnNames = getFnNames("createLocationState");
1739
+ changed = transformLocationState(
1740
+ getBindings(code, fnNames),
1491
1741
  s,
1492
1742
  filePath,
1493
1743
  isBuild
1494
1744
  ) || changed;
1495
- } else {
1496
- changed = stubHandlerExprs(STATIC_CONFIG, bindings, s, filePath, isBuild) || changed;
1497
1745
  }
1746
+ const finalHandlerConfigs = [
1747
+ hasPrerenderHandlerCode && PRERENDER_CONFIG,
1748
+ hasStaticHandlerCode && STATIC_CONFIG
1749
+ ].filter((c) => !!c);
1750
+ for (const cfg of finalHandlerConfigs) {
1751
+ const bindings = getBindings(code, getFnNames(cfg.fnName));
1752
+ changed = (isRscEnv ? transformHandlerIds(cfg, bindings, s, filePath, isBuild) : stubHandlerExprs(cfg, bindings, s, filePath, isBuild)) || changed;
1753
+ }
1754
+ if (!changed) return;
1755
+ return {
1756
+ code: s.toString(),
1757
+ map: s.generateMap({ source: id, includeContent: true })
1758
+ };
1759
+ } finally {
1760
+ counter?.record(id, performance.now() - __t0);
1498
1761
  }
1499
- if (!changed) return;
1500
- return {
1501
- code: s.toString(),
1502
- map: s.generateMap({ source: id, includeContent: true })
1503
- };
1504
1762
  }
1505
1763
  };
1506
1764
  }
1507
1765
 
1508
1766
  // src/vite/plugins/use-cache-transform.ts
1509
1767
  import path5 from "node:path";
1510
- import MagicString5 from "magic-string";
1768
+ import MagicString4 from "magic-string";
1769
+ var debug4 = createRangoDebugger(NS.transform);
1511
1770
  var CACHE_RUNTIME_IMPORT = "@rangojs/router/cache-runtime";
1512
1771
  var LAYOUT_TEMPLATE_PATTERN = /\/(layout|template)\.(tsx?|jsx?)$/;
1772
+ var USE_CACHE_DIRECTIVE_RE = /^use cache(:\s*[\w-]+)?$/;
1513
1773
  function useCacheTransform() {
1514
1774
  let projectRoot = "";
1515
1775
  let isBuild = false;
1516
1776
  let rscTransforms = null;
1777
+ const counter = createCounter(debug4, "use-cache");
1517
1778
  return {
1518
1779
  name: "@rangojs/router:use-cache",
1519
1780
  enforce: "post",
@@ -1521,53 +1782,61 @@ function useCacheTransform() {
1521
1782
  projectRoot = config.root;
1522
1783
  isBuild = config.command === "build";
1523
1784
  },
1785
+ buildEnd() {
1786
+ counter?.flush();
1787
+ },
1524
1788
  async transform(code, id) {
1525
1789
  if (this.environment?.name !== "rsc") return;
1526
1790
  if (!code.includes("use cache")) return;
1527
1791
  if (id.includes("/node_modules/") || id.startsWith("\0")) return;
1528
1792
  if (!/\.(tsx?|jsx?|mjs)$/.test(id)) return;
1529
- if (!rscTransforms) {
1793
+ const start = counter ? performance.now() : 0;
1794
+ try {
1795
+ if (!rscTransforms) {
1796
+ try {
1797
+ rscTransforms = await import("@vitejs/plugin-rsc/transforms");
1798
+ } catch {
1799
+ return;
1800
+ }
1801
+ }
1802
+ const {
1803
+ hasDirective,
1804
+ transformWrapExport,
1805
+ transformHoistInlineDirective
1806
+ } = rscTransforms;
1807
+ let ast;
1530
1808
  try {
1531
- rscTransforms = await import("@vitejs/plugin-rsc/transforms");
1809
+ const { parseAst: parseAst4 } = await import("vite");
1810
+ ast = parseAst4(code, { lang: "tsx" });
1532
1811
  } catch {
1533
1812
  return;
1534
1813
  }
1535
- }
1536
- const {
1537
- hasDirective,
1538
- transformWrapExport,
1539
- transformHoistInlineDirective
1540
- } = rscTransforms;
1541
- let ast;
1542
- try {
1543
- const { parseAst: parseAst4 } = await import("vite");
1544
- ast = parseAst4(code);
1545
- } catch {
1546
- return;
1547
- }
1548
- const filePath = normalizePath(path5.relative(projectRoot, id));
1549
- const isLayoutOrTemplate = LAYOUT_TEMPLATE_PATTERN.test(id);
1550
- if (hasDirective(ast.body, "use cache")) {
1551
- return transformFileLevelUseCache(
1814
+ const filePath = normalizePath(path5.relative(projectRoot, id));
1815
+ const isLayoutOrTemplate = LAYOUT_TEMPLATE_PATTERN.test(id);
1816
+ if (hasDirective(ast.body, "use cache")) {
1817
+ return transformFileLevelUseCache(
1818
+ code,
1819
+ ast,
1820
+ filePath,
1821
+ id,
1822
+ isBuild,
1823
+ isLayoutOrTemplate,
1824
+ transformWrapExport
1825
+ );
1826
+ }
1827
+ const functionResult = transformFunctionLevelUseCache(
1552
1828
  code,
1553
1829
  ast,
1554
1830
  filePath,
1555
1831
  id,
1556
1832
  isBuild,
1557
- isLayoutOrTemplate,
1558
- transformWrapExport
1833
+ transformHoistInlineDirective
1559
1834
  );
1835
+ warnOnNearMissDirectives(ast, id, this.warn.bind(this));
1836
+ if (functionResult) return functionResult;
1837
+ } finally {
1838
+ counter?.record(id, performance.now() - start);
1560
1839
  }
1561
- const functionResult = transformFunctionLevelUseCache(
1562
- code,
1563
- ast,
1564
- filePath,
1565
- id,
1566
- isBuild,
1567
- transformHoistInlineDirective
1568
- );
1569
- warnOnNearMissDirectives(ast, id, this.warn.bind(this));
1570
- if (functionResult) return functionResult;
1571
1840
  }
1572
1841
  };
1573
1842
  }
@@ -1594,7 +1863,7 @@ function transformFileLevelUseCache(code, ast, filePath, sourceId, isBuild, isLa
1594
1863
  );
1595
1864
  }
1596
1865
  if (exportNames.length === 0) {
1597
- const s = new MagicString5(code);
1866
+ const s = new MagicString4(code);
1598
1867
  const directive2 = findFileLevelDirective(ast);
1599
1868
  if (directive2) {
1600
1869
  s.overwrite(
@@ -1629,7 +1898,7 @@ function transformFileLevelUseCache(code, ast, filePath, sourceId, isBuild, isLa
1629
1898
  function transformFunctionLevelUseCache(code, ast, filePath, sourceId, isBuild, transformHoistInlineDirective) {
1630
1899
  try {
1631
1900
  const { output, names } = transformHoistInlineDirective(code, ast, {
1632
- directive: /^use cache(:\s*[\w-]+)?$/,
1901
+ directive: USE_CACHE_DIRECTIVE_RE,
1633
1902
  runtime: (value, name, meta) => {
1634
1903
  const funcId = isBuild ? hashId(filePath, name) : `${filePath}#${name}`;
1635
1904
  const profileMatch = meta.directiveMatch[1];
@@ -1659,14 +1928,13 @@ function findFileLevelDirective(ast) {
1659
1928
  }
1660
1929
  return null;
1661
1930
  }
1662
- var VALID_DIRECTIVE_RE = /^use cache(:\s*[\w-]+)?$/;
1663
1931
  var NEAR_MISS_RE = /^use cache:\s*.+$/;
1664
1932
  function warnOnNearMissDirectives(ast, fileId, warn) {
1665
1933
  const visit = (node) => {
1666
1934
  if (!node || typeof node !== "object") return;
1667
1935
  if (node.type === "ExpressionStatement" && node.expression?.type === "Literal" && typeof node.expression.value === "string") {
1668
1936
  const value = node.expression.value;
1669
- if (value.startsWith("use cache") && NEAR_MISS_RE.test(value) && !VALID_DIRECTIVE_RE.test(value)) {
1937
+ if (value.startsWith("use cache") && NEAR_MISS_RE.test(value) && !USE_CACHE_DIRECTIVE_RE.test(value)) {
1670
1938
  const profilePart = value.slice("use cache:".length).trim();
1671
1939
  warn(
1672
1940
  `[rango:use-cache] "${value}" in ${fileId} has an invalid profile name "${profilePart}". Profile names must match [a-zA-Z0-9_-]+. This directive will be ignored.`
@@ -1690,6 +1958,7 @@ function warnOnNearMissDirectives(ast, fileId, warn) {
1690
1958
  }
1691
1959
 
1692
1960
  // src/vite/plugins/client-ref-dedup.ts
1961
+ var debug5 = createRangoDebugger(NS.transform);
1693
1962
  var CLIENT_IN_SERVER_PROXY_PREFIX = "virtual:vite-rsc/client-in-server-package-proxy/";
1694
1963
  function extractPackageName(absolutePath) {
1695
1964
  const marker = "/node_modules/";
@@ -1706,6 +1975,7 @@ function extractPackageName(absolutePath) {
1706
1975
  }
1707
1976
  function clientRefDedup() {
1708
1977
  let clientExclude = [];
1978
+ const dedupedPackages = /* @__PURE__ */ new Set();
1709
1979
  return {
1710
1980
  name: "@rangojs/router:client-ref-dedup",
1711
1981
  enforce: "pre",
@@ -1714,6 +1984,15 @@ function clientRefDedup() {
1714
1984
  const clientEnv = config.environments?.["client"];
1715
1985
  clientExclude = clientEnv?.optimizeDeps?.exclude ?? config.optimizeDeps?.exclude ?? [];
1716
1986
  },
1987
+ buildEnd() {
1988
+ if (debug5 && dedupedPackages.size > 0) {
1989
+ debug5(
1990
+ "client-ref-dedup: redirected %d package(s) (%s)",
1991
+ dedupedPackages.size,
1992
+ [...dedupedPackages].join(",")
1993
+ );
1994
+ }
1995
+ },
1717
1996
  resolveId(source, importer, options) {
1718
1997
  if (this.environment?.name !== "client") return;
1719
1998
  if (!importer?.includes(CLIENT_IN_SERVER_PROXY_PREFIX)) return;
@@ -1722,6 +2001,7 @@ function clientRefDedup() {
1722
2001
  const packageName = extractPackageName(source);
1723
2002
  if (!packageName) return;
1724
2003
  if (clientExclude.includes(packageName)) return;
2004
+ if (debug5) dedupedPackages.add(packageName);
1725
2005
  return `\0rango:dedup/${packageName}`;
1726
2006
  },
1727
2007
  load(id) {
@@ -1748,7 +2028,7 @@ import {
1748
2028
  import { createElement, StrictMode } from "react";
1749
2029
  import { hydrateRoot } from "react-dom/client";
1750
2030
  import { rscStream } from "@rangojs/router/internal/deps/html-stream-client";
1751
- import { initBrowserApp, RSCRouter } from "@rangojs/router/browser";
2031
+ import { initBrowserApp, Rango } from "@rangojs/router/browser";
1752
2032
 
1753
2033
  async function initializeApp() {
1754
2034
  const deps = {
@@ -1763,7 +2043,7 @@ async function initializeApp() {
1763
2043
 
1764
2044
  hydrateRoot(
1765
2045
  document,
1766
- createElement(StrictMode, null, createElement(RSCRouter))
2046
+ createElement(StrictMode, null, createElement(Rango))
1767
2047
  );
1768
2048
  }
1769
2049
 
@@ -1844,12 +2124,13 @@ function getVirtualVersionContent(version) {
1844
2124
 
1845
2125
  // src/vite/utils/package-resolution.ts
1846
2126
  import { existsSync } from "node:fs";
2127
+ import { createRequire } from "node:module";
1847
2128
  import { resolve } from "node:path";
1848
2129
 
1849
2130
  // package.json
1850
2131
  var package_default = {
1851
2132
  name: "@rangojs/router",
1852
- version: "0.0.0-experimental.dfa55db4",
2133
+ version: "0.0.0-experimental.e16b7c00",
1853
2134
  description: "Django-inspired RSC router with composable URL patterns",
1854
2135
  keywords: [
1855
2136
  "react",
@@ -1982,22 +2263,26 @@ var package_default = {
1982
2263
  tag: "experimental"
1983
2264
  },
1984
2265
  scripts: {
1985
- build: "pnpm dlx esbuild src/vite/index.ts --bundle --format=esm --outfile=dist/vite/index.js --platform=node --packages=external && pnpm dlx esbuild src/bin/rango.ts --bundle --format=esm --outfile=dist/bin/rango.js --platform=node --packages=external --banner:js='#!/usr/bin/env node' && chmod +x dist/bin/rango.js",
2266
+ build: "pnpm dlx esbuild src/vite/index.ts --bundle --format=esm --outfile=dist/vite/index.js --platform=node --packages=external && mkdir -p dist/vite/plugins && cp src/vite/plugins/cloudflare-protocol-loader-hook.mjs dist/vite/plugins/cloudflare-protocol-loader-hook.mjs && pnpm dlx esbuild src/bin/rango.ts --bundle --format=esm --outfile=dist/bin/rango.js --platform=node --packages=external --banner:js='#!/usr/bin/env node' && chmod +x dist/bin/rango.js",
1986
2267
  prepublishOnly: "pnpm build",
1987
- typecheck: "tsc --noEmit",
2268
+ typecheck: "tsc --noEmit && tsc -p tsconfig.strict-check.json --noEmit && tsc -p tsconfig.augment-check.json --noEmit",
1988
2269
  test: "playwright test",
1989
2270
  "test:ui": "playwright test --ui",
2271
+ "test:hmr-local": "playwright test --project=dev-warmup --project=hmr-routes --project=hmr-basename --project=hmr-prerender --no-deps --workers=1",
1990
2272
  "test:unit": "vitest run",
1991
2273
  "test:unit:watch": "vitest"
1992
2274
  },
1993
2275
  dependencies: {
1994
- "@vitejs/plugin-rsc": "^0.5.19",
2276
+ "@types/debug": "^4.1.12",
2277
+ "@vitejs/plugin-rsc": "^0.5.26",
2278
+ debug: "^4.4.1",
1995
2279
  "magic-string": "^0.30.17",
1996
2280
  picomatch: "^4.0.3",
1997
2281
  "rsc-html-stream": "^0.0.7"
1998
2282
  },
1999
2283
  devDependencies: {
2000
2284
  "@playwright/test": "^1.49.1",
2285
+ "@shared/e2e": "workspace:*",
2001
2286
  "@types/node": "^24.10.1",
2002
2287
  "@types/react": "catalog:",
2003
2288
  "@types/react-dom": "catalog:",
@@ -2010,10 +2295,11 @@ var package_default = {
2010
2295
  vitest: "^4.0.0"
2011
2296
  },
2012
2297
  peerDependencies: {
2013
- "@cloudflare/vite-plugin": "^1.25.0",
2014
- "@vitejs/plugin-rsc": "^0.5.14",
2015
- react: "^18.0.0 || ^19.0.0",
2016
- vite: "^7.3.0"
2298
+ "@cloudflare/vite-plugin": "^1.38.0",
2299
+ "@vitejs/plugin-rsc": "^0.5.26",
2300
+ react: ">=19.2.6 <20",
2301
+ "react-dom": ">=19.2.6 <20",
2302
+ vite: "^8.0.0"
2017
2303
  },
2018
2304
  peerDependenciesMeta: {
2019
2305
  "@cloudflare/vite-plugin": {
@@ -2026,6 +2312,7 @@ var package_default = {
2026
2312
  };
2027
2313
 
2028
2314
  // src/vite/utils/package-resolution.ts
2315
+ var require2 = createRequire(import.meta.url);
2029
2316
  var VIRTUAL_PACKAGE_NAME = "@rangojs/router";
2030
2317
  function getPublishedPackageName() {
2031
2318
  return package_default.name;
@@ -2066,6 +2353,20 @@ function getPackageAliases() {
2066
2353
  }
2067
2354
  return aliases;
2068
2355
  }
2356
+ function getVendorAliases() {
2357
+ const specs = [
2358
+ "@vitejs/plugin-rsc/vendor/react-server-dom/client.edge",
2359
+ "@vitejs/plugin-rsc/vendor/react-server-dom/server.edge"
2360
+ ];
2361
+ const aliases = {};
2362
+ for (const spec of specs) {
2363
+ try {
2364
+ aliases[spec] = require2.resolve(spec);
2365
+ } catch {
2366
+ }
2367
+ }
2368
+ return aliases;
2369
+ }
2069
2370
 
2070
2371
  // src/build/route-types/param-extraction.ts
2071
2372
  function extractParamsFromPattern(pattern) {
@@ -2191,7 +2492,7 @@ ${objectBody}
2191
2492
  } as const;
2192
2493
 
2193
2494
  declare global {
2194
- namespace RSCRouter {
2495
+ namespace Rango {
2195
2496
  interface GeneratedRouteMap extends Readonly<typeof NamedRoutes> {}
2196
2497
  }
2197
2498
  }
@@ -2426,7 +2727,7 @@ function buildCombinedRouteMapWithSearch(filePath, variableName, visited, diagno
2426
2727
  const realPath = resolve2(filePath);
2427
2728
  const key = variableName ? `${realPath}:${variableName}` : realPath;
2428
2729
  if (visited.has(key)) {
2429
- console.warn(`[rsc-router] Circular include detected, skipping: ${key}`);
2730
+ console.warn(`[rango] Circular include detected, skipping: ${key}`);
2430
2731
  return { routes: {}, searchSchemas: {} };
2431
2732
  }
2432
2733
  visited.add(key);
@@ -2487,6 +2788,7 @@ function countPublicRouteEntries(source) {
2487
2788
  return count;
2488
2789
  }
2489
2790
  var ROUTER_CALL_PATTERN = /\bcreateRouter\s*[<(]/;
2791
+ var ROUTER_CALL_PATTERN_G = /\bcreateRouter\s*[<(]/g;
2490
2792
  function isRoutableSourceFile(name) {
2491
2793
  return (name.endsWith(".ts") || name.endsWith(".tsx") || name.endsWith(".js") || name.endsWith(".jsx")) && !name.includes(".gen.") && !name.includes(".test.") && !name.includes(".spec.");
2492
2794
  }
@@ -2496,7 +2798,7 @@ function findRouterFilesRecursive(dir, filter, results) {
2496
2798
  entries = readdirSync(dir, { withFileTypes: true });
2497
2799
  } catch (err) {
2498
2800
  console.warn(
2499
- `[rsc-router] Failed to scan directory ${dir}: ${err.message}`
2801
+ `[rango] Failed to scan directory ${dir}: ${err.message}`
2500
2802
  );
2501
2803
  return;
2502
2804
  }
@@ -2514,7 +2816,7 @@ function findRouterFilesRecursive(dir, filter, results) {
2514
2816
  if (filter && !filter(fullPath)) continue;
2515
2817
  try {
2516
2818
  const source = readFileSync2(fullPath, "utf-8");
2517
- if (ROUTER_CALL_PATTERN.test(source)) {
2819
+ if (ROUTER_CALL_PATTERN.test(source) && firstCodeMatchIndex(source, ROUTER_CALL_PATTERN_G) >= 0) {
2518
2820
  routerFilesInDir.push(fullPath);
2519
2821
  }
2520
2822
  } catch {
@@ -2552,7 +2854,7 @@ function findNestedRouterConflict(routerFiles) {
2552
2854
  }
2553
2855
  return null;
2554
2856
  }
2555
- function formatNestedRouterConflictError(conflict, prefix = "[rsc-router]") {
2857
+ function formatNestedRouterConflictError(conflict, prefix = "[rango]") {
2556
2858
  return `${prefix} Nested router roots are not supported.
2557
2859
  Router root: ${conflict.ancestor}
2558
2860
  Nested router: ${conflict.nested}
@@ -2648,19 +2950,38 @@ function extractBasenameFromRouter(code) {
2648
2950
  visit(sourceFile);
2649
2951
  return result;
2650
2952
  }
2651
- function applyBasenameToRoutes(result, basename3) {
2953
+ function applyBasenameToRoutes(result, basename2) {
2652
2954
  const prefixed = {};
2653
2955
  for (const [name, pattern] of Object.entries(result.routes)) {
2654
2956
  if (pattern === "/") {
2655
- prefixed[name] = basename3;
2656
- } else if (basename3.endsWith("/") && pattern.startsWith("/")) {
2657
- prefixed[name] = basename3 + pattern.slice(1);
2957
+ prefixed[name] = basename2;
2958
+ } else if (basename2.endsWith("/") && pattern.startsWith("/")) {
2959
+ prefixed[name] = basename2 + pattern.slice(1);
2658
2960
  } else {
2659
- prefixed[name] = basename3 + pattern;
2961
+ prefixed[name] = basename2 + pattern;
2660
2962
  }
2661
2963
  }
2662
2964
  return { routes: prefixed, searchSchemas: result.searchSchemas };
2663
2965
  }
2966
+ function genFileTsPath(sourceFile) {
2967
+ const base = pathBasename(sourceFile).replace(/\.(tsx?|jsx?)$/, "");
2968
+ return join(dirname2(sourceFile), `${base}.named-routes.gen.ts`);
2969
+ }
2970
+ function resolveSearchSchemas(publicRouteNames, runtimeSchemas, sourceFile) {
2971
+ if (runtimeSchemas && Object.keys(runtimeSchemas).length > 0) {
2972
+ return runtimeSchemas;
2973
+ }
2974
+ const staticParsed = buildCombinedRouteMapForRouterFile(sourceFile);
2975
+ if (Object.keys(staticParsed.searchSchemas).length === 0) {
2976
+ return runtimeSchemas;
2977
+ }
2978
+ const filtered = {};
2979
+ for (const name of publicRouteNames) {
2980
+ const schema = staticParsed.searchSchemas[name];
2981
+ if (schema) filtered[name] = schema;
2982
+ }
2983
+ return Object.keys(filtered).length > 0 ? filtered : runtimeSchemas;
2984
+ }
2664
2985
  function buildCombinedRouteMapForRouterFile(routerFilePath) {
2665
2986
  let routerSource;
2666
2987
  try {
@@ -2673,7 +2994,7 @@ function buildCombinedRouteMapForRouterFile(routerFilePath) {
2673
2994
  return { routes: {}, searchSchemas: {} };
2674
2995
  }
2675
2996
  const rawBasename = extractBasenameFromRouter(routerSource);
2676
- const basename3 = rawBasename ? ("/" + rawBasename.replace(/^\/+|\/+$/g, "")).replace(/^\/$/, "") : void 0;
2997
+ const basename2 = rawBasename ? ("/" + rawBasename.replace(/^\/+|\/+$/g, "")).replace(/^\/$/, "") : void 0;
2677
2998
  let result;
2678
2999
  if (extraction.kind === "inline") {
2679
3000
  result = buildCombinedRouteMapWithSearch(
@@ -2698,8 +3019,8 @@ function buildCombinedRouteMapForRouterFile(routerFilePath) {
2698
3019
  result = buildCombinedRouteMapWithSearch(routerFilePath, extraction.name);
2699
3020
  }
2700
3021
  }
2701
- if (basename3) {
2702
- result = applyBasenameToRoutes(result, basename3);
3022
+ if (basename2) {
3023
+ result = applyBasenameToRoutes(result, basename2);
2703
3024
  }
2704
3025
  return result;
2705
3026
  }
@@ -2714,7 +3035,7 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
2714
3035
  if (existsSync3(oldCombinedPath)) {
2715
3036
  unlinkSync(oldCombinedPath);
2716
3037
  console.log(
2717
- `[rsc-router] Removed stale combined route types: ${oldCombinedPath}`
3038
+ `[rango] Removed stale combined route types: ${oldCombinedPath}`
2718
3039
  );
2719
3040
  }
2720
3041
  } catch {
@@ -2736,18 +3057,12 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
2736
3057
  }
2737
3058
  if (!extractUrlsFromRouter(routerSource)) continue;
2738
3059
  }
2739
- const routerBasename = pathBasename(routerFilePath).replace(
2740
- /\.(tsx?|jsx?)$/,
2741
- ""
2742
- );
2743
- const outPath = join(
2744
- dirname2(routerFilePath),
2745
- `${routerBasename}.named-routes.gen.ts`
2746
- );
3060
+ const outPath = genFileTsPath(routerFilePath);
2747
3061
  const existing = existsSync3(outPath) ? readFileSync2(outPath, "utf-8") : null;
2748
3062
  if (Object.keys(result.routes).length === 0) {
2749
3063
  if (!existing) {
2750
3064
  const emptySource = generateRouteTypesSource({});
3065
+ opts?.onWrite?.(outPath, emptySource);
2751
3066
  writeFileSync(outPath, emptySource);
2752
3067
  }
2753
3068
  continue;
@@ -2767,9 +3082,10 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
2767
3082
  continue;
2768
3083
  }
2769
3084
  }
3085
+ opts?.onWrite?.(outPath, source);
2770
3086
  writeFileSync(outPath, source);
2771
3087
  console.log(
2772
- `[rsc-router] Generated route types (${Object.keys(result.routes).length} routes) -> ${outPath}`
3088
+ `[rango] Generated route types (${Object.keys(result.routes).length} routes) -> ${outPath}`
2773
3089
  );
2774
3090
  }
2775
3091
  }
@@ -2786,7 +3102,7 @@ function normalizeModuleId(id) {
2786
3102
  function getClientModuleSignature(source) {
2787
3103
  let program;
2788
3104
  try {
2789
- program = parseAst3(source, { jsx: true });
3105
+ program = parseAst3(source, { lang: "tsx" });
2790
3106
  } catch {
2791
3107
  return void 0;
2792
3108
  }
@@ -2869,11 +3185,12 @@ function createVersionPlugin() {
2869
3185
  let currentVersion = buildVersion;
2870
3186
  let isDev = false;
2871
3187
  let server = null;
3188
+ let resolvedCacheDir;
2872
3189
  const clientModuleSignatures = /* @__PURE__ */ new Map();
2873
3190
  let versionCounter = 0;
2874
3191
  const bumpVersion = (reason) => {
2875
3192
  currentVersion = Date.now().toString(16) + String(++versionCounter);
2876
- console.log(`[rsc-router] ${reason}, version updated: ${currentVersion}`);
3193
+ console.log(`[rango] ${reason}, version updated: ${currentVersion}`);
2877
3194
  const rscEnv = server?.environments?.rsc;
2878
3195
  const versionMod = rscEnv?.moduleGraph?.getModuleById(
2879
3196
  "\0" + VIRTUAL_IDS.version
@@ -2887,6 +3204,7 @@ function createVersionPlugin() {
2887
3204
  enforce: "pre",
2888
3205
  configResolved(config) {
2889
3206
  isDev = config.command === "serve";
3207
+ resolvedCacheDir = config.cacheDir ? String(config.cacheDir).replace(/\\/g, "/") : void 0;
2890
3208
  },
2891
3209
  configureServer(devServer) {
2892
3210
  server = devServer;
@@ -2928,6 +3246,7 @@ function createVersionPlugin() {
2928
3246
  if (!isDev) return;
2929
3247
  const isRscModule = this.environment?.name === "rsc";
2930
3248
  if (!isRscModule) return;
3249
+ if (isViteDepCachePath(ctx.file, resolvedCacheDir)) return;
2931
3250
  if (ctx.modules.length === 1 && ctx.modules[0].id === "\0" + VIRTUAL_IDS.version) {
2932
3251
  return;
2933
3252
  }
@@ -2957,12 +3276,24 @@ function createVersionPlugin() {
2957
3276
  }
2958
3277
  };
2959
3278
  }
3279
+ function isViteDepCachePath(filePath, cacheDir) {
3280
+ if (!filePath) return false;
3281
+ const normalized = filePath.replace(/\\/g, "/");
3282
+ if (cacheDir) {
3283
+ const normalizedCacheDir = cacheDir.replace(/\\/g, "/").replace(/\/+$/, "");
3284
+ if (normalized === normalizedCacheDir || normalized.startsWith(normalizedCacheDir + "/")) {
3285
+ return true;
3286
+ }
3287
+ }
3288
+ return /\/node_modules\/\.vite[^/]*\//.test(normalized) || normalized.includes("/.vite-isolated/");
3289
+ }
2960
3290
 
2961
3291
  // src/vite/utils/shared-utils.ts
2962
3292
  import * as Vite from "vite";
2963
3293
 
2964
3294
  // src/vite/plugins/performance-tracks.ts
2965
3295
  import { readFile } from "node:fs/promises";
3296
+ var debug6 = createRangoDebugger(NS.transform);
2966
3297
  var RSDW_PATCH_RE = /((?:var|let|const)\s+\w+\s*=\s*root\._children\s*,\s*(\w+)\s*=\s*root\._debugInfo\s*[;,])/;
2967
3298
  function buildPatchReplacement(match, debugInfoVar) {
2968
3299
  return `${match}
@@ -2984,62 +3315,65 @@ function patchRsdwClientDebugInfoRecovery(code) {
2984
3315
  };
2985
3316
  }
2986
3317
  function performanceTracksOptimizeDepsPlugin() {
3318
+ const RSDW_CLIENT_RE = /react-server-dom-webpack-client\.browser\.(development|production)\.js$/;
2987
3319
  return {
2988
3320
  name: "@rangojs/router:performance-tracks-optimize-deps",
2989
- setup(build) {
2990
- build.onLoad(
2991
- {
2992
- filter: /react-server-dom-webpack-client\.browser\.(development|production)\.js$/
2993
- },
2994
- async (args) => {
2995
- const code = await readFile(args.path, "utf8");
2996
- const patched = patchRsdwClientDebugInfoRecovery(code);
2997
- return {
2998
- contents: patched.code,
2999
- loader: "js"
3000
- };
3001
- }
3002
- );
3321
+ // Vite 8 optimizes deps with Rolldown (Rollup-style plugin pipeline), so the
3322
+ // pre-bundled RSDW client is patched via load() rather than esbuild's onLoad.
3323
+ // Returning code overrides Rolldown's default filesystem read for the module.
3324
+ async load(id) {
3325
+ const cleanId = id.split("?")[0] ?? id;
3326
+ if (!RSDW_CLIENT_RE.test(cleanId)) return null;
3327
+ const code = await readFile(cleanId, "utf8");
3328
+ const patched = patchRsdwClientDebugInfoRecovery(code);
3329
+ return { code: patched.code };
3003
3330
  }
3004
3331
  };
3005
3332
  }
3006
3333
  function performanceTracksPlugin() {
3334
+ const counter = createCounter(debug6, "performance-tracks");
3007
3335
  return {
3008
3336
  name: "@rangojs/router:performance-tracks",
3337
+ buildEnd() {
3338
+ counter?.flush();
3339
+ },
3009
3340
  transform(code, id) {
3010
3341
  if (!id.includes("react-server-dom") || !id.includes("client")) return;
3011
- const patched = patchRsdwClientDebugInfoRecovery(code);
3012
- if (!patched.debugInfoVar) return;
3013
- if (process.env.INTERNAL_RANGO_DEBUG)
3014
- console.log(
3015
- "[perf-tracks] patched RSDW client (var:",
3016
- patched.debugInfoVar,
3017
- ")"
3018
- );
3019
- return patched.code;
3342
+ const start = counter ? performance.now() : 0;
3343
+ try {
3344
+ const patched = patchRsdwClientDebugInfoRecovery(code);
3345
+ if (!patched.debugInfoVar) return;
3346
+ debug6?.("patched RSDW client (var: %s)", patched.debugInfoVar);
3347
+ return patched.code;
3348
+ } finally {
3349
+ counter?.record(id, performance.now() - start);
3350
+ }
3020
3351
  }
3021
3352
  };
3022
3353
  }
3023
3354
 
3024
3355
  // src/vite/utils/shared-utils.ts
3025
- var versionEsbuildPlugin = {
3356
+ function resolveRscEntryFromConfig(config) {
3357
+ const entries = config.environments?.["rsc"]?.optimizeDeps?.entries;
3358
+ if (typeof entries === "string") return entries;
3359
+ if (Array.isArray(entries) && entries.length > 0) return entries[0];
3360
+ return void 0;
3361
+ }
3362
+ var versionRolldownPlugin = {
3026
3363
  name: "@rangojs/router-version",
3027
- setup(build) {
3028
- build.onResolve({ filter: /^rsc-router:version$/ }, (args) => ({
3029
- path: args.path,
3030
- namespace: "@rangojs/router-virtual"
3031
- }));
3032
- build.onLoad(
3033
- { filter: /.*/, namespace: "@rangojs/router-virtual" },
3034
- () => ({
3035
- contents: `export const VERSION = "dev";`,
3036
- loader: "js"
3037
- })
3038
- );
3364
+ resolveId(id) {
3365
+ if (id === VIRTUAL_IDS.version) return "\0" + VIRTUAL_IDS.version;
3366
+ return void 0;
3367
+ },
3368
+ load(id) {
3369
+ if (id === "\0" + VIRTUAL_IDS.version) {
3370
+ return getVirtualVersionContent("dev");
3371
+ }
3372
+ return void 0;
3039
3373
  }
3040
3374
  };
3041
- var sharedEsbuildOptions = {
3042
- plugins: [versionEsbuildPlugin, performanceTracksOptimizeDepsPlugin()]
3375
+ var sharedRolldownOptions = {
3376
+ plugins: [versionRolldownPlugin, performanceTracksOptimizeDepsPlugin()]
3043
3377
  };
3044
3378
  function createVirtualEntriesPlugin(entries, routerPathRef) {
3045
3379
  const virtualModules = {};
@@ -3081,8 +3415,29 @@ function createVirtualEntriesPlugin(entries, routerPathRef) {
3081
3415
  }
3082
3416
  };
3083
3417
  }
3418
+ function isContentHashedAssetConflict(message) {
3419
+ if (!message) return false;
3420
+ const match = /The emitted file "?([^"\s]+)"? overwrites a previously emitted file/.exec(
3421
+ message
3422
+ );
3423
+ if (!match) return false;
3424
+ const fileName = match[1];
3425
+ const base = fileName.slice(fileName.lastIndexOf("/") + 1);
3426
+ const dot = base.lastIndexOf(".");
3427
+ if (dot <= 0) return false;
3428
+ const stem = base.slice(0, dot);
3429
+ const HASH_LEN = 8;
3430
+ if (stem.length < HASH_LEN + 1 || stem[stem.length - HASH_LEN - 1] !== "-") {
3431
+ return false;
3432
+ }
3433
+ const hash = stem.slice(-HASH_LEN);
3434
+ return /^[A-Za-z0-9_-]+$/.test(hash) && /[A-Z0-9]/.test(hash);
3435
+ }
3084
3436
  function onwarn(warning, defaultHandler) {
3085
- if (warning.code === "MODULE_LEVEL_DIRECTIVE" || warning.code === "SOURCEMAP_ERROR" || warning.code === "EMPTY_BUNDLE") {
3437
+ if (warning.code === "MODULE_LEVEL_DIRECTIVE" || warning.code === "SOURCEMAP_ERROR" || warning.code === "EMPTY_BUNDLE" || warning.code === "INEFFECTIVE_DYNAMIC_IMPORT") {
3438
+ return;
3439
+ }
3440
+ if (warning.code === "FILE_NAME_CONFLICT" && isContentHashedAssetConflict(warning.message)) {
3086
3441
  return;
3087
3442
  }
3088
3443
  if (warning.message?.includes("Sourcemap is likely to be incorrect")) {
@@ -3101,12 +3456,138 @@ function getManualChunks(id) {
3101
3456
  return "react";
3102
3457
  }
3103
3458
  const packageName = getPublishedPackageName();
3104
- if (normalized.includes(`node_modules/${packageName}/`) || normalized.includes("packages/rsc-router/") || normalized.includes("packages/rangojs-router/")) {
3459
+ if (normalized.includes(`node_modules/${packageName}/`) || /\/packages\/(rsc-router|rangojs-router)\/(src|dist)\//.test(normalized)) {
3105
3460
  return "router";
3106
3461
  }
3107
3462
  return void 0;
3108
3463
  }
3109
3464
 
3465
+ // src/vite/plugins/client-ref-hashing.ts
3466
+ import { relative } from "node:path";
3467
+ import { createHash as createHash2 } from "node:crypto";
3468
+ var debug7 = createRangoDebugger(NS.transform);
3469
+ var CLIENT_PKG_PROXY_PREFIX = "/@id/__x00__virtual:vite-rsc/client-package-proxy/";
3470
+ var CLIENT_IN_SERVER_PKG_PROXY_PREFIX = "/@id/__x00__virtual:vite-rsc/client-in-server-package-proxy/";
3471
+ var FS_PREFIX = "/@fs/";
3472
+ function hashRefKey(relativeId) {
3473
+ return createHash2("sha256").update(relativeId).digest("hex").slice(0, 12);
3474
+ }
3475
+ function computeProductionHash(projectRoot, refKey) {
3476
+ let toHash;
3477
+ if (refKey.startsWith(CLIENT_PKG_PROXY_PREFIX)) {
3478
+ toHash = refKey.slice(CLIENT_PKG_PROXY_PREFIX.length);
3479
+ } else if (refKey.startsWith(CLIENT_IN_SERVER_PKG_PROXY_PREFIX)) {
3480
+ const absPath = decodeURIComponent(
3481
+ refKey.slice(CLIENT_IN_SERVER_PKG_PROXY_PREFIX.length)
3482
+ );
3483
+ toHash = relative(projectRoot, absPath).replaceAll("\\", "/");
3484
+ } else if (refKey.startsWith(FS_PREFIX)) {
3485
+ const absPath = refKey.slice(FS_PREFIX.length - 1);
3486
+ toHash = relative(projectRoot, absPath).replaceAll("\\", "/");
3487
+ } else if (refKey.startsWith("/")) {
3488
+ toHash = refKey.slice(1);
3489
+ } else {
3490
+ return refKey;
3491
+ }
3492
+ return hashRefKey(toHash);
3493
+ }
3494
+ var REGISTER_CLIENT_REF_RE = /registerClientReference\(\s*(?:(?:\([^)]*\))|(?:\(\)[\s\S]*?\}))\s*,\s*"([^"]+)"\s*,\s*"[^"]+"\s*\)/g;
3495
+ function transformClientRefs(code, projectRoot) {
3496
+ if (!code.includes("registerClientReference")) return null;
3497
+ let hasReplacement = false;
3498
+ const result = code.replace(
3499
+ REGISTER_CLIENT_REF_RE,
3500
+ (match, refKey) => {
3501
+ const hash = computeProductionHash(projectRoot, refKey);
3502
+ if (hash === refKey) return match;
3503
+ hasReplacement = true;
3504
+ return match.replace(`"${refKey}"`, `"${hash}"`);
3505
+ }
3506
+ );
3507
+ return hasReplacement ? result : null;
3508
+ }
3509
+ function hashClientRefs(projectRoot) {
3510
+ const counter = createCounter(debug7, "hash-client-refs");
3511
+ return {
3512
+ name: "@rangojs/router:hash-client-refs",
3513
+ // Run after the RSC plugin's transform (default enforce is normal)
3514
+ enforce: "post",
3515
+ applyToEnvironment(env) {
3516
+ return env.name === "rsc";
3517
+ },
3518
+ buildEnd() {
3519
+ counter?.flush();
3520
+ },
3521
+ transform(code, id) {
3522
+ const start = counter ? performance.now() : 0;
3523
+ try {
3524
+ const result = transformClientRefs(code, projectRoot);
3525
+ if (result === null) return;
3526
+ return { code: result, map: null };
3527
+ } finally {
3528
+ counter?.record(id, performance.now() - start);
3529
+ }
3530
+ }
3531
+ };
3532
+ }
3533
+
3534
+ // src/vite/utils/client-chunks.ts
3535
+ var debugChunks = createRangoDebugger(NS.chunks);
3536
+ function isSharedRuntime(meta) {
3537
+ return [meta.id, meta.normalizedId].some(
3538
+ (path6) => path6.includes("/node_modules/") || /\/@rangojs\/router\//.test(path6) || /\/packages\/(rangojs-router|rsc-router)\/(src|dist)\//.test(path6)
3539
+ );
3540
+ }
3541
+ function sanitizeGroup(name) {
3542
+ return name.replace(/[^a-zA-Z0-9_-]+/g, "_").replace(/^_+|_+$/g, "") || "app";
3543
+ }
3544
+ var ROUTE_ROOT_DIRS = /* @__PURE__ */ new Set([
3545
+ "routes",
3546
+ "route",
3547
+ "pages",
3548
+ "page",
3549
+ "app",
3550
+ "features",
3551
+ "feature",
3552
+ "views",
3553
+ "view",
3554
+ "handlers",
3555
+ "urls",
3556
+ "modules",
3557
+ "screens",
3558
+ "sections"
3559
+ ]);
3560
+ function directoryClientChunks(meta, ctx) {
3561
+ if (isSharedRuntime(meta)) {
3562
+ return void 0;
3563
+ }
3564
+ if (ctx?.fallbackRefs.size && ctx.fallbackRefs.has(hashRefKey(meta.normalizedId))) {
3565
+ debugChunks?.("fallback %s -> app-fallback", meta.normalizedId);
3566
+ return "app-fallback";
3567
+ }
3568
+ const segments = meta.normalizedId.split("/").filter(Boolean);
3569
+ const dirCount = segments.length - 1;
3570
+ if (dirCount >= 1) {
3571
+ for (let i = 0; i < dirCount - 1; i++) {
3572
+ if (ROUTE_ROOT_DIRS.has(segments[i].toLowerCase())) {
3573
+ const group = `app-${sanitizeGroup(segments[i + 1])}`;
3574
+ debugChunks?.("split %s -> %s", meta.normalizedId, group);
3575
+ return group;
3576
+ }
3577
+ }
3578
+ }
3579
+ debugChunks?.(
3580
+ "shared %s (no route-root marker; inherits default grouping)",
3581
+ meta.normalizedId
3582
+ );
3583
+ return void 0;
3584
+ }
3585
+ function resolveClientChunks(option, ctx) {
3586
+ if (!option) return void 0;
3587
+ if (option === true) return (meta) => directoryClientChunks(meta, ctx);
3588
+ return option;
3589
+ }
3590
+
3110
3591
  // src/vite/utils/banner.ts
3111
3592
  var rangoVersion = package_default.version;
3112
3593
  var _bannerPrinted = false;
@@ -3143,15 +3624,7 @@ function createVersionInjectorPlugin(rscEntryPath) {
3143
3624
  enforce: "pre",
3144
3625
  configResolved(config) {
3145
3626
  let entryPath = rscEntryPath;
3146
- if (!entryPath) {
3147
- const rscEnvConfig = config.environments?.["rsc"];
3148
- const entries = rscEnvConfig?.optimizeDeps?.entries;
3149
- if (typeof entries === "string") {
3150
- entryPath = entries;
3151
- } else if (Array.isArray(entries) && entries.length > 0) {
3152
- entryPath = entries[0];
3153
- }
3154
- }
3627
+ if (!entryPath) entryPath = resolveRscEntryFromConfig(config);
3155
3628
  if (entryPath) {
3156
3629
  resolvedEntryPath = resolve4(config.root, entryPath);
3157
3630
  }
@@ -3163,11 +3636,10 @@ function createVersionInjectorPlugin(rscEntryPath) {
3163
3636
  if (normalizedId !== normalizedEntry) {
3164
3637
  return null;
3165
3638
  }
3166
- const prepend = [];
3639
+ const prepend = [
3640
+ `import "virtual:rsc-router/routes-manifest";`
3641
+ ];
3167
3642
  let newCode = code;
3168
- if (!code.includes("virtual:rsc-router/routes-manifest")) {
3169
- prepend.push(`import "virtual:rsc-router/routes-manifest";`);
3170
- }
3171
3643
  const needsVersion = code.includes("createRSCHandler") && !code.includes("@rangojs/router:version") && /createRSCHandler\s*\(\s*\{/.test(code);
3172
3644
  if (needsVersion) {
3173
3645
  prepend.push(`import { VERSION } from "@rangojs/router:version";`);
@@ -3176,8 +3648,21 @@ function createVersionInjectorPlugin(rscEntryPath) {
3176
3648
  "createRSCHandler({\n version: VERSION,"
3177
3649
  );
3178
3650
  }
3179
- if (prepend.length === 0 && newCode === code) return null;
3180
- newCode = prepend.join("\n") + (prepend.length > 0 ? "\n" : "") + newCode;
3651
+ const lines = newCode.split("\n");
3652
+ let insertAt = 0;
3653
+ while (insertAt < lines.length) {
3654
+ const trimmed = lines[insertAt].trim();
3655
+ if (trimmed === "" || /^\/\/\/\s*<reference\b/.test(trimmed)) {
3656
+ insertAt++;
3657
+ } else {
3658
+ break;
3659
+ }
3660
+ }
3661
+ newCode = [
3662
+ ...lines.slice(0, insertAt),
3663
+ ...prepend,
3664
+ ...lines.slice(insertAt)
3665
+ ].join("\n");
3181
3666
  return {
3182
3667
  code: newCode,
3183
3668
  map: null
@@ -3187,21 +3672,23 @@ function createVersionInjectorPlugin(rscEntryPath) {
3187
3672
  }
3188
3673
 
3189
3674
  // src/vite/plugins/cjs-to-esm.ts
3675
+ var debug8 = createRangoDebugger(NS.transform);
3190
3676
  function createCjsToEsmPlugin() {
3191
3677
  return {
3192
3678
  name: "@rangojs/router:cjs-to-esm",
3193
3679
  enforce: "pre",
3194
3680
  transform(code, id) {
3195
- const cleanId = id.split("?")[0];
3196
- if (cleanId.includes("vendor/react-server-dom/client.browser.js") || cleanId.includes("vendor\\react-server-dom\\client.browser.js")) {
3681
+ const cleanId = id.split("?")[0].replaceAll("\\", "/");
3682
+ if (cleanId.includes("vendor/react-server-dom/client.browser.js")) {
3197
3683
  const isProd = process.env.NODE_ENV === "production";
3198
3684
  const cjsFile = isProd ? "./cjs/react-server-dom-webpack-client.browser.production.js" : "./cjs/react-server-dom-webpack-client.browser.development.js";
3685
+ debug8?.("cjs-to-esm entry redirect %s", id);
3199
3686
  return {
3200
3687
  code: `export * from "${cjsFile}";`,
3201
3688
  map: null
3202
3689
  };
3203
3690
  }
3204
- if ((cleanId.includes("vendor/react-server-dom/cjs/") || cleanId.includes("vendor\\react-server-dom\\cjs\\")) && cleanId.includes("client.browser")) {
3691
+ if (cleanId.includes("vendor/react-server-dom/cjs/") && cleanId.includes("client.browser")) {
3205
3692
  let transformed = code;
3206
3693
  const licenseMatch = transformed.match(/^\/\*\*[\s\S]*?\*\//);
3207
3694
  const license = licenseMatch ? licenseMatch[0] : "";
@@ -3231,6 +3718,7 @@ function createCjsToEsmPlugin() {
3231
3718
  "export const $1 ="
3232
3719
  );
3233
3720
  transformed = license + "\n" + transformed;
3721
+ debug8?.("cjs-to-esm body rewrite %s", id);
3234
3722
  return {
3235
3723
  code: transformed,
3236
3724
  map: null
@@ -3245,7 +3733,7 @@ function createCjsToEsmPlugin() {
3245
3733
  import { createServer as createViteServer } from "vite";
3246
3734
  import { resolve as resolve8 } from "node:path";
3247
3735
  import { readFileSync as readFileSync6 } from "node:fs";
3248
- import { createRequire } from "node:module";
3736
+ import { createRequire as createRequire2, register } from "node:module";
3249
3737
  import { pathToFileURL } from "node:url";
3250
3738
 
3251
3739
  // src/vite/plugins/virtual-stub-plugin.ts
@@ -3272,61 +3760,112 @@ function createVirtualStubPlugin() {
3272
3760
  };
3273
3761
  }
3274
3762
 
3275
- // src/vite/plugins/client-ref-hashing.ts
3276
- import { relative } from "node:path";
3277
- import { createHash as createHash2 } from "node:crypto";
3278
- var CLIENT_PKG_PROXY_PREFIX = "/@id/__x00__virtual:vite-rsc/client-package-proxy/";
3279
- var CLIENT_IN_SERVER_PKG_PROXY_PREFIX = "/@id/__x00__virtual:vite-rsc/client-in-server-package-proxy/";
3280
- var FS_PREFIX = "/@fs/";
3281
- function computeProductionHash(projectRoot, refKey) {
3282
- let toHash;
3283
- if (refKey.startsWith(CLIENT_PKG_PROXY_PREFIX)) {
3284
- toHash = refKey.slice(CLIENT_PKG_PROXY_PREFIX.length);
3285
- } else if (refKey.startsWith(CLIENT_IN_SERVER_PKG_PROXY_PREFIX)) {
3286
- const absPath = decodeURIComponent(
3287
- refKey.slice(CLIENT_IN_SERVER_PKG_PROXY_PREFIX.length)
3288
- );
3289
- toHash = relative(projectRoot, absPath).replaceAll("\\", "/");
3290
- } else if (refKey.startsWith(FS_PREFIX)) {
3291
- const absPath = refKey.slice(FS_PREFIX.length - 1);
3292
- toHash = relative(projectRoot, absPath).replaceAll("\\", "/");
3293
- } else if (refKey.startsWith("/")) {
3294
- toHash = refKey.slice(1);
3295
- } else {
3296
- return refKey;
3297
- }
3298
- return createHash2("sha256").update(toHash).digest("hex").slice(0, 12);
3299
- }
3300
- var REGISTER_CLIENT_REF_RE = /registerClientReference\(\s*(?:(?:\([^)]*\))|(?:\(\)[\s\S]*?\}))\s*,\s*"([^"]+)"\s*,\s*"[^"]+"\s*\)/g;
3301
- function transformClientRefs(code, projectRoot) {
3302
- if (!code.includes("registerClientReference")) return null;
3303
- let hasReplacement = false;
3304
- const result = code.replace(
3305
- REGISTER_CLIENT_REF_RE,
3306
- (match, refKey) => {
3307
- const hash = computeProductionHash(projectRoot, refKey);
3308
- if (hash === refKey) return match;
3309
- hasReplacement = true;
3310
- return match.replace(`"${refKey}"`, `"${hash}"`);
3311
- }
3312
- );
3313
- return hasReplacement ? result : null;
3314
- }
3315
- function hashClientRefs(projectRoot) {
3763
+ // src/vite/plugins/cloudflare-protocol-stub.ts
3764
+ var VIRTUAL_PREFIX = "virtual:rango-cloudflare-stub-";
3765
+ var NULL_PREFIX = "\0" + VIRTUAL_PREFIX;
3766
+ var CF_PREFIX = "cloudflare:";
3767
+ var BUILD_ENV_GLOBAL_KEY = "__rango_build_env__";
3768
+ var SOURCE_EXT_RE = /\.[mc]?[jt]sx?$/;
3769
+ var IMPORT_NODE_TYPES = /* @__PURE__ */ new Set([
3770
+ "ImportDeclaration",
3771
+ "ImportExpression",
3772
+ "ExportNamedDeclaration",
3773
+ "ExportAllDeclaration"
3774
+ ]);
3775
+ var STUBS = {
3776
+ "cloudflare:workers": `
3777
+ export class DurableObject { constructor(_ctx, _env) {} }
3778
+ export class WorkerEntrypoint { constructor(_ctx, _env) {} }
3779
+ export class WorkflowEntrypoint { constructor(_ctx, _env) {} }
3780
+ export class RpcTarget {}
3781
+ export const env = globalThis[${JSON.stringify(BUILD_ENV_GLOBAL_KEY)}] ?? {};
3782
+ export default {};
3783
+ `,
3784
+ "cloudflare:email": `
3785
+ export class EmailMessage { constructor(_from, _to, _raw) {} }
3786
+ export default {};
3787
+ `,
3788
+ "cloudflare:sockets": `
3789
+ export function connect() { return {}; }
3790
+ export default {};
3791
+ `,
3792
+ "cloudflare:workflows": `
3793
+ export class NonRetryableError extends Error {
3794
+ constructor(message, name) { super(message); this.name = name ?? "NonRetryableError"; }
3795
+ }
3796
+ export default {};
3797
+ `
3798
+ };
3799
+ var FALLBACK_STUB = `export default {};
3800
+ `;
3801
+ function createCloudflareProtocolStubPlugin() {
3316
3802
  return {
3317
- name: "@rangojs/router:hash-client-refs",
3318
- // Run after the RSC plugin's transform (default enforce is normal)
3319
- enforce: "post",
3320
- applyToEnvironment(env) {
3321
- return env.name === "rsc";
3803
+ name: "@rangojs/router:cloudflare-protocol-stub",
3804
+ transform(code, id) {
3805
+ const cleanId = id.split("?")[0] ?? id;
3806
+ if (!SOURCE_EXT_RE.test(cleanId)) return null;
3807
+ if (!code.includes(CF_PREFIX)) return null;
3808
+ let ast;
3809
+ try {
3810
+ ast = this.parse(code, { lang: "tsx" });
3811
+ } catch {
3812
+ return null;
3813
+ }
3814
+ const hits = [];
3815
+ walk(ast, (node) => {
3816
+ if (!IMPORT_NODE_TYPES.has(node.type)) return;
3817
+ const source = node.source;
3818
+ if (!source || source.type !== "Literal") return;
3819
+ if (typeof source.value !== "string") return;
3820
+ if (!source.value.startsWith(CF_PREFIX)) return;
3821
+ if (typeof source.start !== "number" || typeof source.end !== "number")
3822
+ return;
3823
+ hits.push({
3824
+ start: source.start,
3825
+ end: source.end,
3826
+ value: source.value
3827
+ });
3828
+ });
3829
+ if (hits.length === 0) return null;
3830
+ hits.sort((a, b) => b.start - a.start);
3831
+ let out = code;
3832
+ for (const hit of hits) {
3833
+ const submodule = hit.value.slice(CF_PREFIX.length);
3834
+ const quote = code[hit.start] === "'" ? "'" : '"';
3835
+ out = out.slice(0, hit.start) + quote + VIRTUAL_PREFIX + submodule + quote + out.slice(hit.end);
3836
+ }
3837
+ return { code: out, map: null };
3838
+ },
3839
+ resolveId(id) {
3840
+ if (id.startsWith(VIRTUAL_PREFIX)) {
3841
+ return "\0" + id;
3842
+ }
3843
+ return null;
3322
3844
  },
3323
- transform(code, _id) {
3324
- const result = transformClientRefs(code, projectRoot);
3325
- if (result === null) return;
3326
- return { code: result, map: null };
3845
+ load(id) {
3846
+ if (!id.startsWith(NULL_PREFIX)) return null;
3847
+ const submodule = id.slice(NULL_PREFIX.length);
3848
+ const specifier = CF_PREFIX + submodule;
3849
+ return STUBS[specifier] ?? FALLBACK_STUB;
3327
3850
  }
3328
3851
  };
3329
3852
  }
3853
+ function walk(node, visit) {
3854
+ if (!node || typeof node !== "object") return;
3855
+ if (Array.isArray(node)) {
3856
+ for (const child of node) walk(child, visit);
3857
+ return;
3858
+ }
3859
+ const n = node;
3860
+ if (typeof n.type !== "string") return;
3861
+ visit(n);
3862
+ for (const key in n) {
3863
+ if (key === "loc" || key === "start" || key === "end" || key === "range") {
3864
+ continue;
3865
+ }
3866
+ walk(n[key], visit);
3867
+ }
3868
+ }
3330
3869
 
3331
3870
  // src/vite/utils/bundle-analysis.ts
3332
3871
  function findMatchingParenInBundle(code, openParenPos) {
@@ -3358,7 +3897,7 @@ function extractHandlerExportsFromChunk(chunkCode, handlerModules, fnName, detec
3358
3897
  if (detectPassthrough) {
3359
3898
  const eFnName = escapeRegExp(fnName);
3360
3899
  const callStartRe = new RegExp(
3361
- `const\\s+${eName}\\s*=\\s*${eFnName}\\s*(?:<[^>]*>)?\\s*\\(`
3900
+ `(?:const|let|var)\\s+${eName}\\s*=\\s*${eFnName}\\s*(?:<[^>]*>)?\\s*\\(`
3362
3901
  );
3363
3902
  const callStart = callStartRe.exec(chunkCode);
3364
3903
  if (callStart) {
@@ -3383,7 +3922,7 @@ function evictHandlerCode(code, exports, fnName, brand) {
3383
3922
  if (passthrough) continue;
3384
3923
  const eName = escapeRegExp(name);
3385
3924
  const callStartRe = new RegExp(
3386
- `const\\s+${eName}\\s*=\\s*${eFnName}\\s*(?:<[^>]*>)?\\s*\\(`
3925
+ `(?:const|let|var)\\s+${eName}\\s*=\\s*${eFnName}\\s*(?:<[^>]*>)?\\s*\\(`
3387
3926
  );
3388
3927
  const startMatch = callStartRe.exec(modified);
3389
3928
  if (!startMatch) continue;
@@ -3418,6 +3957,8 @@ function createDiscoveryState(entryPath, opts) {
3418
3957
  projectRoot: "",
3419
3958
  isBuildMode: false,
3420
3959
  userResolveAlias: void 0,
3960
+ userRunnerConfig: void 0,
3961
+ userResolvePlugins: [],
3421
3962
  scanFilter: void 0,
3422
3963
  cachedRouterFiles: void 0,
3423
3964
  opts,
@@ -3439,7 +3980,8 @@ function createDiscoveryState(entryPath, opts) {
3439
3980
  devServerOrigin: null,
3440
3981
  devServer: null,
3441
3982
  selfWrittenGenFiles: /* @__PURE__ */ new Map(),
3442
- SELF_WRITE_WINDOW_MS: 5e3
3983
+ SELF_WRITE_WINDOW_MS: 5e3,
3984
+ lastDiscoveryError: null
3443
3985
  };
3444
3986
  }
3445
3987
 
@@ -3451,6 +3993,12 @@ function markSelfGenWrite(state, filePath, content) {
3451
3993
  state.selfWrittenGenFiles.set(filePath, { at: Date.now(), hash });
3452
3994
  }
3453
3995
  function consumeSelfGenWrite(state, filePath) {
3996
+ return checkSelfGenWrite(state, filePath, true);
3997
+ }
3998
+ function peekSelfGenWrite(state, filePath) {
3999
+ return checkSelfGenWrite(state, filePath, false);
4000
+ }
4001
+ function checkSelfGenWrite(state, filePath, consume) {
3454
4002
  const info = state.selfWrittenGenFiles.get(filePath);
3455
4003
  if (!info) return false;
3456
4004
  if (Date.now() - info.at > state.SELF_WRITE_WINDOW_MS) {
@@ -3461,7 +4009,7 @@ function consumeSelfGenWrite(state, filePath) {
3461
4009
  const current = readFileSync3(filePath, "utf-8");
3462
4010
  const currentHash = createHash3("sha256").update(current).digest("hex");
3463
4011
  if (currentHash === info.hash) {
3464
- state.selfWrittenGenFiles.delete(filePath);
4012
+ if (consume) state.selfWrittenGenFiles.delete(filePath);
3465
4013
  return true;
3466
4014
  }
3467
4015
  return false;
@@ -3473,9 +4021,12 @@ function consumeSelfGenWrite(state, filePath) {
3473
4021
 
3474
4022
  // src/vite/utils/manifest-utils.ts
3475
4023
  function flattenLeafEntries(prefixTree, routeManifest, result) {
3476
- function visit(node) {
4024
+ function visit(node, ancestorStaticPrefixes) {
3477
4025
  const children = node.children || {};
3478
4026
  if (Object.keys(children).length === 0 && node.routes && node.routes.length > 0) {
4027
+ if (ancestorStaticPrefixes.has(node.staticPrefix)) {
4028
+ return;
4029
+ }
3479
4030
  const routes = {};
3480
4031
  for (const name of node.routes) {
3481
4032
  if (name in routeManifest) {
@@ -3484,13 +4035,15 @@ function flattenLeafEntries(prefixTree, routeManifest, result) {
3484
4035
  }
3485
4036
  result.push({ staticPrefix: node.staticPrefix, routes });
3486
4037
  } else {
4038
+ const nextAncestors = new Set(ancestorStaticPrefixes);
4039
+ nextAncestors.add(node.staticPrefix);
3487
4040
  for (const child of Object.values(children)) {
3488
- visit(child);
4041
+ visit(child, nextAncestors);
3489
4042
  }
3490
4043
  }
3491
4044
  }
3492
4045
  for (const node of Object.values(prefixTree)) {
3493
- visit(node);
4046
+ visit(node, /* @__PURE__ */ new Set());
3494
4047
  }
3495
4048
  }
3496
4049
  function buildRouteToStaticPrefix(prefixTree, result) {
@@ -3565,11 +4118,19 @@ function substituteRouteParams(pattern, params, encode = encodeURIComponent) {
3565
4118
  let hadOmittedOptional = false;
3566
4119
  for (const [key, value] of Object.entries(params)) {
3567
4120
  const escaped = escapeRegExp2(key);
3568
- result = result.replace(
3569
- new RegExp(`:${escaped}(\\([^)]*\\))?\\??`),
3570
- encode(value)
3571
- );
3572
- result = result.replace(`*${key}`, encode(value));
4121
+ if (value === "") {
4122
+ result = result.replace(
4123
+ new RegExp(`:${escaped}(\\([^)]*\\))?(?!\\?)`),
4124
+ ""
4125
+ );
4126
+ result = result.replace(`*${key}`, "");
4127
+ } else {
4128
+ result = result.replace(
4129
+ new RegExp(`:${escaped}(\\([^)]*\\))?\\??`),
4130
+ encode(value)
4131
+ );
4132
+ result = result.replace(`*${key}`, encode(value));
4133
+ }
3573
4134
  }
3574
4135
  result = result.replace(/:([a-zA-Z_][a-zA-Z0-9_]*)(\([^)]*\))?\?/g, () => {
3575
4136
  hadOmittedOptional = true;
@@ -3675,8 +4236,14 @@ function copyStagedBuildAssets(projectRoot, fileNames) {
3675
4236
  }
3676
4237
 
3677
4238
  // src/vite/discovery/prerender-collection.ts
4239
+ var debug9 = createRangoDebugger(NS.prerender);
3678
4240
  async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
3679
4241
  if (!state.opts?.enableBuildPrerender || !state.isBuildMode) return;
4242
+ const overallStart = debug9 ? performance.now() : 0;
4243
+ debug9?.(
4244
+ "expandPrerenderRoutes: start (%d router manifest(s))",
4245
+ allManifests.length
4246
+ );
3680
4247
  const entries = [];
3681
4248
  const allRoutes = {};
3682
4249
  for (const { manifest: m } of allManifests) {
@@ -3703,7 +4270,7 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
3703
4270
  const progressInterval = totalDynamic > 0 ? setInterval(() => {
3704
4271
  const elapsed = ((performance.now() - paramsStart) / 1e3).toFixed(1);
3705
4272
  console.log(
3706
- `[rsc-router] Resolving prerender params... ${resolvedRoutes}/${totalDynamic} routes (${elapsed}s)`
4273
+ `[rango] Resolving prerender params... ${resolvedRoutes}/${totalDynamic} routes (${elapsed}s)`
3707
4274
  );
3708
4275
  }, 5e3) : void 0;
3709
4276
  try {
@@ -3726,6 +4293,7 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
3726
4293
  });
3727
4294
  } else {
3728
4295
  if (def?.getParams) {
4296
+ const getParamsStart = debug9 ? performance.now() : 0;
3729
4297
  try {
3730
4298
  const buildVars = {};
3731
4299
  const buildEnv = state.resolvedBuildEnv;
@@ -3739,11 +4307,17 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
3739
4307
  get env() {
3740
4308
  if (buildEnv !== void 0) return buildEnv;
3741
4309
  throw new Error(
3742
- "[rsc-router] ctx.env is not available during build-time getParams(). Configure buildEnv in your rango() plugin options to enable build-time env access."
4310
+ "[rango] ctx.env is not available during build-time getParams(). Configure buildEnv in your rango() plugin options to enable build-time env access."
3743
4311
  );
3744
4312
  }
3745
4313
  };
3746
4314
  const paramsList = await def.getParams(getParamsCtx);
4315
+ debug9?.(
4316
+ "getParams %s -> %d params (%sms)",
4317
+ routeName,
4318
+ paramsList.length,
4319
+ (performance.now() - getParamsStart).toFixed(1)
4320
+ );
3747
4321
  const concurrency = def.options?.concurrency ?? 1;
3748
4322
  const hasBuildVars = Object.keys(buildVars).length > 0 || Object.getOwnPropertySymbols(buildVars).length > 0;
3749
4323
  for (const params of paramsList) {
@@ -3774,7 +4348,7 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
3774
4348
  resolvedRoutes++;
3775
4349
  if (err.name === "Skip") {
3776
4350
  console.log(
3777
- `[rsc-router] SKIP route "${routeName}" - ${err.message}`
4351
+ `[rango] SKIP route "${routeName}" - ${err.message}`
3778
4352
  );
3779
4353
  notifyOnError(
3780
4354
  registry,
@@ -3787,14 +4361,14 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
3787
4361
  continue;
3788
4362
  }
3789
4363
  console.error(
3790
- `[rsc-router] Failed to get params for prerender route "${routeName}": ${err.message}`
4364
+ `[rango] Failed to get params for prerender route "${routeName}": ${err.message}`
3791
4365
  );
3792
4366
  notifyOnError(registry, err, "prerender", routeName);
3793
4367
  throw err;
3794
4368
  }
3795
4369
  } else {
3796
4370
  console.warn(
3797
- `[rsc-router] Dynamic prerender route "${routeName}" has no getParams(), skipping`
4371
+ `[rango] Dynamic prerender route "${routeName}" has no getParams(), skipping`
3798
4372
  );
3799
4373
  }
3800
4374
  }
@@ -3805,15 +4379,26 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
3805
4379
  clearInterval(progressInterval);
3806
4380
  const elapsed = ((performance.now() - paramsStart) / 1e3).toFixed(1);
3807
4381
  console.log(
3808
- `[rsc-router] Resolved prerender params: ${resolvedRoutes}/${totalDynamic} routes (${elapsed}s)`
4382
+ `[rango] Resolved prerender params: ${resolvedRoutes}/${totalDynamic} routes (${elapsed}s)`
3809
4383
  );
3810
4384
  }
3811
4385
  }
3812
- if (entries.length === 0) return;
4386
+ if (entries.length === 0) {
4387
+ debug9?.(
4388
+ "no prerender entries (done in %sms)",
4389
+ (performance.now() - overallStart).toFixed(1)
4390
+ );
4391
+ return;
4392
+ }
3813
4393
  const maxConcurrency = Math.max(...entries.map((e) => e.concurrency));
3814
4394
  const concurrencyNote = maxConcurrency > 1 ? ` (concurrency: ${maxConcurrency})` : "";
3815
4395
  console.log(
3816
- `[rsc-router] Pre-rendering ${entries.length} URL(s)${concurrencyNote}...`
4396
+ `[rango] Pre-rendering ${entries.length} URL(s)${concurrencyNote}...`
4397
+ );
4398
+ debug9?.(
4399
+ "prerender loop: %d entries, max concurrency %d",
4400
+ entries.length,
4401
+ maxConcurrency
3817
4402
  );
3818
4403
  const { hashParams } = await rscEnv.runner.import("@rangojs/router/build");
3819
4404
  const manifestEntries = {};
@@ -3841,7 +4426,7 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
3841
4426
  if (result.passthrough) {
3842
4427
  const elapsed2 = (performance.now() - startUrl).toFixed(0);
3843
4428
  console.log(
3844
- `[rsc-router] PASS ${entry.urlPath.padEnd(40)} (${elapsed2}ms) - live fallback`
4429
+ `[rango] PASS ${entry.urlPath.padEnd(40)} (${elapsed2}ms) - live fallback`
3845
4430
  );
3846
4431
  doneCount++;
3847
4432
  break;
@@ -3874,7 +4459,7 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
3874
4459
  }
3875
4460
  const elapsed = (performance.now() - startUrl).toFixed(0);
3876
4461
  console.log(
3877
- `[rsc-router] OK ${entry.urlPath.padEnd(40)} (${elapsed}ms)`
4462
+ `[rango] OK ${entry.urlPath.padEnd(40)} (${elapsed}ms)`
3878
4463
  );
3879
4464
  doneCount++;
3880
4465
  break;
@@ -3882,7 +4467,7 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
3882
4467
  if (err.name === "Skip") {
3883
4468
  const elapsed2 = (performance.now() - startUrl).toFixed(0);
3884
4469
  console.log(
3885
- `[rsc-router] SKIP ${entry.urlPath.padEnd(40)} (${elapsed2}ms) - ${err.message}`
4470
+ `[rango] SKIP ${entry.urlPath.padEnd(40)} (${elapsed2}ms) - ${err.message}`
3886
4471
  );
3887
4472
  skipCount++;
3888
4473
  notifyOnError(
@@ -3897,7 +4482,7 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
3897
4482
  }
3898
4483
  const elapsed = (performance.now() - startUrl).toFixed(0);
3899
4484
  console.error(
3900
- `[rsc-router] FAIL ${entry.urlPath.padEnd(40)} (${elapsed}ms) - ${err.message}`
4485
+ `[rango] FAIL ${entry.urlPath.padEnd(40)} (${elapsed}ms) - ${err.message}`
3901
4486
  );
3902
4487
  notifyOnError(
3903
4488
  registry,
@@ -3919,12 +4504,24 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
3919
4504
  const parts = [`${doneCount} done`];
3920
4505
  if (skipCount > 0) parts.push(`${skipCount} skipped`);
3921
4506
  console.log(
3922
- `[rsc-router] Pre-render complete: ${parts.join(", ")} (${totalElapsed}ms total)`
4507
+ `[rango] Pre-render complete: ${parts.join(", ")} (${totalElapsed}ms total)`
4508
+ );
4509
+ debug9?.(
4510
+ "expandPrerenderRoutes done: %d done, %d skipped, %sms (overall %sms)",
4511
+ doneCount,
4512
+ skipCount,
4513
+ totalElapsed,
4514
+ (performance.now() - overallStart).toFixed(1)
3923
4515
  );
3924
4516
  }
3925
4517
  async function renderStaticHandlers(state, rscEnv, registry) {
3926
4518
  if (!state.opts?.enableBuildPrerender || !state.isBuildMode || !state.resolvedStaticModules?.size)
3927
4519
  return;
4520
+ const overallStart = debug9 ? performance.now() : 0;
4521
+ debug9?.(
4522
+ "renderStaticHandlers: start (%d static module(s))",
4523
+ state.resolvedStaticModules.size
4524
+ );
3928
4525
  const manifestEntries = {};
3929
4526
  let staticDone = 0;
3930
4527
  let staticSkip = 0;
@@ -3933,16 +4530,14 @@ async function renderStaticHandlers(state, rscEnv, registry) {
3933
4530
  totalStaticCount += exportNames.length;
3934
4531
  }
3935
4532
  const startStatic = performance.now();
3936
- console.log(
3937
- `[rsc-router] Rendering ${totalStaticCount} static handler(s)...`
3938
- );
4533
+ console.log(`[rango] Rendering ${totalStaticCount} static handler(s)...`);
3939
4534
  for (const [moduleId, exportNames] of state.resolvedStaticModules) {
3940
4535
  let mod;
3941
4536
  try {
3942
4537
  mod = await rscEnv.runner.import(moduleId);
3943
4538
  } catch (err) {
3944
4539
  console.error(
3945
- `[rsc-router] Failed to import static module ${moduleId}: ${err.message}`
4540
+ `[rango] Failed to import static module ${moduleId}: ${err.message}`
3946
4541
  );
3947
4542
  notifyOnError(registry, err, "static");
3948
4543
  throw err;
@@ -3972,9 +4567,7 @@ async function renderStaticHandlers(state, rscEnv, registry) {
3972
4567
  exportValue
3973
4568
  );
3974
4569
  const elapsed = (performance.now() - startHandler).toFixed(0);
3975
- console.log(
3976
- `[rsc-router] OK ${name.padEnd(40)} (${elapsed}ms)`
3977
- );
4570
+ console.log(`[rango] OK ${name.padEnd(40)} (${elapsed}ms)`);
3978
4571
  staticDone++;
3979
4572
  handled = true;
3980
4573
  break;
@@ -3983,7 +4576,7 @@ async function renderStaticHandlers(state, rscEnv, registry) {
3983
4576
  if (err.name === "Skip") {
3984
4577
  const elapsed2 = (performance.now() - startHandler).toFixed(0);
3985
4578
  console.log(
3986
- `[rsc-router] SKIP ${name.padEnd(40)} (${elapsed2}ms) - ${err.message}`
4579
+ `[rango] SKIP ${name.padEnd(40)} (${elapsed2}ms) - ${err.message}`
3987
4580
  );
3988
4581
  staticSkip++;
3989
4582
  notifyOnError(registry, err, "static", void 0, void 0, true);
@@ -3992,16 +4585,14 @@ async function renderStaticHandlers(state, rscEnv, registry) {
3992
4585
  }
3993
4586
  const elapsed = (performance.now() - startHandler).toFixed(0);
3994
4587
  console.error(
3995
- `[rsc-router] FAIL ${name.padEnd(40)} (${elapsed}ms) - ${err.message}`
4588
+ `[rango] FAIL ${name.padEnd(40)} (${elapsed}ms) - ${err.message}`
3996
4589
  );
3997
4590
  notifyOnError(registry, err, "static");
3998
4591
  throw err;
3999
4592
  }
4000
4593
  }
4001
4594
  if (!handled) {
4002
- console.warn(
4003
- `[rsc-router] No router could render static handler "${name}"`
4004
- );
4595
+ console.warn(`[rango] No router could render static handler "${name}"`);
4005
4596
  }
4006
4597
  }
4007
4598
  }
@@ -4012,38 +4603,118 @@ async function renderStaticHandlers(state, rscEnv, registry) {
4012
4603
  const staticParts = [`${staticDone} done`];
4013
4604
  if (staticSkip > 0) staticParts.push(`${staticSkip} skipped`);
4014
4605
  console.log(
4015
- `[rsc-router] Static render complete: ${staticParts.join(", ")} (${totalStaticElapsed}ms total)`
4606
+ `[rango] Static render complete: ${staticParts.join(", ")} (${totalStaticElapsed}ms total)`
4607
+ );
4608
+ debug9?.(
4609
+ "renderStaticHandlers done: %d done, %d skipped, %sms (overall %sms)",
4610
+ staticDone,
4611
+ staticSkip,
4612
+ totalStaticElapsed,
4613
+ (performance.now() - overallStart).toFixed(1)
4614
+ );
4615
+ }
4616
+
4617
+ // src/vite/discovery/discovery-errors.ts
4618
+ function indent(text, pad) {
4619
+ return text.split("\n").map((line) => line.length > 0 ? pad + line : line).join("\n");
4620
+ }
4621
+ async function invokeLazyMount(loader, context, errors) {
4622
+ try {
4623
+ await loader();
4624
+ } catch (error) {
4625
+ errors.push({ context, error });
4626
+ }
4627
+ }
4628
+ function isLazyMount(route) {
4629
+ return !!route && route.kind === "lazy" && typeof route.handler === "function";
4630
+ }
4631
+ async function resolveHostRouterHandlers(hostRegistry) {
4632
+ const errors = [];
4633
+ for (const [hostId, entry] of hostRegistry) {
4634
+ for (const route of entry.routes) {
4635
+ if (isLazyMount(route)) {
4636
+ await invokeLazyMount(
4637
+ route.handler,
4638
+ `host "${hostId}" route handler`,
4639
+ errors
4640
+ );
4641
+ }
4642
+ }
4643
+ if (isLazyMount(entry.fallback)) {
4644
+ await invokeLazyMount(
4645
+ entry.fallback.handler,
4646
+ `host "${hostId}" fallback handler`,
4647
+ errors
4648
+ );
4649
+ }
4650
+ }
4651
+ return errors;
4652
+ }
4653
+ function formatNoRoutersError(entryPath, errors) {
4654
+ const base = `[rango] No routers found in registry after importing ${entryPath}`;
4655
+ if (errors.length === 0) {
4656
+ return base;
4657
+ }
4658
+ const formatted = errors.map(({ context, error }) => {
4659
+ const err = error instanceof Error ? error : new Error(String(error));
4660
+ const detail = err.stack ?? err.message;
4661
+ return ` - while resolving ${context}:
4662
+ ${indent(detail, " ")}`;
4663
+ }).join("\n");
4664
+ return `${base}
4665
+
4666
+ ${errors.length} error(s) were caught during host-router discovery and likely explain why no routers were registered:
4667
+ ${formatted}`;
4668
+ }
4669
+ function toCause(errors) {
4670
+ if (errors.length === 0) return void 0;
4671
+ if (errors.length === 1) return errors[0].error;
4672
+ return new AggregateError(
4673
+ errors.map((e) => e.error),
4674
+ "Multiple host-router handlers failed during discovery"
4016
4675
  );
4017
4676
  }
4677
+ var DiscoveryError = class _DiscoveryError extends Error {
4678
+ constructor(entryPath, caught) {
4679
+ super(formatNoRoutersError(entryPath, caught));
4680
+ const cause = toCause(caught);
4681
+ if (cause !== void 0) {
4682
+ this.cause = cause;
4683
+ }
4684
+ this.name = "DiscoveryError";
4685
+ this.entryPath = entryPath;
4686
+ this.caught = caught;
4687
+ Object.setPrototypeOf(this, _DiscoveryError.prototype);
4688
+ }
4689
+ };
4018
4690
 
4019
4691
  // src/vite/discovery/discover-routers.ts
4692
+ var debug10 = createRangoDebugger(NS.discovery);
4020
4693
  async function discoverRouters(state, rscEnv) {
4021
4694
  if (!state.resolvedEntryPath) return;
4022
- await rscEnv.runner.import(state.resolvedEntryPath);
4023
- const serverMod = await rscEnv.runner.import("@rangojs/router/server");
4695
+ await timed(
4696
+ debug10,
4697
+ "inner: import entry",
4698
+ () => rscEnv.runner.import(state.resolvedEntryPath)
4699
+ );
4700
+ const serverMod = await timed(
4701
+ debug10,
4702
+ "inner: import @rangojs/router/server",
4703
+ () => rscEnv.runner.import("@rangojs/router/server")
4704
+ );
4024
4705
  let registry = serverMod.RouterRegistry;
4025
4706
  if (!registry || registry.size === 0) {
4707
+ const discoveryErrors = [];
4026
4708
  try {
4027
4709
  const hostRegistry = serverMod.HostRouterRegistry;
4028
4710
  if (hostRegistry && hostRegistry.size > 0) {
4029
4711
  console.log(
4030
- `[rsc-router] Found ${hostRegistry.size} host router(s), resolving lazy handlers...`
4712
+ `[rango] Found ${hostRegistry.size} host router(s), resolving lazy handlers...`
4031
4713
  );
4032
- for (const [, entry] of hostRegistry) {
4033
- for (const route of entry.routes) {
4034
- if (typeof route.handler === "function") {
4035
- try {
4036
- await route.handler();
4037
- } catch {
4038
- }
4039
- }
4040
- }
4041
- if (entry.fallback && typeof entry.fallback.handler === "function") {
4042
- try {
4043
- await entry.fallback.handler();
4044
- } catch {
4045
- }
4046
- }
4714
+ const handlerErrors = await resolveHostRouterHandlers(hostRegistry);
4715
+ discoveryErrors.push(...handlerErrors);
4716
+ for (const { context, error } of handlerErrors) {
4717
+ debug10?.("caught error while resolving %s: %O", context, error);
4047
4718
  }
4048
4719
  const freshServerMod = await rscEnv.runner.import(
4049
4720
  "@rangojs/router/server"
@@ -4054,16 +4725,20 @@ async function discoverRouters(state, rscEnv) {
4054
4725
  registry = freshRegistry;
4055
4726
  }
4056
4727
  }
4057
- } catch {
4728
+ } catch (error) {
4729
+ discoveryErrors.push({ context: "host-router discovery", error });
4058
4730
  }
4059
4731
  if (!registry || registry.size === 0) {
4060
- throw new Error(
4061
- `[rsc-router] No routers found in registry after importing ${state.resolvedEntryPath}`
4062
- );
4732
+ throw new DiscoveryError(state.resolvedEntryPath, discoveryErrors);
4063
4733
  }
4064
4734
  }
4065
- const buildMod = await rscEnv.runner.import("@rangojs/router/build");
4735
+ const buildMod = await timed(
4736
+ debug10,
4737
+ "inner: import @rangojs/router/build",
4738
+ () => rscEnv.runner.import("@rangojs/router/build")
4739
+ );
4066
4740
  const generateManifestFull = buildMod.generateManifestFull;
4741
+ debug10?.("inner: found %d router(s) in registry", registry.size);
4067
4742
  const nestedRouterConflict = findNestedRouterConflict(
4068
4743
  [...registry.values()].map((router) => router.__sourceFile).filter(
4069
4744
  (sourceFile) => typeof sourceFile === "string"
@@ -4082,6 +4757,16 @@ async function discoverRouters(state, rscEnv) {
4082
4757
  let mergedRouteTrailingSlash = {};
4083
4758
  let routerMountIndex = 0;
4084
4759
  const allManifests = [];
4760
+ const clientChunkCtx = state.opts?.clientChunkCtx;
4761
+ const collectClientFallbackRef = clientChunkCtx ? (refKey) => clientChunkCtx.fallbackRefs.add(
4762
+ computeProductionHash(state.projectRoot, refKey)
4763
+ ) : void 0;
4764
+ const collectFromBoundaryNode = (node) => {
4765
+ if (collectClientFallbackRef && buildMod.collectFallbackClientRefs) {
4766
+ buildMod.collectFallbackClientRefs(node, collectClientFallbackRef);
4767
+ }
4768
+ };
4769
+ const manifestGenStart = debug10 ? performance.now() : 0;
4085
4770
  for (const [id, router] of registry) {
4086
4771
  if (!router.urlpatterns || !generateManifestFull) {
4087
4772
  continue;
@@ -4089,10 +4774,18 @@ async function discoverRouters(state, rscEnv) {
4089
4774
  const manifest = generateManifestFull(
4090
4775
  router.urlpatterns,
4091
4776
  routerMountIndex,
4092
- router.__basename ? { urlPrefix: router.__basename } : void 0
4777
+ {
4778
+ ...router.__basename ? { urlPrefix: router.__basename } : {},
4779
+ ...collectClientFallbackRef ? { collectClientFallbackRef } : {}
4780
+ }
4093
4781
  );
4094
4782
  routerMountIndex++;
4095
4783
  allManifests.push({ id, manifest });
4784
+ if (collectClientFallbackRef) {
4785
+ collectFromBoundaryNode(router.__defaultErrorBoundary);
4786
+ collectFromBoundaryNode(router.__defaultNotFoundBoundary);
4787
+ collectFromBoundaryNode(router.__notFound);
4788
+ }
4096
4789
  const routeCount = Object.keys(manifest.routeManifest).length;
4097
4790
  const staticRoutes = Object.values(manifest.routeManifest).filter(
4098
4791
  (p) => !p.includes(":") && !p.includes("*")
@@ -4143,7 +4836,7 @@ async function discoverRouters(state, rscEnv) {
4143
4836
  );
4144
4837
  newPerRouterPrecomputedMap.set(id, routerPrecomputed);
4145
4838
  console.log(
4146
- `[rsc-router] Router "${id}" -> ${routeCount} routes (${staticRoutes} static, ${dynamicRoutes} dynamic)`
4839
+ `[rango] Router "${id}" -> ${routeCount} routes (${staticRoutes} static, ${dynamicRoutes} dynamic)`
4147
4840
  );
4148
4841
  }
4149
4842
  if (registry.size > 1) {
@@ -4152,11 +4845,17 @@ async function discoverRouters(state, rscEnv) {
4152
4845
  );
4153
4846
  if (autoIds.length > 1) {
4154
4847
  console.warn(
4155
- `[rsc-router] WARNING: ${autoIds.length} routers use auto-generated IDs (${autoIds.join(", ")}). In multi-router setups, each createRouter() must have an explicit \`id\` option to ensure per-router manifest data is matched correctly at runtime. Example: createRouter({ id: "site", ... })`
4848
+ `[rango] WARNING: ${autoIds.length} routers use auto-generated IDs (${autoIds.join(", ")}). In multi-router setups, each createRouter() must have an explicit \`id\` option to ensure per-router manifest data is matched correctly at runtime. Example: createRouter({ id: "site", ... })`
4156
4849
  );
4157
4850
  }
4158
4851
  }
4852
+ debug10?.(
4853
+ "inner: generated manifests for %d router(s) (%sms)",
4854
+ allManifests.length,
4855
+ (performance.now() - manifestGenStart).toFixed(1)
4856
+ );
4159
4857
  let newMergedRouteTrie = null;
4858
+ const trieStart = debug10 ? performance.now() : 0;
4160
4859
  if (Object.keys(newMergedRouteManifest).length > 0) {
4161
4860
  const buildRouteTrie = buildMod.buildRouteTrie;
4162
4861
  if (buildRouteTrie && mergedRouteAncestry) {
@@ -4191,10 +4890,10 @@ async function discoverRouters(state, rscEnv) {
4191
4890
  newMergedRouteManifest,
4192
4891
  mergedRouteAncestry,
4193
4892
  routeToStaticPrefix,
4194
- Object.keys(mergedRouteTrailingSlash).length > 0 ? mergedRouteTrailingSlash : void 0,
4195
- prerenderRouteNames.size > 0 ? prerenderRouteNames : void 0,
4196
- passthroughRouteNames.size > 0 ? passthroughRouteNames : void 0,
4197
- Object.keys(mergedResponseTypeRoutes).length > 0 ? mergedResponseTypeRoutes : void 0
4893
+ mergedRouteTrailingSlash,
4894
+ prerenderRouteNames,
4895
+ passthroughRouteNames,
4896
+ mergedResponseTypeRoutes
4198
4897
  );
4199
4898
  for (const { id, manifest } of allManifests) {
4200
4899
  if (!manifest._routeAncestry || Object.keys(manifest._routeAncestry).length === 0)
@@ -4210,15 +4909,19 @@ async function discoverRouters(state, rscEnv) {
4210
4909
  manifest.routeManifest,
4211
4910
  manifest._routeAncestry,
4212
4911
  perRouterStaticPrefix,
4213
- manifest.routeTrailingSlash && Object.keys(manifest.routeTrailingSlash).length > 0 ? manifest.routeTrailingSlash : void 0,
4214
- perRouterPrerenderNames && perRouterPrerenderNames.size > 0 ? perRouterPrerenderNames : void 0,
4215
- perRouterPassthroughNames && perRouterPassthroughNames.size > 0 ? perRouterPassthroughNames : void 0,
4216
- manifest.responseTypeRoutes && Object.keys(manifest.responseTypeRoutes).length > 0 ? manifest.responseTypeRoutes : void 0
4912
+ manifest.routeTrailingSlash,
4913
+ perRouterPrerenderNames,
4914
+ perRouterPassthroughNames,
4915
+ manifest.responseTypeRoutes
4217
4916
  );
4218
4917
  newPerRouterTrieMap.set(id, perRouterTrie);
4219
4918
  }
4220
4919
  }
4221
4920
  }
4921
+ debug10?.(
4922
+ "inner: trie build done (%sms)",
4923
+ (performance.now() - trieStart).toFixed(1)
4924
+ );
4222
4925
  state.mergedRouteManifest = newMergedRouteManifest;
4223
4926
  state.mergedPrecomputedEntries = newMergedPrecomputedEntries;
4224
4927
  state.perRouterManifests = newPerRouterManifests;
@@ -4232,7 +4935,7 @@ async function discoverRouters(state, rscEnv) {
4232
4935
  }
4233
4936
 
4234
4937
  // src/vite/discovery/route-types-writer.ts
4235
- import { dirname as dirname3, basename, join as join2, resolve as resolve6 } from "node:path";
4938
+ import { dirname as dirname3, join as join2, resolve as resolve6 } from "node:path";
4236
4939
  import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, existsSync as existsSync5, unlinkSync as unlinkSync2 } from "node:fs";
4237
4940
  function filterUserNamedRoutes(manifest) {
4238
4941
  const filtered = {};
@@ -4243,39 +4946,20 @@ function filterUserNamedRoutes(manifest) {
4243
4946
  }
4244
4947
  return filtered;
4245
4948
  }
4949
+ function writeGenFileIfChanged(state, outPath, source, opts) {
4950
+ const existing = existsSync5(outPath) ? readFileSync4(outPath, "utf-8") : null;
4951
+ if (existing === source) return;
4952
+ markSelfGenWrite(state, outPath, source);
4953
+ writeFileSync3(outPath, source);
4954
+ if (opts?.log) console.log(`[rango] Generated route types -> ${outPath}`);
4955
+ }
4246
4956
  function writeCombinedRouteTypesWithTracking(state, opts) {
4247
4957
  const routerFiles = state.cachedRouterFiles ?? findRouterFiles(state.projectRoot, state.scanFilter);
4248
4958
  state.cachedRouterFiles = routerFiles;
4249
- const preContent = /* @__PURE__ */ new Map();
4250
- for (const routerFilePath of routerFiles) {
4251
- const routerDir = dirname3(routerFilePath);
4252
- const routerBasename = basename(routerFilePath).replace(
4253
- /\.(tsx?|jsx?)$/,
4254
- ""
4255
- );
4256
- const outPath = join2(routerDir, `${routerBasename}.named-routes.gen.ts`);
4257
- try {
4258
- preContent.set(outPath, readFileSync4(outPath, "utf-8"));
4259
- } catch {
4260
- }
4261
- }
4262
- writeCombinedRouteTypes(state.projectRoot, routerFiles, opts);
4263
- for (const routerFilePath of routerFiles) {
4264
- const routerDir = dirname3(routerFilePath);
4265
- const routerBasename = basename(routerFilePath).replace(
4266
- /\.(tsx?|jsx?)$/,
4267
- ""
4268
- );
4269
- const outPath = join2(routerDir, `${routerBasename}.named-routes.gen.ts`);
4270
- if (!existsSync5(outPath)) continue;
4271
- try {
4272
- const content = readFileSync4(outPath, "utf-8");
4273
- if (content !== preContent.get(outPath)) {
4274
- markSelfGenWrite(state, outPath, content);
4275
- }
4276
- } catch {
4277
- }
4278
- }
4959
+ writeCombinedRouteTypes(state.projectRoot, routerFiles, {
4960
+ ...opts,
4961
+ onWrite: (outPath, content) => markSelfGenWrite(state, outPath, content)
4962
+ });
4279
4963
  }
4280
4964
  function writeRouteTypesFiles(state) {
4281
4965
  if (state.perRouterManifests.length === 0) return;
@@ -4287,7 +4971,7 @@ function writeRouteTypesFiles(state) {
4287
4971
  if (existsSync5(oldCombinedPath)) {
4288
4972
  unlinkSync2(oldCombinedPath);
4289
4973
  console.log(
4290
- `[rsc-router] Removed stale combined route types: ${oldCombinedPath}`
4974
+ `[rango] Removed stale combined route types: ${oldCombinedPath}`
4291
4975
  );
4292
4976
  }
4293
4977
  } catch {
@@ -4301,39 +4985,23 @@ function writeRouteTypesFiles(state) {
4301
4985
  if (!sourceFile) continue;
4302
4986
  if (sourceFile.includes("node_modules")) {
4303
4987
  throw new Error(
4304
- `[rsc-router] Router "${id}" has sourceFile inside node_modules: ${sourceFile}
4988
+ `[rango] Router "${id}" has sourceFile inside node_modules: ${sourceFile}
4305
4989
  This means createRouter() stack trace parsing matched a Vite internal frame.
4306
4990
  Set an explicit \`id\` on createRouter() or check the call site.`
4307
4991
  );
4308
4992
  }
4309
- const routerDir = dirname3(sourceFile);
4310
- const routerBasename = basename(sourceFile).replace(/\.(tsx?|jsx?)$/, "");
4311
- const outPath = join2(routerDir, `${routerBasename}.named-routes.gen.ts`);
4993
+ const outPath = genFileTsPath(sourceFile);
4312
4994
  const userRoutes = filterUserNamedRoutes(routeManifest);
4313
- let effectiveSearchSchemas = routeSearchSchemas;
4314
- if ((!effectiveSearchSchemas || Object.keys(effectiveSearchSchemas).length === 0) && sourceFile) {
4315
- const staticParsed = buildCombinedRouteMapForRouterFile(sourceFile);
4316
- if (Object.keys(staticParsed.searchSchemas).length > 0) {
4317
- const filtered = {};
4318
- for (const name of Object.keys(userRoutes)) {
4319
- const schema = staticParsed.searchSchemas[name];
4320
- if (schema) filtered[name] = schema;
4321
- }
4322
- if (Object.keys(filtered).length > 0) {
4323
- effectiveSearchSchemas = filtered;
4324
- }
4325
- }
4326
- }
4995
+ const effectiveSearchSchemas = resolveSearchSchemas(
4996
+ Object.keys(userRoutes),
4997
+ routeSearchSchemas,
4998
+ sourceFile
4999
+ );
4327
5000
  const source = generateRouteTypesSource(
4328
5001
  userRoutes,
4329
5002
  effectiveSearchSchemas && Object.keys(effectiveSearchSchemas).length > 0 ? effectiveSearchSchemas : void 0
4330
5003
  );
4331
- const existing = existsSync5(outPath) ? readFileSync4(outPath, "utf-8") : null;
4332
- if (existing !== source) {
4333
- markSelfGenWrite(state, outPath, source);
4334
- writeFileSync3(outPath, source);
4335
- console.log(`[rsc-router] Generated route types -> ${outPath}`);
4336
- }
5004
+ writeGenFileIfChanged(state, outPath, source, { log: true });
4337
5005
  }
4338
5006
  }
4339
5007
  function supplementGenFilesWithRuntimeRoutes(state) {
@@ -4371,23 +5039,17 @@ function supplementGenFilesWithRuntimeRoutes(state) {
4371
5039
  }
4372
5040
  }
4373
5041
  }
4374
- const routerDir = dirname3(sourceFile);
4375
- const routerBasename = basename(sourceFile).replace(/\.(tsx?|jsx?)$/, "");
4376
- const outPath = join2(routerDir, `${routerBasename}.named-routes.gen.ts`);
5042
+ const outPath = genFileTsPath(sourceFile);
4377
5043
  const source = generateRouteTypesSource(
4378
5044
  mergedRoutes,
4379
5045
  Object.keys(mergedSearchSchemas).length > 0 ? mergedSearchSchemas : void 0
4380
5046
  );
4381
- const existing = existsSync5(outPath) ? readFileSync4(outPath, "utf-8") : null;
4382
- if (existing !== source) {
4383
- markSelfGenWrite(state, outPath, source);
4384
- writeFileSync3(outPath, source);
4385
- }
5047
+ writeGenFileIfChanged(state, outPath, source);
4386
5048
  }
4387
5049
  }
4388
5050
 
4389
5051
  // src/vite/discovery/virtual-module-codegen.ts
4390
- import { dirname as dirname4, basename as basename2, join as join3 } from "node:path";
5052
+ import { dirname as dirname4, basename, join as join3 } from "node:path";
4391
5053
  function generateRoutesManifestModule(state) {
4392
5054
  const hasManifest = state.mergedRouteManifest && Object.keys(state.mergedRouteManifest).length > 0;
4393
5055
  if (hasManifest) {
@@ -4398,7 +5060,7 @@ function generateRoutesManifestModule(state) {
4398
5060
  for (const entry of state.perRouterManifests) {
4399
5061
  if (entry.sourceFile) {
4400
5062
  const routerDir = dirname4(entry.sourceFile);
4401
- const routerBasename = basename2(entry.sourceFile).replace(
5063
+ const routerBasename = basename(entry.sourceFile).replace(
4402
5064
  /\.(tsx?|jsx?)$/,
4403
5065
  ""
4404
5066
  );
@@ -4419,7 +5081,7 @@ function generateRoutesManifestModule(state) {
4419
5081
  }
4420
5082
  }
4421
5083
  const lines = [
4422
- `import { setCachedManifest, setPrecomputedEntries, setRouteTrie, setRouterManifest, registerRouterManifestLoader, clearAllRouterData } from "@rangojs/router/server";`,
5084
+ `import { setCachedManifest, setRouterManifest, registerRouterManifestLoader, clearAllRouterData } from "@rangojs/router/server";`,
4423
5085
  ...genFileImports,
4424
5086
  // Clear stale per-router cached data (manifest, trie, precomputed entries)
4425
5087
  // before re-populating. In Cloudflare dev mode, program reloads re-evaluate
@@ -4455,18 +5117,6 @@ function generateRoutesManifestModule(state) {
4455
5117
  );
4456
5118
  }
4457
5119
  }
4458
- if (state.isBuildMode) {
4459
- if (state.mergedPrecomputedEntries && state.mergedPrecomputedEntries.length > 0) {
4460
- lines.push(
4461
- `setPrecomputedEntries(${jsonParseExpression(state.mergedPrecomputedEntries)});`
4462
- );
4463
- }
4464
- if (state.mergedRouteTrie) {
4465
- lines.push(
4466
- `setRouteTrie(${jsonParseExpression(state.mergedRouteTrie)});`
4467
- );
4468
- }
4469
- }
4470
5120
  for (const routerId of state.perRouterManifestDataMap.keys()) {
4471
5121
  lines.push(
4472
5122
  `registerRouterManifestLoader(${JSON.stringify(routerId)}, () => import(${JSON.stringify(VIRTUAL_ROUTES_MANIFEST_ID + "/" + routerId)}));`
@@ -4495,7 +5145,7 @@ function generatePerRouterModule(state, routerId) {
4495
5145
  const lines = [];
4496
5146
  if (routerEntry?.sourceFile) {
4497
5147
  const routerDir = dirname4(routerEntry.sourceFile);
4498
- const routerBasename = basename2(routerEntry.sourceFile).replace(
5148
+ const routerBasename = basename(routerEntry.sourceFile).replace(
4499
5149
  /\.(tsx?|jsx?)$/,
4500
5150
  ""
4501
5151
  );
@@ -4566,12 +5216,12 @@ function postprocessBundle(state) {
4566
5216
  writeFileSync4(chunkPath, result.code);
4567
5217
  const savedKB = (result.savedBytes / 1024).toFixed(1);
4568
5218
  console.log(
4569
- `[rsc-router] Evicted ${target.label} (${savedKB} KB saved): ${info.fileName}`
5219
+ `[rango] Evicted ${target.label} (${savedKB} KB saved): ${info.fileName}`
4570
5220
  );
4571
5221
  }
4572
5222
  } catch (replaceErr) {
4573
5223
  console.warn(
4574
- `[rsc-router] Failed to evict ${target.label}: ${replaceErr.message}`
5224
+ `[rango] Failed to evict ${target.label}: ${replaceErr.message}`
4575
5225
  );
4576
5226
  }
4577
5227
  }
@@ -4609,11 +5259,11 @@ function postprocessBundle(state) {
4609
5259
  writeFileSync4(rscEntryPath, injection + rscCode);
4610
5260
  const totalKB = (totalBytes / 1024).toFixed(1);
4611
5261
  console.log(
4612
- `[rsc-router] Wrote prerender assets (${totalKB} KB total, ${Object.keys(state.prerenderManifestEntries).length} entries)`
5262
+ `[rango] Wrote prerender assets (${totalKB} KB total, ${Object.keys(state.prerenderManifestEntries).length} entries)`
4613
5263
  );
4614
5264
  } catch (err) {
4615
5265
  throw new Error(
4616
- `[rsc-router] Failed to write prerender assets: ${err.message}`
5266
+ `[rango] Failed to write prerender assets: ${err.message}`
4617
5267
  );
4618
5268
  }
4619
5269
  }
@@ -4647,28 +5297,180 @@ function postprocessBundle(state) {
4647
5297
  writeFileSync4(rscEntryPath, injection + rscCode);
4648
5298
  const totalKB = (totalBytes / 1024).toFixed(1);
4649
5299
  console.log(
4650
- `[rsc-router] Wrote static assets (${totalKB} KB total, ${Object.keys(state.staticManifestEntries).length} entries)`
5300
+ `[rango] Wrote static assets (${totalKB} KB total, ${Object.keys(state.staticManifestEntries).length} entries)`
4651
5301
  );
4652
5302
  } catch (err) {
4653
5303
  throw new Error(
4654
- `[rsc-router] Failed to write static assets: ${err.message}`
5304
+ `[rango] Failed to write static assets: ${err.message}`
4655
5305
  );
4656
5306
  }
4657
5307
  }
4658
5308
  }
4659
5309
  }
4660
5310
 
5311
+ // src/vite/discovery/gate-state.ts
5312
+ function createDiscoveryGate(s, debug11) {
5313
+ let gatePending = false;
5314
+ let gateResolver = () => {
5315
+ };
5316
+ let inProgress = false;
5317
+ let queued = false;
5318
+ let pendingEvents = false;
5319
+ const beginGate = () => {
5320
+ if (gatePending) return;
5321
+ s.discoveryDone = new Promise((resolve10) => {
5322
+ gateResolver = resolve10;
5323
+ });
5324
+ gatePending = true;
5325
+ };
5326
+ const resolveGate = () => {
5327
+ if (!gatePending) return;
5328
+ if (inProgress || queued || pendingEvents) {
5329
+ debug11?.(
5330
+ "hmr: resolveGate deferred \u2014 work in flight (inProgress=%s queued=%s pendingEvents=%s)",
5331
+ inProgress,
5332
+ queued,
5333
+ pendingEvents
5334
+ );
5335
+ return;
5336
+ }
5337
+ gatePending = false;
5338
+ debug11?.("hmr: discoveryDone resolved");
5339
+ gateResolver();
5340
+ };
5341
+ const noteRouteEvent = () => {
5342
+ pendingEvents = true;
5343
+ beginGate();
5344
+ };
5345
+ const runRefreshCycle = async (work) => {
5346
+ if (inProgress) {
5347
+ queued = true;
5348
+ debug11?.("hmr: rediscovery in flight \u2014 queued for a follow-up cycle");
5349
+ return;
5350
+ }
5351
+ pendingEvents = false;
5352
+ inProgress = true;
5353
+ try {
5354
+ await work();
5355
+ } finally {
5356
+ inProgress = false;
5357
+ if (queued) {
5358
+ queued = false;
5359
+ debug11?.("hmr: consuming queued rediscovery");
5360
+ runRefreshCycle(work).catch((err) => {
5361
+ debug11?.(
5362
+ "hmr: queued cycle rejected \u2014 releasing gate (%s)",
5363
+ err instanceof Error ? err.message : String(err)
5364
+ );
5365
+ resolveGate();
5366
+ });
5367
+ } else if (pendingEvents) {
5368
+ debug11?.(
5369
+ "hmr: holding gate for pending events (debounce not yet fired)"
5370
+ );
5371
+ } else {
5372
+ resolveGate();
5373
+ }
5374
+ }
5375
+ };
5376
+ return {
5377
+ beginGate,
5378
+ resolveGate,
5379
+ noteRouteEvent,
5380
+ runRefreshCycle,
5381
+ state: () => ({ gatePending, inProgress, queued, pendingEvents })
5382
+ };
5383
+ }
5384
+
5385
+ // src/vite/utils/forward-user-plugins.ts
5386
+ function isDenied(name) {
5387
+ return name.startsWith("vite:") || name === "rsc" || name.startsWith("rsc:") || name.startsWith("@rangojs/router") || name.startsWith("@cloudflare/vite-plugin") || name.startsWith("vite-plugin-cloudflare");
5388
+ }
5389
+ function hasResolutionHooks(p) {
5390
+ return Boolean(p.resolveId || p.load);
5391
+ }
5392
+ function stripToResolutionHooks(p) {
5393
+ const stripped = { name: p.name };
5394
+ if (p.enforce) stripped.enforce = p.enforce;
5395
+ if (p.applyToEnvironment)
5396
+ stripped.applyToEnvironment = p.applyToEnvironment;
5397
+ if (p.resolveId) stripped.resolveId = p.resolveId;
5398
+ if (p.load) stripped.load = p.load;
5399
+ return stripped;
5400
+ }
5401
+ function selectForwardableResolvePlugins(plugins) {
5402
+ if (!plugins) return [];
5403
+ const forwarded = [];
5404
+ for (const p of plugins) {
5405
+ const name = p?.name;
5406
+ if (!name || isDenied(name)) continue;
5407
+ if (!hasResolutionHooks(p)) continue;
5408
+ forwarded.push(stripToResolutionHooks(p));
5409
+ }
5410
+ return forwarded;
5411
+ }
5412
+ function pickForwardedRunnerConfig(config) {
5413
+ const r = config.resolve ?? {};
5414
+ const resolve10 = {};
5415
+ if (r.alias !== void 0) resolve10.alias = r.alias;
5416
+ if (r.dedupe !== void 0) resolve10.dedupe = r.dedupe;
5417
+ if (r.conditions !== void 0) resolve10.conditions = r.conditions;
5418
+ if (r.mainFields !== void 0) resolve10.mainFields = r.mainFields;
5419
+ if (r.extensions !== void 0) resolve10.extensions = r.extensions;
5420
+ if (r.preserveSymlinks !== void 0)
5421
+ resolve10.preserveSymlinks = r.preserveSymlinks;
5422
+ if (r.tsconfigPaths !== void 0) resolve10.tsconfigPaths = r.tsconfigPaths;
5423
+ const userOxc = config.oxc;
5424
+ const userJsx = userOxc && typeof userOxc === "object" && typeof userOxc.jsx === "object" && userOxc.jsx !== null ? userOxc.jsx : {};
5425
+ const oxc = userOxc && typeof userOxc === "object" ? {
5426
+ ...userOxc,
5427
+ jsx: { ...userJsx, runtime: "automatic", importSource: "react" }
5428
+ } : { jsx: { runtime: "automatic", importSource: "react" } };
5429
+ return {
5430
+ resolve: resolve10,
5431
+ define: config.define,
5432
+ oxc
5433
+ };
5434
+ }
5435
+
4661
5436
  // src/vite/router-discovery.ts
5437
+ var debugDiscovery = createRangoDebugger(NS.discovery);
5438
+ var debugRoutes = createRangoDebugger(NS.routes);
5439
+ var debugBuild = createRangoDebugger(NS.build);
5440
+ var debugDev = createRangoDebugger(NS.dev);
5441
+ var loaderHookRegistered = false;
5442
+ function ensureCloudflareProtocolLoaderRegistered() {
5443
+ if (loaderHookRegistered) return;
5444
+ loaderHookRegistered = true;
5445
+ try {
5446
+ register(
5447
+ new URL("./plugins/cloudflare-protocol-loader-hook.mjs", import.meta.url)
5448
+ );
5449
+ } catch (err) {
5450
+ console.warn(
5451
+ `[rango] Could not register Node ESM loader hook for cloudflare:* imports (${err?.message ?? err}). Falling back to Vite transform only.`
5452
+ );
5453
+ }
5454
+ }
4662
5455
  async function createTempRscServer(state, options = {}) {
5456
+ ensureCloudflareProtocolLoaderRegistered();
4663
5457
  const { default: rsc } = await import("@vitejs/plugin-rsc");
5458
+ const runnerConfig = state.userRunnerConfig;
5459
+ const resolveConfig = runnerConfig?.resolve ?? {
5460
+ alias: state.userResolveAlias
5461
+ };
5462
+ const oxcConfig = runnerConfig?.oxc ?? {
5463
+ jsx: { runtime: "automatic", importSource: "react" }
5464
+ };
4664
5465
  return createViteServer({
4665
5466
  root: state.projectRoot,
4666
5467
  configFile: false,
4667
5468
  server: { middlewareMode: true },
4668
5469
  appType: "custom",
4669
5470
  logLevel: "silent",
4670
- resolve: { alias: state.userResolveAlias },
4671
- esbuild: { jsx: "automatic", jsxImportSource: "react" },
5471
+ resolve: resolveConfig,
5472
+ ...runnerConfig?.define ? { define: runnerConfig.define } : {},
5473
+ oxc: oxcConfig,
4672
5474
  ...options.cacheDir && { cacheDir: options.cacheDir },
4673
5475
  plugins: [
4674
5476
  rsc({
@@ -4682,10 +5484,15 @@ async function createTempRscServer(state, options = {}) {
4682
5484
  ...options.forceBuild ? [hashClientRefs(state.projectRoot)] : [],
4683
5485
  createVersionPlugin(),
4684
5486
  createVirtualStubPlugin(),
5487
+ createCloudflareProtocolStubPlugin(),
4685
5488
  // Dev prerender must use dev-mode IDs (path-based) to match the workerd
4686
5489
  // runtime. forceBuild produces hashed IDs for production bundle consistency.
4687
5490
  exposeInternalIds(options.forceBuild ? { forceBuild: true } : void 0),
4688
- exposeRouterId()
5491
+ exposeRouterId(),
5492
+ // Forwarded user resolution plugins (e.g. vite-tsconfig-paths). Stripped
5493
+ // to resolveId/load and placed last so framework resolution runs first;
5494
+ // Vite re-sorts by `enforce`, so `enforce: "pre"` resolvers still lead.
5495
+ ...state.userResolvePlugins
4689
5496
  ]
4690
5497
  });
4691
5498
  }
@@ -4694,11 +5501,11 @@ async function resolveBuildEnv(option, factoryCtx) {
4694
5501
  if (option === "auto") {
4695
5502
  if (factoryCtx.preset !== "cloudflare") {
4696
5503
  throw new Error(
4697
- '[rsc-router] buildEnv: "auto" is only supported with preset: "cloudflare". Use a factory function or plain object for other presets.'
5504
+ '[rango] buildEnv: "auto" is only supported with preset: "cloudflare". Use a factory function or plain object for other presets.'
4698
5505
  );
4699
5506
  }
4700
5507
  try {
4701
- const userRequire = createRequire(
5508
+ const userRequire = createRequire2(
4702
5509
  resolve8(factoryCtx.root, "package.json")
4703
5510
  );
4704
5511
  const wranglerPath = userRequire.resolve("wrangler");
@@ -4710,7 +5517,7 @@ async function resolveBuildEnv(option, factoryCtx) {
4710
5517
  };
4711
5518
  } catch (err) {
4712
5519
  throw new Error(
4713
- `[rsc-router] buildEnv: "auto" requires wrangler to be installed.
5520
+ `[rango] buildEnv: "auto" requires wrangler to be installed.
4714
5521
  Install it with: pnpm add -D wrangler
4715
5522
  ${err.message}`
4716
5523
  );
@@ -4733,6 +5540,7 @@ async function acquireBuildEnv(s, command, mode) {
4733
5540
  if (!result) return false;
4734
5541
  s.resolvedBuildEnv = result.env;
4735
5542
  s.buildEnvDispose = result.dispose ?? null;
5543
+ globalThis[BUILD_ENV_GLOBAL_KEY] = result.env;
4736
5544
  return true;
4737
5545
  }
4738
5546
  async function releaseBuildEnv(s) {
@@ -4740,11 +5548,12 @@ async function releaseBuildEnv(s) {
4740
5548
  try {
4741
5549
  await s.buildEnvDispose();
4742
5550
  } catch (err) {
4743
- console.warn(`[rsc-router] buildEnv dispose failed: ${err.message}`);
5551
+ console.warn(`[rango] buildEnv dispose failed: ${err.message}`);
4744
5552
  }
4745
5553
  s.buildEnvDispose = null;
4746
5554
  }
4747
5555
  s.resolvedBuildEnv = void 0;
5556
+ delete globalThis[BUILD_ENV_GLOBAL_KEY];
4748
5557
  }
4749
5558
  function createRouterDiscoveryPlugin(entryPath, opts) {
4750
5559
  const s = createDiscoveryState(entryPath, opts);
@@ -4766,17 +5575,16 @@ function createRouterDiscoveryPlugin(entryPath, opts) {
4766
5575
  viteCommand = config.command;
4767
5576
  viteMode = config.mode;
4768
5577
  s.userResolveAlias = config.resolve.alias;
5578
+ s.userRunnerConfig = pickForwardedRunnerConfig(config);
5579
+ s.userResolvePlugins = selectForwardableResolvePlugins(
5580
+ config.plugins
5581
+ );
4769
5582
  if (!s.resolvedEntryPath && opts?.routerPathRef?.path) {
4770
5583
  s.resolvedEntryPath = opts.routerPathRef.path;
4771
5584
  }
4772
5585
  if (!s.resolvedEntryPath) {
4773
- const rscEnvConfig = config.environments?.["rsc"];
4774
- const entries = rscEnvConfig?.optimizeDeps?.entries;
4775
- if (typeof entries === "string") {
4776
- s.resolvedEntryPath = entries;
4777
- } else if (Array.isArray(entries) && entries.length > 0) {
4778
- s.resolvedEntryPath = entries[0];
4779
- }
5586
+ const entry = resolveRscEntryFromConfig(config);
5587
+ if (entry) s.resolvedEntryPath = entry;
4780
5588
  }
4781
5589
  if (opts?.staticRouteTypesGeneration !== false) {
4782
5590
  s.cachedRouterFiles = findRouterFiles(s.projectRoot, s.scanFilter);
@@ -4800,6 +5608,9 @@ function createRouterDiscoveryPlugin(entryPath, opts) {
4800
5608
  const discoveryPromise = new Promise((resolve10) => {
4801
5609
  resolveDiscovery = resolve10;
4802
5610
  });
5611
+ const gate = createDiscoveryGate(s, debugDiscovery);
5612
+ const beginDiscoveryGate = gate.beginGate;
5613
+ const resolveDiscoveryGate = gate.resolveGate;
4803
5614
  const getDevServerOrigin = () => server.resolvedUrls?.local?.[0]?.replace(/\/$/, "") || `http://localhost:${server.config.server.port || 5173}`;
4804
5615
  let prerenderTempServer = null;
4805
5616
  let prerenderNodeRegistry = null;
@@ -4812,74 +5623,241 @@ function createRouterDiscoveryPlugin(entryPath, opts) {
4812
5623
  releaseBuildEnv(s).catch(() => {
4813
5624
  });
4814
5625
  });
5626
+ async function importEntryAndRegistry(tempRscEnv) {
5627
+ const flagAlreadySet = !!globalThis.__rscRouterDiscoveryActive;
5628
+ if (!flagAlreadySet) {
5629
+ globalThis.__rscRouterDiscoveryActive = true;
5630
+ }
5631
+ try {
5632
+ debugDiscovery?.(
5633
+ "importEntryAndRegistry: importing entry (flag=%s)",
5634
+ globalThis.__rscRouterDiscoveryActive ?? false
5635
+ );
5636
+ await tempRscEnv.runner.import(s.resolvedEntryPath);
5637
+ debugDiscovery?.(
5638
+ "importEntryAndRegistry: entry import OK, fetching RouterRegistry"
5639
+ );
5640
+ const serverMod = await tempRscEnv.runner.import(
5641
+ "@rangojs/router/server"
5642
+ );
5643
+ prerenderNodeRegistry = serverMod.RouterRegistry;
5644
+ debugDiscovery?.(
5645
+ "importEntryAndRegistry: registry size=%d",
5646
+ prerenderNodeRegistry?.size ?? 0
5647
+ );
5648
+ } finally {
5649
+ if (!flagAlreadySet) {
5650
+ delete globalThis.__rscRouterDiscoveryActive;
5651
+ debugDiscovery?.(
5652
+ "importEntryAndRegistry: cleared __rscRouterDiscoveryActive"
5653
+ );
5654
+ }
5655
+ }
5656
+ }
4815
5657
  async function getOrCreateTempServer() {
4816
- if (prerenderNodeRegistry) {
4817
- return prerenderTempServer.environments?.rsc ?? null;
5658
+ if (prerenderTempServer) {
5659
+ const existingEnv = prerenderTempServer.environments?.rsc;
5660
+ if (existingEnv?.runner) {
5661
+ if (prerenderNodeRegistry) {
5662
+ debugDiscovery?.(
5663
+ "getOrCreateTempServer: cached temp runner reused"
5664
+ );
5665
+ return existingEnv;
5666
+ }
5667
+ debugDiscovery?.(
5668
+ "getOrCreateTempServer: server alive but registry missing \u2014 re-importing"
5669
+ );
5670
+ try {
5671
+ await importEntryAndRegistry(existingEnv);
5672
+ return existingEnv;
5673
+ } catch (err) {
5674
+ debugDiscovery?.(
5675
+ "getOrCreateTempServer: reuse import failed (%s) \u2014 closing orphan and creating fresh",
5676
+ err?.message ?? String(err)
5677
+ );
5678
+ await prerenderTempServer.close().catch(() => {
5679
+ });
5680
+ prerenderTempServer = null;
5681
+ prerenderNodeRegistry = null;
5682
+ }
5683
+ } else {
5684
+ debugDiscovery?.(
5685
+ "getOrCreateTempServer: existing server has no rsc.runner \u2014 closing and recreating"
5686
+ );
5687
+ await prerenderTempServer.close().catch(() => {
5688
+ });
5689
+ prerenderTempServer = null;
5690
+ prerenderNodeRegistry = null;
5691
+ }
4818
5692
  }
5693
+ debugDiscovery?.(
5694
+ "getOrCreateTempServer: creating new temp server, entry=%s",
5695
+ s.resolvedEntryPath ?? "(unset)"
5696
+ );
4819
5697
  try {
4820
5698
  prerenderTempServer = await createTempRscServer(s, {
4821
5699
  cacheDir: "node_modules/.vite_prerender"
4822
5700
  });
4823
5701
  const tempRscEnv = prerenderTempServer.environments?.rsc;
4824
5702
  if (tempRscEnv?.runner) {
4825
- await tempRscEnv.runner.import(s.resolvedEntryPath);
4826
- const serverMod = await tempRscEnv.runner.import(
4827
- "@rangojs/router/server"
4828
- );
4829
- prerenderNodeRegistry = serverMod.RouterRegistry;
5703
+ await importEntryAndRegistry(tempRscEnv);
4830
5704
  return tempRscEnv;
4831
5705
  }
5706
+ debugDiscovery?.(
5707
+ "getOrCreateTempServer: tempRscEnv.runner unavailable"
5708
+ );
4832
5709
  } catch (err) {
4833
- console.warn(
4834
- `[rsc-router] Failed to create temp runner: ${err.message}`
5710
+ debugDiscovery?.(
5711
+ "getOrCreateTempServer: FAILED message=%s",
5712
+ err.message
4835
5713
  );
5714
+ console.warn(`[rango] Failed to create temp runner: ${err.message}`);
4836
5715
  }
4837
5716
  return null;
4838
5717
  }
5718
+ async function clearTempRegistries(tempRscEnv) {
5719
+ try {
5720
+ const serverMod = await tempRscEnv.runner.import(
5721
+ "@rangojs/router/server"
5722
+ );
5723
+ if (typeof serverMod?.RouterRegistry?.clear === "function") {
5724
+ serverMod.RouterRegistry.clear();
5725
+ }
5726
+ if (typeof serverMod?.HostRouterRegistry?.clear === "function") {
5727
+ serverMod.HostRouterRegistry.clear();
5728
+ }
5729
+ debugDiscovery?.(
5730
+ "clearTempRegistries: cleared RouterRegistry + HostRouterRegistry"
5731
+ );
5732
+ } catch (err) {
5733
+ debugDiscovery?.(
5734
+ "clearTempRegistries: import @rangojs/router/server failed (%s)",
5735
+ err?.message ?? String(err)
5736
+ );
5737
+ }
5738
+ }
5739
+ async function refreshTempRscEnv() {
5740
+ let tempRscEnv = await getOrCreateTempServer();
5741
+ if (!tempRscEnv) return null;
5742
+ const envGraph = tempRscEnv.moduleGraph;
5743
+ const serverGraph = prerenderTempServer?.moduleGraph;
5744
+ const target = envGraph?.invalidateAll ? envGraph : serverGraph?.invalidateAll ? serverGraph : null;
5745
+ if (!target) {
5746
+ debugDiscovery?.(
5747
+ "refreshTempRscEnv: invalidateAll unavailable on env+server graphs, falling back to close+recreate"
5748
+ );
5749
+ if (prerenderTempServer) {
5750
+ await prerenderTempServer.close().catch(() => {
5751
+ });
5752
+ prerenderTempServer = null;
5753
+ prerenderNodeRegistry = null;
5754
+ }
5755
+ return await getOrCreateTempServer();
5756
+ }
5757
+ debugDiscovery?.(
5758
+ "refreshTempRscEnv: invalidating module graph (%s)",
5759
+ envGraph?.invalidateAll ? "env" : "server"
5760
+ );
5761
+ target.invalidateAll();
5762
+ prerenderNodeRegistry = null;
5763
+ await clearTempRegistries(tempRscEnv);
5764
+ await importEntryAndRegistry(tempRscEnv);
5765
+ return tempRscEnv;
5766
+ }
4839
5767
  const discover = async () => {
5768
+ const discoverStart = performance.now();
4840
5769
  const rscEnv = server.environments?.rsc;
4841
5770
  if (!rscEnv?.runner) {
5771
+ debugDiscovery?.(
5772
+ "dev: cloudflare path start, __rscRouterDiscoveryActive=%s",
5773
+ globalThis.__rscRouterDiscoveryActive ?? false
5774
+ );
4842
5775
  s.devServerOrigin = getDevServerOrigin();
4843
5776
  try {
4844
- await acquireBuildEnv(s, viteCommand, viteMode);
4845
- const tempRscEnv = await getOrCreateTempServer();
5777
+ await timed(
5778
+ debugDiscovery,
5779
+ "acquireBuildEnv",
5780
+ () => acquireBuildEnv(s, viteCommand, viteMode)
5781
+ );
5782
+ const tempRscEnv = await timed(
5783
+ debugDiscovery,
5784
+ "getOrCreateTempServer",
5785
+ () => getOrCreateTempServer()
5786
+ );
4846
5787
  if (tempRscEnv) {
4847
- await discoverRouters(s, tempRscEnv);
4848
- writeRouteTypesFiles(s);
5788
+ await timed(
5789
+ debugDiscovery,
5790
+ "discoverRouters (cloudflare)",
5791
+ () => discoverRouters(s, tempRscEnv)
5792
+ );
5793
+ timedSync(
5794
+ debugDiscovery,
5795
+ "writeRouteTypesFiles",
5796
+ () => writeRouteTypesFiles(s)
5797
+ );
4849
5798
  }
4850
5799
  } catch (err) {
4851
5800
  console.warn(
4852
- `[rsc-router] Cloudflare dev discovery failed: ${err.message}
5801
+ `[rango] Cloudflare dev discovery failed: ${err.message}
4853
5802
  ${err.stack}`
4854
5803
  );
4855
5804
  }
5805
+ debugDiscovery?.(
5806
+ "dev discovery done (%sms)",
5807
+ (performance.now() - discoverStart).toFixed(1)
5808
+ );
4856
5809
  resolveDiscovery();
4857
5810
  return;
4858
5811
  }
4859
5812
  try {
4860
- await acquireBuildEnv(s, viteCommand, viteMode);
4861
- const serverMod = await rscEnv.runner.import(
4862
- "@rangojs/router/server"
5813
+ debugDiscovery?.("dev: node path start");
5814
+ await timed(
5815
+ debugDiscovery,
5816
+ "acquireBuildEnv",
5817
+ () => acquireBuildEnv(s, viteCommand, viteMode)
5818
+ );
5819
+ const serverMod = await timed(
5820
+ debugDiscovery,
5821
+ "import @rangojs/router/server",
5822
+ () => rscEnv.runner.import("@rangojs/router/server")
4863
5823
  );
4864
5824
  if (serverMod?.setManifestReadyPromise) {
4865
5825
  serverMod.setManifestReadyPromise(discoveryPromise);
4866
5826
  }
4867
- await discoverRouters(s, rscEnv);
5827
+ await timed(
5828
+ debugDiscovery,
5829
+ "discoverRouters",
5830
+ () => discoverRouters(s, rscEnv)
5831
+ );
4868
5832
  s.devServerOrigin = getDevServerOrigin();
4869
- writeRouteTypesFiles(s);
4870
- await propagateDiscoveryState(rscEnv);
5833
+ timedSync(
5834
+ debugDiscovery,
5835
+ "writeRouteTypesFiles",
5836
+ () => writeRouteTypesFiles(s)
5837
+ );
5838
+ await timed(
5839
+ debugDiscovery,
5840
+ "propagateDiscoveryState",
5841
+ () => propagateDiscoveryState(rscEnv)
5842
+ );
4871
5843
  } catch (err) {
4872
5844
  console.warn(
4873
- `[rsc-router] Router discovery failed: ${err.message}
5845
+ `[rango] Router discovery failed: ${err.message}
4874
5846
  ${err.stack}`
4875
5847
  );
4876
5848
  } finally {
5849
+ debugDiscovery?.(
5850
+ "dev discovery done (%sms)",
5851
+ (performance.now() - discoverStart).toFixed(1)
5852
+ );
4877
5853
  resolveDiscovery();
4878
5854
  }
4879
5855
  };
4880
- s.discoveryDone = new Promise((resolve10) => {
4881
- setTimeout(() => discover().then(resolve10, resolve10), 0);
4882
- });
5856
+ beginDiscoveryGate();
5857
+ setTimeout(
5858
+ () => discover().then(resolveDiscoveryGate, resolveDiscoveryGate),
5859
+ 0
5860
+ );
4883
5861
  let mainRegistry = null;
4884
5862
  const propagateDiscoveryState = async (rscEnv) => {
4885
5863
  const serverMod = await rscEnv.runner.import("@rangojs/router/server");
@@ -4897,29 +5875,35 @@ ${err.stack}`
4897
5875
  if (s.mergedRouteTrie && serverMod.setRouteTrie) {
4898
5876
  serverMod.setRouteTrie(s.mergedRouteTrie);
4899
5877
  }
4900
- if (serverMod.setRouterManifest) {
4901
- for (const [routerId, manifest] of s.perRouterManifestDataMap) {
4902
- serverMod.setRouterManifest(routerId, manifest);
4903
- }
4904
- }
4905
- if (serverMod.setRouterTrie) {
4906
- for (const [routerId, trie] of s.perRouterTrieMap) {
4907
- serverMod.setRouterTrie(routerId, trie);
4908
- }
4909
- }
4910
- if (serverMod.setRouterPrecomputedEntries) {
4911
- for (const [routerId, entries] of s.perRouterPrecomputedMap) {
4912
- serverMod.setRouterPrecomputedEntries(routerId, entries);
4913
- }
5878
+ const perRouterSetters = [
5879
+ [s.perRouterManifestDataMap, "setRouterManifest"],
5880
+ [s.perRouterTrieMap, "setRouterTrie"],
5881
+ [s.perRouterPrecomputedMap, "setRouterPrecomputedEntries"]
5882
+ ];
5883
+ for (const [map, fn] of perRouterSetters) {
5884
+ const setter = serverMod[fn];
5885
+ if (typeof setter !== "function") continue;
5886
+ for (const [routerId, value] of map) setter(routerId, value);
4914
5887
  }
4915
5888
  };
4916
5889
  server.middlewares.use("/__rsc_prerender", async (req, res) => {
5890
+ const reqStart = debugDev ? performance.now() : 0;
5891
+ const logResult = (status, note) => {
5892
+ debugDev?.(
5893
+ "/__rsc_prerender %s -> %d %s (%sms)",
5894
+ req.url,
5895
+ status,
5896
+ note,
5897
+ (performance.now() - reqStart).toFixed(1)
5898
+ );
5899
+ };
4917
5900
  if (s.discoveryDone) await s.discoveryDone;
4918
5901
  const url = new URL(req.url || "/", "http://localhost");
4919
5902
  const pathname = url.searchParams.get("pathname");
4920
5903
  if (!pathname) {
4921
5904
  res.statusCode = 400;
4922
5905
  res.end("Missing pathname");
5906
+ logResult(400, "missing pathname");
4923
5907
  return;
4924
5908
  }
4925
5909
  const rscEnv = server.environments?.rsc;
@@ -4933,10 +5917,11 @@ ${err.stack}`
4933
5917
  registry = serverMod.RouterRegistry ?? null;
4934
5918
  } catch (err) {
4935
5919
  console.warn(
4936
- `[rsc-router] Dev prerender module refresh failed: ${err.message}`
5920
+ `[rango] Dev prerender module refresh failed: ${err.message}`
4937
5921
  );
4938
5922
  res.statusCode = 500;
4939
5923
  res.end(`Prerender handler error: ${err.message}`);
5924
+ logResult(500, "module refresh failed");
4940
5925
  return;
4941
5926
  }
4942
5927
  } else {
@@ -4951,6 +5936,7 @@ ${err.stack}`
4951
5936
  if (!registry || registry.size === 0) {
4952
5937
  res.statusCode = 503;
4953
5938
  res.end("Prerender runner not available");
5939
+ logResult(503, "no registry");
4954
5940
  return;
4955
5941
  }
4956
5942
  const wantIntercept = url.searchParams.get("intercept") === "1";
@@ -4985,15 +5971,17 @@ ${err.stack}`
4985
5971
  payload = { segments: result.segments, handles: result.handles };
4986
5972
  }
4987
5973
  res.end(JSON.stringify(payload));
5974
+ logResult(200, `match ${result.routeName}`);
4988
5975
  return;
4989
5976
  } catch (err) {
4990
5977
  console.warn(
4991
- `[rsc-router] Dev prerender failed for ${pathname}: ${err.message}`
5978
+ `[rango] Dev prerender failed for ${pathname}: ${err.message}`
4992
5979
  );
4993
5980
  }
4994
5981
  }
4995
5982
  res.statusCode = 404;
4996
5983
  res.end("No prerender match");
5984
+ logResult(404, "no match");
4997
5985
  });
4998
5986
  if (opts?.staticRouteTypesGeneration !== false) {
4999
5987
  const isGeneratedRouteFile = (filePath) => filePath.endsWith(".gen.ts") && (filePath.includes("named-routes.gen.ts") || filePath.includes("urls.gen.ts"));
@@ -5013,59 +6001,185 @@ ${err.stack}`
5013
6001
  return true;
5014
6002
  };
5015
6003
  let routeChangeTimer;
5016
- let runtimeRediscoveryInProgress = false;
5017
6004
  const refreshRuntimeDiscovery = async () => {
5018
6005
  const rscEnv = server.environments?.rsc;
5019
- if (!rscEnv?.runner || runtimeRediscoveryInProgress) return;
5020
- runtimeRediscoveryInProgress = true;
6006
+ const hasMainRunner = !!rscEnv?.runner;
6007
+ if (!hasMainRunner && s.perRouterManifests.length === 0) return;
6008
+ await gate.runRefreshCycle(async () => {
6009
+ const hmrStart = performance.now();
6010
+ try {
6011
+ if (hasMainRunner) {
6012
+ await timed(
6013
+ debugDiscovery,
6014
+ "hmr discoverRouters",
6015
+ () => discoverRouters(s, rscEnv)
6016
+ );
6017
+ timedSync(
6018
+ debugDiscovery,
6019
+ "hmr writeRouteTypesFiles",
6020
+ () => writeRouteTypesFiles(s)
6021
+ );
6022
+ await timed(
6023
+ debugDiscovery,
6024
+ "hmr propagateDiscoveryState",
6025
+ () => propagateDiscoveryState(rscEnv)
6026
+ );
6027
+ } else {
6028
+ const tempRscEnv = await timed(
6029
+ debugDiscovery,
6030
+ "hmr refreshTempRscEnv (cloudflare)",
6031
+ () => refreshTempRscEnv()
6032
+ );
6033
+ if (!tempRscEnv) {
6034
+ throw new Error(
6035
+ "temp runner unavailable for cloudflare HMR rediscovery"
6036
+ );
6037
+ }
6038
+ await timed(
6039
+ debugDiscovery,
6040
+ "hmr discoverRouters (cloudflare)",
6041
+ () => discoverRouters(s, tempRscEnv)
6042
+ );
6043
+ timedSync(
6044
+ debugDiscovery,
6045
+ "hmr writeRouteTypesFiles",
6046
+ () => writeRouteTypesFiles(s)
6047
+ );
6048
+ }
6049
+ if (s.lastDiscoveryError) {
6050
+ debugDiscovery?.(
6051
+ "hmr: cleared lastDiscoveryError (%s) after successful rediscovery",
6052
+ s.lastDiscoveryError.message
6053
+ );
6054
+ s.lastDiscoveryError = null;
6055
+ }
6056
+ if (rscEnv && !rscEnv.runner) forceCloudflareWorkerReload(rscEnv);
6057
+ } catch (err) {
6058
+ s.lastDiscoveryError = {
6059
+ message: err?.message ?? String(err),
6060
+ at: Date.now()
6061
+ };
6062
+ console.warn(
6063
+ `[rango] Runtime re-discovery failed: ${err.message}`
6064
+ );
6065
+ debugDiscovery?.(
6066
+ "hmr: lastDiscoveryError set (%s) \u2014 manifest preserved at last-good; recovery mode active (any in-scan source change will trigger rediscovery)",
6067
+ err?.message
6068
+ );
6069
+ } finally {
6070
+ debugDiscovery?.(
6071
+ "hmr re-discovery done (%sms)",
6072
+ (performance.now() - hmrStart).toFixed(1)
6073
+ );
6074
+ }
6075
+ });
6076
+ };
6077
+ const forceCloudflareWorkerReload = (rscEnv) => {
6078
+ if (!rscEnv?.hot) return;
5021
6079
  try {
5022
- await discoverRouters(s, rscEnv);
5023
- writeRouteTypesFiles(s);
5024
- await propagateDiscoveryState(rscEnv);
6080
+ const graph = rscEnv.moduleGraph;
6081
+ if (graph?.invalidateAll) {
6082
+ graph.invalidateAll();
6083
+ debugDiscovery?.("hmr: invalidated workerd rsc module graph");
6084
+ }
6085
+ rscEnv.hot.send({ type: "full-reload" });
6086
+ debugDiscovery?.(
6087
+ "hmr: forced workerd rsc env reload (full-reload)"
6088
+ );
5025
6089
  } catch (err) {
5026
- console.warn(
5027
- `[rsc-router] Runtime re-discovery failed: ${err.message}`
6090
+ debugDiscovery?.(
6091
+ "hmr: workerd reload failed: %s",
6092
+ err?.message ?? err
5028
6093
  );
5029
- } finally {
5030
- runtimeRediscoveryInProgress = false;
5031
6094
  }
5032
6095
  };
5033
6096
  const scheduleRouteRegeneration = () => {
5034
6097
  clearTimeout(routeChangeTimer);
5035
6098
  routeChangeTimer = setTimeout(() => {
5036
6099
  routeChangeTimer = void 0;
6100
+ const regenStart = debugDiscovery ? performance.now() : 0;
6101
+ const rscEnv = server.environments?.rsc;
6102
+ const skipStaticWrite = !rscEnv?.runner && s.perRouterManifests.length > 0;
5037
6103
  try {
5038
- writeCombinedRouteTypesWithTracking(s);
5039
- if (s.perRouterManifests.length > 0) {
5040
- supplementGenFilesWithRuntimeRoutes(s);
6104
+ if (skipStaticWrite) {
6105
+ debugDiscovery?.(
6106
+ "watcher: skipping static write (cloudflare HMR \u2014 runtime rediscovery owns gen file)"
6107
+ );
6108
+ } else {
6109
+ writeCombinedRouteTypesWithTracking(s);
6110
+ if (s.perRouterManifests.length > 0) {
6111
+ supplementGenFilesWithRuntimeRoutes(s);
6112
+ }
5041
6113
  }
5042
6114
  } catch (err) {
5043
- console.error(
5044
- `[rsc-router] Route regeneration error: ${err.message}`
5045
- );
6115
+ console.error(`[rango] Route regeneration error: ${err.message}`);
5046
6116
  }
6117
+ debugDiscovery?.(
6118
+ "watcher: regenerated gen files (%sms)",
6119
+ (performance.now() - regenStart).toFixed(1)
6120
+ );
5047
6121
  if (s.perRouterManifests.length > 0) {
5048
6122
  refreshRuntimeDiscovery().catch((err) => {
5049
6123
  console.warn(
5050
- `[rsc-router] Runtime re-discovery error: ${err.message}`
6124
+ `[rango] Runtime re-discovery error: ${err.message}`
5051
6125
  );
6126
+ resolveDiscoveryGate();
5052
6127
  });
5053
6128
  }
5054
6129
  }, 100);
5055
6130
  };
5056
6131
  const handleRouteFileChange = (filePath) => {
5057
6132
  if (maybeHandleGeneratedRouteFileMutation(filePath)) return;
5058
- if (!filePath.endsWith(".ts") && !filePath.endsWith(".tsx") && !filePath.endsWith(".js") && !filePath.endsWith(".jsx"))
6133
+ if (!filePath.endsWith(".ts") && !filePath.endsWith(".tsx") && !filePath.endsWith(".js") && !filePath.endsWith(".jsx")) {
6134
+ if (s.lastDiscoveryError) {
6135
+ debugDiscovery?.(
6136
+ "watcher: skip non-source %s [LASTERR %s]",
6137
+ filePath,
6138
+ s.lastDiscoveryError.message
6139
+ );
6140
+ }
5059
6141
  return;
5060
- if (s.scanFilter && !s.scanFilter(filePath)) return;
6142
+ }
6143
+ if (s.scanFilter && !s.scanFilter(filePath)) {
6144
+ if (s.lastDiscoveryError) {
6145
+ debugDiscovery?.(
6146
+ "watcher: skip scan-filter %s [LASTERR %s]",
6147
+ filePath,
6148
+ s.lastDiscoveryError.message
6149
+ );
6150
+ }
6151
+ return;
6152
+ }
6153
+ const inRecoveryMode = !!s.lastDiscoveryError;
5061
6154
  try {
5062
6155
  const source = readFileSync6(filePath, "utf-8");
5063
6156
  const trimmed = source.trimStart();
5064
- if (trimmed.startsWith('"use client"') || trimmed.startsWith("'use client'"))
5065
- return;
5066
- const hasUrls = source.includes("urls(");
5067
- const hasCreateRouter = /\bcreateRouter\s*[<(]/.test(source);
5068
- if (!hasUrls && !hasCreateRouter) return;
6157
+ const isUseClient = trimmed.startsWith('"use client"') || trimmed.startsWith("'use client'");
6158
+ if (!inRecoveryMode && isUseClient) return;
6159
+ let hasUrls = source.includes("urls(");
6160
+ let hasCreateRouter = /\bcreateRouter\s*[<(]/.test(source);
6161
+ if (hasUrls) hasUrls = firstCodeMatchIndex(source, /urls\(/g) >= 0;
6162
+ if (hasCreateRouter) {
6163
+ hasCreateRouter = firstCodeMatchIndex(source, /\bcreateRouter\s*[<(]/g) >= 0;
6164
+ }
6165
+ if (!inRecoveryMode && !hasUrls && !hasCreateRouter) return;
6166
+ if (inRecoveryMode) {
6167
+ debugDiscovery?.(
6168
+ "watcher: recovery rediscovery for %s (urls=%s, router=%s, useClient=%s) [LASTERR %s]",
6169
+ filePath,
6170
+ hasUrls,
6171
+ hasCreateRouter,
6172
+ isUseClient,
6173
+ s.lastDiscoveryError.message
6174
+ );
6175
+ } else {
6176
+ debugDiscovery?.(
6177
+ "watcher: %s matches (urls=%s, router=%s)",
6178
+ filePath,
6179
+ hasUrls,
6180
+ hasCreateRouter
6181
+ );
6182
+ }
5069
6183
  if (hasCreateRouter) {
5070
6184
  const nestedRouterConflict = findNestedRouterConflict([
5071
6185
  ...s.cachedRouterFiles ?? [],
@@ -5079,8 +6193,19 @@ ${err.stack}`
5079
6193
  }
5080
6194
  s.cachedRouterFiles = void 0;
5081
6195
  }
6196
+ if (s.perRouterManifests.length > 0) {
6197
+ gate.noteRouteEvent();
6198
+ }
5082
6199
  scheduleRouteRegeneration();
5083
- } catch {
6200
+ } catch (readErr) {
6201
+ if (s.lastDiscoveryError) {
6202
+ debugDiscovery?.(
6203
+ "watcher: read error %s: %s [LASTERR %s]",
6204
+ filePath,
6205
+ readErr?.message,
6206
+ s.lastDiscoveryError.message
6207
+ );
6208
+ }
5084
6209
  }
5085
6210
  };
5086
6211
  server.watcher.on("add", handleRouteFileChange);
@@ -5098,19 +6223,35 @@ ${err.stack}`
5098
6223
  // The manifest data is stored for the virtual module's load hook.
5099
6224
  async buildStart() {
5100
6225
  if (!s.isBuildMode) return;
5101
- if (s.mergedRouteManifest !== null) return;
6226
+ if (s.mergedRouteManifest !== null) {
6227
+ debugDiscovery?.(
6228
+ "build: skip (already discovered, env=%s)",
6229
+ this.environment?.name ?? "?"
6230
+ );
6231
+ return;
6232
+ }
6233
+ const buildStartTime = performance.now();
6234
+ debugDiscovery?.("build: start (env=%s)", this.environment?.name ?? "?");
5102
6235
  resetStagedBuildAssets(s.projectRoot);
5103
6236
  s.prerenderManifestEntries = null;
5104
6237
  s.staticManifestEntries = null;
5105
- await acquireBuildEnv(s, viteCommand, viteMode);
6238
+ await timed(
6239
+ debugDiscovery,
6240
+ "build acquireBuildEnv",
6241
+ () => acquireBuildEnv(s, viteCommand, viteMode)
6242
+ );
5106
6243
  let tempServer = null;
5107
6244
  globalThis.__rscRouterDiscoveryActive = true;
5108
6245
  try {
5109
- tempServer = await createTempRscServer(s, { forceBuild: true });
6246
+ tempServer = await timed(
6247
+ debugDiscovery,
6248
+ "build createTempRscServer",
6249
+ () => createTempRscServer(s, { forceBuild: true })
6250
+ );
5110
6251
  const rscEnv = tempServer.environments?.rsc;
5111
6252
  if (!rscEnv?.runner) {
5112
6253
  console.warn(
5113
- "[rsc-router] RSC environment runner not available during build, skipping manifest generation"
6254
+ "[rango] RSC environment runner not available during build, skipping manifest generation"
5114
6255
  );
5115
6256
  return;
5116
6257
  }
@@ -5120,8 +6261,16 @@ ${err.stack}`
5120
6261
  if (tempIdsPlugin?.api?.staticHandlerModules) {
5121
6262
  s.resolvedStaticModules = tempIdsPlugin.api.staticHandlerModules;
5122
6263
  }
5123
- await discoverRouters(s, rscEnv);
5124
- writeRouteTypesFiles(s);
6264
+ await timed(
6265
+ debugDiscovery,
6266
+ "build discoverRouters",
6267
+ () => discoverRouters(s, rscEnv)
6268
+ );
6269
+ timedSync(
6270
+ debugDiscovery,
6271
+ "build writeRouteTypesFiles",
6272
+ () => writeRouteTypesFiles(s)
6273
+ );
5125
6274
  } catch (err) {
5126
6275
  const sourceFile = err.stack?.split("\n").find(
5127
6276
  (line) => line.includes(s.projectRoot) && !line.includes("node_modules")
@@ -5134,15 +6283,52 @@ ${err.stack}`
5134
6283
  ${err.stack}` : null
5135
6284
  ].filter(Boolean).join("\n");
5136
6285
  throw new Error(
5137
- `[rsc-router] Build-time router discovery failed:
5138
- ${details}`
6286
+ `[rango] Build-time router discovery failed:
6287
+ ${details}`,
6288
+ { cause: err }
5139
6289
  );
5140
6290
  } finally {
5141
6291
  delete globalThis.__rscRouterDiscoveryActive;
5142
6292
  if (tempServer) {
5143
- await tempServer.close();
6293
+ await timed(
6294
+ debugDiscovery,
6295
+ "build tempServer.close",
6296
+ () => tempServer.close()
6297
+ );
5144
6298
  }
5145
6299
  await releaseBuildEnv(s);
6300
+ debugDiscovery?.(
6301
+ "build discovery done (%sms)",
6302
+ (performance.now() - buildStartTime).toFixed(1)
6303
+ );
6304
+ }
6305
+ },
6306
+ // Suppress vite's HMR cascade for our own gen-file writes.
6307
+ //
6308
+ // After every cf HMR cycle, refreshTempRscEnv → writeRouteTypesFiles
6309
+ // writes the configured gen files (default `router.named-routes.gen.ts`,
6310
+ // but the source filenames and gen suffix are user-configurable). The
6311
+ // chokidar watcher then fires twice independently: our
6312
+ // `handleRouteFileChange` (already short-circuited by
6313
+ // `consumeSelfGenWrite` inside `maybeHandleGeneratedRouteFileMutation`),
6314
+ // AND vite's own HMR pipeline (which invalidates the gen file's
6315
+ // importers and triggers a second workerd full reload — visible to the
6316
+ // user as a duplicate "[Rango] HMR: version changed" on the client).
6317
+ //
6318
+ // `peekSelfGenWrite` is the authoritative filter: its map only contains
6319
+ // paths that `markSelfGenWrite` has registered, so it natively works
6320
+ // for any configured gen-file name. It is non-consuming so the chokidar
6321
+ // handler that fires later can still consume the same entry. Returning
6322
+ // [] tells vite "no modules invalidated by this change" — safe because
6323
+ // `s.perRouterManifests` is already up-to-date (the write that just
6324
+ // happened is the consequence of our just-completed rediscovery).
6325
+ handleHotUpdate(ctx) {
6326
+ if (peekSelfGenWrite(s, ctx.file)) {
6327
+ debugDiscovery?.(
6328
+ "handleHotUpdate: suppressing self-write HMR cascade for %s",
6329
+ ctx.file
6330
+ );
6331
+ return [];
5146
6332
  }
5147
6333
  },
5148
6334
  // Virtual module: provides the pre-generated route manifest as a JS module
@@ -5159,17 +6345,36 @@ ${details}`
5159
6345
  async load(id) {
5160
6346
  if (id === "\0" + VIRTUAL_ROUTES_MANIFEST_ID) {
5161
6347
  if (s.discoveryDone) {
5162
- await s.discoveryDone;
6348
+ await timed(
6349
+ debugRoutes,
6350
+ "await discoveryDone (manifest)",
6351
+ () => s.discoveryDone
6352
+ );
5163
6353
  }
5164
- return generateRoutesManifestModule(s);
6354
+ const code = await timed(
6355
+ debugRoutes,
6356
+ "generateRoutesManifestModule",
6357
+ () => generateRoutesManifestModule(s)
6358
+ );
6359
+ debugRoutes?.("manifest module emitted (%d bytes)", code?.length ?? 0);
6360
+ return code;
5165
6361
  }
5166
6362
  const perRouterPrefix = "\0" + VIRTUAL_ROUTES_MANIFEST_ID + "/";
5167
6363
  if (id.startsWith(perRouterPrefix)) {
5168
6364
  if (s.discoveryDone) {
5169
- await s.discoveryDone;
6365
+ await timed(
6366
+ debugRoutes,
6367
+ "await discoveryDone (per-router)",
6368
+ () => s.discoveryDone
6369
+ );
5170
6370
  }
5171
6371
  const routerId = id.slice(perRouterPrefix.length);
5172
- return generatePerRouterModule(s, routerId);
6372
+ const code = await timed(
6373
+ debugRoutes,
6374
+ `generatePerRouterModule ${routerId}`,
6375
+ () => generatePerRouterModule(s, routerId)
6376
+ );
6377
+ return code;
5173
6378
  }
5174
6379
  return null;
5175
6380
  },
@@ -5177,14 +6382,20 @@ ${details}`
5177
6382
  // Used by closeBundle for handler code eviction and prerender data injection.
5178
6383
  generateBundle(_options, bundle) {
5179
6384
  if (this.environment?.name !== "rsc") return;
6385
+ const genStart = debugBuild ? performance.now() : 0;
5180
6386
  for (const [fileName, chunk] of Object.entries(bundle)) {
5181
6387
  if (chunk.type === "chunk" && chunk.isEntry) {
5182
6388
  s.rscEntryFileName = fileName;
5183
6389
  break;
5184
6390
  }
5185
6391
  }
5186
- if (!s.resolvedPrerenderModules?.size && !s.resolvedStaticModules?.size)
6392
+ if (!s.resolvedPrerenderModules?.size && !s.resolvedStaticModules?.size) {
6393
+ debugBuild?.(
6394
+ "generateBundle (rsc): no handlers to scan (%sms)",
6395
+ (performance.now() - genStart).toFixed(1)
6396
+ );
5187
6397
  return;
6398
+ }
5188
6399
  s.handlerChunkInfoMap.clear();
5189
6400
  s.staticHandlerChunkInfoMap.clear();
5190
6401
  for (const [fileName, chunk] of Object.entries(bundle)) {
@@ -5228,6 +6439,13 @@ ${details}`
5228
6439
  }
5229
6440
  }
5230
6441
  }
6442
+ debugBuild?.(
6443
+ "generateBundle (rsc): scanned %d chunks, %d prerender chunk(s), %d static chunk(s) (%sms)",
6444
+ Object.keys(bundle).length,
6445
+ s.handlerChunkInfoMap.size,
6446
+ s.staticHandlerChunkInfoMap.size,
6447
+ (performance.now() - genStart).toFixed(1)
6448
+ );
5231
6449
  },
5232
6450
  // Build-time pre-rendering: evict handler code and inject collected prerender data.
5233
6451
  // Collection now happens in-process during discoverRouters() via RSC runner.
@@ -5238,29 +6456,45 @@ ${details}`
5238
6456
  async handler() {
5239
6457
  if (!s.isBuildMode) return;
5240
6458
  if (this.environment && this.environment.name !== "rsc") return;
5241
- postprocessBundle(s);
6459
+ timedSync(
6460
+ debugBuild,
6461
+ "closeBundle postprocessBundle",
6462
+ () => postprocessBundle(s)
6463
+ );
5242
6464
  }
5243
6465
  }
5244
6466
  };
5245
6467
  }
5246
6468
 
5247
6469
  // src/vite/rango.ts
6470
+ var debugConfig = createRangoDebugger(NS.config);
5248
6471
  async function rango(options) {
6472
+ const rangoStart = performance.now();
5249
6473
  const resolvedOptions = options ?? { preset: "node" };
5250
6474
  const preset = resolvedOptions.preset ?? "node";
5251
6475
  const showBanner = resolvedOptions.banner ?? true;
6476
+ const clientChunksOption = resolvedOptions.clientChunks ?? true;
6477
+ const useBuiltInClientChunks = clientChunksOption === true;
6478
+ const clientChunkCtx = useBuiltInClientChunks ? { fallbackRefs: /* @__PURE__ */ new Set() } : void 0;
6479
+ const clientChunks = resolveClientChunks(clientChunksOption, clientChunkCtx);
6480
+ debugConfig?.("rango(%s) setup start", preset);
5252
6481
  const plugins = [];
5253
- const rangoAliases = getPackageAliases();
6482
+ const rangoAliases = { ...getPackageAliases(), ...getVendorAliases() };
5254
6483
  const excludeDeps = [
5255
6484
  ...getExcludeDeps(),
5256
- // The public browser entry re-exports the RSDW browser client.
5257
- // Excluding both keeps Vite from freezing the unpatched bundle into
5258
- // .vite/deps before our source transforms run.
6485
+ // plugin-rsc itself injects these into the client env's
6486
+ // optimizeDeps.include, which overrides exclude for the dep's own
6487
+ // pre-bundle entry. What exclude still controls is how *other*
6488
+ // pre-bundled deps treat imports of these specs (external vs inlined)
6489
+ // via esbuildCjsExternalPlugin. The cjs-to-esm transform in
6490
+ // plugins/cjs-to-esm.ts is the fallback for strict-pnpm consumers,
6491
+ // where client.browser's bare include fails to resolve and Vite ends up
6492
+ // serving the raw CJS file at dev-serve time.
5259
6493
  "@vitejs/plugin-rsc/browser",
5260
- // Keep the browser RSDW client out of Vite's dep optimizer so our
5261
- // cjs-to-esm transform can patch the real file.
5262
6494
  "@vitejs/plugin-rsc/vendor/react-server-dom/client.browser"
5263
6495
  ];
6496
+ const pkg = getPublishedPackageName();
6497
+ const nested = (spec) => `${pkg} > ${spec}`;
5264
6498
  const routerRef = { path: void 0 };
5265
6499
  const prerenderEnabled = true;
5266
6500
  if (preset === "cloudflare") {
@@ -5278,10 +6512,18 @@ async function rango(options) {
5278
6512
  // This ensures the same Context instance is used by both browser entry and RSC proxy modules
5279
6513
  optimizeDeps: {
5280
6514
  exclude: excludeDeps,
5281
- esbuildOptions: sharedEsbuildOptions
6515
+ rolldownOptions: sharedRolldownOptions
5282
6516
  },
5283
6517
  resolve: {
5284
- alias: rangoAliases
6518
+ alias: rangoAliases,
6519
+ // Force a single React/React-DOM copy across all three RSC
6520
+ // environments. RSC requires exactly one react/react-dom instance
6521
+ // per environment runtime; consumer install topologies (pnpm
6522
+ // strict layout, experimental React pins, third-party "use client"
6523
+ // packages) can otherwise resolve duplicate copies, causing
6524
+ // "Invalid hook call" / lost context. Child environments inherit
6525
+ // this root dedupe, and Vite merges it with any consumer dedupe.
6526
+ dedupe: ["react", "react-dom"]
5285
6527
  },
5286
6528
  build: {
5287
6529
  rollupOptions: { onwarn }
@@ -5290,6 +6532,14 @@ async function rango(options) {
5290
6532
  client: {
5291
6533
  build: {
5292
6534
  rollupOptions: {
6535
+ // FILE_NAME_CONFLICT (and any other client-build warning) is
6536
+ // emitted by the CLIENT environment build, which consults THIS
6537
+ // env's onwarn -- Vite 8's environment builds do NOT propagate
6538
+ // the top-level build.rollupOptions.onwarn into the client env.
6539
+ // Wire it here so the suppression runs where the conflicts
6540
+ // originate (the top-level handler is invoked 0x for these; the
6541
+ // client-env handler is invoked for all of them).
6542
+ onwarn,
5293
6543
  output: {
5294
6544
  manualChunks: getManualChunks
5295
6545
  }
@@ -5298,9 +6548,9 @@ async function rango(options) {
5298
6548
  // Pre-bundle rsc-html-stream to prevent discovery during first request
5299
6549
  // Exclude rsc-router modules to ensure same Context instance
5300
6550
  optimizeDeps: {
5301
- include: ["rsc-html-stream/client"],
6551
+ include: [nested("rsc-html-stream/client")],
5302
6552
  exclude: excludeDeps,
5303
- esbuildOptions: sharedEsbuildOptions
6553
+ rolldownOptions: sharedRolldownOptions
5304
6554
  }
5305
6555
  },
5306
6556
  ssr: {
@@ -5308,10 +6558,6 @@ async function rango(options) {
5308
6558
  build: {
5309
6559
  outDir: "./dist/rsc/ssr"
5310
6560
  },
5311
- resolve: {
5312
- // Ensure single React instance in SSR child environment
5313
- dedupe: ["react", "react-dom"]
5314
- },
5315
6561
  // Pre-bundle SSR entry and React for proper module linking with childEnvironments
5316
6562
  // All deps must be listed to avoid late discovery triggering ERR_OUTDATED_OPTIMIZED_DEP
5317
6563
  optimizeDeps: {
@@ -5323,11 +6569,13 @@ async function rango(options) {
5323
6569
  "react-dom/static.edge",
5324
6570
  "react/jsx-runtime",
5325
6571
  "react/jsx-dev-runtime",
5326
- "rsc-html-stream/server",
5327
- "@vitejs/plugin-rsc/vendor/react-server-dom/client.edge"
6572
+ nested("rsc-html-stream/server"),
6573
+ nested(
6574
+ "@vitejs/plugin-rsc/vendor/react-server-dom/client.edge"
6575
+ )
5328
6576
  ],
5329
6577
  exclude: excludeDeps,
5330
- esbuildOptions: sharedEsbuildOptions
6578
+ rolldownOptions: sharedRolldownOptions
5331
6579
  }
5332
6580
  },
5333
6581
  rsc: {
@@ -5339,10 +6587,12 @@ async function rango(options) {
5339
6587
  "react",
5340
6588
  "react/jsx-runtime",
5341
6589
  "react/jsx-dev-runtime",
5342
- "@vitejs/plugin-rsc/vendor/react-server-dom/server.edge"
6590
+ nested(
6591
+ "@vitejs/plugin-rsc/vendor/react-server-dom/server.edge"
6592
+ )
5343
6593
  ],
5344
6594
  exclude: excludeDeps,
5345
- esbuildOptions: sharedEsbuildOptions
6595
+ rolldownOptions: sharedRolldownOptions
5346
6596
  }
5347
6597
  }
5348
6598
  }
@@ -5360,7 +6610,8 @@ async function rango(options) {
5360
6610
  plugins.push(
5361
6611
  rsc({
5362
6612
  entries: finalEntries,
5363
- serverHandler: false
6613
+ serverHandler: false,
6614
+ clientChunks
5364
6615
  })
5365
6616
  );
5366
6617
  plugins.push(clientRefDedup());
@@ -5378,7 +6629,7 @@ async function rango(options) {
5378
6629
  const list = candidates.map(
5379
6630
  (f) => " - " + (f.startsWith(root) ? f.slice(root.length + 1) : f)
5380
6631
  ).join("\n");
5381
- throw new Error(`[rsc-router] Multiple routers found:
6632
+ throw new Error(`[rango] Multiple routers found:
5382
6633
  ${list}`);
5383
6634
  }
5384
6635
  }
@@ -5397,18 +6648,34 @@ ${list}`);
5397
6648
  return {
5398
6649
  optimizeDeps: {
5399
6650
  exclude: excludeDeps,
5400
- esbuildOptions: sharedEsbuildOptions
6651
+ rolldownOptions: sharedRolldownOptions
5401
6652
  },
5402
6653
  build: {
5403
6654
  rollupOptions: { onwarn }
5404
6655
  },
5405
6656
  resolve: {
5406
- alias: rangoAliases
6657
+ alias: rangoAliases,
6658
+ // Force a single React/React-DOM copy across all three RSC
6659
+ // environments. RSC requires exactly one react/react-dom instance
6660
+ // per environment runtime; consumer install topologies (pnpm
6661
+ // strict layout, experimental React pins, third-party "use client"
6662
+ // packages) can otherwise resolve duplicate copies, causing
6663
+ // "Invalid hook call" / lost context. Child environments inherit
6664
+ // this root dedupe, and Vite merges it with any consumer dedupe.
6665
+ dedupe: ["react", "react-dom"]
5407
6666
  },
5408
6667
  environments: {
5409
6668
  client: {
5410
6669
  build: {
5411
6670
  rollupOptions: {
6671
+ // FILE_NAME_CONFLICT (and any other client-build warning) is
6672
+ // emitted by the CLIENT environment build, which consults THIS
6673
+ // env's onwarn -- Vite 8's environment builds do NOT propagate
6674
+ // the top-level build.rollupOptions.onwarn into the client env.
6675
+ // Wire it here so the suppression runs where the conflicts
6676
+ // originate (the top-level handler is invoked 0x for these; the
6677
+ // client-env handler is invoked for all of them).
6678
+ onwarn,
5412
6679
  output: {
5413
6680
  manualChunks: getManualChunks
5414
6681
  }
@@ -5420,10 +6687,10 @@ ${list}`);
5420
6687
  "react-dom",
5421
6688
  "react/jsx-runtime",
5422
6689
  "react/jsx-dev-runtime",
5423
- "rsc-html-stream/client"
6690
+ nested("rsc-html-stream/client")
5424
6691
  ],
5425
6692
  exclude: excludeDeps,
5426
- esbuildOptions: sharedEsbuildOptions,
6693
+ rolldownOptions: sharedRolldownOptions,
5427
6694
  entries: [VIRTUAL_IDS.browser]
5428
6695
  }
5429
6696
  },
@@ -5437,10 +6704,12 @@ ${list}`);
5437
6704
  "react-dom/static.edge",
5438
6705
  "react/jsx-runtime",
5439
6706
  "react/jsx-dev-runtime",
5440
- "@vitejs/plugin-rsc/vendor/react-server-dom/client.edge"
6707
+ nested(
6708
+ "@vitejs/plugin-rsc/vendor/react-server-dom/client.edge"
6709
+ )
5441
6710
  ],
5442
6711
  exclude: excludeDeps,
5443
- esbuildOptions: sharedEsbuildOptions
6712
+ rolldownOptions: sharedRolldownOptions
5444
6713
  }
5445
6714
  },
5446
6715
  rsc: {
@@ -5450,9 +6719,11 @@ ${list}`);
5450
6719
  "react",
5451
6720
  "react/jsx-runtime",
5452
6721
  "react/jsx-dev-runtime",
5453
- "@vitejs/plugin-rsc/vendor/react-server-dom/server.edge"
6722
+ nested(
6723
+ "@vitejs/plugin-rsc/vendor/react-server-dom/server.edge"
6724
+ )
5454
6725
  ],
5455
- esbuildOptions: sharedEsbuildOptions
6726
+ rolldownOptions: sharedRolldownOptions
5456
6727
  }
5457
6728
  }
5458
6729
  }
@@ -5469,7 +6740,7 @@ ${list}`);
5469
6740
  if (rscMinimalCount > 1 && !hasWarnedDuplicate) {
5470
6741
  hasWarnedDuplicate = true;
5471
6742
  console.warn(
5472
- "[rsc-router] Duplicate @vitejs/plugin-rsc detected. Remove rsc() from your vite config \u2014 rango() includes it automatically."
6743
+ "[rango] Duplicate @vitejs/plugin-rsc detected. Remove rsc() from your vite config \u2014 rango() includes it automatically."
5473
6744
  );
5474
6745
  }
5475
6746
  }
@@ -5478,7 +6749,8 @@ ${list}`);
5478
6749
  plugins.push(performanceTracksPlugin());
5479
6750
  plugins.push(
5480
6751
  rsc({
5481
- entries: finalEntries
6752
+ entries: finalEntries,
6753
+ clientChunks
5482
6754
  })
5483
6755
  );
5484
6756
  plugins.push(clientRefDedup());
@@ -5517,9 +6789,16 @@ ${list}`);
5517
6789
  routerPathRef: discoveryRouterRef,
5518
6790
  enableBuildPrerender: prerenderEnabled,
5519
6791
  buildEnv: options?.buildEnv,
5520
- preset
6792
+ preset,
6793
+ clientChunkCtx
5521
6794
  })
5522
6795
  );
6796
+ debugConfig?.(
6797
+ "rango(%s) setup done: %d plugin(s) (%sms)",
6798
+ preset,
6799
+ plugins.length,
6800
+ (performance.now() - rangoStart).toFixed(1)
6801
+ );
5523
6802
  return plugins;
5524
6803
  }
5525
6804
 
@@ -5530,7 +6809,7 @@ function poke() {
5530
6809
  apply: "serve",
5531
6810
  configureServer(server) {
5532
6811
  const stdin = process.stdin;
5533
- const debug = process.env.RANGO_POKE_DEBUG === "1";
6812
+ const debug11 = process.env.RANGO_POKE_DEBUG === "1";
5534
6813
  const triggerReload = (source) => {
5535
6814
  server.hot.send({ type: "full-reload", path: "*" });
5536
6815
  server.config.logger.info(` browser reload (${source})`, {
@@ -5563,7 +6842,7 @@ function poke() {
5563
6842
  lines.pop();
5564
6843
  return lines;
5565
6844
  };
5566
- if (debug) {
6845
+ if (debug11) {
5567
6846
  server.config.logger.info(
5568
6847
  ` poke debug enabled (isTTY=${stdin.isTTY ? "yes" : "no"}, isRaw=${stdin.isTTY ? stdin.isRaw ? "yes" : "no" : "n/a"})`,
5569
6848
  { timestamp: true }
@@ -5576,7 +6855,7 @@ function poke() {
5576
6855
  );
5577
6856
  }
5578
6857
  const onData = (data) => {
5579
- if (debug) {
6858
+ if (debug11) {
5580
6859
  server.config.logger.info(` poke stdin ${formatChunk(data)}`, {
5581
6860
  timestamp: true
5582
6861
  });