@rangojs/router 0.0.0-experimental.fb6e2f40 → 0.0.0-experimental.fce7fbd1

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 (1060) hide show
  1. package/README.md +120 -25
  2. package/dist/__internal.d.ts +83 -0
  3. package/dist/__internal.d.ts.map +1 -0
  4. package/dist/__internal.js +19 -0
  5. package/dist/__internal.js.map +1 -0
  6. package/dist/__mocks__/version.d.ts +7 -0
  7. package/dist/__mocks__/version.d.ts.map +1 -0
  8. package/dist/__mocks__/version.js +7 -0
  9. package/dist/__mocks__/version.js.map +1 -0
  10. package/dist/__tests__/client-href.test.d.ts +2 -0
  11. package/dist/__tests__/client-href.test.d.ts.map +1 -0
  12. package/dist/__tests__/client-href.test.js +74 -0
  13. package/dist/__tests__/client-href.test.js.map +1 -0
  14. package/dist/__tests__/component-utils.test.d.ts +2 -0
  15. package/dist/__tests__/component-utils.test.d.ts.map +1 -0
  16. package/dist/__tests__/component-utils.test.js +51 -0
  17. package/dist/__tests__/component-utils.test.js.map +1 -0
  18. package/dist/__tests__/event-controller.test.d.ts +2 -0
  19. package/dist/__tests__/event-controller.test.d.ts.map +1 -0
  20. package/dist/__tests__/event-controller.test.js +538 -0
  21. package/dist/__tests__/event-controller.test.js.map +1 -0
  22. package/dist/__tests__/helpers/route-tree.d.ts +118 -0
  23. package/dist/__tests__/helpers/route-tree.d.ts.map +1 -0
  24. package/dist/__tests__/helpers/route-tree.js +374 -0
  25. package/dist/__tests__/helpers/route-tree.js.map +1 -0
  26. package/dist/__tests__/match-result.test.d.ts +2 -0
  27. package/dist/__tests__/match-result.test.d.ts.map +1 -0
  28. package/dist/__tests__/match-result.test.js +154 -0
  29. package/dist/__tests__/match-result.test.js.map +1 -0
  30. package/dist/__tests__/navigation-store.test.d.ts +2 -0
  31. package/dist/__tests__/navigation-store.test.d.ts.map +1 -0
  32. package/dist/__tests__/navigation-store.test.js +440 -0
  33. package/dist/__tests__/navigation-store.test.js.map +1 -0
  34. package/dist/__tests__/partial-update.test.d.ts +2 -0
  35. package/dist/__tests__/partial-update.test.d.ts.map +1 -0
  36. package/dist/__tests__/partial-update.test.js +1009 -0
  37. package/dist/__tests__/partial-update.test.js.map +1 -0
  38. package/dist/__tests__/reverse-types.test.d.ts +8 -0
  39. package/dist/__tests__/reverse-types.test.d.ts.map +1 -0
  40. package/dist/__tests__/reverse-types.test.js +656 -0
  41. package/dist/__tests__/reverse-types.test.js.map +1 -0
  42. package/dist/__tests__/route-definition.test.d.ts +2 -0
  43. package/dist/__tests__/route-definition.test.d.ts.map +1 -0
  44. package/dist/__tests__/route-definition.test.js +55 -0
  45. package/dist/__tests__/route-definition.test.js.map +1 -0
  46. package/dist/__tests__/router-helpers.test.d.ts +2 -0
  47. package/dist/__tests__/router-helpers.test.d.ts.map +1 -0
  48. package/dist/__tests__/router-helpers.test.js +377 -0
  49. package/dist/__tests__/router-helpers.test.js.map +1 -0
  50. package/dist/__tests__/router-integration-2.test.d.ts +2 -0
  51. package/dist/__tests__/router-integration-2.test.d.ts.map +1 -0
  52. package/dist/__tests__/router-integration-2.test.js +426 -0
  53. package/dist/__tests__/router-integration-2.test.js.map +1 -0
  54. package/dist/__tests__/router-integration.test.d.ts +2 -0
  55. package/dist/__tests__/router-integration.test.d.ts.map +1 -0
  56. package/dist/__tests__/router-integration.test.js +1051 -0
  57. package/dist/__tests__/router-integration.test.js.map +1 -0
  58. package/dist/__tests__/search-params.test.d.ts +5 -0
  59. package/dist/__tests__/search-params.test.d.ts.map +1 -0
  60. package/dist/__tests__/search-params.test.js +306 -0
  61. package/dist/__tests__/search-params.test.js.map +1 -0
  62. package/dist/__tests__/segment-system.test.d.ts +2 -0
  63. package/dist/__tests__/segment-system.test.d.ts.map +1 -0
  64. package/dist/__tests__/segment-system.test.js +627 -0
  65. package/dist/__tests__/segment-system.test.js.map +1 -0
  66. package/dist/__tests__/static-handler-types.test.d.ts +8 -0
  67. package/dist/__tests__/static-handler-types.test.d.ts.map +1 -0
  68. package/dist/__tests__/static-handler-types.test.js +63 -0
  69. package/dist/__tests__/static-handler-types.test.js.map +1 -0
  70. package/dist/__tests__/urls.test.d.ts +2 -0
  71. package/dist/__tests__/urls.test.d.ts.map +1 -0
  72. package/dist/__tests__/urls.test.js +421 -0
  73. package/dist/__tests__/urls.test.js.map +1 -0
  74. package/dist/__tests__/use-mount.test.d.ts +2 -0
  75. package/dist/__tests__/use-mount.test.d.ts.map +1 -0
  76. package/dist/__tests__/use-mount.test.js +35 -0
  77. package/dist/__tests__/use-mount.test.js.map +1 -0
  78. package/dist/bin/rango.d.ts +2 -0
  79. package/dist/bin/rango.d.ts.map +1 -0
  80. package/dist/bin/rango.js +147 -57
  81. package/dist/bin/rango.js.map +1 -0
  82. package/dist/browser/event-controller.d.ts +191 -0
  83. package/dist/browser/event-controller.d.ts.map +1 -0
  84. package/dist/browser/event-controller.js +559 -0
  85. package/dist/browser/event-controller.js.map +1 -0
  86. package/dist/browser/index.d.ts +2 -0
  87. package/dist/browser/index.d.ts.map +1 -0
  88. package/dist/browser/index.js +14 -0
  89. package/dist/browser/index.js.map +1 -0
  90. package/dist/browser/link-interceptor.d.ts +38 -0
  91. package/dist/browser/link-interceptor.d.ts.map +1 -0
  92. package/dist/browser/link-interceptor.js +99 -0
  93. package/dist/browser/link-interceptor.js.map +1 -0
  94. package/dist/browser/logging.d.ts +10 -0
  95. package/dist/browser/logging.d.ts.map +1 -0
  96. package/dist/browser/logging.js +29 -0
  97. package/dist/browser/logging.js.map +1 -0
  98. package/dist/browser/lru-cache.d.ts +17 -0
  99. package/dist/browser/lru-cache.d.ts.map +1 -0
  100. package/dist/browser/lru-cache.js +50 -0
  101. package/dist/browser/lru-cache.js.map +1 -0
  102. package/dist/browser/merge-segment-loaders.d.ts +39 -0
  103. package/dist/browser/merge-segment-loaders.d.ts.map +1 -0
  104. package/dist/browser/merge-segment-loaders.js +102 -0
  105. package/dist/browser/merge-segment-loaders.js.map +1 -0
  106. package/dist/browser/navigation-bridge.d.ts +102 -0
  107. package/dist/browser/navigation-bridge.d.ts.map +1 -0
  108. package/dist/browser/navigation-bridge.js +708 -0
  109. package/dist/browser/navigation-bridge.js.map +1 -0
  110. package/dist/browser/navigation-client.d.ts +25 -0
  111. package/dist/browser/navigation-client.d.ts.map +1 -0
  112. package/dist/browser/navigation-client.js +157 -0
  113. package/dist/browser/navigation-client.js.map +1 -0
  114. package/dist/browser/navigation-store.d.ts +101 -0
  115. package/dist/browser/navigation-store.d.ts.map +1 -0
  116. package/dist/browser/navigation-store.js +625 -0
  117. package/dist/browser/navigation-store.js.map +1 -0
  118. package/dist/browser/partial-update.d.ts +75 -0
  119. package/dist/browser/partial-update.d.ts.map +1 -0
  120. package/dist/browser/partial-update.js +426 -0
  121. package/dist/browser/partial-update.js.map +1 -0
  122. package/dist/browser/react/Link.d.ts +86 -0
  123. package/dist/browser/react/Link.d.ts.map +1 -0
  124. package/dist/browser/react/Link.js +128 -0
  125. package/dist/browser/react/Link.js.map +1 -0
  126. package/dist/browser/react/NavigationProvider.d.ts +63 -0
  127. package/dist/browser/react/NavigationProvider.d.ts.map +1 -0
  128. package/dist/browser/react/NavigationProvider.js +216 -0
  129. package/dist/browser/react/NavigationProvider.js.map +1 -0
  130. package/dist/browser/react/ScrollRestoration.d.ts +75 -0
  131. package/dist/browser/react/ScrollRestoration.d.ts.map +1 -0
  132. package/dist/browser/react/ScrollRestoration.js +57 -0
  133. package/dist/browser/react/ScrollRestoration.js.map +1 -0
  134. package/dist/browser/react/context.d.ts +46 -0
  135. package/dist/browser/react/context.d.ts.map +1 -0
  136. package/dist/browser/react/context.js +10 -0
  137. package/dist/browser/react/context.js.map +1 -0
  138. package/dist/browser/react/index.d.ts +11 -0
  139. package/dist/browser/react/index.d.ts.map +1 -0
  140. package/dist/browser/react/index.js +22 -0
  141. package/dist/browser/react/index.js.map +1 -0
  142. package/dist/browser/react/location-state-shared.d.ts +63 -0
  143. package/dist/browser/react/location-state-shared.d.ts.map +1 -0
  144. package/dist/browser/react/location-state-shared.js +81 -0
  145. package/dist/browser/react/location-state-shared.js.map +1 -0
  146. package/dist/browser/react/location-state.d.ts +23 -0
  147. package/dist/browser/react/location-state.d.ts.map +1 -0
  148. package/dist/browser/react/location-state.js +29 -0
  149. package/dist/browser/react/location-state.js.map +1 -0
  150. package/dist/browser/react/mount-context.d.ts +24 -0
  151. package/dist/browser/react/mount-context.d.ts.map +1 -0
  152. package/dist/browser/react/mount-context.js +24 -0
  153. package/dist/browser/react/mount-context.js.map +1 -0
  154. package/dist/browser/react/use-action.d.ts +64 -0
  155. package/dist/browser/react/use-action.d.ts.map +1 -0
  156. package/dist/browser/react/use-action.js +134 -0
  157. package/dist/browser/react/use-action.js.map +1 -0
  158. package/dist/browser/react/use-client-cache.d.ts +41 -0
  159. package/dist/browser/react/use-client-cache.d.ts.map +1 -0
  160. package/dist/browser/react/use-client-cache.js +39 -0
  161. package/dist/browser/react/use-client-cache.js.map +1 -0
  162. package/dist/browser/react/use-handle.d.ts +31 -0
  163. package/dist/browser/react/use-handle.d.ts.map +1 -0
  164. package/dist/browser/react/use-handle.js +144 -0
  165. package/dist/browser/react/use-handle.js.map +1 -0
  166. package/dist/browser/react/use-href.d.ts +33 -0
  167. package/dist/browser/react/use-href.d.ts.map +1 -0
  168. package/dist/browser/react/use-href.js +39 -0
  169. package/dist/browser/react/use-href.js.map +1 -0
  170. package/dist/browser/react/use-link-status.d.ts +37 -0
  171. package/dist/browser/react/use-link-status.d.ts.map +1 -0
  172. package/dist/browser/react/use-link-status.js +99 -0
  173. package/dist/browser/react/use-link-status.js.map +1 -0
  174. package/dist/browser/react/use-mount.d.ts +25 -0
  175. package/dist/browser/react/use-mount.d.ts.map +1 -0
  176. package/dist/browser/react/use-mount.js +30 -0
  177. package/dist/browser/react/use-mount.js.map +1 -0
  178. package/dist/browser/react/use-navigation.d.ts +27 -0
  179. package/dist/browser/react/use-navigation.d.ts.map +1 -0
  180. package/dist/browser/react/use-navigation.js +87 -0
  181. package/dist/browser/react/use-navigation.js.map +1 -0
  182. package/dist/browser/react/use-segments.d.ts +38 -0
  183. package/dist/browser/react/use-segments.d.ts.map +1 -0
  184. package/dist/browser/react/use-segments.js +130 -0
  185. package/dist/browser/react/use-segments.js.map +1 -0
  186. package/dist/browser/request-controller.d.ts +26 -0
  187. package/dist/browser/request-controller.d.ts.map +1 -0
  188. package/dist/browser/request-controller.js +147 -0
  189. package/dist/browser/request-controller.js.map +1 -0
  190. package/dist/browser/rsc-router.d.ts +129 -0
  191. package/dist/browser/rsc-router.d.ts.map +1 -0
  192. package/dist/browser/rsc-router.js +195 -0
  193. package/dist/browser/rsc-router.js.map +1 -0
  194. package/dist/browser/scroll-restoration.d.ts +93 -0
  195. package/dist/browser/scroll-restoration.d.ts.map +1 -0
  196. package/dist/browser/scroll-restoration.js +321 -0
  197. package/dist/browser/scroll-restoration.js.map +1 -0
  198. package/dist/browser/segment-structure-assert.d.ts +17 -0
  199. package/dist/browser/segment-structure-assert.d.ts.map +1 -0
  200. package/dist/browser/segment-structure-assert.js +59 -0
  201. package/dist/browser/segment-structure-assert.js.map +1 -0
  202. package/dist/browser/server-action-bridge.d.ts +26 -0
  203. package/dist/browser/server-action-bridge.d.ts.map +1 -0
  204. package/dist/browser/server-action-bridge.js +668 -0
  205. package/dist/browser/server-action-bridge.js.map +1 -0
  206. package/dist/browser/shallow.d.ts +12 -0
  207. package/dist/browser/shallow.d.ts.map +1 -0
  208. package/dist/browser/shallow.js +34 -0
  209. package/dist/browser/shallow.js.map +1 -0
  210. package/dist/browser/types.d.ts +369 -0
  211. package/dist/browser/types.d.ts.map +1 -0
  212. package/dist/browser/types.js +2 -0
  213. package/dist/browser/types.js.map +1 -0
  214. package/dist/build/__tests__/generate-cli.test.d.ts +2 -0
  215. package/dist/build/__tests__/generate-cli.test.d.ts.map +1 -0
  216. package/dist/build/__tests__/generate-cli.test.js +237 -0
  217. package/dist/build/__tests__/generate-cli.test.js.map +1 -0
  218. package/dist/build/__tests__/generate-manifest.test.d.ts +2 -0
  219. package/dist/build/__tests__/generate-manifest.test.d.ts.map +1 -0
  220. package/dist/build/__tests__/generate-manifest.test.js +119 -0
  221. package/dist/build/__tests__/generate-manifest.test.js.map +1 -0
  222. package/dist/build/__tests__/generate-route-types.test.d.ts +2 -0
  223. package/dist/build/__tests__/generate-route-types.test.d.ts.map +1 -0
  224. package/dist/build/__tests__/generate-route-types.test.js +620 -0
  225. package/dist/build/__tests__/generate-route-types.test.js.map +1 -0
  226. package/dist/build/__tests__/per-router-manifest.test.d.ts +2 -0
  227. package/dist/build/__tests__/per-router-manifest.test.d.ts.map +1 -0
  228. package/dist/build/__tests__/per-router-manifest.test.js +308 -0
  229. package/dist/build/__tests__/per-router-manifest.test.js.map +1 -0
  230. package/dist/build/generate-manifest.d.ts +81 -0
  231. package/dist/build/generate-manifest.d.ts.map +1 -0
  232. package/dist/build/generate-manifest.js +276 -0
  233. package/dist/build/generate-manifest.js.map +1 -0
  234. package/dist/build/generate-route-types.d.ts +115 -0
  235. package/dist/build/generate-route-types.d.ts.map +1 -0
  236. package/dist/build/generate-route-types.js +740 -0
  237. package/dist/build/generate-route-types.js.map +1 -0
  238. package/dist/build/index.d.ts +21 -0
  239. package/dist/build/index.d.ts.map +1 -0
  240. package/dist/build/index.js +21 -0
  241. package/dist/build/index.js.map +1 -0
  242. package/dist/build/route-trie.d.ts +71 -0
  243. package/dist/build/route-trie.d.ts.map +1 -0
  244. package/dist/build/route-trie.js +175 -0
  245. package/dist/build/route-trie.js.map +1 -0
  246. package/dist/cache/__tests__/cache-scope.test.d.ts +2 -0
  247. package/dist/cache/__tests__/cache-scope.test.d.ts.map +1 -0
  248. package/dist/cache/__tests__/cache-scope.test.js +208 -0
  249. package/dist/cache/__tests__/cache-scope.test.js.map +1 -0
  250. package/dist/cache/__tests__/document-cache.test.d.ts +2 -0
  251. package/dist/cache/__tests__/document-cache.test.d.ts.map +1 -0
  252. package/dist/cache/__tests__/document-cache.test.js +345 -0
  253. package/dist/cache/__tests__/document-cache.test.js.map +1 -0
  254. package/dist/cache/__tests__/memory-segment-store.test.d.ts +2 -0
  255. package/dist/cache/__tests__/memory-segment-store.test.d.ts.map +1 -0
  256. package/dist/cache/__tests__/memory-segment-store.test.js +425 -0
  257. package/dist/cache/__tests__/memory-segment-store.test.js.map +1 -0
  258. package/dist/cache/__tests__/memory-store.test.d.ts +2 -0
  259. package/dist/cache/__tests__/memory-store.test.d.ts.map +1 -0
  260. package/dist/cache/__tests__/memory-store.test.js +367 -0
  261. package/dist/cache/__tests__/memory-store.test.js.map +1 -0
  262. package/dist/cache/cache-scope.d.ts +102 -0
  263. package/dist/cache/cache-scope.d.ts.map +1 -0
  264. package/dist/cache/cache-scope.js +440 -0
  265. package/dist/cache/cache-scope.js.map +1 -0
  266. package/dist/cache/cf/__tests__/cf-cache-store.test.d.ts +2 -0
  267. package/dist/cache/cf/__tests__/cf-cache-store.test.d.ts.map +1 -0
  268. package/dist/cache/cf/__tests__/cf-cache-store.test.js +330 -0
  269. package/dist/cache/cf/__tests__/cf-cache-store.test.js.map +1 -0
  270. package/dist/cache/cf/cf-cache-store.d.ts +165 -0
  271. package/dist/cache/cf/cf-cache-store.d.ts.map +1 -0
  272. package/dist/cache/cf/cf-cache-store.js +242 -0
  273. package/dist/cache/cf/cf-cache-store.js.map +1 -0
  274. package/dist/cache/cf/index.d.ts +14 -0
  275. package/dist/cache/cf/index.d.ts.map +1 -0
  276. package/dist/cache/cf/index.js +17 -0
  277. package/dist/cache/cf/index.js.map +1 -0
  278. package/dist/cache/document-cache.d.ts +64 -0
  279. package/dist/cache/document-cache.d.ts.map +1 -0
  280. package/dist/cache/document-cache.js +228 -0
  281. package/dist/cache/document-cache.js.map +1 -0
  282. package/dist/cache/index.d.ts +19 -0
  283. package/dist/cache/index.d.ts.map +1 -0
  284. package/dist/cache/index.js +21 -0
  285. package/dist/cache/index.js.map +1 -0
  286. package/dist/cache/memory-segment-store.d.ts +110 -0
  287. package/dist/cache/memory-segment-store.d.ts.map +1 -0
  288. package/dist/cache/memory-segment-store.js +117 -0
  289. package/dist/cache/memory-segment-store.js.map +1 -0
  290. package/dist/cache/memory-store.d.ts +41 -0
  291. package/dist/cache/memory-store.d.ts.map +1 -0
  292. package/dist/cache/memory-store.js +191 -0
  293. package/dist/cache/memory-store.js.map +1 -0
  294. package/dist/cache/types.d.ts +317 -0
  295. package/dist/cache/types.d.ts.map +1 -0
  296. package/dist/cache/types.js +12 -0
  297. package/dist/cache/types.js.map +1 -0
  298. package/dist/client.d.ts +248 -0
  299. package/dist/client.d.ts.map +1 -0
  300. package/dist/client.js +367 -0
  301. package/dist/client.js.map +1 -0
  302. package/dist/client.rsc.d.ts +26 -0
  303. package/dist/client.rsc.d.ts.map +1 -0
  304. package/dist/client.rsc.js +46 -0
  305. package/dist/client.rsc.js.map +1 -0
  306. package/dist/component-utils.d.ts +36 -0
  307. package/dist/component-utils.d.ts.map +1 -0
  308. package/dist/component-utils.js +61 -0
  309. package/dist/component-utils.js.map +1 -0
  310. package/dist/components/DefaultDocument.d.ts +13 -0
  311. package/dist/components/DefaultDocument.d.ts.map +1 -0
  312. package/dist/components/DefaultDocument.js +15 -0
  313. package/dist/components/DefaultDocument.js.map +1 -0
  314. package/dist/debug.d.ts +58 -0
  315. package/dist/debug.d.ts.map +1 -0
  316. package/dist/debug.js +157 -0
  317. package/dist/debug.js.map +1 -0
  318. package/dist/default-error-boundary.d.ts +11 -0
  319. package/dist/default-error-boundary.d.ts.map +1 -0
  320. package/dist/default-error-boundary.js +45 -0
  321. package/dist/default-error-boundary.js.map +1 -0
  322. package/dist/deps/browser.d.ts +2 -0
  323. package/dist/deps/browser.d.ts.map +1 -0
  324. package/dist/deps/browser.js +3 -0
  325. package/dist/deps/browser.js.map +1 -0
  326. package/dist/deps/html-stream-client.d.ts +2 -0
  327. package/dist/deps/html-stream-client.d.ts.map +1 -0
  328. package/dist/deps/html-stream-client.js +3 -0
  329. package/dist/deps/html-stream-client.js.map +1 -0
  330. package/dist/deps/html-stream-server.d.ts +2 -0
  331. package/dist/deps/html-stream-server.d.ts.map +1 -0
  332. package/dist/deps/html-stream-server.js +3 -0
  333. package/dist/deps/html-stream-server.js.map +1 -0
  334. package/dist/deps/rsc.d.ts +2 -0
  335. package/dist/deps/rsc.d.ts.map +1 -0
  336. package/dist/deps/rsc.js +4 -0
  337. package/dist/deps/rsc.js.map +1 -0
  338. package/dist/deps/ssr.d.ts +2 -0
  339. package/dist/deps/ssr.d.ts.map +1 -0
  340. package/dist/deps/ssr.js +3 -0
  341. package/dist/deps/ssr.js.map +1 -0
  342. package/dist/errors.d.ts +174 -0
  343. package/dist/errors.d.ts.map +1 -0
  344. package/dist/errors.js +241 -0
  345. package/dist/errors.js.map +1 -0
  346. package/dist/handle.d.ts +78 -0
  347. package/dist/handle.d.ts.map +1 -0
  348. package/dist/handle.js +82 -0
  349. package/dist/handle.js.map +1 -0
  350. package/dist/handles/MetaTags.d.ts +14 -0
  351. package/dist/handles/MetaTags.d.ts.map +1 -0
  352. package/dist/handles/MetaTags.js +136 -0
  353. package/dist/handles/MetaTags.js.map +1 -0
  354. package/dist/handles/index.d.ts +6 -0
  355. package/dist/handles/index.d.ts.map +1 -0
  356. package/dist/handles/index.js +6 -0
  357. package/dist/handles/index.js.map +1 -0
  358. package/dist/handles/meta.d.ts +39 -0
  359. package/dist/handles/meta.d.ts.map +1 -0
  360. package/dist/handles/meta.js +202 -0
  361. package/dist/handles/meta.js.map +1 -0
  362. package/dist/host/__tests__/errors.test.d.ts +2 -0
  363. package/dist/host/__tests__/errors.test.d.ts.map +1 -0
  364. package/dist/host/__tests__/errors.test.js +76 -0
  365. package/dist/host/__tests__/errors.test.js.map +1 -0
  366. package/dist/host/__tests__/pattern-comprehensive.test.d.ts +2 -0
  367. package/dist/host/__tests__/pattern-comprehensive.test.d.ts.map +1 -0
  368. package/dist/host/__tests__/pattern-comprehensive.test.js +732 -0
  369. package/dist/host/__tests__/pattern-comprehensive.test.js.map +1 -0
  370. package/dist/host/__tests__/pattern-matcher.test.d.ts +2 -0
  371. package/dist/host/__tests__/pattern-matcher.test.d.ts.map +1 -0
  372. package/dist/host/__tests__/pattern-matcher.test.js +251 -0
  373. package/dist/host/__tests__/pattern-matcher.test.js.map +1 -0
  374. package/dist/host/__tests__/router.test.d.ts +2 -0
  375. package/dist/host/__tests__/router.test.d.ts.map +1 -0
  376. package/dist/host/__tests__/router.test.js +241 -0
  377. package/dist/host/__tests__/router.test.js.map +1 -0
  378. package/dist/host/__tests__/testing.test.d.ts +2 -0
  379. package/dist/host/__tests__/testing.test.d.ts.map +1 -0
  380. package/dist/host/__tests__/testing.test.js +64 -0
  381. package/dist/host/__tests__/testing.test.js.map +1 -0
  382. package/dist/host/__tests__/utils.test.d.ts +2 -0
  383. package/dist/host/__tests__/utils.test.d.ts.map +1 -0
  384. package/dist/host/__tests__/utils.test.js +29 -0
  385. package/dist/host/__tests__/utils.test.js.map +1 -0
  386. package/dist/host/cookie-handler.d.ts +34 -0
  387. package/dist/host/cookie-handler.d.ts.map +1 -0
  388. package/dist/host/cookie-handler.js +124 -0
  389. package/dist/host/cookie-handler.js.map +1 -0
  390. package/dist/host/errors.d.ts +56 -0
  391. package/dist/host/errors.d.ts.map +1 -0
  392. package/dist/host/errors.js +79 -0
  393. package/dist/host/errors.js.map +1 -0
  394. package/dist/host/index.d.ts +29 -0
  395. package/dist/host/index.d.ts.map +1 -0
  396. package/dist/host/index.js +32 -0
  397. package/dist/host/index.js.map +1 -0
  398. package/dist/host/pattern-matcher.d.ts +36 -0
  399. package/dist/host/pattern-matcher.d.ts.map +1 -0
  400. package/dist/host/pattern-matcher.js +172 -0
  401. package/dist/host/pattern-matcher.js.map +1 -0
  402. package/dist/host/router.d.ts +26 -0
  403. package/dist/host/router.d.ts.map +1 -0
  404. package/dist/host/router.js +218 -0
  405. package/dist/host/router.js.map +1 -0
  406. package/dist/host/testing.d.ts +36 -0
  407. package/dist/host/testing.d.ts.map +1 -0
  408. package/dist/host/testing.js +55 -0
  409. package/dist/host/testing.js.map +1 -0
  410. package/dist/host/types.d.ts +115 -0
  411. package/dist/host/types.d.ts.map +1 -0
  412. package/dist/host/types.js +7 -0
  413. package/dist/host/types.js.map +1 -0
  414. package/dist/host/utils.d.ts +21 -0
  415. package/dist/host/utils.d.ts.map +1 -0
  416. package/dist/host/utils.js +23 -0
  417. package/dist/host/utils.js.map +1 -0
  418. package/dist/href-client.d.ts +131 -0
  419. package/dist/href-client.d.ts.map +1 -0
  420. package/dist/href-client.js +64 -0
  421. package/dist/href-client.js.map +1 -0
  422. package/dist/href-context.d.ts +29 -0
  423. package/dist/href-context.d.ts.map +1 -0
  424. package/dist/href-context.js +21 -0
  425. package/dist/href-context.js.map +1 -0
  426. package/dist/index.d.ts +73 -0
  427. package/dist/index.d.ts.map +1 -0
  428. package/dist/index.js +91 -0
  429. package/dist/index.js.map +1 -0
  430. package/dist/index.rsc.d.ts +32 -0
  431. package/dist/index.rsc.d.ts.map +1 -0
  432. package/dist/index.rsc.js +40 -0
  433. package/dist/index.rsc.js.map +1 -0
  434. package/dist/internal-debug.d.ts +2 -0
  435. package/dist/internal-debug.d.ts.map +1 -0
  436. package/dist/internal-debug.js +5 -0
  437. package/dist/internal-debug.js.map +1 -0
  438. package/dist/loader.d.ts +14 -0
  439. package/dist/loader.d.ts.map +1 -0
  440. package/dist/loader.js +20 -0
  441. package/dist/loader.js.map +1 -0
  442. package/dist/loader.rsc.d.ts +19 -0
  443. package/dist/loader.rsc.d.ts.map +1 -0
  444. package/dist/loader.rsc.js +99 -0
  445. package/dist/loader.rsc.js.map +1 -0
  446. package/dist/network-error-thrower.d.ts +17 -0
  447. package/dist/network-error-thrower.d.ts.map +1 -0
  448. package/dist/network-error-thrower.js +14 -0
  449. package/dist/network-error-thrower.js.map +1 -0
  450. package/dist/outlet-context.d.ts +13 -0
  451. package/dist/outlet-context.d.ts.map +1 -0
  452. package/dist/outlet-context.js +3 -0
  453. package/dist/outlet-context.js.map +1 -0
  454. package/dist/prerender/__tests__/param-hash.test.d.ts +2 -0
  455. package/dist/prerender/__tests__/param-hash.test.d.ts.map +1 -0
  456. package/dist/prerender/__tests__/param-hash.test.js +148 -0
  457. package/dist/prerender/__tests__/param-hash.test.js.map +1 -0
  458. package/dist/prerender/param-hash.d.ts +16 -0
  459. package/dist/prerender/param-hash.d.ts.map +1 -0
  460. package/dist/prerender/param-hash.js +36 -0
  461. package/dist/prerender/param-hash.js.map +1 -0
  462. package/dist/prerender/store.d.ts +38 -0
  463. package/dist/prerender/store.d.ts.map +1 -0
  464. package/dist/prerender/store.js +61 -0
  465. package/dist/prerender/store.js.map +1 -0
  466. package/dist/prerender.d.ts +66 -0
  467. package/dist/prerender.d.ts.map +1 -0
  468. package/dist/prerender.js +57 -0
  469. package/dist/prerender.js.map +1 -0
  470. package/dist/reverse.d.ts +196 -0
  471. package/dist/reverse.d.ts.map +1 -0
  472. package/dist/reverse.js +78 -0
  473. package/dist/reverse.js.map +1 -0
  474. package/dist/root-error-boundary.d.ts +33 -0
  475. package/dist/root-error-boundary.d.ts.map +1 -0
  476. package/dist/root-error-boundary.js +165 -0
  477. package/dist/root-error-boundary.js.map +1 -0
  478. package/dist/route-content-wrapper.d.ts +46 -0
  479. package/dist/route-content-wrapper.d.ts.map +1 -0
  480. package/dist/route-content-wrapper.js +77 -0
  481. package/dist/route-content-wrapper.js.map +1 -0
  482. package/dist/route-definition.d.ts +421 -0
  483. package/dist/route-definition.d.ts.map +1 -0
  484. package/dist/route-definition.js +868 -0
  485. package/dist/route-definition.js.map +1 -0
  486. package/dist/route-map-builder.d.ts +155 -0
  487. package/dist/route-map-builder.d.ts.map +1 -0
  488. package/dist/route-map-builder.js +237 -0
  489. package/dist/route-map-builder.js.map +1 -0
  490. package/dist/route-types.d.ts +165 -0
  491. package/dist/route-types.d.ts.map +1 -0
  492. package/dist/route-types.js +7 -0
  493. package/dist/route-types.js.map +1 -0
  494. package/dist/router/__tests__/handler-context.test.d.ts +2 -0
  495. package/dist/router/__tests__/handler-context.test.d.ts.map +1 -0
  496. package/dist/router/__tests__/handler-context.test.js +65 -0
  497. package/dist/router/__tests__/handler-context.test.js.map +1 -0
  498. package/dist/router/__tests__/loader-cycle-detection.test.d.ts +2 -0
  499. package/dist/router/__tests__/loader-cycle-detection.test.d.ts.map +1 -0
  500. package/dist/router/__tests__/loader-cycle-detection.test.js +221 -0
  501. package/dist/router/__tests__/loader-cycle-detection.test.js.map +1 -0
  502. package/dist/router/__tests__/match-context.test.d.ts +2 -0
  503. package/dist/router/__tests__/match-context.test.d.ts.map +1 -0
  504. package/dist/router/__tests__/match-context.test.js +92 -0
  505. package/dist/router/__tests__/match-context.test.js.map +1 -0
  506. package/dist/router/__tests__/match-pipelines.test.d.ts +2 -0
  507. package/dist/router/__tests__/match-pipelines.test.d.ts.map +1 -0
  508. package/dist/router/__tests__/match-pipelines.test.js +417 -0
  509. package/dist/router/__tests__/match-pipelines.test.js.map +1 -0
  510. package/dist/router/__tests__/match-result.test.d.ts +2 -0
  511. package/dist/router/__tests__/match-result.test.d.ts.map +1 -0
  512. package/dist/router/__tests__/match-result.test.js +457 -0
  513. package/dist/router/__tests__/match-result.test.js.map +1 -0
  514. package/dist/router/__tests__/on-error.test.d.ts +2 -0
  515. package/dist/router/__tests__/on-error.test.d.ts.map +1 -0
  516. package/dist/router/__tests__/on-error.test.js +678 -0
  517. package/dist/router/__tests__/on-error.test.js.map +1 -0
  518. package/dist/router/__tests__/pattern-matching.test.d.ts +2 -0
  519. package/dist/router/__tests__/pattern-matching.test.d.ts.map +1 -0
  520. package/dist/router/__tests__/pattern-matching.test.js +629 -0
  521. package/dist/router/__tests__/pattern-matching.test.js.map +1 -0
  522. package/dist/router/__tests__/segment-resolution-parallel-loading.test.d.ts +2 -0
  523. package/dist/router/__tests__/segment-resolution-parallel-loading.test.d.ts.map +1 -0
  524. package/dist/router/__tests__/segment-resolution-parallel-loading.test.js +155 -0
  525. package/dist/router/__tests__/segment-resolution-parallel-loading.test.js.map +1 -0
  526. package/dist/router/error-handling.d.ts +77 -0
  527. package/dist/router/error-handling.d.ts.map +1 -0
  528. package/dist/router/error-handling.js +202 -0
  529. package/dist/router/error-handling.js.map +1 -0
  530. package/dist/router/handler-context.d.ts +20 -0
  531. package/dist/router/handler-context.d.ts.map +1 -0
  532. package/dist/router/handler-context.js +198 -0
  533. package/dist/router/handler-context.js.map +1 -0
  534. package/dist/router/intercept-resolution.d.ts +66 -0
  535. package/dist/router/intercept-resolution.d.ts.map +1 -0
  536. package/dist/router/intercept-resolution.js +246 -0
  537. package/dist/router/intercept-resolution.js.map +1 -0
  538. package/dist/router/loader-resolution.d.ts +64 -0
  539. package/dist/router/loader-resolution.d.ts.map +1 -0
  540. package/dist/router/loader-resolution.js +284 -0
  541. package/dist/router/loader-resolution.js.map +1 -0
  542. package/dist/router/logging.d.ts +15 -0
  543. package/dist/router/logging.d.ts.map +1 -0
  544. package/dist/router/logging.js +99 -0
  545. package/dist/router/logging.js.map +1 -0
  546. package/dist/router/manifest.d.ts +22 -0
  547. package/dist/router/manifest.d.ts.map +1 -0
  548. package/dist/router/manifest.js +181 -0
  549. package/dist/router/manifest.js.map +1 -0
  550. package/dist/router/match-api.d.ts +35 -0
  551. package/dist/router/match-api.d.ts.map +1 -0
  552. package/dist/router/match-api.js +406 -0
  553. package/dist/router/match-api.js.map +1 -0
  554. package/dist/router/match-context.d.ts +206 -0
  555. package/dist/router/match-context.d.ts.map +1 -0
  556. package/dist/router/match-context.js +17 -0
  557. package/dist/router/match-context.js.map +1 -0
  558. package/dist/router/match-middleware/background-revalidation.d.ts +127 -0
  559. package/dist/router/match-middleware/background-revalidation.d.ts.map +1 -0
  560. package/dist/router/match-middleware/background-revalidation.js +75 -0
  561. package/dist/router/match-middleware/background-revalidation.js.map +1 -0
  562. package/dist/router/match-middleware/cache-lookup.d.ts +112 -0
  563. package/dist/router/match-middleware/cache-lookup.d.ts.map +1 -0
  564. package/dist/router/match-middleware/cache-lookup.js +257 -0
  565. package/dist/router/match-middleware/cache-lookup.js.map +1 -0
  566. package/dist/router/match-middleware/cache-store.d.ts +113 -0
  567. package/dist/router/match-middleware/cache-store.d.ts.map +1 -0
  568. package/dist/router/match-middleware/cache-store.js +108 -0
  569. package/dist/router/match-middleware/cache-store.js.map +1 -0
  570. package/dist/router/match-middleware/index.d.ts +81 -0
  571. package/dist/router/match-middleware/index.d.ts.map +1 -0
  572. package/dist/router/match-middleware/index.js +80 -0
  573. package/dist/router/match-middleware/index.js.map +1 -0
  574. package/dist/router/match-middleware/intercept-resolution.d.ts +117 -0
  575. package/dist/router/match-middleware/intercept-resolution.d.ts.map +1 -0
  576. package/dist/router/match-middleware/intercept-resolution.js +134 -0
  577. package/dist/router/match-middleware/intercept-resolution.js.map +1 -0
  578. package/dist/router/match-middleware/segment-resolution.d.ts +99 -0
  579. package/dist/router/match-middleware/segment-resolution.d.ts.map +1 -0
  580. package/dist/router/match-middleware/segment-resolution.js +53 -0
  581. package/dist/router/match-middleware/segment-resolution.js.map +1 -0
  582. package/dist/router/match-pipelines.d.ts +147 -0
  583. package/dist/router/match-pipelines.d.ts.map +1 -0
  584. package/dist/router/match-pipelines.js +82 -0
  585. package/dist/router/match-pipelines.js.map +1 -0
  586. package/dist/router/match-result.d.ts +126 -0
  587. package/dist/router/match-result.d.ts.map +1 -0
  588. package/dist/router/match-result.js +93 -0
  589. package/dist/router/match-result.js.map +1 -0
  590. package/dist/router/metrics.d.ts +20 -0
  591. package/dist/router/metrics.d.ts.map +1 -0
  592. package/dist/router/metrics.js +47 -0
  593. package/dist/router/metrics.js.map +1 -0
  594. package/dist/router/middleware.d.ts +249 -0
  595. package/dist/router/middleware.d.ts.map +1 -0
  596. package/dist/router/middleware.js +434 -0
  597. package/dist/router/middleware.js.map +1 -0
  598. package/dist/router/middleware.test.d.ts +2 -0
  599. package/dist/router/middleware.test.d.ts.map +1 -0
  600. package/dist/router/middleware.test.js +816 -0
  601. package/dist/router/middleware.test.js.map +1 -0
  602. package/dist/router/pattern-matching.d.ts +149 -0
  603. package/dist/router/pattern-matching.d.ts.map +1 -0
  604. package/dist/router/pattern-matching.js +349 -0
  605. package/dist/router/pattern-matching.js.map +1 -0
  606. package/dist/router/revalidation.d.ts +44 -0
  607. package/dist/router/revalidation.d.ts.map +1 -0
  608. package/dist/router/revalidation.js +147 -0
  609. package/dist/router/revalidation.js.map +1 -0
  610. package/dist/router/router-context.d.ts +135 -0
  611. package/dist/router/router-context.d.ts.map +1 -0
  612. package/dist/router/router-context.js +36 -0
  613. package/dist/router/router-context.js.map +1 -0
  614. package/dist/router/segment-resolution.d.ts +127 -0
  615. package/dist/router/segment-resolution.d.ts.map +1 -0
  616. package/dist/router/segment-resolution.js +919 -0
  617. package/dist/router/segment-resolution.js.map +1 -0
  618. package/dist/router/trie-matching.d.ts +40 -0
  619. package/dist/router/trie-matching.d.ts.map +1 -0
  620. package/dist/router/trie-matching.js +127 -0
  621. package/dist/router/trie-matching.js.map +1 -0
  622. package/dist/router/types.d.ts +136 -0
  623. package/dist/router/types.d.ts.map +1 -0
  624. package/dist/router/types.js +7 -0
  625. package/dist/router/types.js.map +1 -0
  626. package/dist/router.d.ts +753 -0
  627. package/dist/router.d.ts.map +1 -0
  628. package/dist/router.gen.d.ts +6 -0
  629. package/dist/router.gen.d.ts.map +1 -0
  630. package/dist/router.gen.js +6 -0
  631. package/dist/router.gen.js.map +1 -0
  632. package/dist/router.js +1304 -0
  633. package/dist/router.js.map +1 -0
  634. package/dist/rsc/__tests__/helpers.test.d.ts +2 -0
  635. package/dist/rsc/__tests__/helpers.test.d.ts.map +1 -0
  636. package/dist/rsc/__tests__/helpers.test.js +140 -0
  637. package/dist/rsc/__tests__/helpers.test.js.map +1 -0
  638. package/dist/rsc/handler.d.ts +45 -0
  639. package/dist/rsc/handler.d.ts.map +1 -0
  640. package/dist/rsc/handler.js +1172 -0
  641. package/dist/rsc/handler.js.map +1 -0
  642. package/dist/rsc/helpers.d.ts +16 -0
  643. package/dist/rsc/helpers.d.ts.map +1 -0
  644. package/dist/rsc/helpers.js +55 -0
  645. package/dist/rsc/helpers.js.map +1 -0
  646. package/dist/rsc/index.d.ts +22 -0
  647. package/dist/rsc/index.d.ts.map +1 -0
  648. package/dist/rsc/index.js +23 -0
  649. package/dist/rsc/index.js.map +1 -0
  650. package/dist/rsc/nonce.d.ts +9 -0
  651. package/dist/rsc/nonce.d.ts.map +1 -0
  652. package/dist/rsc/nonce.js +18 -0
  653. package/dist/rsc/nonce.js.map +1 -0
  654. package/dist/rsc/types.d.ts +206 -0
  655. package/dist/rsc/types.d.ts.map +1 -0
  656. package/dist/rsc/types.js +8 -0
  657. package/dist/rsc/types.js.map +1 -0
  658. package/dist/search-params.d.ts +103 -0
  659. package/dist/search-params.d.ts.map +1 -0
  660. package/dist/search-params.js +74 -0
  661. package/dist/search-params.js.map +1 -0
  662. package/dist/segment-system.d.ts +75 -0
  663. package/dist/segment-system.d.ts.map +1 -0
  664. package/dist/segment-system.js +336 -0
  665. package/dist/segment-system.js.map +1 -0
  666. package/dist/server/context.d.ts +245 -0
  667. package/dist/server/context.d.ts.map +1 -0
  668. package/dist/server/context.js +197 -0
  669. package/dist/server/context.js.map +1 -0
  670. package/dist/server/fetchable-loader-store.d.ts +18 -0
  671. package/dist/server/fetchable-loader-store.d.ts.map +1 -0
  672. package/dist/server/fetchable-loader-store.js +18 -0
  673. package/dist/server/fetchable-loader-store.js.map +1 -0
  674. package/dist/server/handle-store.d.ts +85 -0
  675. package/dist/server/handle-store.d.ts.map +1 -0
  676. package/dist/server/handle-store.js +142 -0
  677. package/dist/server/handle-store.js.map +1 -0
  678. package/dist/server/loader-registry.d.ts +55 -0
  679. package/dist/server/loader-registry.d.ts.map +1 -0
  680. package/dist/server/loader-registry.js +132 -0
  681. package/dist/server/loader-registry.js.map +1 -0
  682. package/dist/server/request-context.d.ts +226 -0
  683. package/dist/server/request-context.d.ts.map +1 -0
  684. package/dist/server/request-context.js +290 -0
  685. package/dist/server/request-context.js.map +1 -0
  686. package/dist/server/root-layout.d.ts +4 -0
  687. package/dist/server/root-layout.d.ts.map +1 -0
  688. package/dist/server/root-layout.js +5 -0
  689. package/dist/server/root-layout.js.map +1 -0
  690. package/dist/server.d.ts +15 -0
  691. package/dist/server.d.ts.map +1 -0
  692. package/dist/server.js +20 -0
  693. package/dist/server.js.map +1 -0
  694. package/dist/ssr/__tests__/ssr-handler.test.d.ts +2 -0
  695. package/dist/ssr/__tests__/ssr-handler.test.d.ts.map +1 -0
  696. package/dist/ssr/__tests__/ssr-handler.test.js +132 -0
  697. package/dist/ssr/__tests__/ssr-handler.test.js.map +1 -0
  698. package/dist/ssr/index.d.ts +98 -0
  699. package/dist/ssr/index.d.ts.map +1 -0
  700. package/dist/ssr/index.js +158 -0
  701. package/dist/ssr/index.js.map +1 -0
  702. package/dist/static-handler.d.ts +50 -0
  703. package/dist/static-handler.d.ts.map +1 -0
  704. package/dist/static-handler.gen.d.ts +5 -0
  705. package/dist/static-handler.gen.d.ts.map +1 -0
  706. package/dist/static-handler.gen.js +5 -0
  707. package/dist/static-handler.gen.js.map +1 -0
  708. package/dist/static-handler.js +29 -0
  709. package/dist/static-handler.js.map +1 -0
  710. package/dist/testing/vitest.js +48 -0
  711. package/dist/theme/ThemeProvider.d.ts +20 -0
  712. package/dist/theme/ThemeProvider.d.ts.map +1 -0
  713. package/dist/theme/ThemeProvider.js +240 -0
  714. package/dist/theme/ThemeProvider.js.map +1 -0
  715. package/dist/theme/ThemeScript.d.ts +48 -0
  716. package/dist/theme/ThemeScript.d.ts.map +1 -0
  717. package/dist/theme/ThemeScript.js +13 -0
  718. package/dist/theme/ThemeScript.js.map +1 -0
  719. package/dist/theme/__tests__/theme.test.d.ts +2 -0
  720. package/dist/theme/__tests__/theme.test.d.ts.map +1 -0
  721. package/dist/theme/__tests__/theme.test.js +103 -0
  722. package/dist/theme/__tests__/theme.test.js.map +1 -0
  723. package/dist/theme/constants.d.ts +29 -0
  724. package/dist/theme/constants.d.ts.map +1 -0
  725. package/dist/theme/constants.js +48 -0
  726. package/dist/theme/constants.js.map +1 -0
  727. package/dist/theme/index.d.ts +31 -0
  728. package/dist/theme/index.d.ts.map +1 -0
  729. package/dist/theme/index.js +36 -0
  730. package/dist/theme/index.js.map +1 -0
  731. package/dist/theme/theme-context.d.ts +40 -0
  732. package/dist/theme/theme-context.d.ts.map +1 -0
  733. package/dist/theme/theme-context.js +60 -0
  734. package/dist/theme/theme-context.js.map +1 -0
  735. package/dist/theme/theme-script.d.ts +27 -0
  736. package/dist/theme/theme-script.d.ts.map +1 -0
  737. package/dist/theme/theme-script.js +147 -0
  738. package/dist/theme/theme-script.js.map +1 -0
  739. package/dist/theme/types.d.ts +163 -0
  740. package/dist/theme/types.d.ts.map +1 -0
  741. package/dist/theme/types.js +11 -0
  742. package/dist/theme/types.js.map +1 -0
  743. package/dist/theme/use-theme.d.ts +12 -0
  744. package/dist/theme/use-theme.d.ts.map +1 -0
  745. package/dist/theme/use-theme.js +40 -0
  746. package/dist/theme/use-theme.js.map +1 -0
  747. package/dist/types.d.ts +1479 -0
  748. package/dist/types.d.ts.map +1 -0
  749. package/dist/types.js +10 -0
  750. package/dist/types.js.map +1 -0
  751. package/dist/urls.d.ts +441 -0
  752. package/dist/urls.d.ts.map +1 -0
  753. package/dist/urls.gen.d.ts +8 -0
  754. package/dist/urls.gen.d.ts.map +1 -0
  755. package/dist/urls.gen.js +8 -0
  756. package/dist/urls.gen.js.map +1 -0
  757. package/dist/urls.js +443 -0
  758. package/dist/urls.js.map +1 -0
  759. package/dist/use-loader.d.ts +127 -0
  760. package/dist/use-loader.d.ts.map +1 -0
  761. package/dist/use-loader.js +237 -0
  762. package/dist/use-loader.js.map +1 -0
  763. package/dist/vite/__tests__/ast-handler-extract.test.d.ts +2 -0
  764. package/dist/vite/__tests__/ast-handler-extract.test.d.ts.map +1 -0
  765. package/dist/vite/__tests__/ast-handler-extract.test.js +294 -0
  766. package/dist/vite/__tests__/ast-handler-extract.test.js.map +1 -0
  767. package/dist/vite/__tests__/expose-id-utils.test.d.ts +2 -0
  768. package/dist/vite/__tests__/expose-id-utils.test.d.ts.map +1 -0
  769. package/dist/vite/__tests__/expose-id-utils.test.js +224 -0
  770. package/dist/vite/__tests__/expose-id-utils.test.js.map +1 -0
  771. package/dist/vite/__tests__/expose-internal-ids.test.d.ts +2 -0
  772. package/dist/vite/__tests__/expose-internal-ids.test.d.ts.map +1 -0
  773. package/dist/vite/__tests__/expose-internal-ids.test.js +647 -0
  774. package/dist/vite/__tests__/expose-internal-ids.test.js.map +1 -0
  775. package/dist/vite/__tests__/expose-router-id.test.d.ts +2 -0
  776. package/dist/vite/__tests__/expose-router-id.test.d.ts.map +1 -0
  777. package/dist/vite/__tests__/expose-router-id.test.js +39 -0
  778. package/dist/vite/__tests__/expose-router-id.test.js.map +1 -0
  779. package/dist/vite/ast-handler-extract.d.ts +49 -0
  780. package/dist/vite/ast-handler-extract.d.ts.map +1 -0
  781. package/dist/vite/ast-handler-extract.js +249 -0
  782. package/dist/vite/ast-handler-extract.js.map +1 -0
  783. package/dist/vite/expose-action-id.d.ts +19 -0
  784. package/dist/vite/expose-action-id.d.ts.map +1 -0
  785. package/dist/vite/expose-action-id.js +250 -0
  786. package/dist/vite/expose-action-id.js.map +1 -0
  787. package/dist/vite/expose-id-utils.d.ts +69 -0
  788. package/dist/vite/expose-id-utils.d.ts.map +1 -0
  789. package/dist/vite/expose-id-utils.js +289 -0
  790. package/dist/vite/expose-id-utils.js.map +1 -0
  791. package/dist/vite/expose-internal-ids.d.ts +22 -0
  792. package/dist/vite/expose-internal-ids.d.ts.map +1 -0
  793. package/dist/vite/expose-internal-ids.js +886 -0
  794. package/dist/vite/expose-internal-ids.js.map +1 -0
  795. package/dist/vite/index.d.ts +149 -0
  796. package/dist/vite/index.d.ts.map +1 -0
  797. package/dist/vite/index.js +2309 -833
  798. package/dist/vite/index.js.bak +5448 -0
  799. package/dist/vite/index.js.map +1 -0
  800. package/dist/vite/index.named-routes.gen.ts +103 -0
  801. package/dist/vite/package-resolution.d.ts +43 -0
  802. package/dist/vite/package-resolution.d.ts.map +1 -0
  803. package/dist/vite/package-resolution.js +112 -0
  804. package/dist/vite/package-resolution.js.map +1 -0
  805. package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  806. package/dist/vite/virtual-entries.d.ts +25 -0
  807. package/dist/vite/virtual-entries.d.ts.map +1 -0
  808. package/dist/vite/virtual-entries.js +110 -0
  809. package/dist/vite/virtual-entries.js.map +1 -0
  810. package/package.json +57 -11
  811. package/skills/breadcrumbs/SKILL.md +3 -1
  812. package/skills/bundle-analysis/SKILL.md +159 -0
  813. package/skills/cache-guide/SKILL.md +220 -30
  814. package/skills/caching/SKILL.md +116 -8
  815. package/skills/composability/SKILL.md +27 -2
  816. package/skills/document-cache/SKILL.md +78 -55
  817. package/skills/handler-use/SKILL.md +364 -0
  818. package/skills/hooks/SKILL.md +229 -20
  819. package/skills/host-router/SKILL.md +45 -20
  820. package/skills/i18n/SKILL.md +276 -0
  821. package/skills/intercept/SKILL.md +46 -4
  822. package/skills/layout/SKILL.md +28 -7
  823. package/skills/links/SKILL.md +247 -17
  824. package/skills/loader/SKILL.md +219 -9
  825. package/skills/middleware/SKILL.md +47 -12
  826. package/skills/migrate-nextjs/SKILL.md +562 -0
  827. package/skills/migrate-react-router/SKILL.md +769 -0
  828. package/skills/mime-routes/SKILL.md +27 -0
  829. package/skills/observability/SKILL.md +137 -0
  830. package/skills/parallel/SKILL.md +71 -6
  831. package/skills/prerender/SKILL.md +14 -33
  832. package/skills/rango/SKILL.md +242 -22
  833. package/skills/react-compiler/SKILL.md +168 -0
  834. package/skills/response-routes/SKILL.md +66 -9
  835. package/skills/route/SKILL.md +57 -4
  836. package/skills/router-setup/SKILL.md +3 -3
  837. package/skills/server-actions/SKILL.md +751 -0
  838. package/skills/streams-and-websockets/SKILL.md +283 -0
  839. package/skills/testing/SKILL.md +599 -0
  840. package/skills/typesafety/SKILL.md +319 -27
  841. package/skills/use-cache/SKILL.md +34 -5
  842. package/skills/view-transitions/SKILL.md +294 -0
  843. package/src/__augment-tests__/augment.ts +81 -0
  844. package/src/__augment-tests__/augmented.check.ts +117 -0
  845. package/src/browser/action-coordinator.ts +53 -36
  846. package/src/browser/app-shell.ts +52 -0
  847. package/src/browser/event-controller.ts +86 -70
  848. package/src/browser/history-state.ts +21 -0
  849. package/src/browser/index.ts +3 -3
  850. package/src/browser/navigation-bridge.ts +86 -11
  851. package/src/browser/navigation-client.ts +76 -28
  852. package/src/browser/navigation-store.ts +32 -9
  853. package/src/browser/navigation-transaction.ts +10 -28
  854. package/src/browser/partial-update.ts +64 -26
  855. package/src/browser/prefetch/cache.ts +129 -21
  856. package/src/browser/prefetch/fetch.ts +148 -16
  857. package/src/browser/prefetch/queue.ts +36 -5
  858. package/src/browser/rango-state.ts +53 -13
  859. package/src/browser/react/Link.tsx +30 -2
  860. package/src/browser/react/NavigationProvider.tsx +72 -31
  861. package/src/browser/react/filter-segment-order.ts +51 -7
  862. package/src/browser/react/index.ts +3 -0
  863. package/src/browser/react/location-state-shared.ts +175 -4
  864. package/src/browser/react/location-state.ts +39 -13
  865. package/src/browser/react/use-handle.ts +17 -9
  866. package/src/browser/react/use-navigation.ts +22 -2
  867. package/src/browser/react/use-params.ts +20 -8
  868. package/src/browser/react/use-reverse.ts +106 -0
  869. package/src/browser/react/use-router.ts +22 -2
  870. package/src/browser/react/use-segments.ts +11 -8
  871. package/src/browser/response-adapter.ts +25 -0
  872. package/src/browser/rsc-router.tsx +64 -22
  873. package/src/browser/scroll-restoration.ts +22 -14
  874. package/src/browser/segment-reconciler.ts +36 -14
  875. package/src/browser/segment-structure-assert.ts +2 -2
  876. package/src/browser/server-action-bridge.ts +23 -30
  877. package/src/browser/types.ts +21 -0
  878. package/src/build/collect-fallback-refs.ts +107 -0
  879. package/src/build/generate-manifest.ts +60 -35
  880. package/src/build/generate-route-types.ts +2 -0
  881. package/src/build/index.ts +2 -0
  882. package/src/build/route-trie.ts +52 -25
  883. package/src/build/route-types/codegen.ts +4 -4
  884. package/src/build/route-types/include-resolution.ts +1 -1
  885. package/src/build/route-types/per-module-writer.ts +7 -4
  886. package/src/build/route-types/router-processing.ts +55 -14
  887. package/src/build/route-types/scan-filter.ts +1 -1
  888. package/src/build/route-types/source-scan.ts +118 -0
  889. package/src/build/runtime-discovery.ts +9 -20
  890. package/src/cache/cache-scope.ts +28 -42
  891. package/src/cache/cf/cf-cache-store.ts +54 -13
  892. package/src/client.rsc.tsx +3 -0
  893. package/src/client.tsx +92 -182
  894. package/src/context-var.ts +5 -5
  895. package/src/decode-loader-results.ts +36 -0
  896. package/src/errors.ts +30 -1
  897. package/src/handle.ts +26 -13
  898. package/src/host/index.ts +2 -2
  899. package/src/host/router.ts +129 -57
  900. package/src/host/types.ts +31 -2
  901. package/src/host/utils.ts +1 -1
  902. package/src/href-client.ts +140 -20
  903. package/src/index.rsc.ts +9 -4
  904. package/src/index.ts +57 -15
  905. package/src/loader-store.ts +500 -0
  906. package/src/loader.rsc.ts +2 -5
  907. package/src/loader.ts +3 -10
  908. package/src/missing-id-error.ts +68 -0
  909. package/src/outlet-context.ts +1 -1
  910. package/src/prerender.ts +4 -4
  911. package/src/response-utils.ts +37 -0
  912. package/src/reverse.ts +65 -36
  913. package/src/route-content-wrapper.tsx +6 -28
  914. package/src/route-definition/dsl-helpers.ts +384 -257
  915. package/src/route-definition/helper-factories.ts +29 -139
  916. package/src/route-definition/helpers-types.ts +100 -28
  917. package/src/route-definition/resolve-handler-use.ts +6 -0
  918. package/src/route-definition/use-item-types.ts +32 -0
  919. package/src/route-types.ts +26 -41
  920. package/src/router/basename.ts +14 -0
  921. package/src/router/content-negotiation.ts +15 -2
  922. package/src/router/error-handling.ts +1 -1
  923. package/src/router/handler-context.ts +21 -38
  924. package/src/router/intercept-resolution.ts +4 -18
  925. package/src/router/lazy-includes.ts +8 -8
  926. package/src/router/loader-resolution.ts +89 -49
  927. package/src/router/manifest.ts +22 -13
  928. package/src/router/match-api.ts +4 -3
  929. package/src/router/match-handlers.ts +63 -20
  930. package/src/router/match-middleware/cache-lookup.ts +54 -96
  931. package/src/router/match-middleware/cache-store.ts +3 -2
  932. package/src/router/match-middleware/segment-resolution.ts +1 -1
  933. package/src/router/match-result.ts +103 -4
  934. package/src/router/metrics.ts +1 -1
  935. package/src/router/middleware-types.ts +15 -26
  936. package/src/router/middleware.ts +99 -84
  937. package/src/router/pattern-matching.ts +101 -17
  938. package/src/router/prerender-match.ts +1 -1
  939. package/src/router/preview-match.ts +3 -1
  940. package/src/router/request-classification.ts +4 -28
  941. package/src/router/revalidation.ts +58 -2
  942. package/src/router/router-interfaces.ts +45 -28
  943. package/src/router/router-options.ts +40 -1
  944. package/src/router/router-registry.ts +2 -5
  945. package/src/router/segment-resolution/fresh.ts +32 -6
  946. package/src/router/segment-resolution/revalidation.ts +154 -107
  947. package/src/router/segment-resolution/view-transition-default.ts +36 -0
  948. package/src/router/substitute-pattern-params.ts +56 -0
  949. package/src/router/telemetry.ts +99 -0
  950. package/src/router/trie-matching.ts +18 -13
  951. package/src/router/types.ts +8 -0
  952. package/src/router/url-params.ts +49 -0
  953. package/src/router.ts +38 -23
  954. package/src/rsc/handler-context.ts +2 -2
  955. package/src/rsc/handler.ts +41 -74
  956. package/src/rsc/helpers.ts +91 -43
  957. package/src/rsc/index.ts +1 -1
  958. package/src/rsc/loader-fetch.ts +23 -3
  959. package/src/rsc/origin-guard.ts +28 -10
  960. package/src/rsc/progressive-enhancement.ts +14 -2
  961. package/src/rsc/response-route-handler.ts +46 -53
  962. package/src/rsc/rsc-rendering.ts +40 -52
  963. package/src/rsc/runtime-warnings.ts +9 -10
  964. package/src/rsc/server-action.ts +23 -37
  965. package/src/rsc/ssr-setup.ts +16 -0
  966. package/src/rsc/types.ts +9 -2
  967. package/src/search-params.ts +4 -4
  968. package/src/segment-content-promise.ts +67 -0
  969. package/src/segment-loader-promise.ts +122 -0
  970. package/src/segment-system.tsx +132 -116
  971. package/src/serialize.ts +243 -0
  972. package/src/server/context.ts +143 -53
  973. package/src/server/cookie-store.ts +28 -4
  974. package/src/server/handle-store.ts +19 -0
  975. package/src/server/request-context.ts +50 -44
  976. package/src/ssr/index.tsx +5 -1
  977. package/src/static-handler.ts +1 -1
  978. package/src/testing/cache-status.ts +166 -0
  979. package/src/testing/collect-handle.ts +63 -0
  980. package/src/testing/dispatch.ts +440 -0
  981. package/src/testing/dom.entry.ts +22 -0
  982. package/src/testing/e2e/fixture.ts +154 -0
  983. package/src/testing/e2e/index.ts +149 -0
  984. package/src/testing/e2e/matchers.ts +51 -0
  985. package/src/testing/e2e/page-helpers.ts +272 -0
  986. package/src/testing/e2e/parity.ts +306 -0
  987. package/src/testing/e2e/server.ts +183 -0
  988. package/src/testing/flight-matchers.ts +104 -0
  989. package/src/testing/flight-runtime.d.ts +21 -0
  990. package/src/testing/flight.entry.ts +22 -0
  991. package/src/testing/flight.ts +182 -0
  992. package/src/testing/generated-routes.ts +223 -0
  993. package/src/testing/index.ts +105 -0
  994. package/src/testing/internal/context.ts +193 -0
  995. package/src/testing/render-route.tsx +536 -0
  996. package/src/testing/run-loader.ts +296 -0
  997. package/src/testing/run-middleware.ts +170 -0
  998. package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
  999. package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
  1000. package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
  1001. package/src/testing/vitest-stubs/version.ts +5 -0
  1002. package/src/testing/vitest.ts +183 -0
  1003. package/src/types/global-namespace.ts +39 -26
  1004. package/src/types/handler-context.ts +68 -50
  1005. package/src/types/index.ts +1 -0
  1006. package/src/types/loader-types.ts +5 -6
  1007. package/src/types/request-scope.ts +126 -0
  1008. package/src/types/route-entry.ts +11 -0
  1009. package/src/types/segments.ts +36 -2
  1010. package/src/urls/include-helper.ts +34 -67
  1011. package/src/urls/index.ts +0 -3
  1012. package/src/urls/path-helper-types.ts +41 -7
  1013. package/src/urls/path-helper.ts +17 -52
  1014. package/src/urls/pattern-types.ts +36 -19
  1015. package/src/urls/response-types.ts +22 -29
  1016. package/src/urls/type-extraction.ts +26 -116
  1017. package/src/urls/urls-function.ts +1 -5
  1018. package/src/use-loader.tsx +416 -42
  1019. package/src/vite/debug.ts +185 -0
  1020. package/src/vite/discovery/bundle-postprocess.ts +6 -6
  1021. package/src/vite/discovery/discover-routers.ts +101 -51
  1022. package/src/vite/discovery/discovery-errors.ts +194 -0
  1023. package/src/vite/discovery/gate-state.ts +171 -0
  1024. package/src/vite/discovery/prerender-collection.ts +185 -103
  1025. package/src/vite/discovery/route-types-writer.ts +40 -84
  1026. package/src/vite/discovery/self-gen-tracking.ts +27 -1
  1027. package/src/vite/discovery/state.ts +33 -0
  1028. package/src/vite/discovery/virtual-module-codegen.ts +13 -23
  1029. package/src/vite/index.ts +2 -0
  1030. package/src/vite/plugin-types.ts +67 -0
  1031. package/src/vite/plugins/cjs-to-esm.ts +8 -7
  1032. package/src/vite/plugins/client-ref-dedup.ts +16 -0
  1033. package/src/vite/plugins/client-ref-hashing.ts +28 -5
  1034. package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
  1035. package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  1036. package/src/vite/plugins/cloudflare-protocol-stub.ts +214 -0
  1037. package/src/vite/plugins/expose-action-id.ts +54 -30
  1038. package/src/vite/plugins/expose-id-utils.ts +24 -8
  1039. package/src/vite/plugins/expose-ids/export-analysis.ts +100 -20
  1040. package/src/vite/plugins/expose-ids/handler-transform.ts +12 -35
  1041. package/src/vite/plugins/expose-ids/loader-transform.ts +3 -5
  1042. package/src/vite/plugins/expose-ids/router-transform.ts +20 -3
  1043. package/src/vite/plugins/expose-internal-ids.ts +544 -317
  1044. package/src/vite/plugins/performance-tracks.ts +29 -25
  1045. package/src/vite/plugins/use-cache-transform.ts +65 -50
  1046. package/src/vite/plugins/version-injector.ts +39 -23
  1047. package/src/vite/plugins/version-plugin.ts +59 -2
  1048. package/src/vite/plugins/virtual-entries.ts +2 -2
  1049. package/src/vite/rango.ts +116 -29
  1050. package/src/vite/router-discovery.ts +774 -102
  1051. package/src/vite/utils/ast-handler-extract.ts +15 -15
  1052. package/src/vite/utils/banner.ts +1 -1
  1053. package/src/vite/utils/bundle-analysis.ts +4 -2
  1054. package/src/vite/utils/client-chunks.ts +190 -0
  1055. package/src/vite/utils/forward-user-plugins.ts +193 -0
  1056. package/src/vite/utils/manifest-utils.ts +21 -5
  1057. package/src/vite/utils/package-resolution.ts +41 -1
  1058. package/src/vite/utils/prerender-utils.ts +21 -6
  1059. package/src/vite/utils/shared-utils.ts +107 -26
  1060. 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,18 +1136,16 @@ 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 };
912
1143
  }
913
- function generateExprStubs(cfg, bindings, code, filePath, sourceId, isBuild) {
914
- if (bindings.length === 0) return null;
915
- const s = new MagicString2(code);
1144
+ function stubHandlerExprs(cfg, bindings, s, filePath, isBuild) {
916
1145
  let hasChanges = false;
917
1146
  for (const binding of bindings) {
918
1147
  const exportName = binding.exportNames[0];
919
- const handlerId = isBuild ? hashId(filePath, exportName) : `${filePath}#${exportName}`;
1148
+ const handlerId = makeStubId(filePath, exportName, isBuild);
920
1149
  s.overwrite(
921
1150
  binding.callExprStart,
922
1151
  binding.callCloseParenPos + 1,
@@ -924,21 +1153,13 @@ function generateExprStubs(cfg, bindings, code, filePath, sourceId, isBuild) {
924
1153
  );
925
1154
  hasChanges = true;
926
1155
  }
927
- if (!hasChanges) return null;
928
- return {
929
- code: s.toString(),
930
- map: s.generateMap({
931
- source: sourceId,
932
- includeContent: true,
933
- hires: "boundary"
934
- })
935
- };
1156
+ return hasChanges;
936
1157
  }
937
1158
  function transformHandlerIds(cfg, bindings, s, filePath, isBuild) {
938
1159
  let hasChanges = false;
939
1160
  for (const binding of bindings) {
940
1161
  const exportName = binding.exportNames[0];
941
- const handlerId = isBuild ? hashId(filePath, exportName) : `${filePath}#${exportName}`;
1162
+ const handlerId = makeStubId(filePath, exportName, isBuild);
942
1163
  let paramInjection;
943
1164
  if (binding.argCount === 0) {
944
1165
  paramInjection = `undefined, "${handlerId}"`;
@@ -957,19 +1178,20 @@ ${binding.localName}.$$id = "${handlerId}";`;
957
1178
  }
958
1179
 
959
1180
  // src/vite/plugins/expose-ids/router-transform.ts
960
- import MagicString3 from "magic-string";
1181
+ import MagicString2 from "magic-string";
961
1182
  import path3 from "node:path";
962
1183
  import { createHash } from "node:crypto";
1184
+ var debug2 = createRangoDebugger(NS.transform);
963
1185
  function transformRouter(code, filePath, routerFnNames, absolutePath) {
964
1186
  const pat = new RegExp(
965
1187
  `\\b(?:${routerFnNames.map((n) => n.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|")})\\s*(?:<[^>]*>)?\\s*\\(`,
966
1188
  "g"
967
1189
  );
968
1190
  let match;
969
- const s = new MagicString3(code);
1191
+ const s = new MagicString2(code);
970
1192
  let changed = false;
971
- const basename3 = path3.basename(filePath).replace(/\.(tsx?|jsx?)$/, "");
972
- const routeNamesImport = `./${basename3}.named-routes.gen.js`;
1193
+ const basename2 = path3.basename(filePath).replace(/\.(tsx?|jsx?)$/, "");
1194
+ const routeNamesImport = `./${basename2}.named-routes.gen.js`;
973
1195
  const routeNamesVar = `__rsc_rn`;
974
1196
  while ((match = pat.exec(code)) !== null) {
975
1197
  const callStart = match.index;
@@ -1002,11 +1224,15 @@ function transformRouter(code, filePath, routerFnNames, absolutePath) {
1002
1224
  }
1003
1225
  function exposeRouterId() {
1004
1226
  let projectRoot = "";
1227
+ const counter = createCounter(debug2, "expose-router-id");
1005
1228
  return {
1006
1229
  name: "@rangojs/router:expose-router-id",
1007
1230
  configResolved(config) {
1008
1231
  projectRoot = config.root;
1009
1232
  },
1233
+ buildEnd() {
1234
+ counter?.flush();
1235
+ },
1010
1236
  transform(code, id) {
1011
1237
  if (!code.includes("createRouter")) return null;
1012
1238
  if (!/import\s*\{[^}]*\bcreateRouter\b[^}]*\}\s*from\s*["']@rangojs\/router(?:\/server)?["']/.test(
@@ -1015,14 +1241,25 @@ function exposeRouterId() {
1015
1241
  return null;
1016
1242
  }
1017
1243
  if (id.includes("node_modules")) return null;
1018
- const filePath = normalizePath(path3.relative(projectRoot, id));
1019
- const routerFnNames = getImportedFnNames(code, "createRouter");
1020
- 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
+ }
1021
1257
  }
1022
1258
  };
1023
1259
  }
1024
1260
 
1025
1261
  // src/vite/plugins/expose-internal-ids.ts
1262
+ var debug3 = createRangoDebugger(NS.transform);
1026
1263
  var VIRTUAL_LOADER_MANIFEST = "virtual:rsc-router/loader-manifest";
1027
1264
  var RESOLVED_VIRTUAL_LOADER_MANIFEST = "\0" + VIRTUAL_LOADER_MANIFEST;
1028
1265
  var VIRTUAL_HANDLER_PREFIX = "virtual:handler-extract:";
@@ -1035,9 +1272,13 @@ function exposeInternalIds(options) {
1035
1272
  const staticHandlerModules = /* @__PURE__ */ new Map();
1036
1273
  const virtualHandlers = /* @__PURE__ */ new Map();
1037
1274
  const unsupportedShapeWarnings = /* @__PURE__ */ new Set();
1275
+ const counter = createCounter(debug3, "expose-internal-ids");
1038
1276
  return {
1039
1277
  name: "@rangojs/router:expose-internal-ids",
1040
1278
  enforce: "post",
1279
+ buildEnd() {
1280
+ counter?.flush();
1281
+ },
1041
1282
  api: {
1042
1283
  prerenderHandlerModules,
1043
1284
  staticHandlerModules
@@ -1151,11 +1392,13 @@ ${lazyImports.join(",\n")}
1151
1392
  // --------------- Unified transform ---------------
1152
1393
  transform(code, id) {
1153
1394
  if (id.includes("/node_modules/")) return;
1154
- const filePath = normalizePath(path4.relative(projectRoot, id));
1155
- const isRscEnv = this.environment?.name === "rsc";
1156
- if (id.includes(".named-routes.gen.") && !isRscEnv && this.environment?.name === "client") {
1157
- this.warn(
1158
- `
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
+ `
1159
1402
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1160
1403
  !! !!
1161
1404
  !! WARNING: NamedRoutes imported in a CLIENT component! !!
@@ -1175,241 +1418,363 @@ ${lazyImports.join(",\n")}
1175
1418
  !! !!
1176
1419
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1177
1420
  `
1178
- );
1179
- }
1180
- if (!code.includes("@rangojs/router")) return;
1181
- const has = detectImports(code);
1182
- const hasLoaderCode = has.loader && code.includes("createLoader");
1183
- const hasHandleCode = has.handle && code.includes("createHandle");
1184
- const hasLocationStateCode = has.locationState && code.includes("createLocationState");
1185
- const hasPrerenderHandlerCode = has.prerenderHandler && code.includes("Prerender");
1186
- const hasStaticHandlerCode = has.staticHandler && code.includes("Static");
1187
- if (!hasLoaderCode && !hasHandleCode && !hasLocationStateCode && !hasPrerenderHandlerCode && !hasStaticHandlerCode) {
1188
- return;
1189
- }
1190
- const _fnNamesCache = /* @__PURE__ */ new Map();
1191
- const _bindingsCache = /* @__PURE__ */ new Map();
1192
- let _cachedAst;
1193
- let _astParseFailed = false;
1194
- let _astCodeRef = code;
1195
- const getFnNames = (canonicalName) => {
1196
- let result = _fnNamesCache.get(canonicalName);
1197
- if (!result) {
1198
- result = getImportedFnNames(code, canonicalName);
1199
- _fnNamesCache.set(canonicalName, result);
1421
+ );
1200
1422
  }
1201
- return result;
1202
- };
1203
- const lazyAst = () => {
1204
- if (code !== _astCodeRef) {
1205
- _cachedAst = void 0;
1206
- _astParseFailed = false;
1207
- _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;
1208
1432
  }
1209
- if (_cachedAst !== void 0 || _astParseFailed) return _cachedAst;
1210
- try {
1211
- _cachedAst = parseAst2(code, { jsx: true });
1212
- } catch {
1213
- _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));
1214
1487
  }
1215
- return _cachedAst;
1216
- };
1217
- const getBindings = (currentCode, fnNames) => {
1218
- const key = fnNames.join("\0");
1219
- let result = _bindingsCache.get(key);
1220
- if (!result) {
1221
- result = collectCreateExportBindings(currentCode, fnNames, lazyAst());
1222
- _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
+ }
1223
1499
  }
1224
- return result;
1225
- };
1226
- for (const cfg of STRICT_CREATE_CONFIGS) {
1227
- const hasCode = cfg.fnName === "createLoader" ? hasLoaderCode : cfg.fnName === "createHandle" ? hasHandleCode : hasLocationStateCode;
1228
- if (!hasCode) continue;
1229
- const fnNames = getFnNames(cfg.fnName);
1230
- const totalCalls = countCreateCallsForNames(code, fnNames);
1231
- const supportedBindings = getBindings(code, fnNames).length;
1232
- if (totalCalls <= supportedBindings) continue;
1233
- const warnKey = `${id}::${cfg.fnName}`;
1234
- if (unsupportedShapeWarnings.has(warnKey)) continue;
1235
- unsupportedShapeWarnings.add(warnKey);
1236
- this.warn(buildUnsupportedShapeWarning(filePath, cfg.fnName));
1237
- }
1238
- if (hasLoaderCode && isRscEnv) {
1239
- const fnNames = getFnNames("createLoader");
1240
- const bindings = getBindings(code, fnNames);
1241
- for (const binding of bindings) {
1242
- const exportName = binding.exportNames[0];
1243
- const hashedId = hashId(filePath, exportName);
1244
- 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,
1245
1506
  filePath,
1246
- exportName
1247
- });
1507
+ isBuild
1508
+ );
1509
+ if (stubResult) return stubResult;
1248
1510
  }
1249
- }
1250
- if (hasLoaderCode && !isRscEnv) {
1251
- const fnNames = getFnNames("createLoader");
1252
- const bindings = getBindings(code, fnNames);
1253
- const stubResult = generateClientLoaderStubs(
1254
- bindings,
1255
- code,
1256
- filePath,
1257
- isBuild
1258
- );
1259
- if (stubResult) return stubResult;
1260
- }
1261
- if (hasPrerenderHandlerCode && !isRscEnv) {
1262
- const fnNames = getFnNames(PRERENDER_CONFIG.fnName);
1263
- const bindings = getBindings(code, fnNames);
1264
- const wholeFile = generateWholeFileStubs(
1265
- PRERENDER_CONFIG,
1266
- bindings,
1267
- code,
1268
- filePath,
1269
- isBuild
1270
- );
1271
- if (wholeFile) return wholeFile;
1272
- const exprStubs = generateExprStubs(
1273
- PRERENDER_CONFIG,
1274
- bindings,
1275
- code,
1276
- filePath,
1277
- id,
1278
- isBuild
1279
- );
1280
- if (exprStubs) return exprStubs;
1281
- }
1282
- if (hasPrerenderHandlerCode && isRscEnv && isBuild) {
1283
- const fnNames = getFnNames(PRERENDER_CONFIG.fnName);
1284
- const exportNames = getBindings(code, fnNames).map(
1285
- (b) => b.exportNames[0]
1286
- );
1287
- if (exportNames.length > 0) {
1288
- prerenderHandlerModules.set(id, exportNames);
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,
1517
+ code,
1518
+ filePath,
1519
+ isBuild
1520
+ );
1521
+ if (wholeFile) return wholeFile;
1289
1522
  }
1290
- }
1291
- let changed = false;
1292
- const handlerConfigs = [
1293
- hasStaticHandlerCode && STATIC_CONFIG,
1294
- hasPrerenderHandlerCode && PRERENDER_CONFIG
1295
- ].filter((c) => !!c).map((cfg) => {
1296
- const fnNames = getFnNames(cfg.fnName);
1297
- return { cfg, fnNames };
1298
- });
1299
- for (const { cfg, fnNames } of handlerConfigs) {
1300
- const totalCalls = countCreateCallsForNames(code, fnNames);
1301
- const supportedBindings = getBindings(code, fnNames).length;
1302
- if (totalCalls > supportedBindings) {
1303
- const iterS = new MagicString4(code);
1304
- const result = transformInlineHandlers(
1305
- cfg.fnName,
1306
- VIRTUAL_HANDLER_PREFIX,
1307
- iterS,
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
+ }
1551
+ }
1552
+ }
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,
1308
1559
  code,
1309
1560
  filePath,
1310
- virtualHandlers,
1311
- id,
1312
- parseAst2
1561
+ isBuild
1313
1562
  );
1314
- if (result) {
1315
- changed = true;
1316
- code = iterS.toString();
1317
- _bindingsCache.clear();
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));
1581
+ }
1582
+ }
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
+ }
1594
+ }
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`
1619
+ );
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
+ }
1628
+ }
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(
1641
+ binding.callExprStart,
1642
+ binding.callOpenParenPos + 1
1643
+ );
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};`);
1681
+ }
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
+ }
1689
+ lines.push(
1690
+ `export const ${primaryName} = { __brand: "${brand}", $$id: "${stubId}" };`
1691
+ );
1692
+ for (const name of binding.exportNames.slice(1)) {
1693
+ lines.push(`export const ${name} = ${primaryName};`);
1694
+ }
1695
+ }
1696
+ }
1697
+ return { code: lines.join("\n") + "\n", map: null };
1318
1698
  }
1319
1699
  }
1320
- }
1321
- if (hasStaticHandlerCode && !isRscEnv) {
1322
- const fnNames = getFnNames(STATIC_CONFIG.fnName);
1323
- const bindings = getBindings(code, fnNames);
1324
- const wholeFile = generateWholeFileStubs(
1325
- STATIC_CONFIG,
1326
- bindings,
1327
- code,
1328
- filePath,
1329
- isBuild
1330
- );
1331
- if (wholeFile) return wholeFile;
1332
- const exprStubs = generateExprStubs(
1333
- STATIC_CONFIG,
1334
- bindings,
1335
- code,
1336
- filePath,
1337
- id,
1338
- isBuild
1339
- );
1340
- if (exprStubs) return exprStubs;
1341
- }
1342
- if (hasStaticHandlerCode && isRscEnv && isBuild) {
1343
- const fnNames = getFnNames(STATIC_CONFIG.fnName);
1344
- const exportNames = getBindings(code, fnNames).map(
1345
- (b) => b.exportNames[0]
1346
- );
1347
- if (exportNames.length > 0) {
1348
- 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
+ }
1349
1716
  }
1717
+ const s = new MagicString3(code);
1718
+ if (hasLoaderCode) {
1719
+ const fnNames = getFnNames("createLoader");
1720
+ changed = transformLoaders(
1721
+ getBindings(code, fnNames),
1722
+ s,
1723
+ filePath,
1724
+ isBuild
1725
+ ) || changed;
1726
+ }
1727
+ if (hasHandleCode) {
1728
+ const fnNames = getFnNames("createHandle");
1729
+ changed = transformHandles(
1730
+ getBindings(code, fnNames),
1731
+ s,
1732
+ code,
1733
+ filePath,
1734
+ isBuild
1735
+ ) || changed;
1736
+ }
1737
+ if (hasLocationStateCode) {
1738
+ const fnNames = getFnNames("createLocationState");
1739
+ changed = transformLocationState(
1740
+ getBindings(code, fnNames),
1741
+ s,
1742
+ filePath,
1743
+ isBuild
1744
+ ) || changed;
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);
1350
1761
  }
1351
- const s = new MagicString4(code);
1352
- if (hasLoaderCode) {
1353
- const fnNames = getFnNames("createLoader");
1354
- changed = transformLoaders(getBindings(code, fnNames), s, filePath, isBuild) || changed;
1355
- }
1356
- if (hasHandleCode) {
1357
- const fnNames = getFnNames("createHandle");
1358
- changed = transformHandles(
1359
- getBindings(code, fnNames),
1360
- s,
1361
- code,
1362
- filePath,
1363
- isBuild
1364
- ) || changed;
1365
- }
1366
- if (hasLocationStateCode) {
1367
- const fnNames = getFnNames("createLocationState");
1368
- changed = transformLocationState(
1369
- getBindings(code, fnNames),
1370
- s,
1371
- filePath,
1372
- isBuild
1373
- ) || changed;
1374
- }
1375
- if (hasPrerenderHandlerCode && isRscEnv) {
1376
- const fnNames = getFnNames(PRERENDER_CONFIG.fnName);
1377
- changed = transformHandlerIds(
1378
- PRERENDER_CONFIG,
1379
- getBindings(code, fnNames),
1380
- s,
1381
- filePath,
1382
- isBuild
1383
- ) || changed;
1384
- }
1385
- if (hasStaticHandlerCode && isRscEnv) {
1386
- const fnNames = getFnNames(STATIC_CONFIG.fnName);
1387
- changed = transformHandlerIds(
1388
- STATIC_CONFIG,
1389
- getBindings(code, fnNames),
1390
- s,
1391
- filePath,
1392
- isBuild
1393
- ) || changed;
1394
- }
1395
- if (!changed) return;
1396
- return {
1397
- code: s.toString(),
1398
- map: s.generateMap({ source: id, includeContent: true })
1399
- };
1400
1762
  }
1401
1763
  };
1402
1764
  }
1403
1765
 
1404
1766
  // src/vite/plugins/use-cache-transform.ts
1405
1767
  import path5 from "node:path";
1406
- import MagicString5 from "magic-string";
1768
+ import MagicString4 from "magic-string";
1769
+ var debug4 = createRangoDebugger(NS.transform);
1407
1770
  var CACHE_RUNTIME_IMPORT = "@rangojs/router/cache-runtime";
1408
1771
  var LAYOUT_TEMPLATE_PATTERN = /\/(layout|template)\.(tsx?|jsx?)$/;
1772
+ var USE_CACHE_DIRECTIVE_RE = /^use cache(:\s*[\w-]+)?$/;
1409
1773
  function useCacheTransform() {
1410
1774
  let projectRoot = "";
1411
1775
  let isBuild = false;
1412
1776
  let rscTransforms = null;
1777
+ const counter = createCounter(debug4, "use-cache");
1413
1778
  return {
1414
1779
  name: "@rangojs/router:use-cache",
1415
1780
  enforce: "post",
@@ -1417,53 +1782,61 @@ function useCacheTransform() {
1417
1782
  projectRoot = config.root;
1418
1783
  isBuild = config.command === "build";
1419
1784
  },
1785
+ buildEnd() {
1786
+ counter?.flush();
1787
+ },
1420
1788
  async transform(code, id) {
1421
1789
  if (this.environment?.name !== "rsc") return;
1422
1790
  if (!code.includes("use cache")) return;
1423
1791
  if (id.includes("/node_modules/") || id.startsWith("\0")) return;
1424
1792
  if (!/\.(tsx?|jsx?|mjs)$/.test(id)) return;
1425
- 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;
1426
1808
  try {
1427
- rscTransforms = await import("@vitejs/plugin-rsc/transforms");
1809
+ const { parseAst: parseAst4 } = await import("vite");
1810
+ ast = parseAst4(code, { lang: "tsx" });
1428
1811
  } catch {
1429
1812
  return;
1430
1813
  }
1431
- }
1432
- const {
1433
- hasDirective,
1434
- transformWrapExport,
1435
- transformHoistInlineDirective
1436
- } = rscTransforms;
1437
- let ast;
1438
- try {
1439
- const { parseAst: parseAst4 } = await import("vite");
1440
- ast = parseAst4(code);
1441
- } catch {
1442
- return;
1443
- }
1444
- const filePath = normalizePath(path5.relative(projectRoot, id));
1445
- const isLayoutOrTemplate = LAYOUT_TEMPLATE_PATTERN.test(id);
1446
- if (hasDirective(ast.body, "use cache")) {
1447
- 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(
1448
1828
  code,
1449
1829
  ast,
1450
1830
  filePath,
1451
1831
  id,
1452
1832
  isBuild,
1453
- isLayoutOrTemplate,
1454
- transformWrapExport
1833
+ transformHoistInlineDirective
1455
1834
  );
1835
+ warnOnNearMissDirectives(ast, id, this.warn.bind(this));
1836
+ if (functionResult) return functionResult;
1837
+ } finally {
1838
+ counter?.record(id, performance.now() - start);
1456
1839
  }
1457
- const functionResult = transformFunctionLevelUseCache(
1458
- code,
1459
- ast,
1460
- filePath,
1461
- id,
1462
- isBuild,
1463
- transformHoistInlineDirective
1464
- );
1465
- warnOnNearMissDirectives(ast, id, this.warn.bind(this));
1466
- if (functionResult) return functionResult;
1467
1840
  }
1468
1841
  };
1469
1842
  }
@@ -1490,7 +1863,7 @@ function transformFileLevelUseCache(code, ast, filePath, sourceId, isBuild, isLa
1490
1863
  );
1491
1864
  }
1492
1865
  if (exportNames.length === 0) {
1493
- const s = new MagicString5(code);
1866
+ const s = new MagicString4(code);
1494
1867
  const directive2 = findFileLevelDirective(ast);
1495
1868
  if (directive2) {
1496
1869
  s.overwrite(
@@ -1525,7 +1898,7 @@ function transformFileLevelUseCache(code, ast, filePath, sourceId, isBuild, isLa
1525
1898
  function transformFunctionLevelUseCache(code, ast, filePath, sourceId, isBuild, transformHoistInlineDirective) {
1526
1899
  try {
1527
1900
  const { output, names } = transformHoistInlineDirective(code, ast, {
1528
- directive: /^use cache(:\s*[\w-]+)?$/,
1901
+ directive: USE_CACHE_DIRECTIVE_RE,
1529
1902
  runtime: (value, name, meta) => {
1530
1903
  const funcId = isBuild ? hashId(filePath, name) : `${filePath}#${name}`;
1531
1904
  const profileMatch = meta.directiveMatch[1];
@@ -1555,14 +1928,13 @@ function findFileLevelDirective(ast) {
1555
1928
  }
1556
1929
  return null;
1557
1930
  }
1558
- var VALID_DIRECTIVE_RE = /^use cache(:\s*[\w-]+)?$/;
1559
1931
  var NEAR_MISS_RE = /^use cache:\s*.+$/;
1560
1932
  function warnOnNearMissDirectives(ast, fileId, warn) {
1561
1933
  const visit = (node) => {
1562
1934
  if (!node || typeof node !== "object") return;
1563
1935
  if (node.type === "ExpressionStatement" && node.expression?.type === "Literal" && typeof node.expression.value === "string") {
1564
1936
  const value = node.expression.value;
1565
- 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)) {
1566
1938
  const profilePart = value.slice("use cache:".length).trim();
1567
1939
  warn(
1568
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.`
@@ -1586,6 +1958,7 @@ function warnOnNearMissDirectives(ast, fileId, warn) {
1586
1958
  }
1587
1959
 
1588
1960
  // src/vite/plugins/client-ref-dedup.ts
1961
+ var debug5 = createRangoDebugger(NS.transform);
1589
1962
  var CLIENT_IN_SERVER_PROXY_PREFIX = "virtual:vite-rsc/client-in-server-package-proxy/";
1590
1963
  function extractPackageName(absolutePath) {
1591
1964
  const marker = "/node_modules/";
@@ -1602,6 +1975,7 @@ function extractPackageName(absolutePath) {
1602
1975
  }
1603
1976
  function clientRefDedup() {
1604
1977
  let clientExclude = [];
1978
+ const dedupedPackages = /* @__PURE__ */ new Set();
1605
1979
  return {
1606
1980
  name: "@rangojs/router:client-ref-dedup",
1607
1981
  enforce: "pre",
@@ -1610,6 +1984,15 @@ function clientRefDedup() {
1610
1984
  const clientEnv = config.environments?.["client"];
1611
1985
  clientExclude = clientEnv?.optimizeDeps?.exclude ?? config.optimizeDeps?.exclude ?? [];
1612
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
+ },
1613
1996
  resolveId(source, importer, options) {
1614
1997
  if (this.environment?.name !== "client") return;
1615
1998
  if (!importer?.includes(CLIENT_IN_SERVER_PROXY_PREFIX)) return;
@@ -1618,6 +2001,7 @@ function clientRefDedup() {
1618
2001
  const packageName = extractPackageName(source);
1619
2002
  if (!packageName) return;
1620
2003
  if (clientExclude.includes(packageName)) return;
2004
+ if (debug5) dedupedPackages.add(packageName);
1621
2005
  return `\0rango:dedup/${packageName}`;
1622
2006
  },
1623
2007
  load(id) {
@@ -1644,7 +2028,7 @@ import {
1644
2028
  import { createElement, StrictMode } from "react";
1645
2029
  import { hydrateRoot } from "react-dom/client";
1646
2030
  import { rscStream } from "@rangojs/router/internal/deps/html-stream-client";
1647
- import { initBrowserApp, RSCRouter } from "@rangojs/router/browser";
2031
+ import { initBrowserApp, Rango } from "@rangojs/router/browser";
1648
2032
 
1649
2033
  async function initializeApp() {
1650
2034
  const deps = {
@@ -1659,7 +2043,7 @@ async function initializeApp() {
1659
2043
 
1660
2044
  hydrateRoot(
1661
2045
  document,
1662
- createElement(StrictMode, null, createElement(RSCRouter))
2046
+ createElement(StrictMode, null, createElement(Rango))
1663
2047
  );
1664
2048
  }
1665
2049
 
@@ -1740,12 +2124,13 @@ function getVirtualVersionContent(version) {
1740
2124
 
1741
2125
  // src/vite/utils/package-resolution.ts
1742
2126
  import { existsSync } from "node:fs";
2127
+ import { createRequire } from "node:module";
1743
2128
  import { resolve } from "node:path";
1744
2129
 
1745
2130
  // package.json
1746
2131
  var package_default = {
1747
2132
  name: "@rangojs/router",
1748
- version: "0.0.0-experimental.fb6e2f40",
2133
+ version: "0.0.0-experimental.fce7fbd1",
1749
2134
  description: "Django-inspired RSC router with composable URL patterns",
1750
2135
  keywords: [
1751
2136
  "react",
@@ -1871,6 +2256,31 @@ var package_default = {
1871
2256
  "./host/testing": {
1872
2257
  types: "./src/host/testing.ts",
1873
2258
  default: "./src/host/testing.ts"
2259
+ },
2260
+ "./testing": {
2261
+ types: "./src/testing/index.ts",
2262
+ default: "./src/testing/index.ts"
2263
+ },
2264
+ "./testing/vitest": {
2265
+ types: "./src/testing/vitest.ts",
2266
+ default: "./dist/testing/vitest.js"
2267
+ },
2268
+ "./testing/dom": {
2269
+ types: "./src/testing/dom.entry.ts",
2270
+ default: "./src/testing/dom.entry.ts"
2271
+ },
2272
+ "./testing/e2e": {
2273
+ types: "./src/testing/e2e/index.ts",
2274
+ default: "./src/testing/e2e/index.ts"
2275
+ },
2276
+ "./testing/flight": {
2277
+ types: "./src/testing/flight.entry.ts",
2278
+ "react-server": "./src/testing/flight.entry.ts",
2279
+ default: "./src/testing/flight.entry.ts"
2280
+ },
2281
+ "./testing/flight-matchers": {
2282
+ types: "./src/testing/flight-matchers.ts",
2283
+ default: "./src/testing/flight-matchers.ts"
1874
2284
  }
1875
2285
  },
1876
2286
  publishConfig: {
@@ -1878,50 +2288,72 @@ var package_default = {
1878
2288
  tag: "experimental"
1879
2289
  },
1880
2290
  scripts: {
1881
- 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",
2291
+ 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/testing/vitest.ts --bundle --format=esm --outfile=dist/testing/vitest.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",
1882
2292
  prepublishOnly: "pnpm build",
1883
- typecheck: "tsc --noEmit",
2293
+ typecheck: "tsc --noEmit && tsc -p tsconfig.strict-check.json --noEmit && tsc -p tsconfig.augment-check.json --noEmit",
1884
2294
  test: "playwright test",
1885
2295
  "test:ui": "playwright test --ui",
2296
+ "test:hmr-local": "playwright test --project=dev-warmup --project=hmr-routes --project=hmr-basename --project=hmr-prerender --no-deps --workers=1",
1886
2297
  "test:unit": "vitest run",
1887
- "test:unit:watch": "vitest"
2298
+ "test:unit:watch": "vitest",
2299
+ "test:unit:rsc": "vitest run --config vitest.rsc.config.ts"
1888
2300
  },
1889
2301
  dependencies: {
1890
- "@vitejs/plugin-rsc": "^0.5.19",
2302
+ "@types/debug": "^4.1.12",
2303
+ "@vitejs/plugin-rsc": "^0.5.26",
2304
+ debug: "^4.4.1",
1891
2305
  "magic-string": "^0.30.17",
1892
2306
  picomatch: "^4.0.3",
1893
- "rsc-html-stream": "^0.0.7"
2307
+ "rsc-html-stream": "^0.0.7",
2308
+ tinyexec: "^0.3.2"
1894
2309
  },
1895
2310
  devDependencies: {
1896
2311
  "@playwright/test": "^1.49.1",
2312
+ "@shared/e2e": "workspace:*",
2313
+ "@testing-library/dom": "^10.4.1",
2314
+ "@testing-library/react": "^16.3.2",
1897
2315
  "@types/node": "^24.10.1",
1898
2316
  "@types/react": "catalog:",
1899
2317
  "@types/react-dom": "catalog:",
1900
2318
  esbuild: "^0.27.0",
2319
+ "happy-dom": "^20.10.1",
1901
2320
  jiti: "^2.6.1",
1902
2321
  react: "catalog:",
1903
2322
  "react-dom": "catalog:",
1904
- tinyexec: "^0.3.2",
1905
2323
  typescript: "^5.3.0",
1906
2324
  vitest: "^4.0.0"
1907
2325
  },
1908
2326
  peerDependencies: {
1909
- "@cloudflare/vite-plugin": "^1.25.0",
1910
- "@vitejs/plugin-rsc": "^0.5.14",
1911
- react: "^18.0.0 || ^19.0.0",
1912
- vite: "^7.3.0"
2327
+ "@cloudflare/vite-plugin": "^1.38.0",
2328
+ "@playwright/test": "^1.49.1",
2329
+ "@testing-library/react": ">=16",
2330
+ "@vitejs/plugin-rsc": "^0.5.26",
2331
+ react: ">=19.2.6 <20",
2332
+ "react-dom": ">=19.2.6 <20",
2333
+ vite: "^8.0.0",
2334
+ vitest: ">=3"
1913
2335
  },
1914
2336
  peerDependenciesMeta: {
1915
2337
  "@cloudflare/vite-plugin": {
1916
2338
  optional: true
1917
2339
  },
2340
+ "@playwright/test": {
2341
+ optional: true
2342
+ },
2343
+ "@testing-library/react": {
2344
+ optional: true
2345
+ },
1918
2346
  vite: {
1919
2347
  optional: true
2348
+ },
2349
+ vitest: {
2350
+ optional: true
1920
2351
  }
1921
2352
  }
1922
2353
  };
1923
2354
 
1924
2355
  // src/vite/utils/package-resolution.ts
2356
+ var require2 = createRequire(import.meta.url);
1925
2357
  var VIRTUAL_PACKAGE_NAME = "@rangojs/router";
1926
2358
  function getPublishedPackageName() {
1927
2359
  return package_default.name;
@@ -1962,13 +2394,27 @@ function getPackageAliases() {
1962
2394
  }
1963
2395
  return aliases;
1964
2396
  }
1965
-
1966
- // src/build/route-types/param-extraction.ts
1967
- function extractParamsFromPattern(pattern) {
1968
- const params = {};
1969
- const regex = /:([a-zA-Z_$][\w$]*)(?:\([^)]+\))?(\?)?/g;
1970
- let match;
1971
- while ((match = regex.exec(pattern)) !== null) {
2397
+ function getVendorAliases() {
2398
+ const specs = [
2399
+ "@vitejs/plugin-rsc/vendor/react-server-dom/client.edge",
2400
+ "@vitejs/plugin-rsc/vendor/react-server-dom/server.edge"
2401
+ ];
2402
+ const aliases = {};
2403
+ for (const spec of specs) {
2404
+ try {
2405
+ aliases[spec] = require2.resolve(spec);
2406
+ } catch {
2407
+ }
2408
+ }
2409
+ return aliases;
2410
+ }
2411
+
2412
+ // src/build/route-types/param-extraction.ts
2413
+ function extractParamsFromPattern(pattern) {
2414
+ const params = {};
2415
+ const regex = /:([a-zA-Z_$][\w$]*)(?:\([^)]+\))?(\?)?/g;
2416
+ let match;
2417
+ while ((match = regex.exec(pattern)) !== null) {
1972
2418
  params[match[1]] = match[2] ? "string?" : "string";
1973
2419
  }
1974
2420
  return Object.keys(params).length > 0 ? params : void 0;
@@ -2087,7 +2533,7 @@ ${objectBody}
2087
2533
  } as const;
2088
2534
 
2089
2535
  declare global {
2090
- namespace RSCRouter {
2536
+ namespace Rango {
2091
2537
  interface GeneratedRouteMap extends Readonly<typeof NamedRoutes> {}
2092
2538
  }
2093
2539
  }
@@ -2322,7 +2768,7 @@ function buildCombinedRouteMapWithSearch(filePath, variableName, visited, diagno
2322
2768
  const realPath = resolve2(filePath);
2323
2769
  const key = variableName ? `${realPath}:${variableName}` : realPath;
2324
2770
  if (visited.has(key)) {
2325
- console.warn(`[rsc-router] Circular include detected, skipping: ${key}`);
2771
+ console.warn(`[rango] Circular include detected, skipping: ${key}`);
2326
2772
  return { routes: {}, searchSchemas: {} };
2327
2773
  }
2328
2774
  visited.add(key);
@@ -2383,6 +2829,7 @@ function countPublicRouteEntries(source) {
2383
2829
  return count;
2384
2830
  }
2385
2831
  var ROUTER_CALL_PATTERN = /\bcreateRouter\s*[<(]/;
2832
+ var ROUTER_CALL_PATTERN_G = /\bcreateRouter\s*[<(]/g;
2386
2833
  function isRoutableSourceFile(name) {
2387
2834
  return (name.endsWith(".ts") || name.endsWith(".tsx") || name.endsWith(".js") || name.endsWith(".jsx")) && !name.includes(".gen.") && !name.includes(".test.") && !name.includes(".spec.");
2388
2835
  }
@@ -2392,7 +2839,7 @@ function findRouterFilesRecursive(dir, filter, results) {
2392
2839
  entries = readdirSync(dir, { withFileTypes: true });
2393
2840
  } catch (err) {
2394
2841
  console.warn(
2395
- `[rsc-router] Failed to scan directory ${dir}: ${err.message}`
2842
+ `[rango] Failed to scan directory ${dir}: ${err.message}`
2396
2843
  );
2397
2844
  return;
2398
2845
  }
@@ -2410,7 +2857,7 @@ function findRouterFilesRecursive(dir, filter, results) {
2410
2857
  if (filter && !filter(fullPath)) continue;
2411
2858
  try {
2412
2859
  const source = readFileSync2(fullPath, "utf-8");
2413
- if (ROUTER_CALL_PATTERN.test(source)) {
2860
+ if (ROUTER_CALL_PATTERN.test(source) && firstCodeMatchIndex(source, ROUTER_CALL_PATTERN_G) >= 0) {
2414
2861
  routerFilesInDir.push(fullPath);
2415
2862
  }
2416
2863
  } catch {
@@ -2448,7 +2895,7 @@ function findNestedRouterConflict(routerFiles) {
2448
2895
  }
2449
2896
  return null;
2450
2897
  }
2451
- function formatNestedRouterConflictError(conflict, prefix = "[rsc-router]") {
2898
+ function formatNestedRouterConflictError(conflict, prefix = "[rango]") {
2452
2899
  return `${prefix} Nested router roots are not supported.
2453
2900
  Router root: ${conflict.ancestor}
2454
2901
  Nested router: ${conflict.nested}
@@ -2544,19 +2991,38 @@ function extractBasenameFromRouter(code) {
2544
2991
  visit(sourceFile);
2545
2992
  return result;
2546
2993
  }
2547
- function applyBasenameToRoutes(result, basename3) {
2994
+ function applyBasenameToRoutes(result, basename2) {
2548
2995
  const prefixed = {};
2549
2996
  for (const [name, pattern] of Object.entries(result.routes)) {
2550
2997
  if (pattern === "/") {
2551
- prefixed[name] = basename3;
2552
- } else if (basename3.endsWith("/") && pattern.startsWith("/")) {
2553
- prefixed[name] = basename3 + pattern.slice(1);
2998
+ prefixed[name] = basename2;
2999
+ } else if (basename2.endsWith("/") && pattern.startsWith("/")) {
3000
+ prefixed[name] = basename2 + pattern.slice(1);
2554
3001
  } else {
2555
- prefixed[name] = basename3 + pattern;
3002
+ prefixed[name] = basename2 + pattern;
2556
3003
  }
2557
3004
  }
2558
3005
  return { routes: prefixed, searchSchemas: result.searchSchemas };
2559
3006
  }
3007
+ function genFileTsPath(sourceFile) {
3008
+ const base = pathBasename(sourceFile).replace(/\.(tsx?|jsx?)$/, "");
3009
+ return join(dirname2(sourceFile), `${base}.named-routes.gen.ts`);
3010
+ }
3011
+ function resolveSearchSchemas(publicRouteNames, runtimeSchemas, sourceFile) {
3012
+ if (runtimeSchemas && Object.keys(runtimeSchemas).length > 0) {
3013
+ return runtimeSchemas;
3014
+ }
3015
+ const staticParsed = buildCombinedRouteMapForRouterFile(sourceFile);
3016
+ if (Object.keys(staticParsed.searchSchemas).length === 0) {
3017
+ return runtimeSchemas;
3018
+ }
3019
+ const filtered = {};
3020
+ for (const name of publicRouteNames) {
3021
+ const schema = staticParsed.searchSchemas[name];
3022
+ if (schema) filtered[name] = schema;
3023
+ }
3024
+ return Object.keys(filtered).length > 0 ? filtered : runtimeSchemas;
3025
+ }
2560
3026
  function buildCombinedRouteMapForRouterFile(routerFilePath) {
2561
3027
  let routerSource;
2562
3028
  try {
@@ -2569,7 +3035,7 @@ function buildCombinedRouteMapForRouterFile(routerFilePath) {
2569
3035
  return { routes: {}, searchSchemas: {} };
2570
3036
  }
2571
3037
  const rawBasename = extractBasenameFromRouter(routerSource);
2572
- const basename3 = rawBasename ? ("/" + rawBasename.replace(/^\/+|\/+$/g, "")).replace(/^\/$/, "") : void 0;
3038
+ const basename2 = rawBasename ? ("/" + rawBasename.replace(/^\/+|\/+$/g, "")).replace(/^\/$/, "") : void 0;
2573
3039
  let result;
2574
3040
  if (extraction.kind === "inline") {
2575
3041
  result = buildCombinedRouteMapWithSearch(
@@ -2594,8 +3060,8 @@ function buildCombinedRouteMapForRouterFile(routerFilePath) {
2594
3060
  result = buildCombinedRouteMapWithSearch(routerFilePath, extraction.name);
2595
3061
  }
2596
3062
  }
2597
- if (basename3) {
2598
- result = applyBasenameToRoutes(result, basename3);
3063
+ if (basename2) {
3064
+ result = applyBasenameToRoutes(result, basename2);
2599
3065
  }
2600
3066
  return result;
2601
3067
  }
@@ -2610,7 +3076,7 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
2610
3076
  if (existsSync3(oldCombinedPath)) {
2611
3077
  unlinkSync(oldCombinedPath);
2612
3078
  console.log(
2613
- `[rsc-router] Removed stale combined route types: ${oldCombinedPath}`
3079
+ `[rango] Removed stale combined route types: ${oldCombinedPath}`
2614
3080
  );
2615
3081
  }
2616
3082
  } catch {
@@ -2632,18 +3098,12 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
2632
3098
  }
2633
3099
  if (!extractUrlsFromRouter(routerSource)) continue;
2634
3100
  }
2635
- const routerBasename = pathBasename(routerFilePath).replace(
2636
- /\.(tsx?|jsx?)$/,
2637
- ""
2638
- );
2639
- const outPath = join(
2640
- dirname2(routerFilePath),
2641
- `${routerBasename}.named-routes.gen.ts`
2642
- );
3101
+ const outPath = genFileTsPath(routerFilePath);
2643
3102
  const existing = existsSync3(outPath) ? readFileSync2(outPath, "utf-8") : null;
2644
3103
  if (Object.keys(result.routes).length === 0) {
2645
3104
  if (!existing) {
2646
3105
  const emptySource = generateRouteTypesSource({});
3106
+ opts?.onWrite?.(outPath, emptySource);
2647
3107
  writeFileSync(outPath, emptySource);
2648
3108
  }
2649
3109
  continue;
@@ -2663,9 +3123,10 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
2663
3123
  continue;
2664
3124
  }
2665
3125
  }
3126
+ opts?.onWrite?.(outPath, source);
2666
3127
  writeFileSync(outPath, source);
2667
3128
  console.log(
2668
- `[rsc-router] Generated route types (${Object.keys(result.routes).length} routes) -> ${outPath}`
3129
+ `[rango] Generated route types (${Object.keys(result.routes).length} routes) -> ${outPath}`
2669
3130
  );
2670
3131
  }
2671
3132
  }
@@ -2682,7 +3143,7 @@ function normalizeModuleId(id) {
2682
3143
  function getClientModuleSignature(source) {
2683
3144
  let program;
2684
3145
  try {
2685
- program = parseAst3(source, { jsx: true });
3146
+ program = parseAst3(source, { lang: "tsx" });
2686
3147
  } catch {
2687
3148
  return void 0;
2688
3149
  }
@@ -2765,11 +3226,12 @@ function createVersionPlugin() {
2765
3226
  let currentVersion = buildVersion;
2766
3227
  let isDev = false;
2767
3228
  let server = null;
3229
+ let resolvedCacheDir;
2768
3230
  const clientModuleSignatures = /* @__PURE__ */ new Map();
2769
3231
  let versionCounter = 0;
2770
3232
  const bumpVersion = (reason) => {
2771
3233
  currentVersion = Date.now().toString(16) + String(++versionCounter);
2772
- console.log(`[rsc-router] ${reason}, version updated: ${currentVersion}`);
3234
+ console.log(`[rango] ${reason}, version updated: ${currentVersion}`);
2773
3235
  const rscEnv = server?.environments?.rsc;
2774
3236
  const versionMod = rscEnv?.moduleGraph?.getModuleById(
2775
3237
  "\0" + VIRTUAL_IDS.version
@@ -2783,6 +3245,7 @@ function createVersionPlugin() {
2783
3245
  enforce: "pre",
2784
3246
  configResolved(config) {
2785
3247
  isDev = config.command === "serve";
3248
+ resolvedCacheDir = config.cacheDir ? String(config.cacheDir).replace(/\\/g, "/") : void 0;
2786
3249
  },
2787
3250
  configureServer(devServer) {
2788
3251
  server = devServer;
@@ -2824,6 +3287,7 @@ function createVersionPlugin() {
2824
3287
  if (!isDev) return;
2825
3288
  const isRscModule = this.environment?.name === "rsc";
2826
3289
  if (!isRscModule) return;
3290
+ if (isViteDepCachePath(ctx.file, resolvedCacheDir)) return;
2827
3291
  if (ctx.modules.length === 1 && ctx.modules[0].id === "\0" + VIRTUAL_IDS.version) {
2828
3292
  return;
2829
3293
  }
@@ -2853,12 +3317,24 @@ function createVersionPlugin() {
2853
3317
  }
2854
3318
  };
2855
3319
  }
3320
+ function isViteDepCachePath(filePath, cacheDir) {
3321
+ if (!filePath) return false;
3322
+ const normalized = filePath.replace(/\\/g, "/");
3323
+ if (cacheDir) {
3324
+ const normalizedCacheDir = cacheDir.replace(/\\/g, "/").replace(/\/+$/, "");
3325
+ if (normalized === normalizedCacheDir || normalized.startsWith(normalizedCacheDir + "/")) {
3326
+ return true;
3327
+ }
3328
+ }
3329
+ return /\/node_modules\/\.vite[^/]*\//.test(normalized) || normalized.includes("/.vite-isolated/");
3330
+ }
2856
3331
 
2857
3332
  // src/vite/utils/shared-utils.ts
2858
3333
  import * as Vite from "vite";
2859
3334
 
2860
3335
  // src/vite/plugins/performance-tracks.ts
2861
3336
  import { readFile } from "node:fs/promises";
3337
+ var debug6 = createRangoDebugger(NS.transform);
2862
3338
  var RSDW_PATCH_RE = /((?:var|let|const)\s+\w+\s*=\s*root\._children\s*,\s*(\w+)\s*=\s*root\._debugInfo\s*[;,])/;
2863
3339
  function buildPatchReplacement(match, debugInfoVar) {
2864
3340
  return `${match}
@@ -2880,62 +3356,65 @@ function patchRsdwClientDebugInfoRecovery(code) {
2880
3356
  };
2881
3357
  }
2882
3358
  function performanceTracksOptimizeDepsPlugin() {
3359
+ const RSDW_CLIENT_RE = /react-server-dom-webpack-client\.browser\.(development|production)\.js$/;
2883
3360
  return {
2884
3361
  name: "@rangojs/router:performance-tracks-optimize-deps",
2885
- setup(build) {
2886
- build.onLoad(
2887
- {
2888
- filter: /react-server-dom-webpack-client\.browser\.(development|production)\.js$/
2889
- },
2890
- async (args) => {
2891
- const code = await readFile(args.path, "utf8");
2892
- const patched = patchRsdwClientDebugInfoRecovery(code);
2893
- return {
2894
- contents: patched.code,
2895
- loader: "js"
2896
- };
2897
- }
2898
- );
3362
+ // Vite 8 optimizes deps with Rolldown (Rollup-style plugin pipeline), so the
3363
+ // pre-bundled RSDW client is patched via load() rather than esbuild's onLoad.
3364
+ // Returning code overrides Rolldown's default filesystem read for the module.
3365
+ async load(id) {
3366
+ const cleanId = id.split("?")[0] ?? id;
3367
+ if (!RSDW_CLIENT_RE.test(cleanId)) return null;
3368
+ const code = await readFile(cleanId, "utf8");
3369
+ const patched = patchRsdwClientDebugInfoRecovery(code);
3370
+ return { code: patched.code };
2899
3371
  }
2900
3372
  };
2901
3373
  }
2902
3374
  function performanceTracksPlugin() {
3375
+ const counter = createCounter(debug6, "performance-tracks");
2903
3376
  return {
2904
3377
  name: "@rangojs/router:performance-tracks",
3378
+ buildEnd() {
3379
+ counter?.flush();
3380
+ },
2905
3381
  transform(code, id) {
2906
3382
  if (!id.includes("react-server-dom") || !id.includes("client")) return;
2907
- const patched = patchRsdwClientDebugInfoRecovery(code);
2908
- if (!patched.debugInfoVar) return;
2909
- if (process.env.INTERNAL_RANGO_DEBUG)
2910
- console.log(
2911
- "[perf-tracks] patched RSDW client (var:",
2912
- patched.debugInfoVar,
2913
- ")"
2914
- );
2915
- return patched.code;
3383
+ const start = counter ? performance.now() : 0;
3384
+ try {
3385
+ const patched = patchRsdwClientDebugInfoRecovery(code);
3386
+ if (!patched.debugInfoVar) return;
3387
+ debug6?.("patched RSDW client (var: %s)", patched.debugInfoVar);
3388
+ return patched.code;
3389
+ } finally {
3390
+ counter?.record(id, performance.now() - start);
3391
+ }
2916
3392
  }
2917
3393
  };
2918
3394
  }
2919
3395
 
2920
3396
  // src/vite/utils/shared-utils.ts
2921
- var versionEsbuildPlugin = {
3397
+ function resolveRscEntryFromConfig(config) {
3398
+ const entries = config.environments?.["rsc"]?.optimizeDeps?.entries;
3399
+ if (typeof entries === "string") return entries;
3400
+ if (Array.isArray(entries) && entries.length > 0) return entries[0];
3401
+ return void 0;
3402
+ }
3403
+ var versionRolldownPlugin = {
2922
3404
  name: "@rangojs/router-version",
2923
- setup(build) {
2924
- build.onResolve({ filter: /^rsc-router:version$/ }, (args) => ({
2925
- path: args.path,
2926
- namespace: "@rangojs/router-virtual"
2927
- }));
2928
- build.onLoad(
2929
- { filter: /.*/, namespace: "@rangojs/router-virtual" },
2930
- () => ({
2931
- contents: `export const VERSION = "dev";`,
2932
- loader: "js"
2933
- })
2934
- );
3405
+ resolveId(id) {
3406
+ if (id === VIRTUAL_IDS.version) return "\0" + VIRTUAL_IDS.version;
3407
+ return void 0;
3408
+ },
3409
+ load(id) {
3410
+ if (id === "\0" + VIRTUAL_IDS.version) {
3411
+ return getVirtualVersionContent("dev");
3412
+ }
3413
+ return void 0;
2935
3414
  }
2936
3415
  };
2937
- var sharedEsbuildOptions = {
2938
- plugins: [versionEsbuildPlugin, performanceTracksOptimizeDepsPlugin()]
3416
+ var sharedRolldownOptions = {
3417
+ plugins: [versionRolldownPlugin, performanceTracksOptimizeDepsPlugin()]
2939
3418
  };
2940
3419
  function createVirtualEntriesPlugin(entries, routerPathRef) {
2941
3420
  const virtualModules = {};
@@ -2977,8 +3456,29 @@ function createVirtualEntriesPlugin(entries, routerPathRef) {
2977
3456
  }
2978
3457
  };
2979
3458
  }
3459
+ function isContentHashedAssetConflict(message) {
3460
+ if (!message) return false;
3461
+ const match = /The emitted file "?([^"\s]+)"? overwrites a previously emitted file/.exec(
3462
+ message
3463
+ );
3464
+ if (!match) return false;
3465
+ const fileName = match[1];
3466
+ const base = fileName.slice(fileName.lastIndexOf("/") + 1);
3467
+ const dot = base.lastIndexOf(".");
3468
+ if (dot <= 0) return false;
3469
+ const stem = base.slice(0, dot);
3470
+ const HASH_LEN = 8;
3471
+ if (stem.length < HASH_LEN + 1 || stem[stem.length - HASH_LEN - 1] !== "-") {
3472
+ return false;
3473
+ }
3474
+ const hash = stem.slice(-HASH_LEN);
3475
+ return /^[A-Za-z0-9_-]+$/.test(hash) && /[A-Z0-9]/.test(hash);
3476
+ }
2980
3477
  function onwarn(warning, defaultHandler) {
2981
- if (warning.code === "MODULE_LEVEL_DIRECTIVE" || warning.code === "SOURCEMAP_ERROR" || warning.code === "EMPTY_BUNDLE") {
3478
+ if (warning.code === "MODULE_LEVEL_DIRECTIVE" || warning.code === "SOURCEMAP_ERROR" || warning.code === "EMPTY_BUNDLE" || warning.code === "INEFFECTIVE_DYNAMIC_IMPORT") {
3479
+ return;
3480
+ }
3481
+ if (warning.code === "FILE_NAME_CONFLICT" && isContentHashedAssetConflict(warning.message)) {
2982
3482
  return;
2983
3483
  }
2984
3484
  if (warning.message?.includes("Sourcemap is likely to be incorrect")) {
@@ -2997,12 +3497,138 @@ function getManualChunks(id) {
2997
3497
  return "react";
2998
3498
  }
2999
3499
  const packageName = getPublishedPackageName();
3000
- if (normalized.includes(`node_modules/${packageName}/`) || normalized.includes("packages/rsc-router/") || normalized.includes("packages/rangojs-router/")) {
3500
+ if (normalized.includes(`node_modules/${packageName}/`) || /\/packages\/(rsc-router|rangojs-router)\/(src|dist)\//.test(normalized)) {
3001
3501
  return "router";
3002
3502
  }
3003
3503
  return void 0;
3004
3504
  }
3005
3505
 
3506
+ // src/vite/plugins/client-ref-hashing.ts
3507
+ import { relative } from "node:path";
3508
+ import { createHash as createHash2 } from "node:crypto";
3509
+ var debug7 = createRangoDebugger(NS.transform);
3510
+ var CLIENT_PKG_PROXY_PREFIX = "/@id/__x00__virtual:vite-rsc/client-package-proxy/";
3511
+ var CLIENT_IN_SERVER_PKG_PROXY_PREFIX = "/@id/__x00__virtual:vite-rsc/client-in-server-package-proxy/";
3512
+ var FS_PREFIX = "/@fs/";
3513
+ function hashRefKey(relativeId) {
3514
+ return createHash2("sha256").update(relativeId).digest("hex").slice(0, 12);
3515
+ }
3516
+ function computeProductionHash(projectRoot, refKey) {
3517
+ let toHash;
3518
+ if (refKey.startsWith(CLIENT_PKG_PROXY_PREFIX)) {
3519
+ toHash = refKey.slice(CLIENT_PKG_PROXY_PREFIX.length);
3520
+ } else if (refKey.startsWith(CLIENT_IN_SERVER_PKG_PROXY_PREFIX)) {
3521
+ const absPath = decodeURIComponent(
3522
+ refKey.slice(CLIENT_IN_SERVER_PKG_PROXY_PREFIX.length)
3523
+ );
3524
+ toHash = relative(projectRoot, absPath).replaceAll("\\", "/");
3525
+ } else if (refKey.startsWith(FS_PREFIX)) {
3526
+ const absPath = refKey.slice(FS_PREFIX.length - 1);
3527
+ toHash = relative(projectRoot, absPath).replaceAll("\\", "/");
3528
+ } else if (refKey.startsWith("/")) {
3529
+ toHash = refKey.slice(1);
3530
+ } else {
3531
+ return refKey;
3532
+ }
3533
+ return hashRefKey(toHash);
3534
+ }
3535
+ var REGISTER_CLIENT_REF_RE = /registerClientReference\(\s*(?:(?:\([^)]*\))|(?:\(\)[\s\S]*?\}))\s*,\s*"([^"]+)"\s*,\s*"[^"]+"\s*\)/g;
3536
+ function transformClientRefs(code, projectRoot) {
3537
+ if (!code.includes("registerClientReference")) return null;
3538
+ let hasReplacement = false;
3539
+ const result = code.replace(
3540
+ REGISTER_CLIENT_REF_RE,
3541
+ (match, refKey) => {
3542
+ const hash = computeProductionHash(projectRoot, refKey);
3543
+ if (hash === refKey) return match;
3544
+ hasReplacement = true;
3545
+ return match.replace(`"${refKey}"`, `"${hash}"`);
3546
+ }
3547
+ );
3548
+ return hasReplacement ? result : null;
3549
+ }
3550
+ function hashClientRefs(projectRoot) {
3551
+ const counter = createCounter(debug7, "hash-client-refs");
3552
+ return {
3553
+ name: "@rangojs/router:hash-client-refs",
3554
+ // Run after the RSC plugin's transform (default enforce is normal)
3555
+ enforce: "post",
3556
+ applyToEnvironment(env) {
3557
+ return env.name === "rsc";
3558
+ },
3559
+ buildEnd() {
3560
+ counter?.flush();
3561
+ },
3562
+ transform(code, id) {
3563
+ const start = counter ? performance.now() : 0;
3564
+ try {
3565
+ const result = transformClientRefs(code, projectRoot);
3566
+ if (result === null) return;
3567
+ return { code: result, map: null };
3568
+ } finally {
3569
+ counter?.record(id, performance.now() - start);
3570
+ }
3571
+ }
3572
+ };
3573
+ }
3574
+
3575
+ // src/vite/utils/client-chunks.ts
3576
+ var debugChunks = createRangoDebugger(NS.chunks);
3577
+ function isSharedRuntime(meta) {
3578
+ return [meta.id, meta.normalizedId].some(
3579
+ (path6) => path6.includes("/node_modules/") || /\/@rangojs\/router\//.test(path6) || /\/packages\/(rangojs-router|rsc-router)\/(src|dist)\//.test(path6)
3580
+ );
3581
+ }
3582
+ function sanitizeGroup(name) {
3583
+ return name.replace(/[^a-zA-Z0-9_-]+/g, "_").replace(/^_+|_+$/g, "") || "app";
3584
+ }
3585
+ var ROUTE_ROOT_DIRS = /* @__PURE__ */ new Set([
3586
+ "routes",
3587
+ "route",
3588
+ "pages",
3589
+ "page",
3590
+ "app",
3591
+ "features",
3592
+ "feature",
3593
+ "views",
3594
+ "view",
3595
+ "handlers",
3596
+ "urls",
3597
+ "modules",
3598
+ "screens",
3599
+ "sections"
3600
+ ]);
3601
+ function directoryClientChunks(meta, ctx) {
3602
+ if (isSharedRuntime(meta)) {
3603
+ return void 0;
3604
+ }
3605
+ if (ctx?.fallbackRefs.size && ctx.fallbackRefs.has(hashRefKey(meta.normalizedId))) {
3606
+ debugChunks?.("fallback %s -> app-fallback", meta.normalizedId);
3607
+ return "app-fallback";
3608
+ }
3609
+ const segments = meta.normalizedId.split("/").filter(Boolean);
3610
+ const dirCount = segments.length - 1;
3611
+ if (dirCount >= 1) {
3612
+ for (let i = 0; i < dirCount - 1; i++) {
3613
+ if (ROUTE_ROOT_DIRS.has(segments[i].toLowerCase())) {
3614
+ const group = `app-${sanitizeGroup(segments[i + 1])}`;
3615
+ debugChunks?.("split %s -> %s", meta.normalizedId, group);
3616
+ return group;
3617
+ }
3618
+ }
3619
+ }
3620
+ debugChunks?.(
3621
+ "shared %s (no route-root marker; inherits default grouping)",
3622
+ meta.normalizedId
3623
+ );
3624
+ return void 0;
3625
+ }
3626
+ function resolveClientChunks(option, ctx) {
3627
+ if (!option) return void 0;
3628
+ if (option === true) return (meta) => directoryClientChunks(meta, ctx);
3629
+ return option;
3630
+ }
3631
+
3006
3632
  // src/vite/utils/banner.ts
3007
3633
  var rangoVersion = package_default.version;
3008
3634
  var _bannerPrinted = false;
@@ -3039,15 +3665,7 @@ function createVersionInjectorPlugin(rscEntryPath) {
3039
3665
  enforce: "pre",
3040
3666
  configResolved(config) {
3041
3667
  let entryPath = rscEntryPath;
3042
- if (!entryPath) {
3043
- const rscEnvConfig = config.environments?.["rsc"];
3044
- const entries = rscEnvConfig?.optimizeDeps?.entries;
3045
- if (typeof entries === "string") {
3046
- entryPath = entries;
3047
- } else if (Array.isArray(entries) && entries.length > 0) {
3048
- entryPath = entries[0];
3049
- }
3050
- }
3668
+ if (!entryPath) entryPath = resolveRscEntryFromConfig(config);
3051
3669
  if (entryPath) {
3052
3670
  resolvedEntryPath = resolve4(config.root, entryPath);
3053
3671
  }
@@ -3059,11 +3677,10 @@ function createVersionInjectorPlugin(rscEntryPath) {
3059
3677
  if (normalizedId !== normalizedEntry) {
3060
3678
  return null;
3061
3679
  }
3062
- const prepend = [];
3680
+ const prepend = [
3681
+ `import "virtual:rsc-router/routes-manifest";`
3682
+ ];
3063
3683
  let newCode = code;
3064
- if (!code.includes("virtual:rsc-router/routes-manifest")) {
3065
- prepend.push(`import "virtual:rsc-router/routes-manifest";`);
3066
- }
3067
3684
  const needsVersion = code.includes("createRSCHandler") && !code.includes("@rangojs/router:version") && /createRSCHandler\s*\(\s*\{/.test(code);
3068
3685
  if (needsVersion) {
3069
3686
  prepend.push(`import { VERSION } from "@rangojs/router:version";`);
@@ -3072,8 +3689,21 @@ function createVersionInjectorPlugin(rscEntryPath) {
3072
3689
  "createRSCHandler({\n version: VERSION,"
3073
3690
  );
3074
3691
  }
3075
- if (prepend.length === 0 && newCode === code) return null;
3076
- newCode = prepend.join("\n") + (prepend.length > 0 ? "\n" : "") + newCode;
3692
+ const lines = newCode.split("\n");
3693
+ let insertAt = 0;
3694
+ while (insertAt < lines.length) {
3695
+ const trimmed = lines[insertAt].trim();
3696
+ if (trimmed === "" || /^\/\/\/\s*<reference\b/.test(trimmed)) {
3697
+ insertAt++;
3698
+ } else {
3699
+ break;
3700
+ }
3701
+ }
3702
+ newCode = [
3703
+ ...lines.slice(0, insertAt),
3704
+ ...prepend,
3705
+ ...lines.slice(insertAt)
3706
+ ].join("\n");
3077
3707
  return {
3078
3708
  code: newCode,
3079
3709
  map: null
@@ -3083,21 +3713,23 @@ function createVersionInjectorPlugin(rscEntryPath) {
3083
3713
  }
3084
3714
 
3085
3715
  // src/vite/plugins/cjs-to-esm.ts
3716
+ var debug8 = createRangoDebugger(NS.transform);
3086
3717
  function createCjsToEsmPlugin() {
3087
3718
  return {
3088
3719
  name: "@rangojs/router:cjs-to-esm",
3089
3720
  enforce: "pre",
3090
3721
  transform(code, id) {
3091
- const cleanId = id.split("?")[0];
3092
- if (cleanId.includes("vendor/react-server-dom/client.browser.js") || cleanId.includes("vendor\\react-server-dom\\client.browser.js")) {
3722
+ const cleanId = id.split("?")[0].replaceAll("\\", "/");
3723
+ if (cleanId.includes("vendor/react-server-dom/client.browser.js")) {
3093
3724
  const isProd = process.env.NODE_ENV === "production";
3094
3725
  const cjsFile = isProd ? "./cjs/react-server-dom-webpack-client.browser.production.js" : "./cjs/react-server-dom-webpack-client.browser.development.js";
3726
+ debug8?.("cjs-to-esm entry redirect %s", id);
3095
3727
  return {
3096
3728
  code: `export * from "${cjsFile}";`,
3097
3729
  map: null
3098
3730
  };
3099
3731
  }
3100
- if ((cleanId.includes("vendor/react-server-dom/cjs/") || cleanId.includes("vendor\\react-server-dom\\cjs\\")) && cleanId.includes("client.browser")) {
3732
+ if (cleanId.includes("vendor/react-server-dom/cjs/") && cleanId.includes("client.browser")) {
3101
3733
  let transformed = code;
3102
3734
  const licenseMatch = transformed.match(/^\/\*\*[\s\S]*?\*\//);
3103
3735
  const license = licenseMatch ? licenseMatch[0] : "";
@@ -3127,6 +3759,7 @@ function createCjsToEsmPlugin() {
3127
3759
  "export const $1 ="
3128
3760
  );
3129
3761
  transformed = license + "\n" + transformed;
3762
+ debug8?.("cjs-to-esm body rewrite %s", id);
3130
3763
  return {
3131
3764
  code: transformed,
3132
3765
  map: null
@@ -3141,7 +3774,7 @@ function createCjsToEsmPlugin() {
3141
3774
  import { createServer as createViteServer } from "vite";
3142
3775
  import { resolve as resolve8 } from "node:path";
3143
3776
  import { readFileSync as readFileSync6 } from "node:fs";
3144
- import { createRequire } from "node:module";
3777
+ import { createRequire as createRequire2, register } from "node:module";
3145
3778
  import { pathToFileURL } from "node:url";
3146
3779
 
3147
3780
  // src/vite/plugins/virtual-stub-plugin.ts
@@ -3168,61 +3801,112 @@ function createVirtualStubPlugin() {
3168
3801
  };
3169
3802
  }
3170
3803
 
3171
- // src/vite/plugins/client-ref-hashing.ts
3172
- import { relative } from "node:path";
3173
- import { createHash as createHash2 } from "node:crypto";
3174
- var CLIENT_PKG_PROXY_PREFIX = "/@id/__x00__virtual:vite-rsc/client-package-proxy/";
3175
- var CLIENT_IN_SERVER_PKG_PROXY_PREFIX = "/@id/__x00__virtual:vite-rsc/client-in-server-package-proxy/";
3176
- var FS_PREFIX = "/@fs/";
3177
- function computeProductionHash(projectRoot, refKey) {
3178
- let toHash;
3179
- if (refKey.startsWith(CLIENT_PKG_PROXY_PREFIX)) {
3180
- toHash = refKey.slice(CLIENT_PKG_PROXY_PREFIX.length);
3181
- } else if (refKey.startsWith(CLIENT_IN_SERVER_PKG_PROXY_PREFIX)) {
3182
- const absPath = decodeURIComponent(
3183
- refKey.slice(CLIENT_IN_SERVER_PKG_PROXY_PREFIX.length)
3184
- );
3185
- toHash = relative(projectRoot, absPath).replaceAll("\\", "/");
3186
- } else if (refKey.startsWith(FS_PREFIX)) {
3187
- const absPath = refKey.slice(FS_PREFIX.length - 1);
3188
- toHash = relative(projectRoot, absPath).replaceAll("\\", "/");
3189
- } else if (refKey.startsWith("/")) {
3190
- toHash = refKey.slice(1);
3191
- } else {
3192
- return refKey;
3193
- }
3194
- return createHash2("sha256").update(toHash).digest("hex").slice(0, 12);
3195
- }
3196
- var REGISTER_CLIENT_REF_RE = /registerClientReference\(\s*(?:(?:\([^)]*\))|(?:\(\)[\s\S]*?\}))\s*,\s*"([^"]+)"\s*,\s*"[^"]+"\s*\)/g;
3197
- function transformClientRefs(code, projectRoot) {
3198
- if (!code.includes("registerClientReference")) return null;
3199
- let hasReplacement = false;
3200
- const result = code.replace(
3201
- REGISTER_CLIENT_REF_RE,
3202
- (match, refKey) => {
3203
- const hash = computeProductionHash(projectRoot, refKey);
3204
- if (hash === refKey) return match;
3205
- hasReplacement = true;
3206
- return match.replace(`"${refKey}"`, `"${hash}"`);
3207
- }
3208
- );
3209
- return hasReplacement ? result : null;
3210
- }
3211
- function hashClientRefs(projectRoot) {
3804
+ // src/vite/plugins/cloudflare-protocol-stub.ts
3805
+ var VIRTUAL_PREFIX = "virtual:rango-cloudflare-stub-";
3806
+ var NULL_PREFIX = "\0" + VIRTUAL_PREFIX;
3807
+ var CF_PREFIX = "cloudflare:";
3808
+ var BUILD_ENV_GLOBAL_KEY = "__rango_build_env__";
3809
+ var SOURCE_EXT_RE = /\.[mc]?[jt]sx?$/;
3810
+ var IMPORT_NODE_TYPES = /* @__PURE__ */ new Set([
3811
+ "ImportDeclaration",
3812
+ "ImportExpression",
3813
+ "ExportNamedDeclaration",
3814
+ "ExportAllDeclaration"
3815
+ ]);
3816
+ var STUBS = {
3817
+ "cloudflare:workers": `
3818
+ export class DurableObject { constructor(_ctx, _env) {} }
3819
+ export class WorkerEntrypoint { constructor(_ctx, _env) {} }
3820
+ export class WorkflowEntrypoint { constructor(_ctx, _env) {} }
3821
+ export class RpcTarget {}
3822
+ export const env = globalThis[${JSON.stringify(BUILD_ENV_GLOBAL_KEY)}] ?? {};
3823
+ export default {};
3824
+ `,
3825
+ "cloudflare:email": `
3826
+ export class EmailMessage { constructor(_from, _to, _raw) {} }
3827
+ export default {};
3828
+ `,
3829
+ "cloudflare:sockets": `
3830
+ export function connect() { return {}; }
3831
+ export default {};
3832
+ `,
3833
+ "cloudflare:workflows": `
3834
+ export class NonRetryableError extends Error {
3835
+ constructor(message, name) { super(message); this.name = name ?? "NonRetryableError"; }
3836
+ }
3837
+ export default {};
3838
+ `
3839
+ };
3840
+ var FALLBACK_STUB = `export default {};
3841
+ `;
3842
+ function createCloudflareProtocolStubPlugin() {
3212
3843
  return {
3213
- name: "@rangojs/router:hash-client-refs",
3214
- // Run after the RSC plugin's transform (default enforce is normal)
3215
- enforce: "post",
3216
- applyToEnvironment(env) {
3217
- return env.name === "rsc";
3844
+ name: "@rangojs/router:cloudflare-protocol-stub",
3845
+ transform(code, id) {
3846
+ const cleanId = id.split("?")[0] ?? id;
3847
+ if (!SOURCE_EXT_RE.test(cleanId)) return null;
3848
+ if (!code.includes(CF_PREFIX)) return null;
3849
+ let ast;
3850
+ try {
3851
+ ast = this.parse(code, { lang: "tsx" });
3852
+ } catch {
3853
+ return null;
3854
+ }
3855
+ const hits = [];
3856
+ walk(ast, (node) => {
3857
+ if (!IMPORT_NODE_TYPES.has(node.type)) return;
3858
+ const source = node.source;
3859
+ if (!source || source.type !== "Literal") return;
3860
+ if (typeof source.value !== "string") return;
3861
+ if (!source.value.startsWith(CF_PREFIX)) return;
3862
+ if (typeof source.start !== "number" || typeof source.end !== "number")
3863
+ return;
3864
+ hits.push({
3865
+ start: source.start,
3866
+ end: source.end,
3867
+ value: source.value
3868
+ });
3869
+ });
3870
+ if (hits.length === 0) return null;
3871
+ hits.sort((a, b) => b.start - a.start);
3872
+ let out = code;
3873
+ for (const hit of hits) {
3874
+ const submodule = hit.value.slice(CF_PREFIX.length);
3875
+ const quote = code[hit.start] === "'" ? "'" : '"';
3876
+ out = out.slice(0, hit.start) + quote + VIRTUAL_PREFIX + submodule + quote + out.slice(hit.end);
3877
+ }
3878
+ return { code: out, map: null };
3879
+ },
3880
+ resolveId(id) {
3881
+ if (id.startsWith(VIRTUAL_PREFIX)) {
3882
+ return "\0" + id;
3883
+ }
3884
+ return null;
3218
3885
  },
3219
- transform(code, _id) {
3220
- const result = transformClientRefs(code, projectRoot);
3221
- if (result === null) return;
3222
- return { code: result, map: null };
3886
+ load(id) {
3887
+ if (!id.startsWith(NULL_PREFIX)) return null;
3888
+ const submodule = id.slice(NULL_PREFIX.length);
3889
+ const specifier = CF_PREFIX + submodule;
3890
+ return STUBS[specifier] ?? FALLBACK_STUB;
3223
3891
  }
3224
3892
  };
3225
3893
  }
3894
+ function walk(node, visit) {
3895
+ if (!node || typeof node !== "object") return;
3896
+ if (Array.isArray(node)) {
3897
+ for (const child of node) walk(child, visit);
3898
+ return;
3899
+ }
3900
+ const n = node;
3901
+ if (typeof n.type !== "string") return;
3902
+ visit(n);
3903
+ for (const key in n) {
3904
+ if (key === "loc" || key === "start" || key === "end" || key === "range") {
3905
+ continue;
3906
+ }
3907
+ walk(n[key], visit);
3908
+ }
3909
+ }
3226
3910
 
3227
3911
  // src/vite/utils/bundle-analysis.ts
3228
3912
  function findMatchingParenInBundle(code, openParenPos) {
@@ -3254,7 +3938,7 @@ function extractHandlerExportsFromChunk(chunkCode, handlerModules, fnName, detec
3254
3938
  if (detectPassthrough) {
3255
3939
  const eFnName = escapeRegExp(fnName);
3256
3940
  const callStartRe = new RegExp(
3257
- `const\\s+${eName}\\s*=\\s*${eFnName}\\s*(?:<[^>]*>)?\\s*\\(`
3941
+ `(?:const|let|var)\\s+${eName}\\s*=\\s*${eFnName}\\s*(?:<[^>]*>)?\\s*\\(`
3258
3942
  );
3259
3943
  const callStart = callStartRe.exec(chunkCode);
3260
3944
  if (callStart) {
@@ -3279,7 +3963,7 @@ function evictHandlerCode(code, exports, fnName, brand) {
3279
3963
  if (passthrough) continue;
3280
3964
  const eName = escapeRegExp(name);
3281
3965
  const callStartRe = new RegExp(
3282
- `const\\s+${eName}\\s*=\\s*${eFnName}\\s*(?:<[^>]*>)?\\s*\\(`
3966
+ `(?:const|let|var)\\s+${eName}\\s*=\\s*${eFnName}\\s*(?:<[^>]*>)?\\s*\\(`
3283
3967
  );
3284
3968
  const startMatch = callStartRe.exec(modified);
3285
3969
  if (!startMatch) continue;
@@ -3314,6 +3998,8 @@ function createDiscoveryState(entryPath, opts) {
3314
3998
  projectRoot: "",
3315
3999
  isBuildMode: false,
3316
4000
  userResolveAlias: void 0,
4001
+ userRunnerConfig: void 0,
4002
+ userResolvePlugins: [],
3317
4003
  scanFilter: void 0,
3318
4004
  cachedRouterFiles: void 0,
3319
4005
  opts,
@@ -3335,7 +4021,8 @@ function createDiscoveryState(entryPath, opts) {
3335
4021
  devServerOrigin: null,
3336
4022
  devServer: null,
3337
4023
  selfWrittenGenFiles: /* @__PURE__ */ new Map(),
3338
- SELF_WRITE_WINDOW_MS: 5e3
4024
+ SELF_WRITE_WINDOW_MS: 5e3,
4025
+ lastDiscoveryError: null
3339
4026
  };
3340
4027
  }
3341
4028
 
@@ -3347,6 +4034,12 @@ function markSelfGenWrite(state, filePath, content) {
3347
4034
  state.selfWrittenGenFiles.set(filePath, { at: Date.now(), hash });
3348
4035
  }
3349
4036
  function consumeSelfGenWrite(state, filePath) {
4037
+ return checkSelfGenWrite(state, filePath, true);
4038
+ }
4039
+ function peekSelfGenWrite(state, filePath) {
4040
+ return checkSelfGenWrite(state, filePath, false);
4041
+ }
4042
+ function checkSelfGenWrite(state, filePath, consume) {
3350
4043
  const info = state.selfWrittenGenFiles.get(filePath);
3351
4044
  if (!info) return false;
3352
4045
  if (Date.now() - info.at > state.SELF_WRITE_WINDOW_MS) {
@@ -3357,7 +4050,7 @@ function consumeSelfGenWrite(state, filePath) {
3357
4050
  const current = readFileSync3(filePath, "utf-8");
3358
4051
  const currentHash = createHash3("sha256").update(current).digest("hex");
3359
4052
  if (currentHash === info.hash) {
3360
- state.selfWrittenGenFiles.delete(filePath);
4053
+ if (consume) state.selfWrittenGenFiles.delete(filePath);
3361
4054
  return true;
3362
4055
  }
3363
4056
  return false;
@@ -3369,9 +4062,12 @@ function consumeSelfGenWrite(state, filePath) {
3369
4062
 
3370
4063
  // src/vite/utils/manifest-utils.ts
3371
4064
  function flattenLeafEntries(prefixTree, routeManifest, result) {
3372
- function visit(node) {
4065
+ function visit(node, ancestorStaticPrefixes) {
3373
4066
  const children = node.children || {};
3374
4067
  if (Object.keys(children).length === 0 && node.routes && node.routes.length > 0) {
4068
+ if (ancestorStaticPrefixes.has(node.staticPrefix)) {
4069
+ return;
4070
+ }
3375
4071
  const routes = {};
3376
4072
  for (const name of node.routes) {
3377
4073
  if (name in routeManifest) {
@@ -3380,13 +4076,15 @@ function flattenLeafEntries(prefixTree, routeManifest, result) {
3380
4076
  }
3381
4077
  result.push({ staticPrefix: node.staticPrefix, routes });
3382
4078
  } else {
4079
+ const nextAncestors = new Set(ancestorStaticPrefixes);
4080
+ nextAncestors.add(node.staticPrefix);
3383
4081
  for (const child of Object.values(children)) {
3384
- visit(child);
4082
+ visit(child, nextAncestors);
3385
4083
  }
3386
4084
  }
3387
4085
  }
3388
4086
  for (const node of Object.values(prefixTree)) {
3389
- visit(node);
4087
+ visit(node, /* @__PURE__ */ new Set());
3390
4088
  }
3391
4089
  }
3392
4090
  function buildRouteToStaticPrefix(prefixTree, result) {
@@ -3461,11 +4159,19 @@ function substituteRouteParams(pattern, params, encode = encodeURIComponent) {
3461
4159
  let hadOmittedOptional = false;
3462
4160
  for (const [key, value] of Object.entries(params)) {
3463
4161
  const escaped = escapeRegExp2(key);
3464
- result = result.replace(
3465
- new RegExp(`:${escaped}(\\([^)]*\\))?\\??`),
3466
- encode(value)
3467
- );
3468
- result = result.replace(`*${key}`, encode(value));
4162
+ if (value === "") {
4163
+ result = result.replace(
4164
+ new RegExp(`:${escaped}(\\([^)]*\\))?(?!\\?)`),
4165
+ ""
4166
+ );
4167
+ result = result.replace(`*${key}`, "");
4168
+ } else {
4169
+ result = result.replace(
4170
+ new RegExp(`:${escaped}(\\([^)]*\\))?\\??`),
4171
+ encode(value)
4172
+ );
4173
+ result = result.replace(`*${key}`, encode(value));
4174
+ }
3469
4175
  }
3470
4176
  result = result.replace(/:([a-zA-Z_][a-zA-Z0-9_]*)(\([^)]*\))?\?/g, () => {
3471
4177
  hadOmittedOptional = true;
@@ -3571,8 +4277,14 @@ function copyStagedBuildAssets(projectRoot, fileNames) {
3571
4277
  }
3572
4278
 
3573
4279
  // src/vite/discovery/prerender-collection.ts
4280
+ var debug9 = createRangoDebugger(NS.prerender);
3574
4281
  async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
3575
4282
  if (!state.opts?.enableBuildPrerender || !state.isBuildMode) return;
4283
+ const overallStart = debug9 ? performance.now() : 0;
4284
+ debug9?.(
4285
+ "expandPrerenderRoutes: start (%d router manifest(s))",
4286
+ allManifests.length
4287
+ );
3576
4288
  const entries = [];
3577
4289
  const allRoutes = {};
3578
4290
  for (const { manifest: m } of allManifests) {
@@ -3584,99 +4296,150 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
3584
4296
  if (!params) return pattern;
3585
4297
  return substituteRouteParams(pattern, params);
3586
4298
  };
4299
+ let resolvedRoutes = 0;
4300
+ let totalDynamic = 0;
3587
4301
  for (const { manifest } of allManifests) {
3588
4302
  if (!manifest.prerenderRoutes) continue;
3589
- const defs = manifest._prerenderDefs || {};
3590
- const passthroughSet = new Set(manifest.passthroughRoutes || []);
3591
4303
  for (const routeName of manifest.prerenderRoutes) {
3592
4304
  const pattern = manifest.routeManifest[routeName];
3593
- if (!pattern) continue;
3594
- const def = defs[routeName];
3595
- const isPassthroughRoute = passthroughSet.has(routeName);
3596
- const hasDynamic = pattern.includes(":") || pattern.includes("*");
3597
- if (!hasDynamic) {
3598
- entries.push({
3599
- urlPath: pattern.replace(/\/$/, "") || "/",
3600
- routeName,
3601
- concurrency: 1,
3602
- isPassthroughRoute
3603
- });
3604
- } else {
3605
- if (def?.getParams) {
3606
- try {
3607
- const buildVars = {};
3608
- const buildEnv = state.resolvedBuildEnv;
3609
- const getParamsCtx = {
3610
- build: true,
3611
- dev: !state.isBuildMode,
3612
- set: ((keyOrVar, value) => {
3613
- contextSet(buildVars, keyOrVar, value);
3614
- }),
3615
- reverse: getParamsReverse,
3616
- get env() {
3617
- if (buildEnv !== void 0) return buildEnv;
3618
- throw new Error(
3619
- "[rsc-router] ctx.env is not available during build-time getParams(). Configure buildEnv in your rango() plugin options to enable build-time env access."
3620
- );
3621
- }
3622
- };
3623
- const paramsList = await def.getParams(getParamsCtx);
3624
- const concurrency = def.options?.concurrency ?? 1;
3625
- const hasBuildVars = Object.keys(buildVars).length > 0 || Object.getOwnPropertySymbols(buildVars).length > 0;
3626
- for (const params of paramsList) {
3627
- let url = substituteRouteParams(
3628
- pattern,
3629
- params,
3630
- encodePathParam
3631
- );
3632
- if (url.includes("*")) {
3633
- const wildcardValue = params["*"] ?? params.splat;
3634
- if (wildcardValue !== void 0) {
3635
- url = url.replace(/\*[^/]*$/, encodePathParam(wildcardValue));
4305
+ if (pattern && (pattern.includes(":") || pattern.includes("*"))) {
4306
+ totalDynamic++;
4307
+ }
4308
+ }
4309
+ }
4310
+ const paramsStart = performance.now();
4311
+ const progressInterval = totalDynamic > 0 ? setInterval(() => {
4312
+ const elapsed = ((performance.now() - paramsStart) / 1e3).toFixed(1);
4313
+ console.log(
4314
+ `[rango] Resolving prerender params... ${resolvedRoutes}/${totalDynamic} routes (${elapsed}s)`
4315
+ );
4316
+ }, 5e3) : void 0;
4317
+ try {
4318
+ for (const { manifest } of allManifests) {
4319
+ if (!manifest.prerenderRoutes) continue;
4320
+ const defs = manifest._prerenderDefs || {};
4321
+ const passthroughSet = new Set(manifest.passthroughRoutes || []);
4322
+ for (const routeName of manifest.prerenderRoutes) {
4323
+ const pattern = manifest.routeManifest[routeName];
4324
+ if (!pattern) continue;
4325
+ const def = defs[routeName];
4326
+ const isPassthroughRoute = passthroughSet.has(routeName);
4327
+ const hasDynamic = pattern.includes(":") || pattern.includes("*");
4328
+ if (!hasDynamic) {
4329
+ entries.push({
4330
+ urlPath: pattern.replace(/\/$/, "") || "/",
4331
+ routeName,
4332
+ concurrency: 1,
4333
+ isPassthroughRoute
4334
+ });
4335
+ } else {
4336
+ if (def?.getParams) {
4337
+ const getParamsStart = debug9 ? performance.now() : 0;
4338
+ try {
4339
+ const buildVars = {};
4340
+ const buildEnv = state.resolvedBuildEnv;
4341
+ const getParamsCtx = {
4342
+ build: true,
4343
+ dev: !state.isBuildMode,
4344
+ set: ((keyOrVar, value) => {
4345
+ contextSet(buildVars, keyOrVar, value);
4346
+ }),
4347
+ reverse: getParamsReverse,
4348
+ get env() {
4349
+ if (buildEnv !== void 0) return buildEnv;
4350
+ throw new Error(
4351
+ "[rango] ctx.env is not available during build-time getParams(). Configure buildEnv in your rango() plugin options to enable build-time env access."
4352
+ );
3636
4353
  }
3637
- }
3638
- entries.push({
3639
- urlPath: url.replace(/\/$/, "") || "/",
4354
+ };
4355
+ const paramsList = await def.getParams(getParamsCtx);
4356
+ debug9?.(
4357
+ "getParams %s -> %d params (%sms)",
3640
4358
  routeName,
3641
- concurrency,
3642
- ...hasBuildVars ? { buildVars } : {},
3643
- isPassthroughRoute
3644
- });
3645
- }
3646
- } catch (err) {
3647
- if (err.name === "Skip") {
3648
- console.log(
3649
- `[rsc-router] SKIP route "${routeName}" - ${err.message}`
4359
+ paramsList.length,
4360
+ (performance.now() - getParamsStart).toFixed(1)
3650
4361
  );
3651
- notifyOnError(
3652
- registry,
3653
- err,
3654
- "prerender",
3655
- routeName,
3656
- void 0,
3657
- true
4362
+ const concurrency = def.options?.concurrency ?? 1;
4363
+ const hasBuildVars = Object.keys(buildVars).length > 0 || Object.getOwnPropertySymbols(buildVars).length > 0;
4364
+ for (const params of paramsList) {
4365
+ let url = substituteRouteParams(
4366
+ pattern,
4367
+ params,
4368
+ encodePathParam
4369
+ );
4370
+ if (url.includes("*")) {
4371
+ const wildcardValue = params["*"] ?? params.splat;
4372
+ if (wildcardValue !== void 0) {
4373
+ url = url.replace(
4374
+ /\*[^/]*$/,
4375
+ encodePathParam(wildcardValue)
4376
+ );
4377
+ }
4378
+ }
4379
+ entries.push({
4380
+ urlPath: url.replace(/\/$/, "") || "/",
4381
+ routeName,
4382
+ concurrency,
4383
+ ...hasBuildVars ? { buildVars } : {},
4384
+ isPassthroughRoute
4385
+ });
4386
+ }
4387
+ resolvedRoutes++;
4388
+ } catch (err) {
4389
+ resolvedRoutes++;
4390
+ if (err.name === "Skip") {
4391
+ console.log(
4392
+ `[rango] SKIP route "${routeName}" - ${err.message}`
4393
+ );
4394
+ notifyOnError(
4395
+ registry,
4396
+ err,
4397
+ "prerender",
4398
+ routeName,
4399
+ void 0,
4400
+ true
4401
+ );
4402
+ continue;
4403
+ }
4404
+ console.error(
4405
+ `[rango] Failed to get params for prerender route "${routeName}": ${err.message}`
3658
4406
  );
3659
- continue;
4407
+ notifyOnError(registry, err, "prerender", routeName);
4408
+ throw err;
3660
4409
  }
3661
- console.error(
3662
- `[rsc-router] Failed to get params for prerender route "${routeName}": ${err.message}`
4410
+ } else {
4411
+ console.warn(
4412
+ `[rango] Dynamic prerender route "${routeName}" has no getParams(), skipping`
3663
4413
  );
3664
- notifyOnError(registry, err, "prerender", routeName);
3665
- throw err;
3666
4414
  }
3667
- } else {
3668
- console.warn(
3669
- `[rsc-router] Dynamic prerender route "${routeName}" has no getParams(), skipping`
3670
- );
3671
4415
  }
3672
4416
  }
3673
4417
  }
4418
+ } finally {
4419
+ if (progressInterval) {
4420
+ clearInterval(progressInterval);
4421
+ const elapsed = ((performance.now() - paramsStart) / 1e3).toFixed(1);
4422
+ console.log(
4423
+ `[rango] Resolved prerender params: ${resolvedRoutes}/${totalDynamic} routes (${elapsed}s)`
4424
+ );
4425
+ }
4426
+ }
4427
+ if (entries.length === 0) {
4428
+ debug9?.(
4429
+ "no prerender entries (done in %sms)",
4430
+ (performance.now() - overallStart).toFixed(1)
4431
+ );
4432
+ return;
3674
4433
  }
3675
- if (entries.length === 0) return;
3676
4434
  const maxConcurrency = Math.max(...entries.map((e) => e.concurrency));
3677
4435
  const concurrencyNote = maxConcurrency > 1 ? ` (concurrency: ${maxConcurrency})` : "";
3678
4436
  console.log(
3679
- `[rsc-router] Pre-rendering ${entries.length} URL(s)${concurrencyNote}...`
4437
+ `[rango] Pre-rendering ${entries.length} URL(s)${concurrencyNote}...`
4438
+ );
4439
+ debug9?.(
4440
+ "prerender loop: %d entries, max concurrency %d",
4441
+ entries.length,
4442
+ maxConcurrency
3680
4443
  );
3681
4444
  const { hashParams } = await rscEnv.runner.import("@rangojs/router/build");
3682
4445
  const manifestEntries = {};
@@ -3704,7 +4467,7 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
3704
4467
  if (result.passthrough) {
3705
4468
  const elapsed2 = (performance.now() - startUrl).toFixed(0);
3706
4469
  console.log(
3707
- `[rsc-router] PASS ${entry.urlPath.padEnd(40)} (${elapsed2}ms) - live fallback`
4470
+ `[rango] PASS ${entry.urlPath.padEnd(40)} (${elapsed2}ms) - live fallback`
3708
4471
  );
3709
4472
  doneCount++;
3710
4473
  break;
@@ -3737,7 +4500,7 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
3737
4500
  }
3738
4501
  const elapsed = (performance.now() - startUrl).toFixed(0);
3739
4502
  console.log(
3740
- `[rsc-router] OK ${entry.urlPath.padEnd(40)} (${elapsed}ms)`
4503
+ `[rango] OK ${entry.urlPath.padEnd(40)} (${elapsed}ms)`
3741
4504
  );
3742
4505
  doneCount++;
3743
4506
  break;
@@ -3745,7 +4508,7 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
3745
4508
  if (err.name === "Skip") {
3746
4509
  const elapsed2 = (performance.now() - startUrl).toFixed(0);
3747
4510
  console.log(
3748
- `[rsc-router] SKIP ${entry.urlPath.padEnd(40)} (${elapsed2}ms) - ${err.message}`
4511
+ `[rango] SKIP ${entry.urlPath.padEnd(40)} (${elapsed2}ms) - ${err.message}`
3749
4512
  );
3750
4513
  skipCount++;
3751
4514
  notifyOnError(
@@ -3760,7 +4523,7 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
3760
4523
  }
3761
4524
  const elapsed = (performance.now() - startUrl).toFixed(0);
3762
4525
  console.error(
3763
- `[rsc-router] FAIL ${entry.urlPath.padEnd(40)} (${elapsed}ms) - ${err.message}`
4526
+ `[rango] FAIL ${entry.urlPath.padEnd(40)} (${elapsed}ms) - ${err.message}`
3764
4527
  );
3765
4528
  notifyOnError(
3766
4529
  registry,
@@ -3782,12 +4545,24 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
3782
4545
  const parts = [`${doneCount} done`];
3783
4546
  if (skipCount > 0) parts.push(`${skipCount} skipped`);
3784
4547
  console.log(
3785
- `[rsc-router] Pre-render complete: ${parts.join(", ")} (${totalElapsed}ms total)`
4548
+ `[rango] Pre-render complete: ${parts.join(", ")} (${totalElapsed}ms total)`
4549
+ );
4550
+ debug9?.(
4551
+ "expandPrerenderRoutes done: %d done, %d skipped, %sms (overall %sms)",
4552
+ doneCount,
4553
+ skipCount,
4554
+ totalElapsed,
4555
+ (performance.now() - overallStart).toFixed(1)
3786
4556
  );
3787
4557
  }
3788
4558
  async function renderStaticHandlers(state, rscEnv, registry) {
3789
4559
  if (!state.opts?.enableBuildPrerender || !state.isBuildMode || !state.resolvedStaticModules?.size)
3790
4560
  return;
4561
+ const overallStart = debug9 ? performance.now() : 0;
4562
+ debug9?.(
4563
+ "renderStaticHandlers: start (%d static module(s))",
4564
+ state.resolvedStaticModules.size
4565
+ );
3791
4566
  const manifestEntries = {};
3792
4567
  let staticDone = 0;
3793
4568
  let staticSkip = 0;
@@ -3796,16 +4571,14 @@ async function renderStaticHandlers(state, rscEnv, registry) {
3796
4571
  totalStaticCount += exportNames.length;
3797
4572
  }
3798
4573
  const startStatic = performance.now();
3799
- console.log(
3800
- `[rsc-router] Rendering ${totalStaticCount} static handler(s)...`
3801
- );
4574
+ console.log(`[rango] Rendering ${totalStaticCount} static handler(s)...`);
3802
4575
  for (const [moduleId, exportNames] of state.resolvedStaticModules) {
3803
4576
  let mod;
3804
4577
  try {
3805
4578
  mod = await rscEnv.runner.import(moduleId);
3806
4579
  } catch (err) {
3807
4580
  console.error(
3808
- `[rsc-router] Failed to import static module ${moduleId}: ${err.message}`
4581
+ `[rango] Failed to import static module ${moduleId}: ${err.message}`
3809
4582
  );
3810
4583
  notifyOnError(registry, err, "static");
3811
4584
  throw err;
@@ -3835,9 +4608,7 @@ async function renderStaticHandlers(state, rscEnv, registry) {
3835
4608
  exportValue
3836
4609
  );
3837
4610
  const elapsed = (performance.now() - startHandler).toFixed(0);
3838
- console.log(
3839
- `[rsc-router] OK ${name.padEnd(40)} (${elapsed}ms)`
3840
- );
4611
+ console.log(`[rango] OK ${name.padEnd(40)} (${elapsed}ms)`);
3841
4612
  staticDone++;
3842
4613
  handled = true;
3843
4614
  break;
@@ -3846,7 +4617,7 @@ async function renderStaticHandlers(state, rscEnv, registry) {
3846
4617
  if (err.name === "Skip") {
3847
4618
  const elapsed2 = (performance.now() - startHandler).toFixed(0);
3848
4619
  console.log(
3849
- `[rsc-router] SKIP ${name.padEnd(40)} (${elapsed2}ms) - ${err.message}`
4620
+ `[rango] SKIP ${name.padEnd(40)} (${elapsed2}ms) - ${err.message}`
3850
4621
  );
3851
4622
  staticSkip++;
3852
4623
  notifyOnError(registry, err, "static", void 0, void 0, true);
@@ -3855,16 +4626,14 @@ async function renderStaticHandlers(state, rscEnv, registry) {
3855
4626
  }
3856
4627
  const elapsed = (performance.now() - startHandler).toFixed(0);
3857
4628
  console.error(
3858
- `[rsc-router] FAIL ${name.padEnd(40)} (${elapsed}ms) - ${err.message}`
4629
+ `[rango] FAIL ${name.padEnd(40)} (${elapsed}ms) - ${err.message}`
3859
4630
  );
3860
4631
  notifyOnError(registry, err, "static");
3861
4632
  throw err;
3862
4633
  }
3863
4634
  }
3864
4635
  if (!handled) {
3865
- console.warn(
3866
- `[rsc-router] No router could render static handler "${name}"`
3867
- );
4636
+ console.warn(`[rango] No router could render static handler "${name}"`);
3868
4637
  }
3869
4638
  }
3870
4639
  }
@@ -3875,38 +4644,118 @@ async function renderStaticHandlers(state, rscEnv, registry) {
3875
4644
  const staticParts = [`${staticDone} done`];
3876
4645
  if (staticSkip > 0) staticParts.push(`${staticSkip} skipped`);
3877
4646
  console.log(
3878
- `[rsc-router] Static render complete: ${staticParts.join(", ")} (${totalStaticElapsed}ms total)`
4647
+ `[rango] Static render complete: ${staticParts.join(", ")} (${totalStaticElapsed}ms total)`
4648
+ );
4649
+ debug9?.(
4650
+ "renderStaticHandlers done: %d done, %d skipped, %sms (overall %sms)",
4651
+ staticDone,
4652
+ staticSkip,
4653
+ totalStaticElapsed,
4654
+ (performance.now() - overallStart).toFixed(1)
4655
+ );
4656
+ }
4657
+
4658
+ // src/vite/discovery/discovery-errors.ts
4659
+ function indent(text, pad) {
4660
+ return text.split("\n").map((line) => line.length > 0 ? pad + line : line).join("\n");
4661
+ }
4662
+ async function invokeLazyMount(loader, context, errors) {
4663
+ try {
4664
+ await loader();
4665
+ } catch (error) {
4666
+ errors.push({ context, error });
4667
+ }
4668
+ }
4669
+ function isLazyMount(route) {
4670
+ return !!route && route.kind === "lazy" && typeof route.handler === "function";
4671
+ }
4672
+ async function resolveHostRouterHandlers(hostRegistry) {
4673
+ const errors = [];
4674
+ for (const [hostId, entry] of hostRegistry) {
4675
+ for (const route of entry.routes) {
4676
+ if (isLazyMount(route)) {
4677
+ await invokeLazyMount(
4678
+ route.handler,
4679
+ `host "${hostId}" route handler`,
4680
+ errors
4681
+ );
4682
+ }
4683
+ }
4684
+ if (isLazyMount(entry.fallback)) {
4685
+ await invokeLazyMount(
4686
+ entry.fallback.handler,
4687
+ `host "${hostId}" fallback handler`,
4688
+ errors
4689
+ );
4690
+ }
4691
+ }
4692
+ return errors;
4693
+ }
4694
+ function formatNoRoutersError(entryPath, errors) {
4695
+ const base = `[rango] No routers found in registry after importing ${entryPath}`;
4696
+ if (errors.length === 0) {
4697
+ return base;
4698
+ }
4699
+ const formatted = errors.map(({ context, error }) => {
4700
+ const err = error instanceof Error ? error : new Error(String(error));
4701
+ const detail = err.stack ?? err.message;
4702
+ return ` - while resolving ${context}:
4703
+ ${indent(detail, " ")}`;
4704
+ }).join("\n");
4705
+ return `${base}
4706
+
4707
+ ${errors.length} error(s) were caught during host-router discovery and likely explain why no routers were registered:
4708
+ ${formatted}`;
4709
+ }
4710
+ function toCause(errors) {
4711
+ if (errors.length === 0) return void 0;
4712
+ if (errors.length === 1) return errors[0].error;
4713
+ return new AggregateError(
4714
+ errors.map((e) => e.error),
4715
+ "Multiple host-router handlers failed during discovery"
3879
4716
  );
3880
4717
  }
4718
+ var DiscoveryError = class _DiscoveryError extends Error {
4719
+ constructor(entryPath, caught) {
4720
+ super(formatNoRoutersError(entryPath, caught));
4721
+ const cause = toCause(caught);
4722
+ if (cause !== void 0) {
4723
+ this.cause = cause;
4724
+ }
4725
+ this.name = "DiscoveryError";
4726
+ this.entryPath = entryPath;
4727
+ this.caught = caught;
4728
+ Object.setPrototypeOf(this, _DiscoveryError.prototype);
4729
+ }
4730
+ };
3881
4731
 
3882
4732
  // src/vite/discovery/discover-routers.ts
4733
+ var debug10 = createRangoDebugger(NS.discovery);
3883
4734
  async function discoverRouters(state, rscEnv) {
3884
4735
  if (!state.resolvedEntryPath) return;
3885
- await rscEnv.runner.import(state.resolvedEntryPath);
3886
- const serverMod = await rscEnv.runner.import("@rangojs/router/server");
4736
+ await timed(
4737
+ debug10,
4738
+ "inner: import entry",
4739
+ () => rscEnv.runner.import(state.resolvedEntryPath)
4740
+ );
4741
+ const serverMod = await timed(
4742
+ debug10,
4743
+ "inner: import @rangojs/router/server",
4744
+ () => rscEnv.runner.import("@rangojs/router/server")
4745
+ );
3887
4746
  let registry = serverMod.RouterRegistry;
3888
4747
  if (!registry || registry.size === 0) {
4748
+ const discoveryErrors = [];
3889
4749
  try {
3890
4750
  const hostRegistry = serverMod.HostRouterRegistry;
3891
4751
  if (hostRegistry && hostRegistry.size > 0) {
3892
4752
  console.log(
3893
- `[rsc-router] Found ${hostRegistry.size} host router(s), resolving lazy handlers...`
4753
+ `[rango] Found ${hostRegistry.size} host router(s), resolving lazy handlers...`
3894
4754
  );
3895
- for (const [, entry] of hostRegistry) {
3896
- for (const route of entry.routes) {
3897
- if (typeof route.handler === "function") {
3898
- try {
3899
- await route.handler();
3900
- } catch {
3901
- }
3902
- }
3903
- }
3904
- if (entry.fallback && typeof entry.fallback.handler === "function") {
3905
- try {
3906
- await entry.fallback.handler();
3907
- } catch {
3908
- }
3909
- }
4755
+ const handlerErrors = await resolveHostRouterHandlers(hostRegistry);
4756
+ discoveryErrors.push(...handlerErrors);
4757
+ for (const { context, error } of handlerErrors) {
4758
+ debug10?.("caught error while resolving %s: %O", context, error);
3910
4759
  }
3911
4760
  const freshServerMod = await rscEnv.runner.import(
3912
4761
  "@rangojs/router/server"
@@ -3917,16 +4766,20 @@ async function discoverRouters(state, rscEnv) {
3917
4766
  registry = freshRegistry;
3918
4767
  }
3919
4768
  }
3920
- } catch {
4769
+ } catch (error) {
4770
+ discoveryErrors.push({ context: "host-router discovery", error });
3921
4771
  }
3922
4772
  if (!registry || registry.size === 0) {
3923
- throw new Error(
3924
- `[rsc-router] No routers found in registry after importing ${state.resolvedEntryPath}`
3925
- );
4773
+ throw new DiscoveryError(state.resolvedEntryPath, discoveryErrors);
3926
4774
  }
3927
4775
  }
3928
- const buildMod = await rscEnv.runner.import("@rangojs/router/build");
4776
+ const buildMod = await timed(
4777
+ debug10,
4778
+ "inner: import @rangojs/router/build",
4779
+ () => rscEnv.runner.import("@rangojs/router/build")
4780
+ );
3929
4781
  const generateManifestFull = buildMod.generateManifestFull;
4782
+ debug10?.("inner: found %d router(s) in registry", registry.size);
3930
4783
  const nestedRouterConflict = findNestedRouterConflict(
3931
4784
  [...registry.values()].map((router) => router.__sourceFile).filter(
3932
4785
  (sourceFile) => typeof sourceFile === "string"
@@ -3945,6 +4798,16 @@ async function discoverRouters(state, rscEnv) {
3945
4798
  let mergedRouteTrailingSlash = {};
3946
4799
  let routerMountIndex = 0;
3947
4800
  const allManifests = [];
4801
+ const clientChunkCtx = state.opts?.clientChunkCtx;
4802
+ const collectClientFallbackRef = clientChunkCtx ? (refKey) => clientChunkCtx.fallbackRefs.add(
4803
+ computeProductionHash(state.projectRoot, refKey)
4804
+ ) : void 0;
4805
+ const collectFromBoundaryNode = (node) => {
4806
+ if (collectClientFallbackRef && buildMod.collectFallbackClientRefs) {
4807
+ buildMod.collectFallbackClientRefs(node, collectClientFallbackRef);
4808
+ }
4809
+ };
4810
+ const manifestGenStart = debug10 ? performance.now() : 0;
3948
4811
  for (const [id, router] of registry) {
3949
4812
  if (!router.urlpatterns || !generateManifestFull) {
3950
4813
  continue;
@@ -3952,10 +4815,18 @@ async function discoverRouters(state, rscEnv) {
3952
4815
  const manifest = generateManifestFull(
3953
4816
  router.urlpatterns,
3954
4817
  routerMountIndex,
3955
- router.__basename ? { urlPrefix: router.__basename } : void 0
4818
+ {
4819
+ ...router.__basename ? { urlPrefix: router.__basename } : {},
4820
+ ...collectClientFallbackRef ? { collectClientFallbackRef } : {}
4821
+ }
3956
4822
  );
3957
4823
  routerMountIndex++;
3958
4824
  allManifests.push({ id, manifest });
4825
+ if (collectClientFallbackRef) {
4826
+ collectFromBoundaryNode(router.__defaultErrorBoundary);
4827
+ collectFromBoundaryNode(router.__defaultNotFoundBoundary);
4828
+ collectFromBoundaryNode(router.__notFound);
4829
+ }
3959
4830
  const routeCount = Object.keys(manifest.routeManifest).length;
3960
4831
  const staticRoutes = Object.values(manifest.routeManifest).filter(
3961
4832
  (p) => !p.includes(":") && !p.includes("*")
@@ -4006,7 +4877,7 @@ async function discoverRouters(state, rscEnv) {
4006
4877
  );
4007
4878
  newPerRouterPrecomputedMap.set(id, routerPrecomputed);
4008
4879
  console.log(
4009
- `[rsc-router] Router "${id}" -> ${routeCount} routes (${staticRoutes} static, ${dynamicRoutes} dynamic)`
4880
+ `[rango] Router "${id}" -> ${routeCount} routes (${staticRoutes} static, ${dynamicRoutes} dynamic)`
4010
4881
  );
4011
4882
  }
4012
4883
  if (registry.size > 1) {
@@ -4015,11 +4886,17 @@ async function discoverRouters(state, rscEnv) {
4015
4886
  );
4016
4887
  if (autoIds.length > 1) {
4017
4888
  console.warn(
4018
- `[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", ... })`
4889
+ `[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", ... })`
4019
4890
  );
4020
4891
  }
4021
4892
  }
4893
+ debug10?.(
4894
+ "inner: generated manifests for %d router(s) (%sms)",
4895
+ allManifests.length,
4896
+ (performance.now() - manifestGenStart).toFixed(1)
4897
+ );
4022
4898
  let newMergedRouteTrie = null;
4899
+ const trieStart = debug10 ? performance.now() : 0;
4023
4900
  if (Object.keys(newMergedRouteManifest).length > 0) {
4024
4901
  const buildRouteTrie = buildMod.buildRouteTrie;
4025
4902
  if (buildRouteTrie && mergedRouteAncestry) {
@@ -4054,10 +4931,10 @@ async function discoverRouters(state, rscEnv) {
4054
4931
  newMergedRouteManifest,
4055
4932
  mergedRouteAncestry,
4056
4933
  routeToStaticPrefix,
4057
- Object.keys(mergedRouteTrailingSlash).length > 0 ? mergedRouteTrailingSlash : void 0,
4058
- prerenderRouteNames.size > 0 ? prerenderRouteNames : void 0,
4059
- passthroughRouteNames.size > 0 ? passthroughRouteNames : void 0,
4060
- Object.keys(mergedResponseTypeRoutes).length > 0 ? mergedResponseTypeRoutes : void 0
4934
+ mergedRouteTrailingSlash,
4935
+ prerenderRouteNames,
4936
+ passthroughRouteNames,
4937
+ mergedResponseTypeRoutes
4061
4938
  );
4062
4939
  for (const { id, manifest } of allManifests) {
4063
4940
  if (!manifest._routeAncestry || Object.keys(manifest._routeAncestry).length === 0)
@@ -4073,15 +4950,19 @@ async function discoverRouters(state, rscEnv) {
4073
4950
  manifest.routeManifest,
4074
4951
  manifest._routeAncestry,
4075
4952
  perRouterStaticPrefix,
4076
- manifest.routeTrailingSlash && Object.keys(manifest.routeTrailingSlash).length > 0 ? manifest.routeTrailingSlash : void 0,
4077
- perRouterPrerenderNames && perRouterPrerenderNames.size > 0 ? perRouterPrerenderNames : void 0,
4078
- perRouterPassthroughNames && perRouterPassthroughNames.size > 0 ? perRouterPassthroughNames : void 0,
4079
- manifest.responseTypeRoutes && Object.keys(manifest.responseTypeRoutes).length > 0 ? manifest.responseTypeRoutes : void 0
4953
+ manifest.routeTrailingSlash,
4954
+ perRouterPrerenderNames,
4955
+ perRouterPassthroughNames,
4956
+ manifest.responseTypeRoutes
4080
4957
  );
4081
4958
  newPerRouterTrieMap.set(id, perRouterTrie);
4082
4959
  }
4083
4960
  }
4084
4961
  }
4962
+ debug10?.(
4963
+ "inner: trie build done (%sms)",
4964
+ (performance.now() - trieStart).toFixed(1)
4965
+ );
4085
4966
  state.mergedRouteManifest = newMergedRouteManifest;
4086
4967
  state.mergedPrecomputedEntries = newMergedPrecomputedEntries;
4087
4968
  state.perRouterManifests = newPerRouterManifests;
@@ -4095,7 +4976,7 @@ async function discoverRouters(state, rscEnv) {
4095
4976
  }
4096
4977
 
4097
4978
  // src/vite/discovery/route-types-writer.ts
4098
- import { dirname as dirname3, basename, join as join2, resolve as resolve6 } from "node:path";
4979
+ import { dirname as dirname3, join as join2, resolve as resolve6 } from "node:path";
4099
4980
  import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, existsSync as existsSync5, unlinkSync as unlinkSync2 } from "node:fs";
4100
4981
  function filterUserNamedRoutes(manifest) {
4101
4982
  const filtered = {};
@@ -4106,39 +4987,20 @@ function filterUserNamedRoutes(manifest) {
4106
4987
  }
4107
4988
  return filtered;
4108
4989
  }
4990
+ function writeGenFileIfChanged(state, outPath, source, opts) {
4991
+ const existing = existsSync5(outPath) ? readFileSync4(outPath, "utf-8") : null;
4992
+ if (existing === source) return;
4993
+ markSelfGenWrite(state, outPath, source);
4994
+ writeFileSync3(outPath, source);
4995
+ if (opts?.log) console.log(`[rango] Generated route types -> ${outPath}`);
4996
+ }
4109
4997
  function writeCombinedRouteTypesWithTracking(state, opts) {
4110
4998
  const routerFiles = state.cachedRouterFiles ?? findRouterFiles(state.projectRoot, state.scanFilter);
4111
4999
  state.cachedRouterFiles = routerFiles;
4112
- const preContent = /* @__PURE__ */ new Map();
4113
- for (const routerFilePath of routerFiles) {
4114
- const routerDir = dirname3(routerFilePath);
4115
- const routerBasename = basename(routerFilePath).replace(
4116
- /\.(tsx?|jsx?)$/,
4117
- ""
4118
- );
4119
- const outPath = join2(routerDir, `${routerBasename}.named-routes.gen.ts`);
4120
- try {
4121
- preContent.set(outPath, readFileSync4(outPath, "utf-8"));
4122
- } catch {
4123
- }
4124
- }
4125
- writeCombinedRouteTypes(state.projectRoot, routerFiles, opts);
4126
- for (const routerFilePath of routerFiles) {
4127
- const routerDir = dirname3(routerFilePath);
4128
- const routerBasename = basename(routerFilePath).replace(
4129
- /\.(tsx?|jsx?)$/,
4130
- ""
4131
- );
4132
- const outPath = join2(routerDir, `${routerBasename}.named-routes.gen.ts`);
4133
- if (!existsSync5(outPath)) continue;
4134
- try {
4135
- const content = readFileSync4(outPath, "utf-8");
4136
- if (content !== preContent.get(outPath)) {
4137
- markSelfGenWrite(state, outPath, content);
4138
- }
4139
- } catch {
4140
- }
4141
- }
5000
+ writeCombinedRouteTypes(state.projectRoot, routerFiles, {
5001
+ ...opts,
5002
+ onWrite: (outPath, content) => markSelfGenWrite(state, outPath, content)
5003
+ });
4142
5004
  }
4143
5005
  function writeRouteTypesFiles(state) {
4144
5006
  if (state.perRouterManifests.length === 0) return;
@@ -4150,7 +5012,7 @@ function writeRouteTypesFiles(state) {
4150
5012
  if (existsSync5(oldCombinedPath)) {
4151
5013
  unlinkSync2(oldCombinedPath);
4152
5014
  console.log(
4153
- `[rsc-router] Removed stale combined route types: ${oldCombinedPath}`
5015
+ `[rango] Removed stale combined route types: ${oldCombinedPath}`
4154
5016
  );
4155
5017
  }
4156
5018
  } catch {
@@ -4164,39 +5026,23 @@ function writeRouteTypesFiles(state) {
4164
5026
  if (!sourceFile) continue;
4165
5027
  if (sourceFile.includes("node_modules")) {
4166
5028
  throw new Error(
4167
- `[rsc-router] Router "${id}" has sourceFile inside node_modules: ${sourceFile}
5029
+ `[rango] Router "${id}" has sourceFile inside node_modules: ${sourceFile}
4168
5030
  This means createRouter() stack trace parsing matched a Vite internal frame.
4169
5031
  Set an explicit \`id\` on createRouter() or check the call site.`
4170
5032
  );
4171
5033
  }
4172
- const routerDir = dirname3(sourceFile);
4173
- const routerBasename = basename(sourceFile).replace(/\.(tsx?|jsx?)$/, "");
4174
- const outPath = join2(routerDir, `${routerBasename}.named-routes.gen.ts`);
5034
+ const outPath = genFileTsPath(sourceFile);
4175
5035
  const userRoutes = filterUserNamedRoutes(routeManifest);
4176
- let effectiveSearchSchemas = routeSearchSchemas;
4177
- if ((!effectiveSearchSchemas || Object.keys(effectiveSearchSchemas).length === 0) && sourceFile) {
4178
- const staticParsed = buildCombinedRouteMapForRouterFile(sourceFile);
4179
- if (Object.keys(staticParsed.searchSchemas).length > 0) {
4180
- const filtered = {};
4181
- for (const name of Object.keys(userRoutes)) {
4182
- const schema = staticParsed.searchSchemas[name];
4183
- if (schema) filtered[name] = schema;
4184
- }
4185
- if (Object.keys(filtered).length > 0) {
4186
- effectiveSearchSchemas = filtered;
4187
- }
4188
- }
4189
- }
5036
+ const effectiveSearchSchemas = resolveSearchSchemas(
5037
+ Object.keys(userRoutes),
5038
+ routeSearchSchemas,
5039
+ sourceFile
5040
+ );
4190
5041
  const source = generateRouteTypesSource(
4191
5042
  userRoutes,
4192
5043
  effectiveSearchSchemas && Object.keys(effectiveSearchSchemas).length > 0 ? effectiveSearchSchemas : void 0
4193
5044
  );
4194
- const existing = existsSync5(outPath) ? readFileSync4(outPath, "utf-8") : null;
4195
- if (existing !== source) {
4196
- markSelfGenWrite(state, outPath, source);
4197
- writeFileSync3(outPath, source);
4198
- console.log(`[rsc-router] Generated route types -> ${outPath}`);
4199
- }
5045
+ writeGenFileIfChanged(state, outPath, source, { log: true });
4200
5046
  }
4201
5047
  }
4202
5048
  function supplementGenFilesWithRuntimeRoutes(state) {
@@ -4234,23 +5080,17 @@ function supplementGenFilesWithRuntimeRoutes(state) {
4234
5080
  }
4235
5081
  }
4236
5082
  }
4237
- const routerDir = dirname3(sourceFile);
4238
- const routerBasename = basename(sourceFile).replace(/\.(tsx?|jsx?)$/, "");
4239
- const outPath = join2(routerDir, `${routerBasename}.named-routes.gen.ts`);
5083
+ const outPath = genFileTsPath(sourceFile);
4240
5084
  const source = generateRouteTypesSource(
4241
5085
  mergedRoutes,
4242
5086
  Object.keys(mergedSearchSchemas).length > 0 ? mergedSearchSchemas : void 0
4243
5087
  );
4244
- const existing = existsSync5(outPath) ? readFileSync4(outPath, "utf-8") : null;
4245
- if (existing !== source) {
4246
- markSelfGenWrite(state, outPath, source);
4247
- writeFileSync3(outPath, source);
4248
- }
5088
+ writeGenFileIfChanged(state, outPath, source);
4249
5089
  }
4250
5090
  }
4251
5091
 
4252
5092
  // src/vite/discovery/virtual-module-codegen.ts
4253
- import { dirname as dirname4, basename as basename2, join as join3 } from "node:path";
5093
+ import { dirname as dirname4, basename, join as join3 } from "node:path";
4254
5094
  function generateRoutesManifestModule(state) {
4255
5095
  const hasManifest = state.mergedRouteManifest && Object.keys(state.mergedRouteManifest).length > 0;
4256
5096
  if (hasManifest) {
@@ -4261,7 +5101,7 @@ function generateRoutesManifestModule(state) {
4261
5101
  for (const entry of state.perRouterManifests) {
4262
5102
  if (entry.sourceFile) {
4263
5103
  const routerDir = dirname4(entry.sourceFile);
4264
- const routerBasename = basename2(entry.sourceFile).replace(
5104
+ const routerBasename = basename(entry.sourceFile).replace(
4265
5105
  /\.(tsx?|jsx?)$/,
4266
5106
  ""
4267
5107
  );
@@ -4282,7 +5122,7 @@ function generateRoutesManifestModule(state) {
4282
5122
  }
4283
5123
  }
4284
5124
  const lines = [
4285
- `import { setCachedManifest, setPrecomputedEntries, setRouteTrie, setRouterManifest, registerRouterManifestLoader, clearAllRouterData } from "@rangojs/router/server";`,
5125
+ `import { setCachedManifest, setRouterManifest, registerRouterManifestLoader, clearAllRouterData } from "@rangojs/router/server";`,
4286
5126
  ...genFileImports,
4287
5127
  // Clear stale per-router cached data (manifest, trie, precomputed entries)
4288
5128
  // before re-populating. In Cloudflare dev mode, program reloads re-evaluate
@@ -4318,18 +5158,6 @@ function generateRoutesManifestModule(state) {
4318
5158
  );
4319
5159
  }
4320
5160
  }
4321
- if (state.isBuildMode) {
4322
- if (state.mergedPrecomputedEntries && state.mergedPrecomputedEntries.length > 0) {
4323
- lines.push(
4324
- `setPrecomputedEntries(${jsonParseExpression(state.mergedPrecomputedEntries)});`
4325
- );
4326
- }
4327
- if (state.mergedRouteTrie) {
4328
- lines.push(
4329
- `setRouteTrie(${jsonParseExpression(state.mergedRouteTrie)});`
4330
- );
4331
- }
4332
- }
4333
5161
  for (const routerId of state.perRouterManifestDataMap.keys()) {
4334
5162
  lines.push(
4335
5163
  `registerRouterManifestLoader(${JSON.stringify(routerId)}, () => import(${JSON.stringify(VIRTUAL_ROUTES_MANIFEST_ID + "/" + routerId)}));`
@@ -4358,7 +5186,7 @@ function generatePerRouterModule(state, routerId) {
4358
5186
  const lines = [];
4359
5187
  if (routerEntry?.sourceFile) {
4360
5188
  const routerDir = dirname4(routerEntry.sourceFile);
4361
- const routerBasename = basename2(routerEntry.sourceFile).replace(
5189
+ const routerBasename = basename(routerEntry.sourceFile).replace(
4362
5190
  /\.(tsx?|jsx?)$/,
4363
5191
  ""
4364
5192
  );
@@ -4429,12 +5257,12 @@ function postprocessBundle(state) {
4429
5257
  writeFileSync4(chunkPath, result.code);
4430
5258
  const savedKB = (result.savedBytes / 1024).toFixed(1);
4431
5259
  console.log(
4432
- `[rsc-router] Evicted ${target.label} (${savedKB} KB saved): ${info.fileName}`
5260
+ `[rango] Evicted ${target.label} (${savedKB} KB saved): ${info.fileName}`
4433
5261
  );
4434
5262
  }
4435
5263
  } catch (replaceErr) {
4436
5264
  console.warn(
4437
- `[rsc-router] Failed to evict ${target.label}: ${replaceErr.message}`
5265
+ `[rango] Failed to evict ${target.label}: ${replaceErr.message}`
4438
5266
  );
4439
5267
  }
4440
5268
  }
@@ -4472,11 +5300,11 @@ function postprocessBundle(state) {
4472
5300
  writeFileSync4(rscEntryPath, injection + rscCode);
4473
5301
  const totalKB = (totalBytes / 1024).toFixed(1);
4474
5302
  console.log(
4475
- `[rsc-router] Wrote prerender assets (${totalKB} KB total, ${Object.keys(state.prerenderManifestEntries).length} entries)`
5303
+ `[rango] Wrote prerender assets (${totalKB} KB total, ${Object.keys(state.prerenderManifestEntries).length} entries)`
4476
5304
  );
4477
5305
  } catch (err) {
4478
5306
  throw new Error(
4479
- `[rsc-router] Failed to write prerender assets: ${err.message}`
5307
+ `[rango] Failed to write prerender assets: ${err.message}`
4480
5308
  );
4481
5309
  }
4482
5310
  }
@@ -4510,28 +5338,180 @@ function postprocessBundle(state) {
4510
5338
  writeFileSync4(rscEntryPath, injection + rscCode);
4511
5339
  const totalKB = (totalBytes / 1024).toFixed(1);
4512
5340
  console.log(
4513
- `[rsc-router] Wrote static assets (${totalKB} KB total, ${Object.keys(state.staticManifestEntries).length} entries)`
5341
+ `[rango] Wrote static assets (${totalKB} KB total, ${Object.keys(state.staticManifestEntries).length} entries)`
4514
5342
  );
4515
5343
  } catch (err) {
4516
5344
  throw new Error(
4517
- `[rsc-router] Failed to write static assets: ${err.message}`
5345
+ `[rango] Failed to write static assets: ${err.message}`
4518
5346
  );
4519
5347
  }
4520
5348
  }
4521
5349
  }
4522
5350
  }
4523
5351
 
5352
+ // src/vite/discovery/gate-state.ts
5353
+ function createDiscoveryGate(s, debug11) {
5354
+ let gatePending = false;
5355
+ let gateResolver = () => {
5356
+ };
5357
+ let inProgress = false;
5358
+ let queued = false;
5359
+ let pendingEvents = false;
5360
+ const beginGate = () => {
5361
+ if (gatePending) return;
5362
+ s.discoveryDone = new Promise((resolve10) => {
5363
+ gateResolver = resolve10;
5364
+ });
5365
+ gatePending = true;
5366
+ };
5367
+ const resolveGate = () => {
5368
+ if (!gatePending) return;
5369
+ if (inProgress || queued || pendingEvents) {
5370
+ debug11?.(
5371
+ "hmr: resolveGate deferred \u2014 work in flight (inProgress=%s queued=%s pendingEvents=%s)",
5372
+ inProgress,
5373
+ queued,
5374
+ pendingEvents
5375
+ );
5376
+ return;
5377
+ }
5378
+ gatePending = false;
5379
+ debug11?.("hmr: discoveryDone resolved");
5380
+ gateResolver();
5381
+ };
5382
+ const noteRouteEvent = () => {
5383
+ pendingEvents = true;
5384
+ beginGate();
5385
+ };
5386
+ const runRefreshCycle = async (work) => {
5387
+ if (inProgress) {
5388
+ queued = true;
5389
+ debug11?.("hmr: rediscovery in flight \u2014 queued for a follow-up cycle");
5390
+ return;
5391
+ }
5392
+ pendingEvents = false;
5393
+ inProgress = true;
5394
+ try {
5395
+ await work();
5396
+ } finally {
5397
+ inProgress = false;
5398
+ if (queued) {
5399
+ queued = false;
5400
+ debug11?.("hmr: consuming queued rediscovery");
5401
+ runRefreshCycle(work).catch((err) => {
5402
+ debug11?.(
5403
+ "hmr: queued cycle rejected \u2014 releasing gate (%s)",
5404
+ err instanceof Error ? err.message : String(err)
5405
+ );
5406
+ resolveGate();
5407
+ });
5408
+ } else if (pendingEvents) {
5409
+ debug11?.(
5410
+ "hmr: holding gate for pending events (debounce not yet fired)"
5411
+ );
5412
+ } else {
5413
+ resolveGate();
5414
+ }
5415
+ }
5416
+ };
5417
+ return {
5418
+ beginGate,
5419
+ resolveGate,
5420
+ noteRouteEvent,
5421
+ runRefreshCycle,
5422
+ state: () => ({ gatePending, inProgress, queued, pendingEvents })
5423
+ };
5424
+ }
5425
+
5426
+ // src/vite/utils/forward-user-plugins.ts
5427
+ function isDenied(name) {
5428
+ return name.startsWith("vite:") || name === "rsc" || name.startsWith("rsc:") || name.startsWith("@rangojs/router") || name.startsWith("@cloudflare/vite-plugin") || name.startsWith("vite-plugin-cloudflare");
5429
+ }
5430
+ function hasResolutionHooks(p) {
5431
+ return Boolean(p.resolveId || p.load);
5432
+ }
5433
+ function stripToResolutionHooks(p) {
5434
+ const stripped = { name: p.name };
5435
+ if (p.enforce) stripped.enforce = p.enforce;
5436
+ if (p.applyToEnvironment)
5437
+ stripped.applyToEnvironment = p.applyToEnvironment;
5438
+ if (p.resolveId) stripped.resolveId = p.resolveId;
5439
+ if (p.load) stripped.load = p.load;
5440
+ return stripped;
5441
+ }
5442
+ function selectForwardableResolvePlugins(plugins) {
5443
+ if (!plugins) return [];
5444
+ const forwarded = [];
5445
+ for (const p of plugins) {
5446
+ const name = p?.name;
5447
+ if (!name || isDenied(name)) continue;
5448
+ if (!hasResolutionHooks(p)) continue;
5449
+ forwarded.push(stripToResolutionHooks(p));
5450
+ }
5451
+ return forwarded;
5452
+ }
5453
+ function pickForwardedRunnerConfig(config) {
5454
+ const r = config.resolve ?? {};
5455
+ const resolve10 = {};
5456
+ if (r.alias !== void 0) resolve10.alias = r.alias;
5457
+ if (r.dedupe !== void 0) resolve10.dedupe = r.dedupe;
5458
+ if (r.conditions !== void 0) resolve10.conditions = r.conditions;
5459
+ if (r.mainFields !== void 0) resolve10.mainFields = r.mainFields;
5460
+ if (r.extensions !== void 0) resolve10.extensions = r.extensions;
5461
+ if (r.preserveSymlinks !== void 0)
5462
+ resolve10.preserveSymlinks = r.preserveSymlinks;
5463
+ if (r.tsconfigPaths !== void 0) resolve10.tsconfigPaths = r.tsconfigPaths;
5464
+ const userOxc = config.oxc;
5465
+ const userJsx = userOxc && typeof userOxc === "object" && typeof userOxc.jsx === "object" && userOxc.jsx !== null ? userOxc.jsx : {};
5466
+ const oxc = userOxc && typeof userOxc === "object" ? {
5467
+ ...userOxc,
5468
+ jsx: { ...userJsx, runtime: "automatic", importSource: "react" }
5469
+ } : { jsx: { runtime: "automatic", importSource: "react" } };
5470
+ return {
5471
+ resolve: resolve10,
5472
+ define: config.define,
5473
+ oxc
5474
+ };
5475
+ }
5476
+
4524
5477
  // src/vite/router-discovery.ts
5478
+ var debugDiscovery = createRangoDebugger(NS.discovery);
5479
+ var debugRoutes = createRangoDebugger(NS.routes);
5480
+ var debugBuild = createRangoDebugger(NS.build);
5481
+ var debugDev = createRangoDebugger(NS.dev);
5482
+ var loaderHookRegistered = false;
5483
+ function ensureCloudflareProtocolLoaderRegistered() {
5484
+ if (loaderHookRegistered) return;
5485
+ loaderHookRegistered = true;
5486
+ try {
5487
+ register(
5488
+ new URL("./plugins/cloudflare-protocol-loader-hook.mjs", import.meta.url)
5489
+ );
5490
+ } catch (err) {
5491
+ console.warn(
5492
+ `[rango] Could not register Node ESM loader hook for cloudflare:* imports (${err?.message ?? err}). Falling back to Vite transform only.`
5493
+ );
5494
+ }
5495
+ }
4525
5496
  async function createTempRscServer(state, options = {}) {
5497
+ ensureCloudflareProtocolLoaderRegistered();
4526
5498
  const { default: rsc } = await import("@vitejs/plugin-rsc");
5499
+ const runnerConfig = state.userRunnerConfig;
5500
+ const resolveConfig = runnerConfig?.resolve ?? {
5501
+ alias: state.userResolveAlias
5502
+ };
5503
+ const oxcConfig = runnerConfig?.oxc ?? {
5504
+ jsx: { runtime: "automatic", importSource: "react" }
5505
+ };
4527
5506
  return createViteServer({
4528
5507
  root: state.projectRoot,
4529
5508
  configFile: false,
4530
5509
  server: { middlewareMode: true },
4531
5510
  appType: "custom",
4532
5511
  logLevel: "silent",
4533
- resolve: { alias: state.userResolveAlias },
4534
- esbuild: { jsx: "automatic", jsxImportSource: "react" },
5512
+ resolve: resolveConfig,
5513
+ ...runnerConfig?.define ? { define: runnerConfig.define } : {},
5514
+ oxc: oxcConfig,
4535
5515
  ...options.cacheDir && { cacheDir: options.cacheDir },
4536
5516
  plugins: [
4537
5517
  rsc({
@@ -4545,10 +5525,15 @@ async function createTempRscServer(state, options = {}) {
4545
5525
  ...options.forceBuild ? [hashClientRefs(state.projectRoot)] : [],
4546
5526
  createVersionPlugin(),
4547
5527
  createVirtualStubPlugin(),
5528
+ createCloudflareProtocolStubPlugin(),
4548
5529
  // Dev prerender must use dev-mode IDs (path-based) to match the workerd
4549
5530
  // runtime. forceBuild produces hashed IDs for production bundle consistency.
4550
5531
  exposeInternalIds(options.forceBuild ? { forceBuild: true } : void 0),
4551
- exposeRouterId()
5532
+ exposeRouterId(),
5533
+ // Forwarded user resolution plugins (e.g. vite-tsconfig-paths). Stripped
5534
+ // to resolveId/load and placed last so framework resolution runs first;
5535
+ // Vite re-sorts by `enforce`, so `enforce: "pre"` resolvers still lead.
5536
+ ...state.userResolvePlugins
4552
5537
  ]
4553
5538
  });
4554
5539
  }
@@ -4557,11 +5542,11 @@ async function resolveBuildEnv(option, factoryCtx) {
4557
5542
  if (option === "auto") {
4558
5543
  if (factoryCtx.preset !== "cloudflare") {
4559
5544
  throw new Error(
4560
- '[rsc-router] buildEnv: "auto" is only supported with preset: "cloudflare". Use a factory function or plain object for other presets.'
5545
+ '[rango] buildEnv: "auto" is only supported with preset: "cloudflare". Use a factory function or plain object for other presets.'
4561
5546
  );
4562
5547
  }
4563
5548
  try {
4564
- const userRequire = createRequire(
5549
+ const userRequire = createRequire2(
4565
5550
  resolve8(factoryCtx.root, "package.json")
4566
5551
  );
4567
5552
  const wranglerPath = userRequire.resolve("wrangler");
@@ -4573,7 +5558,7 @@ async function resolveBuildEnv(option, factoryCtx) {
4573
5558
  };
4574
5559
  } catch (err) {
4575
5560
  throw new Error(
4576
- `[rsc-router] buildEnv: "auto" requires wrangler to be installed.
5561
+ `[rango] buildEnv: "auto" requires wrangler to be installed.
4577
5562
  Install it with: pnpm add -D wrangler
4578
5563
  ${err.message}`
4579
5564
  );
@@ -4596,6 +5581,7 @@ async function acquireBuildEnv(s, command, mode) {
4596
5581
  if (!result) return false;
4597
5582
  s.resolvedBuildEnv = result.env;
4598
5583
  s.buildEnvDispose = result.dispose ?? null;
5584
+ globalThis[BUILD_ENV_GLOBAL_KEY] = result.env;
4599
5585
  return true;
4600
5586
  }
4601
5587
  async function releaseBuildEnv(s) {
@@ -4603,11 +5589,12 @@ async function releaseBuildEnv(s) {
4603
5589
  try {
4604
5590
  await s.buildEnvDispose();
4605
5591
  } catch (err) {
4606
- console.warn(`[rsc-router] buildEnv dispose failed: ${err.message}`);
5592
+ console.warn(`[rango] buildEnv dispose failed: ${err.message}`);
4607
5593
  }
4608
5594
  s.buildEnvDispose = null;
4609
5595
  }
4610
5596
  s.resolvedBuildEnv = void 0;
5597
+ delete globalThis[BUILD_ENV_GLOBAL_KEY];
4611
5598
  }
4612
5599
  function createRouterDiscoveryPlugin(entryPath, opts) {
4613
5600
  const s = createDiscoveryState(entryPath, opts);
@@ -4629,17 +5616,16 @@ function createRouterDiscoveryPlugin(entryPath, opts) {
4629
5616
  viteCommand = config.command;
4630
5617
  viteMode = config.mode;
4631
5618
  s.userResolveAlias = config.resolve.alias;
5619
+ s.userRunnerConfig = pickForwardedRunnerConfig(config);
5620
+ s.userResolvePlugins = selectForwardableResolvePlugins(
5621
+ config.plugins
5622
+ );
4632
5623
  if (!s.resolvedEntryPath && opts?.routerPathRef?.path) {
4633
5624
  s.resolvedEntryPath = opts.routerPathRef.path;
4634
5625
  }
4635
5626
  if (!s.resolvedEntryPath) {
4636
- const rscEnvConfig = config.environments?.["rsc"];
4637
- const entries = rscEnvConfig?.optimizeDeps?.entries;
4638
- if (typeof entries === "string") {
4639
- s.resolvedEntryPath = entries;
4640
- } else if (Array.isArray(entries) && entries.length > 0) {
4641
- s.resolvedEntryPath = entries[0];
4642
- }
5627
+ const entry = resolveRscEntryFromConfig(config);
5628
+ if (entry) s.resolvedEntryPath = entry;
4643
5629
  }
4644
5630
  if (opts?.staticRouteTypesGeneration !== false) {
4645
5631
  s.cachedRouterFiles = findRouterFiles(s.projectRoot, s.scanFilter);
@@ -4663,6 +5649,9 @@ function createRouterDiscoveryPlugin(entryPath, opts) {
4663
5649
  const discoveryPromise = new Promise((resolve10) => {
4664
5650
  resolveDiscovery = resolve10;
4665
5651
  });
5652
+ const gate = createDiscoveryGate(s, debugDiscovery);
5653
+ const beginDiscoveryGate = gate.beginGate;
5654
+ const resolveDiscoveryGate = gate.resolveGate;
4666
5655
  const getDevServerOrigin = () => server.resolvedUrls?.local?.[0]?.replace(/\/$/, "") || `http://localhost:${server.config.server.port || 5173}`;
4667
5656
  let prerenderTempServer = null;
4668
5657
  let prerenderNodeRegistry = null;
@@ -4675,74 +5664,241 @@ function createRouterDiscoveryPlugin(entryPath, opts) {
4675
5664
  releaseBuildEnv(s).catch(() => {
4676
5665
  });
4677
5666
  });
5667
+ async function importEntryAndRegistry(tempRscEnv) {
5668
+ const flagAlreadySet = !!globalThis.__rscRouterDiscoveryActive;
5669
+ if (!flagAlreadySet) {
5670
+ globalThis.__rscRouterDiscoveryActive = true;
5671
+ }
5672
+ try {
5673
+ debugDiscovery?.(
5674
+ "importEntryAndRegistry: importing entry (flag=%s)",
5675
+ globalThis.__rscRouterDiscoveryActive ?? false
5676
+ );
5677
+ await tempRscEnv.runner.import(s.resolvedEntryPath);
5678
+ debugDiscovery?.(
5679
+ "importEntryAndRegistry: entry import OK, fetching RouterRegistry"
5680
+ );
5681
+ const serverMod = await tempRscEnv.runner.import(
5682
+ "@rangojs/router/server"
5683
+ );
5684
+ prerenderNodeRegistry = serverMod.RouterRegistry;
5685
+ debugDiscovery?.(
5686
+ "importEntryAndRegistry: registry size=%d",
5687
+ prerenderNodeRegistry?.size ?? 0
5688
+ );
5689
+ } finally {
5690
+ if (!flagAlreadySet) {
5691
+ delete globalThis.__rscRouterDiscoveryActive;
5692
+ debugDiscovery?.(
5693
+ "importEntryAndRegistry: cleared __rscRouterDiscoveryActive"
5694
+ );
5695
+ }
5696
+ }
5697
+ }
4678
5698
  async function getOrCreateTempServer() {
4679
- if (prerenderNodeRegistry) {
4680
- return prerenderTempServer.environments?.rsc ?? null;
5699
+ if (prerenderTempServer) {
5700
+ const existingEnv = prerenderTempServer.environments?.rsc;
5701
+ if (existingEnv?.runner) {
5702
+ if (prerenderNodeRegistry) {
5703
+ debugDiscovery?.(
5704
+ "getOrCreateTempServer: cached temp runner reused"
5705
+ );
5706
+ return existingEnv;
5707
+ }
5708
+ debugDiscovery?.(
5709
+ "getOrCreateTempServer: server alive but registry missing \u2014 re-importing"
5710
+ );
5711
+ try {
5712
+ await importEntryAndRegistry(existingEnv);
5713
+ return existingEnv;
5714
+ } catch (err) {
5715
+ debugDiscovery?.(
5716
+ "getOrCreateTempServer: reuse import failed (%s) \u2014 closing orphan and creating fresh",
5717
+ err?.message ?? String(err)
5718
+ );
5719
+ await prerenderTempServer.close().catch(() => {
5720
+ });
5721
+ prerenderTempServer = null;
5722
+ prerenderNodeRegistry = null;
5723
+ }
5724
+ } else {
5725
+ debugDiscovery?.(
5726
+ "getOrCreateTempServer: existing server has no rsc.runner \u2014 closing and recreating"
5727
+ );
5728
+ await prerenderTempServer.close().catch(() => {
5729
+ });
5730
+ prerenderTempServer = null;
5731
+ prerenderNodeRegistry = null;
5732
+ }
4681
5733
  }
5734
+ debugDiscovery?.(
5735
+ "getOrCreateTempServer: creating new temp server, entry=%s",
5736
+ s.resolvedEntryPath ?? "(unset)"
5737
+ );
4682
5738
  try {
4683
5739
  prerenderTempServer = await createTempRscServer(s, {
4684
5740
  cacheDir: "node_modules/.vite_prerender"
4685
5741
  });
4686
5742
  const tempRscEnv = prerenderTempServer.environments?.rsc;
4687
5743
  if (tempRscEnv?.runner) {
4688
- await tempRscEnv.runner.import(s.resolvedEntryPath);
4689
- const serverMod = await tempRscEnv.runner.import(
4690
- "@rangojs/router/server"
4691
- );
4692
- prerenderNodeRegistry = serverMod.RouterRegistry;
5744
+ await importEntryAndRegistry(tempRscEnv);
4693
5745
  return tempRscEnv;
4694
5746
  }
5747
+ debugDiscovery?.(
5748
+ "getOrCreateTempServer: tempRscEnv.runner unavailable"
5749
+ );
4695
5750
  } catch (err) {
4696
- console.warn(
4697
- `[rsc-router] Failed to create temp runner: ${err.message}`
5751
+ debugDiscovery?.(
5752
+ "getOrCreateTempServer: FAILED message=%s",
5753
+ err.message
4698
5754
  );
5755
+ console.warn(`[rango] Failed to create temp runner: ${err.message}`);
4699
5756
  }
4700
5757
  return null;
4701
5758
  }
5759
+ async function clearTempRegistries(tempRscEnv) {
5760
+ try {
5761
+ const serverMod = await tempRscEnv.runner.import(
5762
+ "@rangojs/router/server"
5763
+ );
5764
+ if (typeof serverMod?.RouterRegistry?.clear === "function") {
5765
+ serverMod.RouterRegistry.clear();
5766
+ }
5767
+ if (typeof serverMod?.HostRouterRegistry?.clear === "function") {
5768
+ serverMod.HostRouterRegistry.clear();
5769
+ }
5770
+ debugDiscovery?.(
5771
+ "clearTempRegistries: cleared RouterRegistry + HostRouterRegistry"
5772
+ );
5773
+ } catch (err) {
5774
+ debugDiscovery?.(
5775
+ "clearTempRegistries: import @rangojs/router/server failed (%s)",
5776
+ err?.message ?? String(err)
5777
+ );
5778
+ }
5779
+ }
5780
+ async function refreshTempRscEnv() {
5781
+ let tempRscEnv = await getOrCreateTempServer();
5782
+ if (!tempRscEnv) return null;
5783
+ const envGraph = tempRscEnv.moduleGraph;
5784
+ const serverGraph = prerenderTempServer?.moduleGraph;
5785
+ const target = envGraph?.invalidateAll ? envGraph : serverGraph?.invalidateAll ? serverGraph : null;
5786
+ if (!target) {
5787
+ debugDiscovery?.(
5788
+ "refreshTempRscEnv: invalidateAll unavailable on env+server graphs, falling back to close+recreate"
5789
+ );
5790
+ if (prerenderTempServer) {
5791
+ await prerenderTempServer.close().catch(() => {
5792
+ });
5793
+ prerenderTempServer = null;
5794
+ prerenderNodeRegistry = null;
5795
+ }
5796
+ return await getOrCreateTempServer();
5797
+ }
5798
+ debugDiscovery?.(
5799
+ "refreshTempRscEnv: invalidating module graph (%s)",
5800
+ envGraph?.invalidateAll ? "env" : "server"
5801
+ );
5802
+ target.invalidateAll();
5803
+ prerenderNodeRegistry = null;
5804
+ await clearTempRegistries(tempRscEnv);
5805
+ await importEntryAndRegistry(tempRscEnv);
5806
+ return tempRscEnv;
5807
+ }
4702
5808
  const discover = async () => {
5809
+ const discoverStart = performance.now();
4703
5810
  const rscEnv = server.environments?.rsc;
4704
5811
  if (!rscEnv?.runner) {
5812
+ debugDiscovery?.(
5813
+ "dev: cloudflare path start, __rscRouterDiscoveryActive=%s",
5814
+ globalThis.__rscRouterDiscoveryActive ?? false
5815
+ );
4705
5816
  s.devServerOrigin = getDevServerOrigin();
4706
5817
  try {
4707
- await acquireBuildEnv(s, viteCommand, viteMode);
4708
- const tempRscEnv = await getOrCreateTempServer();
5818
+ await timed(
5819
+ debugDiscovery,
5820
+ "acquireBuildEnv",
5821
+ () => acquireBuildEnv(s, viteCommand, viteMode)
5822
+ );
5823
+ const tempRscEnv = await timed(
5824
+ debugDiscovery,
5825
+ "getOrCreateTempServer",
5826
+ () => getOrCreateTempServer()
5827
+ );
4709
5828
  if (tempRscEnv) {
4710
- await discoverRouters(s, tempRscEnv);
4711
- writeRouteTypesFiles(s);
5829
+ await timed(
5830
+ debugDiscovery,
5831
+ "discoverRouters (cloudflare)",
5832
+ () => discoverRouters(s, tempRscEnv)
5833
+ );
5834
+ timedSync(
5835
+ debugDiscovery,
5836
+ "writeRouteTypesFiles",
5837
+ () => writeRouteTypesFiles(s)
5838
+ );
4712
5839
  }
4713
5840
  } catch (err) {
4714
5841
  console.warn(
4715
- `[rsc-router] Cloudflare dev discovery failed: ${err.message}
5842
+ `[rango] Cloudflare dev discovery failed: ${err.message}
4716
5843
  ${err.stack}`
4717
5844
  );
4718
5845
  }
5846
+ debugDiscovery?.(
5847
+ "dev discovery done (%sms)",
5848
+ (performance.now() - discoverStart).toFixed(1)
5849
+ );
4719
5850
  resolveDiscovery();
4720
5851
  return;
4721
5852
  }
4722
5853
  try {
4723
- await acquireBuildEnv(s, viteCommand, viteMode);
4724
- const serverMod = await rscEnv.runner.import(
4725
- "@rangojs/router/server"
5854
+ debugDiscovery?.("dev: node path start");
5855
+ await timed(
5856
+ debugDiscovery,
5857
+ "acquireBuildEnv",
5858
+ () => acquireBuildEnv(s, viteCommand, viteMode)
5859
+ );
5860
+ const serverMod = await timed(
5861
+ debugDiscovery,
5862
+ "import @rangojs/router/server",
5863
+ () => rscEnv.runner.import("@rangojs/router/server")
4726
5864
  );
4727
5865
  if (serverMod?.setManifestReadyPromise) {
4728
5866
  serverMod.setManifestReadyPromise(discoveryPromise);
4729
5867
  }
4730
- await discoverRouters(s, rscEnv);
5868
+ await timed(
5869
+ debugDiscovery,
5870
+ "discoverRouters",
5871
+ () => discoverRouters(s, rscEnv)
5872
+ );
4731
5873
  s.devServerOrigin = getDevServerOrigin();
4732
- writeRouteTypesFiles(s);
4733
- await propagateDiscoveryState(rscEnv);
5874
+ timedSync(
5875
+ debugDiscovery,
5876
+ "writeRouteTypesFiles",
5877
+ () => writeRouteTypesFiles(s)
5878
+ );
5879
+ await timed(
5880
+ debugDiscovery,
5881
+ "propagateDiscoveryState",
5882
+ () => propagateDiscoveryState(rscEnv)
5883
+ );
4734
5884
  } catch (err) {
4735
5885
  console.warn(
4736
- `[rsc-router] Router discovery failed: ${err.message}
5886
+ `[rango] Router discovery failed: ${err.message}
4737
5887
  ${err.stack}`
4738
5888
  );
4739
5889
  } finally {
5890
+ debugDiscovery?.(
5891
+ "dev discovery done (%sms)",
5892
+ (performance.now() - discoverStart).toFixed(1)
5893
+ );
4740
5894
  resolveDiscovery();
4741
5895
  }
4742
5896
  };
4743
- s.discoveryDone = new Promise((resolve10) => {
4744
- setTimeout(() => discover().then(resolve10, resolve10), 0);
4745
- });
5897
+ beginDiscoveryGate();
5898
+ setTimeout(
5899
+ () => discover().then(resolveDiscoveryGate, resolveDiscoveryGate),
5900
+ 0
5901
+ );
4746
5902
  let mainRegistry = null;
4747
5903
  const propagateDiscoveryState = async (rscEnv) => {
4748
5904
  const serverMod = await rscEnv.runner.import("@rangojs/router/server");
@@ -4760,32 +5916,58 @@ ${err.stack}`
4760
5916
  if (s.mergedRouteTrie && serverMod.setRouteTrie) {
4761
5917
  serverMod.setRouteTrie(s.mergedRouteTrie);
4762
5918
  }
4763
- if (serverMod.setRouterManifest) {
4764
- for (const [routerId, manifest] of s.perRouterManifestDataMap) {
4765
- serverMod.setRouterManifest(routerId, manifest);
4766
- }
4767
- }
4768
- if (serverMod.setRouterTrie) {
4769
- for (const [routerId, trie] of s.perRouterTrieMap) {
4770
- serverMod.setRouterTrie(routerId, trie);
4771
- }
4772
- }
4773
- if (serverMod.setRouterPrecomputedEntries) {
4774
- for (const [routerId, entries] of s.perRouterPrecomputedMap) {
4775
- serverMod.setRouterPrecomputedEntries(routerId, entries);
4776
- }
5919
+ const perRouterSetters = [
5920
+ [s.perRouterManifestDataMap, "setRouterManifest"],
5921
+ [s.perRouterTrieMap, "setRouterTrie"],
5922
+ [s.perRouterPrecomputedMap, "setRouterPrecomputedEntries"]
5923
+ ];
5924
+ for (const [map, fn] of perRouterSetters) {
5925
+ const setter = serverMod[fn];
5926
+ if (typeof setter !== "function") continue;
5927
+ for (const [routerId, value] of map) setter(routerId, value);
4777
5928
  }
4778
5929
  };
4779
5930
  server.middlewares.use("/__rsc_prerender", async (req, res) => {
5931
+ const reqStart = debugDev ? performance.now() : 0;
5932
+ const logResult = (status, note) => {
5933
+ debugDev?.(
5934
+ "/__rsc_prerender %s -> %d %s (%sms)",
5935
+ req.url,
5936
+ status,
5937
+ note,
5938
+ (performance.now() - reqStart).toFixed(1)
5939
+ );
5940
+ };
4780
5941
  if (s.discoveryDone) await s.discoveryDone;
4781
5942
  const url = new URL(req.url || "/", "http://localhost");
4782
5943
  const pathname = url.searchParams.get("pathname");
4783
5944
  if (!pathname) {
4784
5945
  res.statusCode = 400;
4785
5946
  res.end("Missing pathname");
5947
+ logResult(400, "missing pathname");
4786
5948
  return;
4787
5949
  }
4788
- let registry = mainRegistry;
5950
+ const rscEnv = server.environments?.rsc;
5951
+ let registry = null;
5952
+ if (rscEnv?.runner && s.resolvedEntryPath) {
5953
+ try {
5954
+ await rscEnv.runner.import(s.resolvedEntryPath);
5955
+ const serverMod = await rscEnv.runner.import(
5956
+ "@rangojs/router/server"
5957
+ );
5958
+ registry = serverMod.RouterRegistry ?? null;
5959
+ } catch (err) {
5960
+ console.warn(
5961
+ `[rango] Dev prerender module refresh failed: ${err.message}`
5962
+ );
5963
+ res.statusCode = 500;
5964
+ res.end(`Prerender handler error: ${err.message}`);
5965
+ logResult(500, "module refresh failed");
5966
+ return;
5967
+ }
5968
+ } else {
5969
+ registry = mainRegistry;
5970
+ }
4789
5971
  if (!registry) {
4790
5972
  if (!prerenderNodeRegistry) {
4791
5973
  await getOrCreateTempServer();
@@ -4795,6 +5977,7 @@ ${err.stack}`
4795
5977
  if (!registry || registry.size === 0) {
4796
5978
  res.statusCode = 503;
4797
5979
  res.end("Prerender runner not available");
5980
+ logResult(503, "no registry");
4798
5981
  return;
4799
5982
  }
4800
5983
  const wantIntercept = url.searchParams.get("intercept") === "1";
@@ -4829,15 +6012,17 @@ ${err.stack}`
4829
6012
  payload = { segments: result.segments, handles: result.handles };
4830
6013
  }
4831
6014
  res.end(JSON.stringify(payload));
6015
+ logResult(200, `match ${result.routeName}`);
4832
6016
  return;
4833
6017
  } catch (err) {
4834
6018
  console.warn(
4835
- `[rsc-router] Dev prerender failed for ${pathname}: ${err.message}`
6019
+ `[rango] Dev prerender failed for ${pathname}: ${err.message}`
4836
6020
  );
4837
6021
  }
4838
6022
  }
4839
6023
  res.statusCode = 404;
4840
6024
  res.end("No prerender match");
6025
+ logResult(404, "no match");
4841
6026
  });
4842
6027
  if (opts?.staticRouteTypesGeneration !== false) {
4843
6028
  const isGeneratedRouteFile = (filePath) => filePath.endsWith(".gen.ts") && (filePath.includes("named-routes.gen.ts") || filePath.includes("urls.gen.ts"));
@@ -4857,59 +6042,185 @@ ${err.stack}`
4857
6042
  return true;
4858
6043
  };
4859
6044
  let routeChangeTimer;
4860
- let runtimeRediscoveryInProgress = false;
4861
6045
  const refreshRuntimeDiscovery = async () => {
4862
6046
  const rscEnv = server.environments?.rsc;
4863
- if (!rscEnv?.runner || runtimeRediscoveryInProgress) return;
4864
- runtimeRediscoveryInProgress = true;
6047
+ const hasMainRunner = !!rscEnv?.runner;
6048
+ if (!hasMainRunner && s.perRouterManifests.length === 0) return;
6049
+ await gate.runRefreshCycle(async () => {
6050
+ const hmrStart = performance.now();
6051
+ try {
6052
+ if (hasMainRunner) {
6053
+ await timed(
6054
+ debugDiscovery,
6055
+ "hmr discoverRouters",
6056
+ () => discoverRouters(s, rscEnv)
6057
+ );
6058
+ timedSync(
6059
+ debugDiscovery,
6060
+ "hmr writeRouteTypesFiles",
6061
+ () => writeRouteTypesFiles(s)
6062
+ );
6063
+ await timed(
6064
+ debugDiscovery,
6065
+ "hmr propagateDiscoveryState",
6066
+ () => propagateDiscoveryState(rscEnv)
6067
+ );
6068
+ } else {
6069
+ const tempRscEnv = await timed(
6070
+ debugDiscovery,
6071
+ "hmr refreshTempRscEnv (cloudflare)",
6072
+ () => refreshTempRscEnv()
6073
+ );
6074
+ if (!tempRscEnv) {
6075
+ throw new Error(
6076
+ "temp runner unavailable for cloudflare HMR rediscovery"
6077
+ );
6078
+ }
6079
+ await timed(
6080
+ debugDiscovery,
6081
+ "hmr discoverRouters (cloudflare)",
6082
+ () => discoverRouters(s, tempRscEnv)
6083
+ );
6084
+ timedSync(
6085
+ debugDiscovery,
6086
+ "hmr writeRouteTypesFiles",
6087
+ () => writeRouteTypesFiles(s)
6088
+ );
6089
+ }
6090
+ if (s.lastDiscoveryError) {
6091
+ debugDiscovery?.(
6092
+ "hmr: cleared lastDiscoveryError (%s) after successful rediscovery",
6093
+ s.lastDiscoveryError.message
6094
+ );
6095
+ s.lastDiscoveryError = null;
6096
+ }
6097
+ if (rscEnv && !rscEnv.runner) forceCloudflareWorkerReload(rscEnv);
6098
+ } catch (err) {
6099
+ s.lastDiscoveryError = {
6100
+ message: err?.message ?? String(err),
6101
+ at: Date.now()
6102
+ };
6103
+ console.warn(
6104
+ `[rango] Runtime re-discovery failed: ${err.message}`
6105
+ );
6106
+ debugDiscovery?.(
6107
+ "hmr: lastDiscoveryError set (%s) \u2014 manifest preserved at last-good; recovery mode active (any in-scan source change will trigger rediscovery)",
6108
+ err?.message
6109
+ );
6110
+ } finally {
6111
+ debugDiscovery?.(
6112
+ "hmr re-discovery done (%sms)",
6113
+ (performance.now() - hmrStart).toFixed(1)
6114
+ );
6115
+ }
6116
+ });
6117
+ };
6118
+ const forceCloudflareWorkerReload = (rscEnv) => {
6119
+ if (!rscEnv?.hot) return;
4865
6120
  try {
4866
- await discoverRouters(s, rscEnv);
4867
- writeRouteTypesFiles(s);
4868
- await propagateDiscoveryState(rscEnv);
6121
+ const graph = rscEnv.moduleGraph;
6122
+ if (graph?.invalidateAll) {
6123
+ graph.invalidateAll();
6124
+ debugDiscovery?.("hmr: invalidated workerd rsc module graph");
6125
+ }
6126
+ rscEnv.hot.send({ type: "full-reload" });
6127
+ debugDiscovery?.(
6128
+ "hmr: forced workerd rsc env reload (full-reload)"
6129
+ );
4869
6130
  } catch (err) {
4870
- console.warn(
4871
- `[rsc-router] Runtime re-discovery failed: ${err.message}`
6131
+ debugDiscovery?.(
6132
+ "hmr: workerd reload failed: %s",
6133
+ err?.message ?? err
4872
6134
  );
4873
- } finally {
4874
- runtimeRediscoveryInProgress = false;
4875
6135
  }
4876
6136
  };
4877
6137
  const scheduleRouteRegeneration = () => {
4878
6138
  clearTimeout(routeChangeTimer);
4879
6139
  routeChangeTimer = setTimeout(() => {
4880
6140
  routeChangeTimer = void 0;
6141
+ const regenStart = debugDiscovery ? performance.now() : 0;
6142
+ const rscEnv = server.environments?.rsc;
6143
+ const skipStaticWrite = !rscEnv?.runner && s.perRouterManifests.length > 0;
4881
6144
  try {
4882
- writeCombinedRouteTypesWithTracking(s);
4883
- if (s.perRouterManifests.length > 0) {
4884
- supplementGenFilesWithRuntimeRoutes(s);
6145
+ if (skipStaticWrite) {
6146
+ debugDiscovery?.(
6147
+ "watcher: skipping static write (cloudflare HMR \u2014 runtime rediscovery owns gen file)"
6148
+ );
6149
+ } else {
6150
+ writeCombinedRouteTypesWithTracking(s);
6151
+ if (s.perRouterManifests.length > 0) {
6152
+ supplementGenFilesWithRuntimeRoutes(s);
6153
+ }
4885
6154
  }
4886
6155
  } catch (err) {
4887
- console.error(
4888
- `[rsc-router] Route regeneration error: ${err.message}`
4889
- );
6156
+ console.error(`[rango] Route regeneration error: ${err.message}`);
4890
6157
  }
6158
+ debugDiscovery?.(
6159
+ "watcher: regenerated gen files (%sms)",
6160
+ (performance.now() - regenStart).toFixed(1)
6161
+ );
4891
6162
  if (s.perRouterManifests.length > 0) {
4892
6163
  refreshRuntimeDiscovery().catch((err) => {
4893
6164
  console.warn(
4894
- `[rsc-router] Runtime re-discovery error: ${err.message}`
6165
+ `[rango] Runtime re-discovery error: ${err.message}`
4895
6166
  );
6167
+ resolveDiscoveryGate();
4896
6168
  });
4897
6169
  }
4898
6170
  }, 100);
4899
6171
  };
4900
6172
  const handleRouteFileChange = (filePath) => {
4901
6173
  if (maybeHandleGeneratedRouteFileMutation(filePath)) return;
4902
- if (!filePath.endsWith(".ts") && !filePath.endsWith(".tsx") && !filePath.endsWith(".js") && !filePath.endsWith(".jsx"))
6174
+ if (!filePath.endsWith(".ts") && !filePath.endsWith(".tsx") && !filePath.endsWith(".js") && !filePath.endsWith(".jsx")) {
6175
+ if (s.lastDiscoveryError) {
6176
+ debugDiscovery?.(
6177
+ "watcher: skip non-source %s [LASTERR %s]",
6178
+ filePath,
6179
+ s.lastDiscoveryError.message
6180
+ );
6181
+ }
6182
+ return;
6183
+ }
6184
+ if (s.scanFilter && !s.scanFilter(filePath)) {
6185
+ if (s.lastDiscoveryError) {
6186
+ debugDiscovery?.(
6187
+ "watcher: skip scan-filter %s [LASTERR %s]",
6188
+ filePath,
6189
+ s.lastDiscoveryError.message
6190
+ );
6191
+ }
4903
6192
  return;
4904
- if (s.scanFilter && !s.scanFilter(filePath)) return;
6193
+ }
6194
+ const inRecoveryMode = !!s.lastDiscoveryError;
4905
6195
  try {
4906
6196
  const source = readFileSync6(filePath, "utf-8");
4907
6197
  const trimmed = source.trimStart();
4908
- if (trimmed.startsWith('"use client"') || trimmed.startsWith("'use client'"))
4909
- return;
4910
- const hasUrls = source.includes("urls(");
4911
- const hasCreateRouter = /\bcreateRouter\s*[<(]/.test(source);
4912
- if (!hasUrls && !hasCreateRouter) return;
6198
+ const isUseClient = trimmed.startsWith('"use client"') || trimmed.startsWith("'use client'");
6199
+ if (!inRecoveryMode && isUseClient) return;
6200
+ let hasUrls = source.includes("urls(");
6201
+ let hasCreateRouter = /\bcreateRouter\s*[<(]/.test(source);
6202
+ if (hasUrls) hasUrls = firstCodeMatchIndex(source, /urls\(/g) >= 0;
6203
+ if (hasCreateRouter) {
6204
+ hasCreateRouter = firstCodeMatchIndex(source, /\bcreateRouter\s*[<(]/g) >= 0;
6205
+ }
6206
+ if (!inRecoveryMode && !hasUrls && !hasCreateRouter) return;
6207
+ if (inRecoveryMode) {
6208
+ debugDiscovery?.(
6209
+ "watcher: recovery rediscovery for %s (urls=%s, router=%s, useClient=%s) [LASTERR %s]",
6210
+ filePath,
6211
+ hasUrls,
6212
+ hasCreateRouter,
6213
+ isUseClient,
6214
+ s.lastDiscoveryError.message
6215
+ );
6216
+ } else {
6217
+ debugDiscovery?.(
6218
+ "watcher: %s matches (urls=%s, router=%s)",
6219
+ filePath,
6220
+ hasUrls,
6221
+ hasCreateRouter
6222
+ );
6223
+ }
4913
6224
  if (hasCreateRouter) {
4914
6225
  const nestedRouterConflict = findNestedRouterConflict([
4915
6226
  ...s.cachedRouterFiles ?? [],
@@ -4923,8 +6234,19 @@ ${err.stack}`
4923
6234
  }
4924
6235
  s.cachedRouterFiles = void 0;
4925
6236
  }
6237
+ if (s.perRouterManifests.length > 0) {
6238
+ gate.noteRouteEvent();
6239
+ }
4926
6240
  scheduleRouteRegeneration();
4927
- } catch {
6241
+ } catch (readErr) {
6242
+ if (s.lastDiscoveryError) {
6243
+ debugDiscovery?.(
6244
+ "watcher: read error %s: %s [LASTERR %s]",
6245
+ filePath,
6246
+ readErr?.message,
6247
+ s.lastDiscoveryError.message
6248
+ );
6249
+ }
4928
6250
  }
4929
6251
  };
4930
6252
  server.watcher.on("add", handleRouteFileChange);
@@ -4942,19 +6264,35 @@ ${err.stack}`
4942
6264
  // The manifest data is stored for the virtual module's load hook.
4943
6265
  async buildStart() {
4944
6266
  if (!s.isBuildMode) return;
4945
- if (s.mergedRouteManifest !== null) return;
6267
+ if (s.mergedRouteManifest !== null) {
6268
+ debugDiscovery?.(
6269
+ "build: skip (already discovered, env=%s)",
6270
+ this.environment?.name ?? "?"
6271
+ );
6272
+ return;
6273
+ }
6274
+ const buildStartTime = performance.now();
6275
+ debugDiscovery?.("build: start (env=%s)", this.environment?.name ?? "?");
4946
6276
  resetStagedBuildAssets(s.projectRoot);
4947
6277
  s.prerenderManifestEntries = null;
4948
6278
  s.staticManifestEntries = null;
4949
- await acquireBuildEnv(s, viteCommand, viteMode);
6279
+ await timed(
6280
+ debugDiscovery,
6281
+ "build acquireBuildEnv",
6282
+ () => acquireBuildEnv(s, viteCommand, viteMode)
6283
+ );
4950
6284
  let tempServer = null;
4951
6285
  globalThis.__rscRouterDiscoveryActive = true;
4952
6286
  try {
4953
- tempServer = await createTempRscServer(s, { forceBuild: true });
6287
+ tempServer = await timed(
6288
+ debugDiscovery,
6289
+ "build createTempRscServer",
6290
+ () => createTempRscServer(s, { forceBuild: true })
6291
+ );
4954
6292
  const rscEnv = tempServer.environments?.rsc;
4955
6293
  if (!rscEnv?.runner) {
4956
6294
  console.warn(
4957
- "[rsc-router] RSC environment runner not available during build, skipping manifest generation"
6295
+ "[rango] RSC environment runner not available during build, skipping manifest generation"
4958
6296
  );
4959
6297
  return;
4960
6298
  }
@@ -4964,8 +6302,16 @@ ${err.stack}`
4964
6302
  if (tempIdsPlugin?.api?.staticHandlerModules) {
4965
6303
  s.resolvedStaticModules = tempIdsPlugin.api.staticHandlerModules;
4966
6304
  }
4967
- await discoverRouters(s, rscEnv);
4968
- writeRouteTypesFiles(s);
6305
+ await timed(
6306
+ debugDiscovery,
6307
+ "build discoverRouters",
6308
+ () => discoverRouters(s, rscEnv)
6309
+ );
6310
+ timedSync(
6311
+ debugDiscovery,
6312
+ "build writeRouteTypesFiles",
6313
+ () => writeRouteTypesFiles(s)
6314
+ );
4969
6315
  } catch (err) {
4970
6316
  const sourceFile = err.stack?.split("\n").find(
4971
6317
  (line) => line.includes(s.projectRoot) && !line.includes("node_modules")
@@ -4978,15 +6324,52 @@ ${err.stack}`
4978
6324
  ${err.stack}` : null
4979
6325
  ].filter(Boolean).join("\n");
4980
6326
  throw new Error(
4981
- `[rsc-router] Build-time router discovery failed:
4982
- ${details}`
6327
+ `[rango] Build-time router discovery failed:
6328
+ ${details}`,
6329
+ { cause: err }
4983
6330
  );
4984
6331
  } finally {
4985
6332
  delete globalThis.__rscRouterDiscoveryActive;
4986
6333
  if (tempServer) {
4987
- await tempServer.close();
6334
+ await timed(
6335
+ debugDiscovery,
6336
+ "build tempServer.close",
6337
+ () => tempServer.close()
6338
+ );
4988
6339
  }
4989
6340
  await releaseBuildEnv(s);
6341
+ debugDiscovery?.(
6342
+ "build discovery done (%sms)",
6343
+ (performance.now() - buildStartTime).toFixed(1)
6344
+ );
6345
+ }
6346
+ },
6347
+ // Suppress vite's HMR cascade for our own gen-file writes.
6348
+ //
6349
+ // After every cf HMR cycle, refreshTempRscEnv → writeRouteTypesFiles
6350
+ // writes the configured gen files (default `router.named-routes.gen.ts`,
6351
+ // but the source filenames and gen suffix are user-configurable). The
6352
+ // chokidar watcher then fires twice independently: our
6353
+ // `handleRouteFileChange` (already short-circuited by
6354
+ // `consumeSelfGenWrite` inside `maybeHandleGeneratedRouteFileMutation`),
6355
+ // AND vite's own HMR pipeline (which invalidates the gen file's
6356
+ // importers and triggers a second workerd full reload — visible to the
6357
+ // user as a duplicate "[Rango] HMR: version changed" on the client).
6358
+ //
6359
+ // `peekSelfGenWrite` is the authoritative filter: its map only contains
6360
+ // paths that `markSelfGenWrite` has registered, so it natively works
6361
+ // for any configured gen-file name. It is non-consuming so the chokidar
6362
+ // handler that fires later can still consume the same entry. Returning
6363
+ // [] tells vite "no modules invalidated by this change" — safe because
6364
+ // `s.perRouterManifests` is already up-to-date (the write that just
6365
+ // happened is the consequence of our just-completed rediscovery).
6366
+ handleHotUpdate(ctx) {
6367
+ if (peekSelfGenWrite(s, ctx.file)) {
6368
+ debugDiscovery?.(
6369
+ "handleHotUpdate: suppressing self-write HMR cascade for %s",
6370
+ ctx.file
6371
+ );
6372
+ return [];
4990
6373
  }
4991
6374
  },
4992
6375
  // Virtual module: provides the pre-generated route manifest as a JS module
@@ -5003,17 +6386,36 @@ ${details}`
5003
6386
  async load(id) {
5004
6387
  if (id === "\0" + VIRTUAL_ROUTES_MANIFEST_ID) {
5005
6388
  if (s.discoveryDone) {
5006
- await s.discoveryDone;
6389
+ await timed(
6390
+ debugRoutes,
6391
+ "await discoveryDone (manifest)",
6392
+ () => s.discoveryDone
6393
+ );
5007
6394
  }
5008
- return generateRoutesManifestModule(s);
6395
+ const code = await timed(
6396
+ debugRoutes,
6397
+ "generateRoutesManifestModule",
6398
+ () => generateRoutesManifestModule(s)
6399
+ );
6400
+ debugRoutes?.("manifest module emitted (%d bytes)", code?.length ?? 0);
6401
+ return code;
5009
6402
  }
5010
6403
  const perRouterPrefix = "\0" + VIRTUAL_ROUTES_MANIFEST_ID + "/";
5011
6404
  if (id.startsWith(perRouterPrefix)) {
5012
6405
  if (s.discoveryDone) {
5013
- await s.discoveryDone;
6406
+ await timed(
6407
+ debugRoutes,
6408
+ "await discoveryDone (per-router)",
6409
+ () => s.discoveryDone
6410
+ );
5014
6411
  }
5015
6412
  const routerId = id.slice(perRouterPrefix.length);
5016
- return generatePerRouterModule(s, routerId);
6413
+ const code = await timed(
6414
+ debugRoutes,
6415
+ `generatePerRouterModule ${routerId}`,
6416
+ () => generatePerRouterModule(s, routerId)
6417
+ );
6418
+ return code;
5017
6419
  }
5018
6420
  return null;
5019
6421
  },
@@ -5021,14 +6423,20 @@ ${details}`
5021
6423
  // Used by closeBundle for handler code eviction and prerender data injection.
5022
6424
  generateBundle(_options, bundle) {
5023
6425
  if (this.environment?.name !== "rsc") return;
6426
+ const genStart = debugBuild ? performance.now() : 0;
5024
6427
  for (const [fileName, chunk] of Object.entries(bundle)) {
5025
6428
  if (chunk.type === "chunk" && chunk.isEntry) {
5026
6429
  s.rscEntryFileName = fileName;
5027
6430
  break;
5028
6431
  }
5029
6432
  }
5030
- if (!s.resolvedPrerenderModules?.size && !s.resolvedStaticModules?.size)
6433
+ if (!s.resolvedPrerenderModules?.size && !s.resolvedStaticModules?.size) {
6434
+ debugBuild?.(
6435
+ "generateBundle (rsc): no handlers to scan (%sms)",
6436
+ (performance.now() - genStart).toFixed(1)
6437
+ );
5031
6438
  return;
6439
+ }
5032
6440
  s.handlerChunkInfoMap.clear();
5033
6441
  s.staticHandlerChunkInfoMap.clear();
5034
6442
  for (const [fileName, chunk] of Object.entries(bundle)) {
@@ -5072,6 +6480,13 @@ ${details}`
5072
6480
  }
5073
6481
  }
5074
6482
  }
6483
+ debugBuild?.(
6484
+ "generateBundle (rsc): scanned %d chunks, %d prerender chunk(s), %d static chunk(s) (%sms)",
6485
+ Object.keys(bundle).length,
6486
+ s.handlerChunkInfoMap.size,
6487
+ s.staticHandlerChunkInfoMap.size,
6488
+ (performance.now() - genStart).toFixed(1)
6489
+ );
5075
6490
  },
5076
6491
  // Build-time pre-rendering: evict handler code and inject collected prerender data.
5077
6492
  // Collection now happens in-process during discoverRouters() via RSC runner.
@@ -5082,29 +6497,45 @@ ${details}`
5082
6497
  async handler() {
5083
6498
  if (!s.isBuildMode) return;
5084
6499
  if (this.environment && this.environment.name !== "rsc") return;
5085
- postprocessBundle(s);
6500
+ timedSync(
6501
+ debugBuild,
6502
+ "closeBundle postprocessBundle",
6503
+ () => postprocessBundle(s)
6504
+ );
5086
6505
  }
5087
6506
  }
5088
6507
  };
5089
6508
  }
5090
6509
 
5091
6510
  // src/vite/rango.ts
6511
+ var debugConfig = createRangoDebugger(NS.config);
5092
6512
  async function rango(options) {
6513
+ const rangoStart = performance.now();
5093
6514
  const resolvedOptions = options ?? { preset: "node" };
5094
6515
  const preset = resolvedOptions.preset ?? "node";
5095
6516
  const showBanner = resolvedOptions.banner ?? true;
6517
+ const clientChunksOption = resolvedOptions.clientChunks ?? true;
6518
+ const useBuiltInClientChunks = clientChunksOption === true;
6519
+ const clientChunkCtx = useBuiltInClientChunks ? { fallbackRefs: /* @__PURE__ */ new Set() } : void 0;
6520
+ const clientChunks = resolveClientChunks(clientChunksOption, clientChunkCtx);
6521
+ debugConfig?.("rango(%s) setup start", preset);
5096
6522
  const plugins = [];
5097
- const rangoAliases = getPackageAliases();
6523
+ const rangoAliases = { ...getPackageAliases(), ...getVendorAliases() };
5098
6524
  const excludeDeps = [
5099
6525
  ...getExcludeDeps(),
5100
- // The public browser entry re-exports the RSDW browser client.
5101
- // Excluding both keeps Vite from freezing the unpatched bundle into
5102
- // .vite/deps before our source transforms run.
6526
+ // plugin-rsc itself injects these into the client env's
6527
+ // optimizeDeps.include, which overrides exclude for the dep's own
6528
+ // pre-bundle entry. What exclude still controls is how *other*
6529
+ // pre-bundled deps treat imports of these specs (external vs inlined)
6530
+ // via esbuildCjsExternalPlugin. The cjs-to-esm transform in
6531
+ // plugins/cjs-to-esm.ts is the fallback for strict-pnpm consumers,
6532
+ // where client.browser's bare include fails to resolve and Vite ends up
6533
+ // serving the raw CJS file at dev-serve time.
5103
6534
  "@vitejs/plugin-rsc/browser",
5104
- // Keep the browser RSDW client out of Vite's dep optimizer so our
5105
- // cjs-to-esm transform can patch the real file.
5106
6535
  "@vitejs/plugin-rsc/vendor/react-server-dom/client.browser"
5107
6536
  ];
6537
+ const pkg = getPublishedPackageName();
6538
+ const nested = (spec) => `${pkg} > ${spec}`;
5108
6539
  const routerRef = { path: void 0 };
5109
6540
  const prerenderEnabled = true;
5110
6541
  if (preset === "cloudflare") {
@@ -5122,10 +6553,18 @@ async function rango(options) {
5122
6553
  // This ensures the same Context instance is used by both browser entry and RSC proxy modules
5123
6554
  optimizeDeps: {
5124
6555
  exclude: excludeDeps,
5125
- esbuildOptions: sharedEsbuildOptions
6556
+ rolldownOptions: sharedRolldownOptions
5126
6557
  },
5127
6558
  resolve: {
5128
- alias: rangoAliases
6559
+ alias: rangoAliases,
6560
+ // Force a single React/React-DOM copy across all three RSC
6561
+ // environments. RSC requires exactly one react/react-dom instance
6562
+ // per environment runtime; consumer install topologies (pnpm
6563
+ // strict layout, experimental React pins, third-party "use client"
6564
+ // packages) can otherwise resolve duplicate copies, causing
6565
+ // "Invalid hook call" / lost context. Child environments inherit
6566
+ // this root dedupe, and Vite merges it with any consumer dedupe.
6567
+ dedupe: ["react", "react-dom"]
5129
6568
  },
5130
6569
  build: {
5131
6570
  rollupOptions: { onwarn }
@@ -5134,6 +6573,14 @@ async function rango(options) {
5134
6573
  client: {
5135
6574
  build: {
5136
6575
  rollupOptions: {
6576
+ // FILE_NAME_CONFLICT (and any other client-build warning) is
6577
+ // emitted by the CLIENT environment build, which consults THIS
6578
+ // env's onwarn -- Vite 8's environment builds do NOT propagate
6579
+ // the top-level build.rollupOptions.onwarn into the client env.
6580
+ // Wire it here so the suppression runs where the conflicts
6581
+ // originate (the top-level handler is invoked 0x for these; the
6582
+ // client-env handler is invoked for all of them).
6583
+ onwarn,
5137
6584
  output: {
5138
6585
  manualChunks: getManualChunks
5139
6586
  }
@@ -5142,9 +6589,9 @@ async function rango(options) {
5142
6589
  // Pre-bundle rsc-html-stream to prevent discovery during first request
5143
6590
  // Exclude rsc-router modules to ensure same Context instance
5144
6591
  optimizeDeps: {
5145
- include: ["rsc-html-stream/client"],
6592
+ include: [nested("rsc-html-stream/client")],
5146
6593
  exclude: excludeDeps,
5147
- esbuildOptions: sharedEsbuildOptions
6594
+ rolldownOptions: sharedRolldownOptions
5148
6595
  }
5149
6596
  },
5150
6597
  ssr: {
@@ -5152,10 +6599,6 @@ async function rango(options) {
5152
6599
  build: {
5153
6600
  outDir: "./dist/rsc/ssr"
5154
6601
  },
5155
- resolve: {
5156
- // Ensure single React instance in SSR child environment
5157
- dedupe: ["react", "react-dom"]
5158
- },
5159
6602
  // Pre-bundle SSR entry and React for proper module linking with childEnvironments
5160
6603
  // All deps must be listed to avoid late discovery triggering ERR_OUTDATED_OPTIMIZED_DEP
5161
6604
  optimizeDeps: {
@@ -5167,11 +6610,13 @@ async function rango(options) {
5167
6610
  "react-dom/static.edge",
5168
6611
  "react/jsx-runtime",
5169
6612
  "react/jsx-dev-runtime",
5170
- "rsc-html-stream/server",
5171
- "@vitejs/plugin-rsc/vendor/react-server-dom/client.edge"
6613
+ nested("rsc-html-stream/server"),
6614
+ nested(
6615
+ "@vitejs/plugin-rsc/vendor/react-server-dom/client.edge"
6616
+ )
5172
6617
  ],
5173
6618
  exclude: excludeDeps,
5174
- esbuildOptions: sharedEsbuildOptions
6619
+ rolldownOptions: sharedRolldownOptions
5175
6620
  }
5176
6621
  },
5177
6622
  rsc: {
@@ -5183,10 +6628,12 @@ async function rango(options) {
5183
6628
  "react",
5184
6629
  "react/jsx-runtime",
5185
6630
  "react/jsx-dev-runtime",
5186
- "@vitejs/plugin-rsc/vendor/react-server-dom/server.edge"
6631
+ nested(
6632
+ "@vitejs/plugin-rsc/vendor/react-server-dom/server.edge"
6633
+ )
5187
6634
  ],
5188
6635
  exclude: excludeDeps,
5189
- esbuildOptions: sharedEsbuildOptions
6636
+ rolldownOptions: sharedRolldownOptions
5190
6637
  }
5191
6638
  }
5192
6639
  }
@@ -5204,7 +6651,8 @@ async function rango(options) {
5204
6651
  plugins.push(
5205
6652
  rsc({
5206
6653
  entries: finalEntries,
5207
- serverHandler: false
6654
+ serverHandler: false,
6655
+ clientChunks
5208
6656
  })
5209
6657
  );
5210
6658
  plugins.push(clientRefDedup());
@@ -5222,7 +6670,7 @@ async function rango(options) {
5222
6670
  const list = candidates.map(
5223
6671
  (f) => " - " + (f.startsWith(root) ? f.slice(root.length + 1) : f)
5224
6672
  ).join("\n");
5225
- throw new Error(`[rsc-router] Multiple routers found:
6673
+ throw new Error(`[rango] Multiple routers found:
5226
6674
  ${list}`);
5227
6675
  }
5228
6676
  }
@@ -5241,18 +6689,34 @@ ${list}`);
5241
6689
  return {
5242
6690
  optimizeDeps: {
5243
6691
  exclude: excludeDeps,
5244
- esbuildOptions: sharedEsbuildOptions
6692
+ rolldownOptions: sharedRolldownOptions
5245
6693
  },
5246
6694
  build: {
5247
6695
  rollupOptions: { onwarn }
5248
6696
  },
5249
6697
  resolve: {
5250
- alias: rangoAliases
6698
+ alias: rangoAliases,
6699
+ // Force a single React/React-DOM copy across all three RSC
6700
+ // environments. RSC requires exactly one react/react-dom instance
6701
+ // per environment runtime; consumer install topologies (pnpm
6702
+ // strict layout, experimental React pins, third-party "use client"
6703
+ // packages) can otherwise resolve duplicate copies, causing
6704
+ // "Invalid hook call" / lost context. Child environments inherit
6705
+ // this root dedupe, and Vite merges it with any consumer dedupe.
6706
+ dedupe: ["react", "react-dom"]
5251
6707
  },
5252
6708
  environments: {
5253
6709
  client: {
5254
6710
  build: {
5255
6711
  rollupOptions: {
6712
+ // FILE_NAME_CONFLICT (and any other client-build warning) is
6713
+ // emitted by the CLIENT environment build, which consults THIS
6714
+ // env's onwarn -- Vite 8's environment builds do NOT propagate
6715
+ // the top-level build.rollupOptions.onwarn into the client env.
6716
+ // Wire it here so the suppression runs where the conflicts
6717
+ // originate (the top-level handler is invoked 0x for these; the
6718
+ // client-env handler is invoked for all of them).
6719
+ onwarn,
5256
6720
  output: {
5257
6721
  manualChunks: getManualChunks
5258
6722
  }
@@ -5264,10 +6728,10 @@ ${list}`);
5264
6728
  "react-dom",
5265
6729
  "react/jsx-runtime",
5266
6730
  "react/jsx-dev-runtime",
5267
- "rsc-html-stream/client"
6731
+ nested("rsc-html-stream/client")
5268
6732
  ],
5269
6733
  exclude: excludeDeps,
5270
- esbuildOptions: sharedEsbuildOptions,
6734
+ rolldownOptions: sharedRolldownOptions,
5271
6735
  entries: [VIRTUAL_IDS.browser]
5272
6736
  }
5273
6737
  },
@@ -5281,10 +6745,12 @@ ${list}`);
5281
6745
  "react-dom/static.edge",
5282
6746
  "react/jsx-runtime",
5283
6747
  "react/jsx-dev-runtime",
5284
- "@vitejs/plugin-rsc/vendor/react-server-dom/client.edge"
6748
+ nested(
6749
+ "@vitejs/plugin-rsc/vendor/react-server-dom/client.edge"
6750
+ )
5285
6751
  ],
5286
6752
  exclude: excludeDeps,
5287
- esbuildOptions: sharedEsbuildOptions
6753
+ rolldownOptions: sharedRolldownOptions
5288
6754
  }
5289
6755
  },
5290
6756
  rsc: {
@@ -5294,9 +6760,11 @@ ${list}`);
5294
6760
  "react",
5295
6761
  "react/jsx-runtime",
5296
6762
  "react/jsx-dev-runtime",
5297
- "@vitejs/plugin-rsc/vendor/react-server-dom/server.edge"
6763
+ nested(
6764
+ "@vitejs/plugin-rsc/vendor/react-server-dom/server.edge"
6765
+ )
5298
6766
  ],
5299
- esbuildOptions: sharedEsbuildOptions
6767
+ rolldownOptions: sharedRolldownOptions
5300
6768
  }
5301
6769
  }
5302
6770
  }
@@ -5313,7 +6781,7 @@ ${list}`);
5313
6781
  if (rscMinimalCount > 1 && !hasWarnedDuplicate) {
5314
6782
  hasWarnedDuplicate = true;
5315
6783
  console.warn(
5316
- "[rsc-router] Duplicate @vitejs/plugin-rsc detected. Remove rsc() from your vite config \u2014 rango() includes it automatically."
6784
+ "[rango] Duplicate @vitejs/plugin-rsc detected. Remove rsc() from your vite config \u2014 rango() includes it automatically."
5317
6785
  );
5318
6786
  }
5319
6787
  }
@@ -5322,7 +6790,8 @@ ${list}`);
5322
6790
  plugins.push(performanceTracksPlugin());
5323
6791
  plugins.push(
5324
6792
  rsc({
5325
- entries: finalEntries
6793
+ entries: finalEntries,
6794
+ clientChunks
5326
6795
  })
5327
6796
  );
5328
6797
  plugins.push(clientRefDedup());
@@ -5361,9 +6830,16 @@ ${list}`);
5361
6830
  routerPathRef: discoveryRouterRef,
5362
6831
  enableBuildPrerender: prerenderEnabled,
5363
6832
  buildEnv: options?.buildEnv,
5364
- preset
6833
+ preset,
6834
+ clientChunkCtx
5365
6835
  })
5366
6836
  );
6837
+ debugConfig?.(
6838
+ "rango(%s) setup done: %d plugin(s) (%sms)",
6839
+ preset,
6840
+ plugins.length,
6841
+ (performance.now() - rangoStart).toFixed(1)
6842
+ );
5367
6843
  return plugins;
5368
6844
  }
5369
6845
 
@@ -5374,7 +6850,7 @@ function poke() {
5374
6850
  apply: "serve",
5375
6851
  configureServer(server) {
5376
6852
  const stdin = process.stdin;
5377
- const debug = process.env.RANGO_POKE_DEBUG === "1";
6853
+ const debug11 = process.env.RANGO_POKE_DEBUG === "1";
5378
6854
  const triggerReload = (source) => {
5379
6855
  server.hot.send({ type: "full-reload", path: "*" });
5380
6856
  server.config.logger.info(` browser reload (${source})`, {
@@ -5407,7 +6883,7 @@ function poke() {
5407
6883
  lines.pop();
5408
6884
  return lines;
5409
6885
  };
5410
- if (debug) {
6886
+ if (debug11) {
5411
6887
  server.config.logger.info(
5412
6888
  ` poke debug enabled (isTTY=${stdin.isTTY ? "yes" : "no"}, isRaw=${stdin.isTTY ? stdin.isRaw ? "yes" : "no" : "n/a"})`,
5413
6889
  { timestamp: true }
@@ -5420,7 +6896,7 @@ function poke() {
5420
6896
  );
5421
6897
  }
5422
6898
  const onData = (data) => {
5423
- if (debug) {
6899
+ if (debug11) {
5424
6900
  server.config.logger.info(` poke stdin ${formatChunk(data)}`, {
5425
6901
  timestamp: true
5426
6902
  });