@rangojs/router 0.0.0-experimental.c65e9248 → 0.0.0-experimental.c7e2ee4c

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 (984) hide show
  1. package/README.md +188 -35
  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 +133 -47
  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/theme/ThemeProvider.d.ts +20 -0
  711. package/dist/theme/ThemeProvider.d.ts.map +1 -0
  712. package/dist/theme/ThemeProvider.js +240 -0
  713. package/dist/theme/ThemeProvider.js.map +1 -0
  714. package/dist/theme/ThemeScript.d.ts +48 -0
  715. package/dist/theme/ThemeScript.d.ts.map +1 -0
  716. package/dist/theme/ThemeScript.js +13 -0
  717. package/dist/theme/ThemeScript.js.map +1 -0
  718. package/dist/theme/__tests__/theme.test.d.ts +2 -0
  719. package/dist/theme/__tests__/theme.test.d.ts.map +1 -0
  720. package/dist/theme/__tests__/theme.test.js +103 -0
  721. package/dist/theme/__tests__/theme.test.js.map +1 -0
  722. package/dist/theme/constants.d.ts +29 -0
  723. package/dist/theme/constants.d.ts.map +1 -0
  724. package/dist/theme/constants.js +48 -0
  725. package/dist/theme/constants.js.map +1 -0
  726. package/dist/theme/index.d.ts +31 -0
  727. package/dist/theme/index.d.ts.map +1 -0
  728. package/dist/theme/index.js +36 -0
  729. package/dist/theme/index.js.map +1 -0
  730. package/dist/theme/theme-context.d.ts +40 -0
  731. package/dist/theme/theme-context.d.ts.map +1 -0
  732. package/dist/theme/theme-context.js +60 -0
  733. package/dist/theme/theme-context.js.map +1 -0
  734. package/dist/theme/theme-script.d.ts +27 -0
  735. package/dist/theme/theme-script.d.ts.map +1 -0
  736. package/dist/theme/theme-script.js +147 -0
  737. package/dist/theme/theme-script.js.map +1 -0
  738. package/dist/theme/types.d.ts +163 -0
  739. package/dist/theme/types.d.ts.map +1 -0
  740. package/dist/theme/types.js +11 -0
  741. package/dist/theme/types.js.map +1 -0
  742. package/dist/theme/use-theme.d.ts +12 -0
  743. package/dist/theme/use-theme.d.ts.map +1 -0
  744. package/dist/theme/use-theme.js +40 -0
  745. package/dist/theme/use-theme.js.map +1 -0
  746. package/dist/types.d.ts +1479 -0
  747. package/dist/types.d.ts.map +1 -0
  748. package/dist/types.js +10 -0
  749. package/dist/types.js.map +1 -0
  750. package/dist/urls.d.ts +441 -0
  751. package/dist/urls.d.ts.map +1 -0
  752. package/dist/urls.gen.d.ts +8 -0
  753. package/dist/urls.gen.d.ts.map +1 -0
  754. package/dist/urls.gen.js +8 -0
  755. package/dist/urls.gen.js.map +1 -0
  756. package/dist/urls.js +443 -0
  757. package/dist/urls.js.map +1 -0
  758. package/dist/use-loader.d.ts +127 -0
  759. package/dist/use-loader.d.ts.map +1 -0
  760. package/dist/use-loader.js +237 -0
  761. package/dist/use-loader.js.map +1 -0
  762. package/dist/vite/__tests__/ast-handler-extract.test.d.ts +2 -0
  763. package/dist/vite/__tests__/ast-handler-extract.test.d.ts.map +1 -0
  764. package/dist/vite/__tests__/ast-handler-extract.test.js +294 -0
  765. package/dist/vite/__tests__/ast-handler-extract.test.js.map +1 -0
  766. package/dist/vite/__tests__/expose-id-utils.test.d.ts +2 -0
  767. package/dist/vite/__tests__/expose-id-utils.test.d.ts.map +1 -0
  768. package/dist/vite/__tests__/expose-id-utils.test.js +224 -0
  769. package/dist/vite/__tests__/expose-id-utils.test.js.map +1 -0
  770. package/dist/vite/__tests__/expose-internal-ids.test.d.ts +2 -0
  771. package/dist/vite/__tests__/expose-internal-ids.test.d.ts.map +1 -0
  772. package/dist/vite/__tests__/expose-internal-ids.test.js +647 -0
  773. package/dist/vite/__tests__/expose-internal-ids.test.js.map +1 -0
  774. package/dist/vite/__tests__/expose-router-id.test.d.ts +2 -0
  775. package/dist/vite/__tests__/expose-router-id.test.d.ts.map +1 -0
  776. package/dist/vite/__tests__/expose-router-id.test.js +39 -0
  777. package/dist/vite/__tests__/expose-router-id.test.js.map +1 -0
  778. package/dist/vite/ast-handler-extract.d.ts +49 -0
  779. package/dist/vite/ast-handler-extract.d.ts.map +1 -0
  780. package/dist/vite/ast-handler-extract.js +249 -0
  781. package/dist/vite/ast-handler-extract.js.map +1 -0
  782. package/dist/vite/expose-action-id.d.ts +19 -0
  783. package/dist/vite/expose-action-id.d.ts.map +1 -0
  784. package/dist/vite/expose-action-id.js +250 -0
  785. package/dist/vite/expose-action-id.js.map +1 -0
  786. package/dist/vite/expose-id-utils.d.ts +69 -0
  787. package/dist/vite/expose-id-utils.d.ts.map +1 -0
  788. package/dist/vite/expose-id-utils.js +289 -0
  789. package/dist/vite/expose-id-utils.js.map +1 -0
  790. package/dist/vite/expose-internal-ids.d.ts +22 -0
  791. package/dist/vite/expose-internal-ids.d.ts.map +1 -0
  792. package/dist/vite/expose-internal-ids.js +886 -0
  793. package/dist/vite/expose-internal-ids.js.map +1 -0
  794. package/dist/vite/index.d.ts +149 -0
  795. package/dist/vite/index.d.ts.map +1 -0
  796. package/dist/vite/index.js +1890 -540
  797. package/dist/vite/index.js.bak +5448 -0
  798. package/dist/vite/index.js.map +1 -0
  799. package/dist/vite/index.named-routes.gen.ts +103 -0
  800. package/dist/vite/package-resolution.d.ts +43 -0
  801. package/dist/vite/package-resolution.d.ts.map +1 -0
  802. package/dist/vite/package-resolution.js +112 -0
  803. package/dist/vite/package-resolution.js.map +1 -0
  804. package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  805. package/dist/vite/virtual-entries.d.ts +25 -0
  806. package/dist/vite/virtual-entries.d.ts.map +1 -0
  807. package/dist/vite/virtual-entries.js +110 -0
  808. package/dist/vite/virtual-entries.js.map +1 -0
  809. package/package.json +7 -5
  810. package/skills/breadcrumbs/SKILL.md +3 -1
  811. package/skills/cache-guide/SKILL.md +32 -0
  812. package/skills/caching/SKILL.md +8 -0
  813. package/skills/handler-use/SKILL.md +362 -0
  814. package/skills/hooks/SKILL.md +33 -20
  815. package/skills/i18n/SKILL.md +276 -0
  816. package/skills/intercept/SKILL.md +20 -0
  817. package/skills/layout/SKILL.md +22 -0
  818. package/skills/links/SKILL.md +93 -17
  819. package/skills/loader/SKILL.md +123 -46
  820. package/skills/middleware/SKILL.md +36 -3
  821. package/skills/migrate-nextjs/SKILL.md +562 -0
  822. package/skills/migrate-react-router/SKILL.md +769 -0
  823. package/skills/parallel/SKILL.md +192 -0
  824. package/skills/prerender/SKILL.md +110 -68
  825. package/skills/rango/SKILL.md +26 -22
  826. package/skills/response-routes/SKILL.md +8 -0
  827. package/skills/route/SKILL.md +75 -0
  828. package/skills/router-setup/SKILL.md +87 -2
  829. package/skills/server-actions/SKILL.md +739 -0
  830. package/skills/streams-and-websockets/SKILL.md +283 -0
  831. package/skills/typesafety/SKILL.md +19 -1
  832. package/src/__internal.ts +1 -1
  833. package/src/browser/app-shell.ts +52 -0
  834. package/src/browser/app-version.ts +14 -0
  835. package/src/browser/event-controller.ts +49 -4
  836. package/src/browser/navigation-bridge.ts +95 -7
  837. package/src/browser/navigation-client.ts +132 -70
  838. package/src/browser/navigation-store.ts +68 -9
  839. package/src/browser/partial-update.ts +93 -12
  840. package/src/browser/prefetch/cache.ts +134 -26
  841. package/src/browser/prefetch/fetch.ts +168 -31
  842. package/src/browser/prefetch/queue.ts +92 -29
  843. package/src/browser/prefetch/resource-ready.ts +77 -0
  844. package/src/browser/rango-state.ts +53 -13
  845. package/src/browser/react/Link.tsx +72 -8
  846. package/src/browser/react/NavigationProvider.tsx +82 -21
  847. package/src/browser/react/context.ts +7 -2
  848. package/src/browser/react/filter-segment-order.ts +51 -7
  849. package/src/browser/react/use-handle.ts +9 -58
  850. package/src/browser/react/use-navigation.ts +22 -2
  851. package/src/browser/react/use-params.ts +17 -4
  852. package/src/browser/react/use-router.ts +29 -9
  853. package/src/browser/react/use-segments.ts +11 -8
  854. package/src/browser/rsc-router.tsx +82 -10
  855. package/src/browser/scroll-restoration.ts +10 -8
  856. package/src/browser/segment-reconciler.ts +36 -9
  857. package/src/browser/server-action-bridge.ts +8 -6
  858. package/src/browser/types.ts +46 -5
  859. package/src/build/generate-manifest.ts +6 -6
  860. package/src/build/generate-route-types.ts +3 -0
  861. package/src/build/route-trie.ts +52 -25
  862. package/src/build/route-types/include-resolution.ts +8 -1
  863. package/src/build/route-types/router-processing.ts +211 -72
  864. package/src/build/route-types/scan-filter.ts +8 -1
  865. package/src/cache/cache-runtime.ts +15 -11
  866. package/src/cache/cache-scope.ts +46 -5
  867. package/src/cache/cf/cf-cache-store.ts +5 -7
  868. package/src/cache/document-cache.ts +17 -7
  869. package/src/cache/taint.ts +55 -0
  870. package/src/client.tsx +84 -230
  871. package/src/context-var.ts +72 -2
  872. package/src/debug.ts +2 -2
  873. package/src/handle.ts +40 -0
  874. package/src/index.rsc.ts +6 -1
  875. package/src/index.ts +49 -6
  876. package/src/outlet-context.ts +1 -1
  877. package/src/prerender/store.ts +5 -4
  878. package/src/prerender.ts +138 -77
  879. package/src/response-utils.ts +28 -0
  880. package/src/reverse.ts +28 -2
  881. package/src/route-definition/dsl-helpers.ts +240 -40
  882. package/src/route-definition/helpers-types.ts +73 -20
  883. package/src/route-definition/index.ts +3 -0
  884. package/src/route-definition/redirect.ts +9 -1
  885. package/src/route-definition/resolve-handler-use.ts +155 -0
  886. package/src/route-types.ts +18 -0
  887. package/src/router/content-negotiation.ts +100 -1
  888. package/src/router/handler-context.ts +102 -25
  889. package/src/router/intercept-resolution.ts +9 -4
  890. package/src/router/lazy-includes.ts +8 -7
  891. package/src/router/loader-resolution.ts +159 -21
  892. package/src/router/logging.ts +1 -1
  893. package/src/router/manifest.ts +28 -15
  894. package/src/router/match-api.ts +128 -192
  895. package/src/router/match-handlers.ts +1 -0
  896. package/src/router/match-middleware/background-revalidation.ts +30 -2
  897. package/src/router/match-middleware/cache-lookup.ts +94 -17
  898. package/src/router/match-middleware/cache-store.ts +53 -10
  899. package/src/router/match-middleware/intercept-resolution.ts +9 -7
  900. package/src/router/match-middleware/segment-resolution.ts +60 -5
  901. package/src/router/match-result.ts +123 -10
  902. package/src/router/metrics.ts +6 -1
  903. package/src/router/middleware-types.ts +20 -33
  904. package/src/router/middleware.ts +56 -12
  905. package/src/router/navigation-snapshot.ts +182 -0
  906. package/src/router/pattern-matching.ts +101 -17
  907. package/src/router/prerender-match.ts +110 -10
  908. package/src/router/preview-match.ts +30 -102
  909. package/src/router/request-classification.ts +310 -0
  910. package/src/router/revalidation.ts +15 -1
  911. package/src/router/route-snapshot.ts +245 -0
  912. package/src/router/router-context.ts +1 -0
  913. package/src/router/router-interfaces.ts +36 -4
  914. package/src/router/router-options.ts +37 -11
  915. package/src/router/segment-resolution/fresh.ts +206 -20
  916. package/src/router/segment-resolution/helpers.ts +29 -24
  917. package/src/router/segment-resolution/loader-cache.ts +1 -0
  918. package/src/router/segment-resolution/revalidation.ts +447 -282
  919. package/src/router/trie-matching.ts +18 -13
  920. package/src/router/types.ts +1 -0
  921. package/src/router/url-params.ts +49 -0
  922. package/src/router.ts +56 -8
  923. package/src/rsc/handler.ts +478 -374
  924. package/src/rsc/helpers.ts +69 -41
  925. package/src/rsc/loader-fetch.ts +23 -3
  926. package/src/rsc/manifest-init.ts +5 -1
  927. package/src/rsc/progressive-enhancement.ts +18 -2
  928. package/src/rsc/response-route-handler.ts +14 -1
  929. package/src/rsc/rsc-rendering.ts +20 -1
  930. package/src/rsc/server-action.ts +12 -0
  931. package/src/rsc/ssr-setup.ts +2 -2
  932. package/src/rsc/types.ts +15 -1
  933. package/src/segment-content-promise.ts +67 -0
  934. package/src/segment-loader-promise.ts +122 -0
  935. package/src/segment-system.tsx +131 -31
  936. package/src/server/context.ts +166 -17
  937. package/src/server/handle-store.ts +19 -0
  938. package/src/server/loader-registry.ts +9 -8
  939. package/src/server/request-context.ts +185 -57
  940. package/src/ssr/index.tsx +9 -1
  941. package/src/static-handler.ts +18 -6
  942. package/src/types/cache-types.ts +4 -4
  943. package/src/types/handler-context.ts +145 -68
  944. package/src/types/loader-types.ts +41 -15
  945. package/src/types/request-scope.ts +126 -0
  946. package/src/types/route-entry.ts +12 -1
  947. package/src/types/segments.ts +19 -0
  948. package/src/urls/include-helper.ts +24 -14
  949. package/src/urls/path-helper-types.ts +39 -6
  950. package/src/urls/path-helper.ts +48 -13
  951. package/src/urls/pattern-types.ts +12 -0
  952. package/src/urls/response-types.ts +18 -16
  953. package/src/use-loader.tsx +77 -5
  954. package/src/vite/debug.ts +184 -0
  955. package/src/vite/discovery/bundle-postprocess.ts +30 -33
  956. package/src/vite/discovery/discover-routers.ts +36 -4
  957. package/src/vite/discovery/gate-state.ts +171 -0
  958. package/src/vite/discovery/prerender-collection.ts +175 -74
  959. package/src/vite/discovery/self-gen-tracking.ts +27 -1
  960. package/src/vite/discovery/state.ts +13 -4
  961. package/src/vite/index.ts +4 -0
  962. package/src/vite/plugin-types.ts +60 -5
  963. package/src/vite/plugins/cjs-to-esm.ts +5 -0
  964. package/src/vite/plugins/client-ref-dedup.ts +16 -0
  965. package/src/vite/plugins/client-ref-hashing.ts +16 -4
  966. package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
  967. package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  968. package/src/vite/plugins/cloudflare-protocol-stub.ts +214 -0
  969. package/src/vite/plugins/expose-action-id.ts +52 -28
  970. package/src/vite/plugins/expose-id-utils.ts +12 -0
  971. package/src/vite/plugins/expose-ids/handler-transform.ts +30 -0
  972. package/src/vite/plugins/expose-ids/router-transform.ts +20 -3
  973. package/src/vite/plugins/expose-internal-ids.ts +563 -316
  974. package/src/vite/plugins/performance-tracks.ts +96 -0
  975. package/src/vite/plugins/refresh-cmd.ts +88 -26
  976. package/src/vite/plugins/use-cache-transform.ts +56 -43
  977. package/src/vite/plugins/version-injector.ts +37 -11
  978. package/src/vite/plugins/version-plugin.ts +9 -0
  979. package/src/vite/rango.ts +63 -11
  980. package/src/vite/router-discovery.ts +732 -86
  981. package/src/vite/utils/banner.ts +4 -4
  982. package/src/vite/utils/package-resolution.ts +41 -1
  983. package/src/vite/utils/prerender-utils.ts +38 -5
  984. package/src/vite/utils/shared-utils.ts +3 -2
@@ -18,6 +18,9 @@ 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 makeStubId(filePath, exportName, isBuild) {
22
+ return isBuild ? hashId(filePath, exportName) : `${filePath}#${exportName}`;
23
+ }
21
24
  function hashInlineId(filePath, lineNumber, index) {
22
25
  const input = index !== void 0 && index > 0 ? `${filePath}:${lineNumber}:${index}` : `${filePath}:${lineNumber}`;
23
26
  return crypto.createHash("sha256").update(input).digest("hex").slice(0, 8);
@@ -188,7 +191,99 @@ 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
+ };
205
+ if (process.env.INTERNAL_RANGO_DEBUG) {
206
+ const existing = debugFactory.disable();
207
+ debugFactory.enable(existing ? `${existing},rango:*` : "rango:*");
208
+ }
209
+ function createRangoDebugger(namespace) {
210
+ const primary = debugFactory(namespace);
211
+ const shadow = debugFactory(`vite:${namespace}`);
212
+ if (primary.enabled) return primary;
213
+ if (shadow.enabled) return shadow;
214
+ return void 0;
215
+ }
216
+ async function timed(debug11, label, fn) {
217
+ if (!debug11) return await fn();
218
+ const start = performance.now();
219
+ try {
220
+ return await fn();
221
+ } finally {
222
+ debug11("%s (%sms)", label, (performance.now() - start).toFixed(1));
223
+ }
224
+ }
225
+ function timedSync(debug11, label, fn) {
226
+ if (!debug11) return fn();
227
+ const start = performance.now();
228
+ try {
229
+ return fn();
230
+ } finally {
231
+ debug11("%s (%sms)", label, (performance.now() - start).toFixed(1));
232
+ }
233
+ }
234
+ function createCounter(debug11, label) {
235
+ if (!debug11) return void 0;
236
+ let n = 0;
237
+ let totalMs = 0;
238
+ let slowestMs = 0;
239
+ let slowestFile = "";
240
+ const record = (file, ms) => {
241
+ n++;
242
+ totalMs += ms;
243
+ if (ms > slowestMs) {
244
+ slowestMs = ms;
245
+ slowestFile = file;
246
+ }
247
+ };
248
+ return {
249
+ record,
250
+ time(file, fn) {
251
+ const start = performance.now();
252
+ let out;
253
+ try {
254
+ out = fn();
255
+ } catch (err) {
256
+ record(file, performance.now() - start);
257
+ throw err;
258
+ }
259
+ if (out && typeof out.then === "function") {
260
+ return out.finally(
261
+ () => record(file, performance.now() - start)
262
+ );
263
+ }
264
+ record(file, performance.now() - start);
265
+ return out;
266
+ },
267
+ flush() {
268
+ if (n === 0) return;
269
+ debug11(
270
+ "%s: %d files, %sms total, slowest %sms %s",
271
+ label,
272
+ n,
273
+ totalMs.toFixed(1),
274
+ slowestMs.toFixed(1),
275
+ slowestFile
276
+ );
277
+ n = 0;
278
+ totalMs = 0;
279
+ slowestMs = 0;
280
+ slowestFile = "";
281
+ }
282
+ };
283
+ }
284
+
191
285
  // src/vite/plugins/expose-action-id.ts
286
+ var debug = createRangoDebugger(NS.transform);
192
287
  function getRscPluginApi(config) {
193
288
  let plugin = config.plugins.find((p) => p.name === "rsc:minimal");
194
289
  if (!plugin) {
@@ -277,6 +372,8 @@ function exposeActionId() {
277
372
  let isBuild = false;
278
373
  let hashToFileMap;
279
374
  let rscPluginApi;
375
+ const counterTransform = createCounter(debug, "expose-action-id transform");
376
+ const counterRender = createCounter(debug, "expose-action-id renderChunk");
280
377
  return {
281
378
  name: "@rangojs/router:expose-action-id",
282
379
  // Run after all other plugins (including RSC plugin's transforms)
@@ -286,6 +383,10 @@ function exposeActionId() {
286
383
  isBuild = config.command === "build";
287
384
  rscPluginApi = getRscPluginApi(config);
288
385
  },
386
+ buildEnd() {
387
+ counterTransform?.flush();
388
+ counterRender?.flush();
389
+ },
289
390
  buildStart() {
290
391
  if (!rscPluginApi) {
291
392
  rscPluginApi = getRscPluginApi(config);
@@ -322,28 +423,42 @@ function exposeActionId() {
322
423
  if (id.includes("/node_modules/")) {
323
424
  return;
324
425
  }
325
- return transformServerReferences(code, id);
426
+ const start = counterTransform ? performance.now() : 0;
427
+ try {
428
+ return transformServerReferences(code, id);
429
+ } finally {
430
+ counterTransform?.record(id, performance.now() - start);
431
+ }
326
432
  },
327
433
  // Build mode: renderChunk runs after all transforms and bundling complete
328
434
  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
- };
435
+ const start = counterRender ? performance.now() : 0;
436
+ try {
437
+ const isRscEnv = this.environment?.name === "rsc";
438
+ const effectiveMap = isRscEnv ? hashToFileMap : void 0;
439
+ if (isRscEnv && hashToFileMap) {
440
+ const s = new MagicString(code);
441
+ const changed1 = applyServerReferenceWrapping(code, s, effectiveMap);
442
+ const changed2 = applyRegisterReferenceWrapping(
443
+ code,
444
+ s,
445
+ hashToFileMap
446
+ );
447
+ if (changed1 || changed2) {
448
+ return {
449
+ code: s.toString(),
450
+ map: s.generateMap({
451
+ source: chunk.fileName,
452
+ includeContent: true
453
+ })
454
+ };
455
+ }
456
+ return null;
343
457
  }
344
- return null;
458
+ return transformServerReferences(code, chunk.fileName, effectiveMap);
459
+ } finally {
460
+ counterRender?.record(chunk.fileName, performance.now() - start);
345
461
  }
346
- return transformServerReferences(code, chunk.fileName, effectiveMap);
347
462
  }
348
463
  };
349
464
  }
@@ -910,9 +1025,7 @@ function generateWholeFileStubs(cfg, bindings, code, filePath, isBuild) {
910
1025
  });
911
1026
  return { code: stubs.join("\n") + "\n", map: null };
912
1027
  }
913
- function generateExprStubs(cfg, bindings, code, filePath, sourceId, isBuild) {
914
- if (bindings.length === 0) return null;
915
- const s = new MagicString2(code);
1028
+ function stubHandlerExprs(cfg, bindings, s, filePath, isBuild) {
916
1029
  let hasChanges = false;
917
1030
  for (const binding of bindings) {
918
1031
  const exportName = binding.exportNames[0];
@@ -924,15 +1037,7 @@ function generateExprStubs(cfg, bindings, code, filePath, sourceId, isBuild) {
924
1037
  );
925
1038
  hasChanges = true;
926
1039
  }
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
- };
1040
+ return hasChanges;
936
1041
  }
937
1042
  function transformHandlerIds(cfg, bindings, s, filePath, isBuild) {
938
1043
  let hasChanges = false;
@@ -960,6 +1065,7 @@ ${binding.localName}.$$id = "${handlerId}";`;
960
1065
  import MagicString3 from "magic-string";
961
1066
  import path3 from "node:path";
962
1067
  import { createHash } from "node:crypto";
1068
+ var debug2 = createRangoDebugger(NS.transform);
963
1069
  function transformRouter(code, filePath, routerFnNames, absolutePath) {
964
1070
  const pat = new RegExp(
965
1071
  `\\b(?:${routerFnNames.map((n) => n.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|")})\\s*(?:<[^>]*>)?\\s*\\(`,
@@ -1002,11 +1108,15 @@ function transformRouter(code, filePath, routerFnNames, absolutePath) {
1002
1108
  }
1003
1109
  function exposeRouterId() {
1004
1110
  let projectRoot = "";
1111
+ const counter = createCounter(debug2, "expose-router-id");
1005
1112
  return {
1006
1113
  name: "@rangojs/router:expose-router-id",
1007
1114
  configResolved(config) {
1008
1115
  projectRoot = config.root;
1009
1116
  },
1117
+ buildEnd() {
1118
+ counter?.flush();
1119
+ },
1010
1120
  transform(code, id) {
1011
1121
  if (!code.includes("createRouter")) return null;
1012
1122
  if (!/import\s*\{[^}]*\bcreateRouter\b[^}]*\}\s*from\s*["']@rangojs\/router(?:\/server)?["']/.test(
@@ -1015,14 +1125,25 @@ function exposeRouterId() {
1015
1125
  return null;
1016
1126
  }
1017
1127
  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));
1128
+ const start = counter ? performance.now() : 0;
1129
+ try {
1130
+ const filePath = normalizePath(path3.relative(projectRoot, id));
1131
+ const routerFnNames = getImportedFnNames(code, "createRouter");
1132
+ return transformRouter(
1133
+ code,
1134
+ filePath,
1135
+ routerFnNames,
1136
+ normalizePath(id)
1137
+ );
1138
+ } finally {
1139
+ counter?.record(id, performance.now() - start);
1140
+ }
1021
1141
  }
1022
1142
  };
1023
1143
  }
1024
1144
 
1025
1145
  // src/vite/plugins/expose-internal-ids.ts
1146
+ var debug3 = createRangoDebugger(NS.transform);
1026
1147
  var VIRTUAL_LOADER_MANIFEST = "virtual:rsc-router/loader-manifest";
1027
1148
  var RESOLVED_VIRTUAL_LOADER_MANIFEST = "\0" + VIRTUAL_LOADER_MANIFEST;
1028
1149
  var VIRTUAL_HANDLER_PREFIX = "virtual:handler-extract:";
@@ -1035,9 +1156,13 @@ function exposeInternalIds(options) {
1035
1156
  const staticHandlerModules = /* @__PURE__ */ new Map();
1036
1157
  const virtualHandlers = /* @__PURE__ */ new Map();
1037
1158
  const unsupportedShapeWarnings = /* @__PURE__ */ new Set();
1159
+ const counter = createCounter(debug3, "expose-internal-ids");
1038
1160
  return {
1039
1161
  name: "@rangojs/router:expose-internal-ids",
1040
1162
  enforce: "post",
1163
+ buildEnd() {
1164
+ counter?.flush();
1165
+ },
1041
1166
  api: {
1042
1167
  prerenderHandlerModules,
1043
1168
  staticHandlerModules
@@ -1151,11 +1276,13 @@ ${lazyImports.join(",\n")}
1151
1276
  // --------------- Unified transform ---------------
1152
1277
  transform(code, id) {
1153
1278
  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
- `
1279
+ const __t0 = counter ? performance.now() : 0;
1280
+ try {
1281
+ const filePath = normalizePath(path4.relative(projectRoot, id));
1282
+ const isRscEnv = this.environment?.name === "rsc";
1283
+ if (id.includes(".named-routes.gen.") && !isRscEnv && this.environment?.name === "client") {
1284
+ this.warn(
1285
+ `
1159
1286
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1160
1287
  !! !!
1161
1288
  !! WARNING: NamedRoutes imported in a CLIENT component! !!
@@ -1175,228 +1302,373 @@ ${lazyImports.join(",\n")}
1175
1302
  !! !!
1176
1303
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1177
1304
  `
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);
1305
+ );
1200
1306
  }
1201
- return result;
1202
- };
1203
- const lazyAst = () => {
1204
- if (code !== _astCodeRef) {
1205
- _cachedAst = void 0;
1206
- _astParseFailed = false;
1207
- _astCodeRef = code;
1307
+ if (!code.includes("@rangojs/router")) return;
1308
+ const has = detectImports(code);
1309
+ const hasLoaderCode = has.loader && code.includes("createLoader");
1310
+ const hasHandleCode = has.handle && code.includes("createHandle");
1311
+ const hasLocationStateCode = has.locationState && code.includes("createLocationState");
1312
+ const hasPrerenderHandlerCode = has.prerenderHandler && code.includes("Prerender");
1313
+ const hasStaticHandlerCode = has.staticHandler && code.includes("Static");
1314
+ if (!hasLoaderCode && !hasHandleCode && !hasLocationStateCode && !hasPrerenderHandlerCode && !hasStaticHandlerCode) {
1315
+ return;
1208
1316
  }
1209
- if (_cachedAst !== void 0 || _astParseFailed) return _cachedAst;
1210
- try {
1211
- _cachedAst = parseAst2(code, { jsx: true });
1212
- } catch {
1213
- _astParseFailed = true;
1317
+ const _fnNamesCache = /* @__PURE__ */ new Map();
1318
+ const _bindingsCache = /* @__PURE__ */ new Map();
1319
+ let _cachedAst;
1320
+ let _astParseFailed = false;
1321
+ let _astCodeRef = code;
1322
+ const getFnNames = (canonicalName) => {
1323
+ let result = _fnNamesCache.get(canonicalName);
1324
+ if (!result) {
1325
+ result = getImportedFnNames(code, canonicalName);
1326
+ _fnNamesCache.set(canonicalName, result);
1327
+ }
1328
+ return result;
1329
+ };
1330
+ const lazyAst = () => {
1331
+ if (code !== _astCodeRef) {
1332
+ _cachedAst = void 0;
1333
+ _astParseFailed = false;
1334
+ _astCodeRef = code;
1335
+ }
1336
+ if (_cachedAst !== void 0 || _astParseFailed) return _cachedAst;
1337
+ try {
1338
+ _cachedAst = parseAst2(code, { jsx: true });
1339
+ } catch {
1340
+ _astParseFailed = true;
1341
+ }
1342
+ return _cachedAst;
1343
+ };
1344
+ const getBindings = (currentCode, fnNames) => {
1345
+ const key = fnNames.join("\0");
1346
+ let result = _bindingsCache.get(key);
1347
+ if (!result) {
1348
+ result = collectCreateExportBindings(
1349
+ currentCode,
1350
+ fnNames,
1351
+ lazyAst()
1352
+ );
1353
+ _bindingsCache.set(key, result);
1354
+ }
1355
+ return result;
1356
+ };
1357
+ for (const cfg of STRICT_CREATE_CONFIGS) {
1358
+ const hasCode = cfg.fnName === "createLoader" ? hasLoaderCode : cfg.fnName === "createHandle" ? hasHandleCode : hasLocationStateCode;
1359
+ if (!hasCode) continue;
1360
+ const fnNames = getFnNames(cfg.fnName);
1361
+ const totalCalls = countCreateCallsForNames(code, fnNames);
1362
+ const supportedBindings = getBindings(code, fnNames).length;
1363
+ if (totalCalls <= supportedBindings) continue;
1364
+ const warnKey = `${id}::${cfg.fnName}`;
1365
+ if (unsupportedShapeWarnings.has(warnKey)) continue;
1366
+ unsupportedShapeWarnings.add(warnKey);
1367
+ this.warn(buildUnsupportedShapeWarning(filePath, cfg.fnName));
1214
1368
  }
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);
1369
+ if (hasLoaderCode && isRscEnv) {
1370
+ const fnNames = getFnNames("createLoader");
1371
+ const bindings = getBindings(code, fnNames);
1372
+ for (const binding of bindings) {
1373
+ const exportName = binding.exportNames[0];
1374
+ const hashedId = hashId(filePath, exportName);
1375
+ loaderRegistry.set(hashedId, {
1376
+ filePath,
1377
+ exportName
1378
+ });
1379
+ }
1223
1380
  }
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, {
1381
+ if (hasLoaderCode && !isRscEnv) {
1382
+ const fnNames = getFnNames("createLoader");
1383
+ const bindings = getBindings(code, fnNames);
1384
+ const stubResult = generateClientLoaderStubs(
1385
+ bindings,
1386
+ code,
1245
1387
  filePath,
1246
- exportName
1247
- });
1388
+ isBuild
1389
+ );
1390
+ if (stubResult) return stubResult;
1248
1391
  }
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);
1392
+ if (hasPrerenderHandlerCode && !isRscEnv) {
1393
+ const fnNames = getFnNames(PRERENDER_CONFIG.fnName);
1394
+ const bindings = getBindings(code, fnNames);
1395
+ const wholeFile = generateWholeFileStubs(
1396
+ PRERENDER_CONFIG,
1397
+ bindings,
1398
+ code,
1399
+ filePath,
1400
+ isBuild
1401
+ );
1402
+ if (wholeFile) return wholeFile;
1289
1403
  }
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,
1404
+ if (hasPrerenderHandlerCode && isRscEnv && isBuild) {
1405
+ const fnNames = getFnNames(PRERENDER_CONFIG.fnName);
1406
+ const exportNames = getBindings(code, fnNames).map(
1407
+ (b) => b.exportNames[0]
1408
+ );
1409
+ if (exportNames.length > 0) {
1410
+ prerenderHandlerModules.set(id, exportNames);
1411
+ }
1412
+ }
1413
+ let changed = false;
1414
+ const handlerConfigs = [
1415
+ hasStaticHandlerCode && STATIC_CONFIG,
1416
+ hasPrerenderHandlerCode && PRERENDER_CONFIG
1417
+ ].filter((c) => !!c).map((cfg) => {
1418
+ const fnNames = getFnNames(cfg.fnName);
1419
+ return { cfg, fnNames };
1420
+ });
1421
+ for (const { cfg, fnNames } of handlerConfigs) {
1422
+ const totalCalls = countCreateCallsForNames(code, fnNames);
1423
+ const supportedBindings = getBindings(code, fnNames).length;
1424
+ if (totalCalls > supportedBindings) {
1425
+ const iterS = new MagicString4(code);
1426
+ const result = transformInlineHandlers(
1427
+ cfg.fnName,
1428
+ VIRTUAL_HANDLER_PREFIX,
1429
+ iterS,
1430
+ code,
1431
+ filePath,
1432
+ virtualHandlers,
1433
+ id,
1434
+ parseAst2
1435
+ );
1436
+ if (result) {
1437
+ changed = true;
1438
+ code = iterS.toString();
1439
+ _bindingsCache.clear();
1440
+ }
1441
+ }
1442
+ }
1443
+ if (hasStaticHandlerCode && !isRscEnv) {
1444
+ const fnNames = getFnNames(STATIC_CONFIG.fnName);
1445
+ const bindings = getBindings(code, fnNames);
1446
+ const wholeFile = generateWholeFileStubs(
1447
+ STATIC_CONFIG,
1448
+ bindings,
1308
1449
  code,
1309
1450
  filePath,
1310
- virtualHandlers,
1311
- id,
1312
- parseAst2
1451
+ isBuild
1313
1452
  );
1314
- if (result) {
1315
- changed = true;
1316
- code = iterS.toString();
1317
- _bindingsCache.clear();
1453
+ if (wholeFile) return wholeFile;
1454
+ }
1455
+ if (!isRscEnv && (hasPrerenderHandlerCode || hasStaticHandlerCode)) {
1456
+ const prerenderFnNames = hasPrerenderHandlerCode ? getFnNames(PRERENDER_CONFIG.fnName) : [];
1457
+ const staticFnNames = hasStaticHandlerCode ? getFnNames(STATIC_CONFIG.fnName) : [];
1458
+ const loaderFnNames = hasLoaderCode ? getFnNames("createLoader") : [];
1459
+ const handleFnNames = hasHandleCode ? getFnNames("createHandle") : [];
1460
+ const lsFnNames = hasLocationStateCode ? getFnNames("createLocationState") : [];
1461
+ const allBindings = [];
1462
+ for (const fnNames of [
1463
+ prerenderFnNames,
1464
+ staticFnNames,
1465
+ loaderFnNames,
1466
+ handleFnNames,
1467
+ lsFnNames
1468
+ ]) {
1469
+ if (fnNames.length > 0) {
1470
+ allBindings.push(...getBindings(code, fnNames));
1471
+ }
1472
+ }
1473
+ let canStubWholeFile = allBindings.length > 0 && isExportOnlyFile(code, allBindings);
1474
+ if (canStubWholeFile && (handleFnNames.length > 0 || lsFnNames.length > 0)) {
1475
+ const exportedLocals = new Set(allBindings.map((b) => b.localName));
1476
+ const strippedBindings = [];
1477
+ const localDeclPattern = /(?:^|;|\n)\s*(?:const|let|var|function)\s+(\w+)/g;
1478
+ let declMatch;
1479
+ while ((declMatch = localDeclPattern.exec(code)) !== null) {
1480
+ const name = declMatch[1];
1481
+ if (!exportedLocals.has(name) && !/^_c\d*$/.test(name)) {
1482
+ strippedBindings.push(name);
1483
+ }
1484
+ }
1485
+ const importPattern = /import\s*\{([^}]*)\}\s*from\s*["'](?!@rangojs\/router)[^"']*["']/g;
1486
+ let importMatch;
1487
+ while ((importMatch = importPattern.exec(code)) !== null) {
1488
+ for (const spec of importMatch[1].split(",")) {
1489
+ const m = spec.trim().match(/^[A-Za-z_$][\w$]*(?:\s+as\s+([A-Za-z_$][\w$]*))?$/);
1490
+ if (m)
1491
+ strippedBindings.push(m[1] || m[0].trim().split(/\s/)[0]);
1492
+ }
1493
+ }
1494
+ const defaultImportPattern = /import\s+([A-Za-z_$][\w$]*)\s+from\s*["'](?!@rangojs\/router)[^"']*["']/g;
1495
+ while ((importMatch = defaultImportPattern.exec(code)) !== null) {
1496
+ strippedBindings.push(importMatch[1]);
1497
+ }
1498
+ const nsImportPattern = /import\s+\*\s+as\s+([A-Za-z_$][\w$]*)\s+from\s*["'](?!@rangojs\/router)[^"']*["']/g;
1499
+ while ((importMatch = nsImportPattern.exec(code)) !== null) {
1500
+ strippedBindings.push(importMatch[1]);
1501
+ }
1502
+ if (strippedBindings.length > 0) {
1503
+ const preservedBindings = allBindings.filter((b) => {
1504
+ const fc = code.slice(b.callExprStart, b.callOpenParenPos + 1);
1505
+ return handleFnNames.some((n) => fc.includes(n)) || lsFnNames.some((n) => fc.includes(n));
1506
+ });
1507
+ const strippedRe = new RegExp(
1508
+ `\\b(?:${strippedBindings.join("|")})\\b`
1509
+ );
1510
+ canStubWholeFile = !preservedBindings.some((b) => {
1511
+ const expr = code.slice(
1512
+ b.callExprStart,
1513
+ b.callCloseParenPos + 1
1514
+ );
1515
+ return strippedRe.test(expr);
1516
+ });
1517
+ }
1518
+ }
1519
+ if (canStubWholeFile) {
1520
+ const lines = [];
1521
+ const neededImports = [];
1522
+ if (handleFnNames.length > 0) neededImports.push("createHandle");
1523
+ if (lsFnNames.length > 0) neededImports.push("createLocationState");
1524
+ if (neededImports.length > 0) {
1525
+ lines.push(
1526
+ `import { ${neededImports.join(", ")} } from "@rangojs/router";`
1527
+ );
1528
+ }
1529
+ for (const binding of allBindings) {
1530
+ const fnCall = code.slice(
1531
+ binding.callExprStart,
1532
+ binding.callOpenParenPos + 1
1533
+ );
1534
+ const isHandle = handleFnNames.some((n) => fnCall.includes(n));
1535
+ const isLocationState = lsFnNames.some((n) => fnCall.includes(n));
1536
+ const primaryName = binding.exportNames[0];
1537
+ const stubId = makeStubId(filePath, primaryName, isBuild);
1538
+ if (isHandle || isLocationState) {
1539
+ const rawArgs = code.slice(
1540
+ binding.callOpenParenPos + 1,
1541
+ binding.callCloseParenPos
1542
+ ).replace(/\b_c\d*\s*=\s*/g, "");
1543
+ const canonicalName = isHandle ? "createHandle" : "createLocationState";
1544
+ const activeFnNames = isHandle ? handleFnNames : lsFnNames;
1545
+ let rawCallee = code.slice(
1546
+ binding.callExprStart,
1547
+ binding.callOpenParenPos
1548
+ );
1549
+ for (const alias of activeFnNames) {
1550
+ if (alias !== canonicalName && rawCallee.startsWith(alias)) {
1551
+ rawCallee = canonicalName + rawCallee.slice(alias.length);
1552
+ break;
1553
+ }
1554
+ }
1555
+ if (isHandle) {
1556
+ const idParam = binding.argCount === 0 ? `undefined, "${stubId}"` : `, "${stubId}"`;
1557
+ lines.push(
1558
+ `export const ${primaryName} = ${rawCallee}(${rawArgs}${idParam});`
1559
+ );
1560
+ lines.push(`${primaryName}.$$id = "${stubId}";`);
1561
+ } else {
1562
+ lines.push(
1563
+ `export const ${primaryName} = ${rawCallee}(${rawArgs});`
1564
+ );
1565
+ lines.push(
1566
+ `${primaryName}.__rsc_ls_key = "__rsc_ls_${stubId}";`
1567
+ );
1568
+ }
1569
+ for (const name of binding.exportNames.slice(1)) {
1570
+ lines.push(`export const ${name} = ${primaryName};`);
1571
+ }
1572
+ } else {
1573
+ let brand = "loader";
1574
+ if (prerenderFnNames.some((n) => fnCall.includes(n))) {
1575
+ brand = PRERENDER_CONFIG.brand;
1576
+ } else if (staticFnNames.some((n) => fnCall.includes(n))) {
1577
+ brand = STATIC_CONFIG.brand;
1578
+ }
1579
+ lines.push(
1580
+ `export const ${primaryName} = { __brand: "${brand}", $$id: "${stubId}" };`
1581
+ );
1582
+ for (const name of binding.exportNames.slice(1)) {
1583
+ lines.push(`export const ${name} = ${primaryName};`);
1584
+ }
1585
+ }
1586
+ }
1587
+ return { code: lines.join("\n") + "\n", map: null };
1318
1588
  }
1319
1589
  }
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);
1590
+ if (hasStaticHandlerCode && isRscEnv && isBuild) {
1591
+ const fnNames = getFnNames(STATIC_CONFIG.fnName);
1592
+ const exportNames = getBindings(code, fnNames).map(
1593
+ (b) => b.exportNames[0]
1594
+ );
1595
+ if (exportNames.length > 0) {
1596
+ staticHandlerModules.set(id, exportNames);
1597
+ }
1349
1598
  }
1599
+ const s = new MagicString4(code);
1600
+ if (hasLoaderCode) {
1601
+ const fnNames = getFnNames("createLoader");
1602
+ changed = transformLoaders(
1603
+ getBindings(code, fnNames),
1604
+ s,
1605
+ filePath,
1606
+ isBuild
1607
+ ) || changed;
1608
+ }
1609
+ if (hasHandleCode) {
1610
+ const fnNames = getFnNames("createHandle");
1611
+ changed = transformHandles(
1612
+ getBindings(code, fnNames),
1613
+ s,
1614
+ code,
1615
+ filePath,
1616
+ isBuild
1617
+ ) || changed;
1618
+ }
1619
+ if (hasLocationStateCode) {
1620
+ const fnNames = getFnNames("createLocationState");
1621
+ changed = transformLocationState(
1622
+ getBindings(code, fnNames),
1623
+ s,
1624
+ filePath,
1625
+ isBuild
1626
+ ) || changed;
1627
+ }
1628
+ if (hasPrerenderHandlerCode) {
1629
+ const fnNames = getFnNames(PRERENDER_CONFIG.fnName);
1630
+ const bindings = getBindings(code, fnNames);
1631
+ if (isRscEnv) {
1632
+ changed = transformHandlerIds(
1633
+ PRERENDER_CONFIG,
1634
+ bindings,
1635
+ s,
1636
+ filePath,
1637
+ isBuild
1638
+ ) || changed;
1639
+ } else {
1640
+ changed = stubHandlerExprs(
1641
+ PRERENDER_CONFIG,
1642
+ bindings,
1643
+ s,
1644
+ filePath,
1645
+ isBuild
1646
+ ) || changed;
1647
+ }
1648
+ }
1649
+ if (hasStaticHandlerCode) {
1650
+ const fnNames = getFnNames(STATIC_CONFIG.fnName);
1651
+ const bindings = getBindings(code, fnNames);
1652
+ if (isRscEnv) {
1653
+ changed = transformHandlerIds(
1654
+ STATIC_CONFIG,
1655
+ bindings,
1656
+ s,
1657
+ filePath,
1658
+ isBuild
1659
+ ) || changed;
1660
+ } else {
1661
+ changed = stubHandlerExprs(STATIC_CONFIG, bindings, s, filePath, isBuild) || changed;
1662
+ }
1663
+ }
1664
+ if (!changed) return;
1665
+ return {
1666
+ code: s.toString(),
1667
+ map: s.generateMap({ source: id, includeContent: true })
1668
+ };
1669
+ } finally {
1670
+ counter?.record(id, performance.now() - __t0);
1350
1671
  }
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
1672
  }
1401
1673
  };
1402
1674
  }
@@ -1404,12 +1676,14 @@ ${lazyImports.join(",\n")}
1404
1676
  // src/vite/plugins/use-cache-transform.ts
1405
1677
  import path5 from "node:path";
1406
1678
  import MagicString5 from "magic-string";
1679
+ var debug4 = createRangoDebugger(NS.transform);
1407
1680
  var CACHE_RUNTIME_IMPORT = "@rangojs/router/cache-runtime";
1408
1681
  var LAYOUT_TEMPLATE_PATTERN = /\/(layout|template)\.(tsx?|jsx?)$/;
1409
1682
  function useCacheTransform() {
1410
1683
  let projectRoot = "";
1411
1684
  let isBuild = false;
1412
1685
  let rscTransforms = null;
1686
+ const counter = createCounter(debug4, "use-cache");
1413
1687
  return {
1414
1688
  name: "@rangojs/router:use-cache",
1415
1689
  enforce: "post",
@@ -1417,53 +1691,61 @@ function useCacheTransform() {
1417
1691
  projectRoot = config.root;
1418
1692
  isBuild = config.command === "build";
1419
1693
  },
1694
+ buildEnd() {
1695
+ counter?.flush();
1696
+ },
1420
1697
  async transform(code, id) {
1421
1698
  if (this.environment?.name !== "rsc") return;
1422
1699
  if (!code.includes("use cache")) return;
1423
1700
  if (id.includes("/node_modules/") || id.startsWith("\0")) return;
1424
1701
  if (!/\.(tsx?|jsx?|mjs)$/.test(id)) return;
1425
- if (!rscTransforms) {
1702
+ const start = counter ? performance.now() : 0;
1703
+ try {
1704
+ if (!rscTransforms) {
1705
+ try {
1706
+ rscTransforms = await import("@vitejs/plugin-rsc/transforms");
1707
+ } catch {
1708
+ return;
1709
+ }
1710
+ }
1711
+ const {
1712
+ hasDirective,
1713
+ transformWrapExport,
1714
+ transformHoistInlineDirective
1715
+ } = rscTransforms;
1716
+ let ast;
1426
1717
  try {
1427
- rscTransforms = await import("@vitejs/plugin-rsc/transforms");
1718
+ const { parseAst: parseAst4 } = await import("vite");
1719
+ ast = parseAst4(code);
1428
1720
  } catch {
1429
1721
  return;
1430
1722
  }
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(
1723
+ const filePath = normalizePath(path5.relative(projectRoot, id));
1724
+ const isLayoutOrTemplate = LAYOUT_TEMPLATE_PATTERN.test(id);
1725
+ if (hasDirective(ast.body, "use cache")) {
1726
+ return transformFileLevelUseCache(
1727
+ code,
1728
+ ast,
1729
+ filePath,
1730
+ id,
1731
+ isBuild,
1732
+ isLayoutOrTemplate,
1733
+ transformWrapExport
1734
+ );
1735
+ }
1736
+ const functionResult = transformFunctionLevelUseCache(
1448
1737
  code,
1449
1738
  ast,
1450
1739
  filePath,
1451
1740
  id,
1452
1741
  isBuild,
1453
- isLayoutOrTemplate,
1454
- transformWrapExport
1742
+ transformHoistInlineDirective
1455
1743
  );
1744
+ warnOnNearMissDirectives(ast, id, this.warn.bind(this));
1745
+ if (functionResult) return functionResult;
1746
+ } finally {
1747
+ counter?.record(id, performance.now() - start);
1456
1748
  }
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
1749
  }
1468
1750
  };
1469
1751
  }
@@ -1586,6 +1868,7 @@ function warnOnNearMissDirectives(ast, fileId, warn) {
1586
1868
  }
1587
1869
 
1588
1870
  // src/vite/plugins/client-ref-dedup.ts
1871
+ var debug5 = createRangoDebugger(NS.transform);
1589
1872
  var CLIENT_IN_SERVER_PROXY_PREFIX = "virtual:vite-rsc/client-in-server-package-proxy/";
1590
1873
  function extractPackageName(absolutePath) {
1591
1874
  const marker = "/node_modules/";
@@ -1602,6 +1885,7 @@ function extractPackageName(absolutePath) {
1602
1885
  }
1603
1886
  function clientRefDedup() {
1604
1887
  let clientExclude = [];
1888
+ const dedupedPackages = /* @__PURE__ */ new Set();
1605
1889
  return {
1606
1890
  name: "@rangojs/router:client-ref-dedup",
1607
1891
  enforce: "pre",
@@ -1610,6 +1894,15 @@ function clientRefDedup() {
1610
1894
  const clientEnv = config.environments?.["client"];
1611
1895
  clientExclude = clientEnv?.optimizeDeps?.exclude ?? config.optimizeDeps?.exclude ?? [];
1612
1896
  },
1897
+ buildEnd() {
1898
+ if (debug5 && dedupedPackages.size > 0) {
1899
+ debug5(
1900
+ "client-ref-dedup: redirected %d package(s) (%s)",
1901
+ dedupedPackages.size,
1902
+ [...dedupedPackages].join(",")
1903
+ );
1904
+ }
1905
+ },
1613
1906
  resolveId(source, importer, options) {
1614
1907
  if (this.environment?.name !== "client") return;
1615
1908
  if (!importer?.includes(CLIENT_IN_SERVER_PROXY_PREFIX)) return;
@@ -1618,6 +1911,7 @@ function clientRefDedup() {
1618
1911
  const packageName = extractPackageName(source);
1619
1912
  if (!packageName) return;
1620
1913
  if (clientExclude.includes(packageName)) return;
1914
+ if (debug5) dedupedPackages.add(packageName);
1621
1915
  return `\0rango:dedup/${packageName}`;
1622
1916
  },
1623
1917
  load(id) {
@@ -1740,12 +2034,13 @@ function getVirtualVersionContent(version) {
1740
2034
 
1741
2035
  // src/vite/utils/package-resolution.ts
1742
2036
  import { existsSync } from "node:fs";
2037
+ import { createRequire } from "node:module";
1743
2038
  import { resolve } from "node:path";
1744
2039
 
1745
2040
  // package.json
1746
2041
  var package_default = {
1747
2042
  name: "@rangojs/router",
1748
- version: "0.0.0-experimental.c65e9248",
2043
+ version: "0.0.0-experimental.c7e2ee4c",
1749
2044
  description: "Django-inspired RSC router with composable URL patterns",
1750
2045
  keywords: [
1751
2046
  "react",
@@ -1878,16 +2173,18 @@ var package_default = {
1878
2173
  tag: "experimental"
1879
2174
  },
1880
2175
  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",
2176
+ build: "pnpm dlx esbuild src/vite/index.ts --bundle --format=esm --outfile=dist/vite/index.js --platform=node --packages=external && mkdir -p dist/vite/plugins && cp src/vite/plugins/cloudflare-protocol-loader-hook.mjs dist/vite/plugins/cloudflare-protocol-loader-hook.mjs && pnpm dlx esbuild src/bin/rango.ts --bundle --format=esm --outfile=dist/bin/rango.js --platform=node --packages=external --banner:js='#!/usr/bin/env node' && chmod +x dist/bin/rango.js",
1882
2177
  prepublishOnly: "pnpm build",
1883
- typecheck: "tsc --noEmit",
2178
+ typecheck: "tsc --noEmit && tsc -p tsconfig.strict-check.json --noEmit",
1884
2179
  test: "playwright test",
1885
2180
  "test:ui": "playwright test --ui",
1886
2181
  "test:unit": "vitest run",
1887
2182
  "test:unit:watch": "vitest"
1888
2183
  },
1889
2184
  dependencies: {
1890
- "@vitejs/plugin-rsc": "^0.5.14",
2185
+ "@types/debug": "^4.1.12",
2186
+ "@vitejs/plugin-rsc": "^0.5.23",
2187
+ debug: "^4.4.1",
1891
2188
  "magic-string": "^0.30.17",
1892
2189
  picomatch: "^4.0.3",
1893
2190
  "rsc-html-stream": "^0.0.7"
@@ -1907,7 +2204,7 @@ var package_default = {
1907
2204
  },
1908
2205
  peerDependencies: {
1909
2206
  "@cloudflare/vite-plugin": "^1.25.0",
1910
- "@vitejs/plugin-rsc": "^0.5.14",
2207
+ "@vitejs/plugin-rsc": "^0.5.23",
1911
2208
  react: "^18.0.0 || ^19.0.0",
1912
2209
  vite: "^7.3.0"
1913
2210
  },
@@ -1922,6 +2219,7 @@ var package_default = {
1922
2219
  };
1923
2220
 
1924
2221
  // src/vite/utils/package-resolution.ts
2222
+ var require2 = createRequire(import.meta.url);
1925
2223
  var VIRTUAL_PACKAGE_NAME = "@rangojs/router";
1926
2224
  function getPublishedPackageName() {
1927
2225
  return package_default.name;
@@ -1962,6 +2260,20 @@ function getPackageAliases() {
1962
2260
  }
1963
2261
  return aliases;
1964
2262
  }
2263
+ function getVendorAliases() {
2264
+ const specs = [
2265
+ "@vitejs/plugin-rsc/vendor/react-server-dom/client.edge",
2266
+ "@vitejs/plugin-rsc/vendor/react-server-dom/server.edge"
2267
+ ];
2268
+ const aliases = {};
2269
+ for (const spec of specs) {
2270
+ try {
2271
+ aliases[spec] = require2.resolve(spec);
2272
+ } catch {
2273
+ }
2274
+ }
2275
+ return aliases;
2276
+ }
1965
2277
 
1966
2278
  // src/build/route-types/param-extraction.ts
1967
2279
  function extractParamsFromPattern(pattern) {
@@ -2317,7 +2629,7 @@ function buildRouteMapFromBlock(block, fullSource, filePath, visited, searchSche
2317
2629
  }
2318
2630
  return routeMap;
2319
2631
  }
2320
- function buildCombinedRouteMapWithSearch(filePath, variableName, visited, diagnosticsOut) {
2632
+ function buildCombinedRouteMapWithSearch(filePath, variableName, visited, diagnosticsOut, inlineBlock) {
2321
2633
  visited = visited ?? /* @__PURE__ */ new Set();
2322
2634
  const realPath = resolve2(filePath);
2323
2635
  const key = variableName ? `${realPath}:${variableName}` : realPath;
@@ -2333,7 +2645,9 @@ function buildCombinedRouteMapWithSearch(filePath, variableName, visited, diagno
2333
2645
  return { routes: {}, searchSchemas: {} };
2334
2646
  }
2335
2647
  let block;
2336
- if (variableName) {
2648
+ if (inlineBlock) {
2649
+ block = inlineBlock;
2650
+ } else if (variableName) {
2337
2651
  const extracted = extractUrlsBlockForVariable(source, variableName);
2338
2652
  if (!extracted) return { routes: {}, searchSchemas: {} };
2339
2653
  block = extracted;
@@ -2452,7 +2766,7 @@ Router root: ${conflict.ancestor}
2452
2766
  Nested router: ${conflict.nested}
2453
2767
  Move the nested router into a sibling directory or configure it as a separate app root.`;
2454
2768
  }
2455
- function extractUrlsVariableFromRouter(code) {
2769
+ function extractUrlsFromRouter(code) {
2456
2770
  const sourceFile = ts5.createSourceFile(
2457
2771
  "router.tsx",
2458
2772
  code,
@@ -2466,24 +2780,70 @@ function extractUrlsVariableFromRouter(code) {
2466
2780
  const callee = node.expression;
2467
2781
  return ts5.isIdentifier(callee) && callee.text === "createRouter";
2468
2782
  }
2783
+ function isInlineBuilder(node) {
2784
+ return ts5.isArrowFunction(node) || ts5.isFunctionExpression(node);
2785
+ }
2786
+ function isRoutesOnCreateRouter(node) {
2787
+ if (!ts5.isPropertyAccessExpression(node.expression) || node.expression.name.text !== "routes")
2788
+ return false;
2789
+ let inner = node.expression.expression;
2790
+ while (ts5.isCallExpression(inner) && ts5.isPropertyAccessExpression(inner.expression)) {
2791
+ inner = inner.expression.expression;
2792
+ }
2793
+ return isCreateRouterCall(inner);
2794
+ }
2469
2795
  function visit(node) {
2470
2796
  if (result) return;
2471
- if (ts5.isCallExpression(node) && ts5.isPropertyAccessExpression(node.expression) && node.expression.name.text === "routes" && node.arguments.length >= 1 && ts5.isIdentifier(node.arguments[0])) {
2472
- let inner = node.expression.expression;
2473
- while (ts5.isCallExpression(inner) && ts5.isPropertyAccessExpression(inner.expression)) {
2474
- inner = inner.expression.expression;
2475
- }
2476
- if (isCreateRouterCall(inner)) {
2477
- result = node.arguments[0].text;
2478
- return;
2797
+ if (ts5.isCallExpression(node) && node.arguments.length >= 1 && isRoutesOnCreateRouter(node)) {
2798
+ const arg = node.arguments[0];
2799
+ if (ts5.isIdentifier(arg)) {
2800
+ result = { kind: "variable", name: arg.text };
2801
+ } else if (isInlineBuilder(arg)) {
2802
+ result = { kind: "inline", block: arg.getText(sourceFile) };
2479
2803
  }
2804
+ return;
2480
2805
  }
2481
2806
  if (isCreateRouterCall(node)) {
2482
2807
  const callExpr = node;
2483
- for (const arg of callExpr.arguments) {
2808
+ for (const callArg of callExpr.arguments) {
2809
+ if (ts5.isObjectLiteralExpression(callArg)) {
2810
+ for (const prop of callArg.properties) {
2811
+ if (ts5.isPropertyAssignment(prop) && ts5.isIdentifier(prop.name) && prop.name.text === "urls") {
2812
+ if (ts5.isIdentifier(prop.initializer)) {
2813
+ result = { kind: "variable", name: prop.initializer.text };
2814
+ } else if (isInlineBuilder(prop.initializer)) {
2815
+ result = {
2816
+ kind: "inline",
2817
+ block: prop.initializer.getText(sourceFile)
2818
+ };
2819
+ }
2820
+ return;
2821
+ }
2822
+ }
2823
+ }
2824
+ }
2825
+ }
2826
+ ts5.forEachChild(node, visit);
2827
+ }
2828
+ visit(sourceFile);
2829
+ return result;
2830
+ }
2831
+ function extractBasenameFromRouter(code) {
2832
+ const sourceFile = ts5.createSourceFile(
2833
+ "router.tsx",
2834
+ code,
2835
+ ts5.ScriptTarget.Latest,
2836
+ true,
2837
+ ts5.ScriptKind.TSX
2838
+ );
2839
+ let result;
2840
+ function visit(node) {
2841
+ if (result !== void 0) return;
2842
+ if (ts5.isCallExpression(node) && ts5.isIdentifier(node.expression) && node.expression.text === "createRouter") {
2843
+ for (const arg of node.arguments) {
2484
2844
  if (ts5.isObjectLiteralExpression(arg)) {
2485
2845
  for (const prop of arg.properties) {
2486
- if (ts5.isPropertyAssignment(prop) && ts5.isIdentifier(prop.name) && prop.name.text === "urls" && ts5.isIdentifier(prop.initializer)) {
2846
+ if (ts5.isPropertyAssignment(prop) && ts5.isIdentifier(prop.name) && prop.name.text === "basename" && ts5.isStringLiteral(prop.initializer)) {
2487
2847
  result = prop.initializer.text;
2488
2848
  return;
2489
2849
  }
@@ -2496,6 +2856,19 @@ function extractUrlsVariableFromRouter(code) {
2496
2856
  visit(sourceFile);
2497
2857
  return result;
2498
2858
  }
2859
+ function applyBasenameToRoutes(result, basename3) {
2860
+ const prefixed = {};
2861
+ for (const [name, pattern] of Object.entries(result.routes)) {
2862
+ if (pattern === "/") {
2863
+ prefixed[name] = basename3;
2864
+ } else if (basename3.endsWith("/") && pattern.startsWith("/")) {
2865
+ prefixed[name] = basename3 + pattern.slice(1);
2866
+ } else {
2867
+ prefixed[name] = basename3 + pattern;
2868
+ }
2869
+ }
2870
+ return { routes: prefixed, searchSchemas: result.searchSchemas };
2871
+ }
2499
2872
  function buildCombinedRouteMapForRouterFile(routerFilePath) {
2500
2873
  let routerSource;
2501
2874
  try {
@@ -2503,19 +2876,40 @@ function buildCombinedRouteMapForRouterFile(routerFilePath) {
2503
2876
  } catch {
2504
2877
  return { routes: {}, searchSchemas: {} };
2505
2878
  }
2506
- const urlsVarName = extractUrlsVariableFromRouter(routerSource);
2507
- if (!urlsVarName) {
2879
+ const extraction = extractUrlsFromRouter(routerSource);
2880
+ if (!extraction) {
2508
2881
  return { routes: {}, searchSchemas: {} };
2509
2882
  }
2510
- const imported = resolveImportedVariable(routerSource, urlsVarName);
2511
- if (imported) {
2512
- const targetFile = resolveImportPath(imported.specifier, routerFilePath);
2513
- if (!targetFile) {
2514
- return { routes: {}, searchSchemas: {} };
2883
+ const rawBasename = extractBasenameFromRouter(routerSource);
2884
+ const basename3 = rawBasename ? ("/" + rawBasename.replace(/^\/+|\/+$/g, "")).replace(/^\/$/, "") : void 0;
2885
+ let result;
2886
+ if (extraction.kind === "inline") {
2887
+ result = buildCombinedRouteMapWithSearch(
2888
+ routerFilePath,
2889
+ void 0,
2890
+ void 0,
2891
+ void 0,
2892
+ extraction.block
2893
+ );
2894
+ } else {
2895
+ const imported = resolveImportedVariable(routerSource, extraction.name);
2896
+ if (imported) {
2897
+ const targetFile = resolveImportPath(imported.specifier, routerFilePath);
2898
+ if (!targetFile) {
2899
+ return { routes: {}, searchSchemas: {} };
2900
+ }
2901
+ result = buildCombinedRouteMapWithSearch(
2902
+ targetFile,
2903
+ imported.exportedName
2904
+ );
2905
+ } else {
2906
+ result = buildCombinedRouteMapWithSearch(routerFilePath, extraction.name);
2515
2907
  }
2516
- return buildCombinedRouteMapWithSearch(targetFile, imported.exportedName);
2517
2908
  }
2518
- return buildCombinedRouteMapWithSearch(routerFilePath, urlsVarName);
2909
+ if (basename3) {
2910
+ result = applyBasenameToRoutes(result, basename3);
2911
+ }
2912
+ return result;
2519
2913
  }
2520
2914
  function findRouterFiles(root, filter) {
2521
2915
  const result = [];
@@ -2540,25 +2934,15 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
2540
2934
  throw new Error(formatNestedRouterConflictError(nestedRouterConflict));
2541
2935
  }
2542
2936
  for (const routerFilePath of routerFilePaths) {
2543
- let routerSource;
2544
- try {
2545
- routerSource = readFileSync2(routerFilePath, "utf-8");
2546
- } catch {
2547
- continue;
2548
- }
2549
- const urlsVarName = extractUrlsVariableFromRouter(routerSource);
2550
- if (!urlsVarName) continue;
2551
- let result;
2552
- const imported = resolveImportedVariable(routerSource, urlsVarName);
2553
- if (imported) {
2554
- const targetFile = resolveImportPath(imported.specifier, routerFilePath);
2555
- if (!targetFile) continue;
2556
- result = buildCombinedRouteMapWithSearch(
2557
- targetFile,
2558
- imported.exportedName
2559
- );
2560
- } else {
2561
- result = buildCombinedRouteMapWithSearch(routerFilePath, urlsVarName);
2937
+ const result = buildCombinedRouteMapForRouterFile(routerFilePath);
2938
+ if (Object.keys(result.routes).length === 0 && Object.keys(result.searchSchemas).length === 0) {
2939
+ let routerSource;
2940
+ try {
2941
+ routerSource = readFileSync2(routerFilePath, "utf-8");
2942
+ } catch {
2943
+ continue;
2944
+ }
2945
+ if (!extractUrlsFromRouter(routerSource)) continue;
2562
2946
  }
2563
2947
  const routerBasename = pathBasename(routerFilePath).replace(
2564
2948
  /\.(tsx?|jsx?)$/,
@@ -2752,6 +3136,9 @@ function createVersionPlugin() {
2752
3136
  if (!isDev) return;
2753
3137
  const isRscModule = this.environment?.name === "rsc";
2754
3138
  if (!isRscModule) return;
3139
+ if (ctx.modules.length === 1 && ctx.modules[0].id === "\0" + VIRTUAL_IDS.version) {
3140
+ return;
3141
+ }
2755
3142
  if (isCodeModule(ctx.file)) {
2756
3143
  const filePath = normalizeModuleId(ctx.file);
2757
3144
  const previousSignature = clientModuleSignatures.get(filePath);
@@ -2781,6 +3168,73 @@ function createVersionPlugin() {
2781
3168
 
2782
3169
  // src/vite/utils/shared-utils.ts
2783
3170
  import * as Vite from "vite";
3171
+
3172
+ // src/vite/plugins/performance-tracks.ts
3173
+ import { readFile } from "node:fs/promises";
3174
+ var debug6 = createRangoDebugger(NS.transform);
3175
+ var RSDW_PATCH_RE = /((?:var|let|const)\s+\w+\s*=\s*root\._children\s*,\s*(\w+)\s*=\s*root\._debugInfo\s*[;,])/;
3176
+ function buildPatchReplacement(match, debugInfoVar) {
3177
+ return `${match}
3178
+ if (${debugInfoVar} && 0 === ${debugInfoVar}.length && "fulfilled" === root.status) {
3179
+ var _resolved = "function" === typeof resolveLazy ? resolveLazy(root.value) : root.value;
3180
+ if ("object" === typeof _resolved && null !== _resolved && isArrayImpl(_resolved._debugInfo)) {
3181
+ ${debugInfoVar} = _resolved._debugInfo;
3182
+ }
3183
+ }`;
3184
+ }
3185
+ function patchRsdwClientDebugInfoRecovery(code) {
3186
+ const match = code.match(RSDW_PATCH_RE);
3187
+ if (!match) {
3188
+ return { code, debugInfoVar: null };
3189
+ }
3190
+ return {
3191
+ code: code.replace(match[1], buildPatchReplacement(match[1], match[2])),
3192
+ debugInfoVar: match[2]
3193
+ };
3194
+ }
3195
+ function performanceTracksOptimizeDepsPlugin() {
3196
+ return {
3197
+ name: "@rangojs/router:performance-tracks-optimize-deps",
3198
+ setup(build) {
3199
+ build.onLoad(
3200
+ {
3201
+ filter: /react-server-dom-webpack-client\.browser\.(development|production)\.js$/
3202
+ },
3203
+ async (args) => {
3204
+ const code = await readFile(args.path, "utf8");
3205
+ const patched = patchRsdwClientDebugInfoRecovery(code);
3206
+ return {
3207
+ contents: patched.code,
3208
+ loader: "js"
3209
+ };
3210
+ }
3211
+ );
3212
+ }
3213
+ };
3214
+ }
3215
+ function performanceTracksPlugin() {
3216
+ const counter = createCounter(debug6, "performance-tracks");
3217
+ return {
3218
+ name: "@rangojs/router:performance-tracks",
3219
+ buildEnd() {
3220
+ counter?.flush();
3221
+ },
3222
+ transform(code, id) {
3223
+ if (!id.includes("react-server-dom") || !id.includes("client")) return;
3224
+ const start = counter ? performance.now() : 0;
3225
+ try {
3226
+ const patched = patchRsdwClientDebugInfoRecovery(code);
3227
+ if (!patched.debugInfoVar) return;
3228
+ debug6?.("patched RSDW client (var: %s)", patched.debugInfoVar);
3229
+ return patched.code;
3230
+ } finally {
3231
+ counter?.record(id, performance.now() - start);
3232
+ }
3233
+ }
3234
+ };
3235
+ }
3236
+
3237
+ // src/vite/utils/shared-utils.ts
2784
3238
  var versionEsbuildPlugin = {
2785
3239
  name: "@rangojs/router-version",
2786
3240
  setup(build) {
@@ -2798,7 +3252,7 @@ var versionEsbuildPlugin = {
2798
3252
  }
2799
3253
  };
2800
3254
  var sharedEsbuildOptions = {
2801
- plugins: [versionEsbuildPlugin]
3255
+ plugins: [versionEsbuildPlugin, performanceTracksOptimizeDepsPlugin()]
2802
3256
  };
2803
3257
  function createVirtualEntriesPlugin(entries, routerPathRef) {
2804
3258
  const virtualModules = {};
@@ -2881,11 +3335,11 @@ ${dim} \u2571${reset} ${bold}\u2554\u2550\u2557${reset}${dim} * \u2
2881
3335
  ${dim} ${reset}${bold}\u2551 \u2551${reset} ${bold}\u2554\u2550\u2557${reset}${dim} * \u2727. \u2571${reset}
2882
3336
  ${dim} ${reset}${bold}\u2554\u2557 \u2551 \u2551 \u2551 \u2551${reset}${dim} * \u2571${reset}
2883
3337
  ${dim} ${reset}${bold}\u2551\u2551 \u2551 \u2551 \u2551 \u2551 \u2566\u2550\u2557\u2554\u2550\u2557\u2554\u2557\u2554\u2554\u2550\u2557\u2554\u2550\u2557${reset}${dim} \u2727 \u2726${reset}
2884
- ${dim} ${reset}${bold}\u2550\u2563\u2551 \u2551 \u2560\u2550\u255D \u2551 \u2560\u2566\u255D\u2560\u2550\u2563\u2551\u2551\u2551\u2551 \u2566\u2551 \u2551${reset}${dim} * \u2727${reset}
3338
+ ${dim} ${reset}${bold}\u2551\u2551 \u2551 \u2560\u2550\u255D \u2551 \u2560\u2566\u255D\u2560\u2550\u2563\u2551\u2551\u2551\u2551 \u2566\u2551 \u2551${reset}${dim} * \u2727${reset}
2885
3339
  ${dim} ${reset}${bold}\u2551\u255A\u2550\u255D \u2554\u2550\u2550\u2550\u255D \u2569\u255A\u2550\u2569 \u2569\u255D\u255A\u255D\u255A\u2550\u255D\u255A\u2550\u255D${reset}${dim} \u2726 . *${reset}
2886
3340
  ${dim} ${reset}${bold}\u255A\u2550\u2550\u2557 \u2551${reset}${dim} * RSC Wrangler \u2727 \u2726${reset}
2887
- ${dim} * ${reset}${bold}\u2551 \u2560\u2550${reset}${dim} * \u2727. \u2571${reset}
2888
- ${bold}\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2569\u2550\u2550\u2550${reset}${dim} \u2726 *${reset}
3341
+ ${dim} * ${reset}${bold}\u2551 \u2551${reset}${dim} * \u2727. \u2571${reset}
3342
+ ${dim} ${reset}${bold}\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550${reset}${dim} \u2726 *${reset}
2889
3343
 
2890
3344
  v${version} \xB7 ${preset} \xB7 ${mode}
2891
3345
  `;
@@ -2922,11 +3376,10 @@ function createVersionInjectorPlugin(rscEntryPath) {
2922
3376
  if (normalizedId !== normalizedEntry) {
2923
3377
  return null;
2924
3378
  }
2925
- const prepend = [];
3379
+ const prepend = [
3380
+ `import "virtual:rsc-router/routes-manifest";`
3381
+ ];
2926
3382
  let newCode = code;
2927
- if (!code.includes("virtual:rsc-router/routes-manifest")) {
2928
- prepend.push(`import "virtual:rsc-router/routes-manifest";`);
2929
- }
2930
3383
  const needsVersion = code.includes("createRSCHandler") && !code.includes("@rangojs/router:version") && /createRSCHandler\s*\(\s*\{/.test(code);
2931
3384
  if (needsVersion) {
2932
3385
  prepend.push(`import { VERSION } from "@rangojs/router:version";`);
@@ -2935,8 +3388,21 @@ function createVersionInjectorPlugin(rscEntryPath) {
2935
3388
  "createRSCHandler({\n version: VERSION,"
2936
3389
  );
2937
3390
  }
2938
- if (prepend.length === 0 && newCode === code) return null;
2939
- newCode = prepend.join("\n") + (prepend.length > 0 ? "\n" : "") + newCode;
3391
+ const lines = newCode.split("\n");
3392
+ let insertAt = 0;
3393
+ while (insertAt < lines.length) {
3394
+ const trimmed = lines[insertAt].trim();
3395
+ if (trimmed === "" || /^\/\/\/\s*<reference\b/.test(trimmed)) {
3396
+ insertAt++;
3397
+ } else {
3398
+ break;
3399
+ }
3400
+ }
3401
+ newCode = [
3402
+ ...lines.slice(0, insertAt),
3403
+ ...prepend,
3404
+ ...lines.slice(insertAt)
3405
+ ].join("\n");
2940
3406
  return {
2941
3407
  code: newCode,
2942
3408
  map: null
@@ -2946,6 +3412,7 @@ function createVersionInjectorPlugin(rscEntryPath) {
2946
3412
  }
2947
3413
 
2948
3414
  // src/vite/plugins/cjs-to-esm.ts
3415
+ var debug7 = createRangoDebugger(NS.transform);
2949
3416
  function createCjsToEsmPlugin() {
2950
3417
  return {
2951
3418
  name: "@rangojs/router:cjs-to-esm",
@@ -2955,6 +3422,7 @@ function createCjsToEsmPlugin() {
2955
3422
  if (cleanId.includes("vendor/react-server-dom/client.browser.js") || cleanId.includes("vendor\\react-server-dom\\client.browser.js")) {
2956
3423
  const isProd = process.env.NODE_ENV === "production";
2957
3424
  const cjsFile = isProd ? "./cjs/react-server-dom-webpack-client.browser.production.js" : "./cjs/react-server-dom-webpack-client.browser.development.js";
3425
+ debug7?.("cjs-to-esm entry redirect %s", id);
2958
3426
  return {
2959
3427
  code: `export * from "${cjsFile}";`,
2960
3428
  map: null
@@ -2990,6 +3458,7 @@ function createCjsToEsmPlugin() {
2990
3458
  "export const $1 ="
2991
3459
  );
2992
3460
  transformed = license + "\n" + transformed;
3461
+ debug7?.("cjs-to-esm body rewrite %s", id);
2993
3462
  return {
2994
3463
  code: transformed,
2995
3464
  map: null
@@ -3004,6 +3473,8 @@ function createCjsToEsmPlugin() {
3004
3473
  import { createServer as createViteServer } from "vite";
3005
3474
  import { resolve as resolve8 } from "node:path";
3006
3475
  import { readFileSync as readFileSync6 } from "node:fs";
3476
+ import { createRequire as createRequire2, register } from "node:module";
3477
+ import { pathToFileURL } from "node:url";
3007
3478
 
3008
3479
  // src/vite/plugins/virtual-stub-plugin.ts
3009
3480
  function createVirtualStubPlugin() {
@@ -3029,9 +3500,117 @@ function createVirtualStubPlugin() {
3029
3500
  };
3030
3501
  }
3031
3502
 
3503
+ // src/vite/plugins/cloudflare-protocol-stub.ts
3504
+ var VIRTUAL_PREFIX = "virtual:rango-cloudflare-stub-";
3505
+ var NULL_PREFIX = "\0" + VIRTUAL_PREFIX;
3506
+ var CF_PREFIX = "cloudflare:";
3507
+ var BUILD_ENV_GLOBAL_KEY = "__rango_build_env__";
3508
+ var SOURCE_EXT_RE = /\.[mc]?[jt]sx?$/;
3509
+ var IMPORT_NODE_TYPES = /* @__PURE__ */ new Set([
3510
+ "ImportDeclaration",
3511
+ "ImportExpression",
3512
+ "ExportNamedDeclaration",
3513
+ "ExportAllDeclaration"
3514
+ ]);
3515
+ var STUBS = {
3516
+ "cloudflare:workers": `
3517
+ export class DurableObject { constructor(_ctx, _env) {} }
3518
+ export class WorkerEntrypoint { constructor(_ctx, _env) {} }
3519
+ export class WorkflowEntrypoint { constructor(_ctx, _env) {} }
3520
+ export class RpcTarget {}
3521
+ export const env = globalThis[${JSON.stringify(BUILD_ENV_GLOBAL_KEY)}] ?? {};
3522
+ export default {};
3523
+ `,
3524
+ "cloudflare:email": `
3525
+ export class EmailMessage { constructor(_from, _to, _raw) {} }
3526
+ export default {};
3527
+ `,
3528
+ "cloudflare:sockets": `
3529
+ export function connect() { return {}; }
3530
+ export default {};
3531
+ `,
3532
+ "cloudflare:workflows": `
3533
+ export class NonRetryableError extends Error {
3534
+ constructor(message, name) { super(message); this.name = name ?? "NonRetryableError"; }
3535
+ }
3536
+ export default {};
3537
+ `
3538
+ };
3539
+ var FALLBACK_STUB = `export default {};
3540
+ `;
3541
+ function createCloudflareProtocolStubPlugin() {
3542
+ return {
3543
+ name: "@rangojs/router:cloudflare-protocol-stub",
3544
+ transform(code, id) {
3545
+ const cleanId = id.split("?")[0] ?? id;
3546
+ if (!SOURCE_EXT_RE.test(cleanId)) return null;
3547
+ if (!code.includes(CF_PREFIX)) return null;
3548
+ let ast;
3549
+ try {
3550
+ ast = this.parse(code);
3551
+ } catch {
3552
+ return null;
3553
+ }
3554
+ const hits = [];
3555
+ walk(ast, (node) => {
3556
+ if (!IMPORT_NODE_TYPES.has(node.type)) return;
3557
+ const source = node.source;
3558
+ if (!source || source.type !== "Literal") return;
3559
+ if (typeof source.value !== "string") return;
3560
+ if (!source.value.startsWith(CF_PREFIX)) return;
3561
+ if (typeof source.start !== "number" || typeof source.end !== "number")
3562
+ return;
3563
+ hits.push({
3564
+ start: source.start,
3565
+ end: source.end,
3566
+ value: source.value
3567
+ });
3568
+ });
3569
+ if (hits.length === 0) return null;
3570
+ hits.sort((a, b) => b.start - a.start);
3571
+ let out = code;
3572
+ for (const hit of hits) {
3573
+ const submodule = hit.value.slice(CF_PREFIX.length);
3574
+ const quote = code[hit.start] === "'" ? "'" : '"';
3575
+ out = out.slice(0, hit.start) + quote + VIRTUAL_PREFIX + submodule + quote + out.slice(hit.end);
3576
+ }
3577
+ return { code: out, map: null };
3578
+ },
3579
+ resolveId(id) {
3580
+ if (id.startsWith(VIRTUAL_PREFIX)) {
3581
+ return "\0" + id;
3582
+ }
3583
+ return null;
3584
+ },
3585
+ load(id) {
3586
+ if (!id.startsWith(NULL_PREFIX)) return null;
3587
+ const submodule = id.slice(NULL_PREFIX.length);
3588
+ const specifier = CF_PREFIX + submodule;
3589
+ return STUBS[specifier] ?? FALLBACK_STUB;
3590
+ }
3591
+ };
3592
+ }
3593
+ function walk(node, visit) {
3594
+ if (!node || typeof node !== "object") return;
3595
+ if (Array.isArray(node)) {
3596
+ for (const child of node) walk(child, visit);
3597
+ return;
3598
+ }
3599
+ const n = node;
3600
+ if (typeof n.type !== "string") return;
3601
+ visit(n);
3602
+ for (const key in n) {
3603
+ if (key === "loc" || key === "start" || key === "end" || key === "range") {
3604
+ continue;
3605
+ }
3606
+ walk(n[key], visit);
3607
+ }
3608
+ }
3609
+
3032
3610
  // src/vite/plugins/client-ref-hashing.ts
3033
3611
  import { relative } from "node:path";
3034
3612
  import { createHash as createHash2 } from "node:crypto";
3613
+ var debug8 = createRangoDebugger(NS.transform);
3035
3614
  var CLIENT_PKG_PROXY_PREFIX = "/@id/__x00__virtual:vite-rsc/client-package-proxy/";
3036
3615
  var CLIENT_IN_SERVER_PKG_PROXY_PREFIX = "/@id/__x00__virtual:vite-rsc/client-in-server-package-proxy/";
3037
3616
  var FS_PREFIX = "/@fs/";
@@ -3070,6 +3649,7 @@ function transformClientRefs(code, projectRoot) {
3070
3649
  return hasReplacement ? result : null;
3071
3650
  }
3072
3651
  function hashClientRefs(projectRoot) {
3652
+ const counter = createCounter(debug8, "hash-client-refs");
3073
3653
  return {
3074
3654
  name: "@rangojs/router:hash-client-refs",
3075
3655
  // Run after the RSC plugin's transform (default enforce is normal)
@@ -3077,10 +3657,18 @@ function hashClientRefs(projectRoot) {
3077
3657
  applyToEnvironment(env) {
3078
3658
  return env.name === "rsc";
3079
3659
  },
3080
- transform(code, _id) {
3081
- const result = transformClientRefs(code, projectRoot);
3082
- if (result === null) return;
3083
- return { code: result, map: null };
3660
+ buildEnd() {
3661
+ counter?.flush();
3662
+ },
3663
+ transform(code, id) {
3664
+ const start = counter ? performance.now() : 0;
3665
+ try {
3666
+ const result = transformClientRefs(code, projectRoot);
3667
+ if (result === null) return;
3668
+ return { code: result, map: null };
3669
+ } finally {
3670
+ counter?.record(id, performance.now() - start);
3671
+ }
3084
3672
  }
3085
3673
  };
3086
3674
  }
@@ -3187,8 +3775,8 @@ function createDiscoveryState(entryPath, opts) {
3187
3775
  perRouterManifestDataMap: /* @__PURE__ */ new Map(),
3188
3776
  prerenderManifestEntries: null,
3189
3777
  staticManifestEntries: null,
3190
- handlerChunkInfo: null,
3191
- staticHandlerChunkInfo: null,
3778
+ handlerChunkInfoMap: /* @__PURE__ */ new Map(),
3779
+ staticHandlerChunkInfoMap: /* @__PURE__ */ new Map(),
3192
3780
  rscEntryFileName: null,
3193
3781
  resolvedPrerenderModules: void 0,
3194
3782
  resolvedStaticModules: void 0,
@@ -3208,6 +3796,12 @@ function markSelfGenWrite(state, filePath, content) {
3208
3796
  state.selfWrittenGenFiles.set(filePath, { at: Date.now(), hash });
3209
3797
  }
3210
3798
  function consumeSelfGenWrite(state, filePath) {
3799
+ return checkSelfGenWrite(state, filePath, true);
3800
+ }
3801
+ function peekSelfGenWrite(state, filePath) {
3802
+ return checkSelfGenWrite(state, filePath, false);
3803
+ }
3804
+ function checkSelfGenWrite(state, filePath, consume) {
3211
3805
  const info = state.selfWrittenGenFiles.get(filePath);
3212
3806
  if (!info) return false;
3213
3807
  if (Date.now() - info.at > state.SELF_WRITE_WINDOW_MS) {
@@ -3218,7 +3812,7 @@ function consumeSelfGenWrite(state, filePath) {
3218
3812
  const current = readFileSync3(filePath, "utf-8");
3219
3813
  const currentHash = createHash3("sha256").update(current).digest("hex");
3220
3814
  if (currentHash === info.hash) {
3221
- state.selfWrittenGenFiles.delete(filePath);
3815
+ if (consume) state.selfWrittenGenFiles.delete(filePath);
3222
3816
  return true;
3223
3817
  }
3224
3818
  return false;
@@ -3271,8 +3865,17 @@ function jsonParseExpression(value) {
3271
3865
  }
3272
3866
 
3273
3867
  // src/context-var.ts
3868
+ var NON_CACHEABLE_KEYS = /* @__PURE__ */ Symbol.for(
3869
+ "rango:non-cacheable-keys"
3870
+ );
3871
+ function getNonCacheableKeys(variables) {
3872
+ if (!variables[NON_CACHEABLE_KEYS]) {
3873
+ variables[NON_CACHEABLE_KEYS] = /* @__PURE__ */ new Set();
3874
+ }
3875
+ return variables[NON_CACHEABLE_KEYS];
3876
+ }
3274
3877
  var FORBIDDEN_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
3275
- function contextSet(variables, keyOrVar, value) {
3878
+ function contextSet(variables, keyOrVar, value, options) {
3276
3879
  if (typeof keyOrVar === "string") {
3277
3880
  if (FORBIDDEN_KEYS.has(keyOrVar)) {
3278
3881
  throw new Error(
@@ -3280,8 +3883,14 @@ function contextSet(variables, keyOrVar, value) {
3280
3883
  );
3281
3884
  }
3282
3885
  variables[keyOrVar] = value;
3886
+ if (options?.cache === false) {
3887
+ getNonCacheableKeys(variables).add(keyOrVar);
3888
+ }
3283
3889
  } else {
3284
3890
  variables[keyOrVar.key] = value;
3891
+ if (options?.cache === false) {
3892
+ getNonCacheableKeys(variables).add(keyOrVar.key);
3893
+ }
3285
3894
  }
3286
3895
  }
3287
3896
 
@@ -3304,13 +3913,31 @@ function encodePathParam(value) {
3304
3913
  }
3305
3914
  function substituteRouteParams(pattern, params, encode = encodeURIComponent) {
3306
3915
  let result = pattern;
3916
+ let hadOmittedOptional = false;
3307
3917
  for (const [key, value] of Object.entries(params)) {
3308
3918
  const escaped = escapeRegExp2(key);
3309
- result = result.replace(
3310
- new RegExp(`:${escaped}(\\([^)]*\\))?\\??`),
3311
- encode(value)
3312
- );
3313
- result = result.replace(`*${key}`, encode(value));
3919
+ if (value === "") {
3920
+ result = result.replace(
3921
+ new RegExp(`:${escaped}(\\([^)]*\\))?(?!\\?)`),
3922
+ ""
3923
+ );
3924
+ result = result.replace(`*${key}`, "");
3925
+ } else {
3926
+ result = result.replace(
3927
+ new RegExp(`:${escaped}(\\([^)]*\\))?\\??`),
3928
+ encode(value)
3929
+ );
3930
+ result = result.replace(`*${key}`, encode(value));
3931
+ }
3932
+ }
3933
+ result = result.replace(/:([a-zA-Z_][a-zA-Z0-9_]*)(\([^)]*\))?\?/g, () => {
3934
+ hadOmittedOptional = true;
3935
+ return "";
3936
+ });
3937
+ if (hadOmittedOptional) {
3938
+ const hadTrailingSlash = pattern.length > 1 && pattern.endsWith("/");
3939
+ result = result.replace(/\/\/+/g, "/").replace(/\/+$/, "") || "/";
3940
+ if (hadTrailingSlash && !result.endsWith("/")) result += "/";
3314
3941
  }
3315
3942
  return result;
3316
3943
  }
@@ -3407,8 +4034,14 @@ function copyStagedBuildAssets(projectRoot, fileNames) {
3407
4034
  }
3408
4035
 
3409
4036
  // src/vite/discovery/prerender-collection.ts
4037
+ var debug9 = createRangoDebugger(NS.prerender);
3410
4038
  async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
3411
4039
  if (!state.opts?.enableBuildPrerender || !state.isBuildMode) return;
4040
+ const overallStart = debug9 ? performance.now() : 0;
4041
+ debug9?.(
4042
+ "expandPrerenderRoutes: start (%d router manifest(s))",
4043
+ allManifests.length
4044
+ );
3412
4045
  const entries = [];
3413
4046
  const allRoutes = {};
3414
4047
  for (const { manifest: m } of allManifests) {
@@ -3420,91 +4053,151 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
3420
4053
  if (!params) return pattern;
3421
4054
  return substituteRouteParams(pattern, params);
3422
4055
  };
4056
+ let resolvedRoutes = 0;
4057
+ let totalDynamic = 0;
3423
4058
  for (const { manifest } of allManifests) {
3424
4059
  if (!manifest.prerenderRoutes) continue;
3425
- const defs = manifest._prerenderDefs || {};
3426
4060
  for (const routeName of manifest.prerenderRoutes) {
3427
4061
  const pattern = manifest.routeManifest[routeName];
3428
- if (!pattern) continue;
3429
- const def = defs[routeName];
3430
- const isPassthroughRoute = !!def?.options?.passthrough;
3431
- const hasDynamic = pattern.includes(":") || pattern.includes("*");
3432
- if (!hasDynamic) {
3433
- entries.push({
3434
- urlPath: pattern.replace(/\/$/, "") || "/",
3435
- routeName,
3436
- concurrency: 1,
3437
- isPassthroughRoute
3438
- });
3439
- } else {
3440
- if (def?.getParams) {
3441
- try {
3442
- const buildVars = {};
3443
- const getParamsCtx = {
3444
- build: true,
3445
- set: ((keyOrVar, value) => {
3446
- contextSet(buildVars, keyOrVar, value);
3447
- }),
3448
- reverse: getParamsReverse
3449
- };
3450
- const paramsList = await def.getParams(getParamsCtx);
3451
- const concurrency = def.options?.concurrency ?? 1;
3452
- const hasBuildVars = Object.keys(buildVars).length > 0 || Object.getOwnPropertySymbols(buildVars).length > 0;
3453
- for (const params of paramsList) {
3454
- let url = substituteRouteParams(
3455
- pattern,
3456
- params,
3457
- encodePathParam
3458
- );
3459
- if (url.includes("*")) {
3460
- const wildcardValue = params["*"] ?? params.splat;
3461
- if (wildcardValue !== void 0) {
3462
- url = url.replace(/\*[^/]*$/, encodePathParam(wildcardValue));
4062
+ if (pattern && (pattern.includes(":") || pattern.includes("*"))) {
4063
+ totalDynamic++;
4064
+ }
4065
+ }
4066
+ }
4067
+ const paramsStart = performance.now();
4068
+ const progressInterval = totalDynamic > 0 ? setInterval(() => {
4069
+ const elapsed = ((performance.now() - paramsStart) / 1e3).toFixed(1);
4070
+ console.log(
4071
+ `[rsc-router] Resolving prerender params... ${resolvedRoutes}/${totalDynamic} routes (${elapsed}s)`
4072
+ );
4073
+ }, 5e3) : void 0;
4074
+ try {
4075
+ for (const { manifest } of allManifests) {
4076
+ if (!manifest.prerenderRoutes) continue;
4077
+ const defs = manifest._prerenderDefs || {};
4078
+ const passthroughSet = new Set(manifest.passthroughRoutes || []);
4079
+ for (const routeName of manifest.prerenderRoutes) {
4080
+ const pattern = manifest.routeManifest[routeName];
4081
+ if (!pattern) continue;
4082
+ const def = defs[routeName];
4083
+ const isPassthroughRoute = passthroughSet.has(routeName);
4084
+ const hasDynamic = pattern.includes(":") || pattern.includes("*");
4085
+ if (!hasDynamic) {
4086
+ entries.push({
4087
+ urlPath: pattern.replace(/\/$/, "") || "/",
4088
+ routeName,
4089
+ concurrency: 1,
4090
+ isPassthroughRoute
4091
+ });
4092
+ } else {
4093
+ if (def?.getParams) {
4094
+ const getParamsStart = debug9 ? performance.now() : 0;
4095
+ try {
4096
+ const buildVars = {};
4097
+ const buildEnv = state.resolvedBuildEnv;
4098
+ const getParamsCtx = {
4099
+ build: true,
4100
+ dev: !state.isBuildMode,
4101
+ set: ((keyOrVar, value) => {
4102
+ contextSet(buildVars, keyOrVar, value);
4103
+ }),
4104
+ reverse: getParamsReverse,
4105
+ get env() {
4106
+ if (buildEnv !== void 0) return buildEnv;
4107
+ throw new Error(
4108
+ "[rsc-router] ctx.env is not available during build-time getParams(). Configure buildEnv in your rango() plugin options to enable build-time env access."
4109
+ );
3463
4110
  }
3464
- }
3465
- entries.push({
3466
- urlPath: url.replace(/\/$/, "") || "/",
4111
+ };
4112
+ const paramsList = await def.getParams(getParamsCtx);
4113
+ debug9?.(
4114
+ "getParams %s -> %d params (%sms)",
3467
4115
  routeName,
3468
- concurrency,
3469
- ...hasBuildVars ? { buildVars } : {},
3470
- isPassthroughRoute
3471
- });
3472
- }
3473
- } catch (err) {
3474
- if (err.name === "Skip") {
3475
- console.log(
3476
- `[rsc-router] SKIP route "${routeName}" - ${err.message}`
4116
+ paramsList.length,
4117
+ (performance.now() - getParamsStart).toFixed(1)
3477
4118
  );
3478
- notifyOnError(
3479
- registry,
3480
- err,
3481
- "prerender",
3482
- routeName,
3483
- void 0,
3484
- true
4119
+ const concurrency = def.options?.concurrency ?? 1;
4120
+ const hasBuildVars = Object.keys(buildVars).length > 0 || Object.getOwnPropertySymbols(buildVars).length > 0;
4121
+ for (const params of paramsList) {
4122
+ let url = substituteRouteParams(
4123
+ pattern,
4124
+ params,
4125
+ encodePathParam
4126
+ );
4127
+ if (url.includes("*")) {
4128
+ const wildcardValue = params["*"] ?? params.splat;
4129
+ if (wildcardValue !== void 0) {
4130
+ url = url.replace(
4131
+ /\*[^/]*$/,
4132
+ encodePathParam(wildcardValue)
4133
+ );
4134
+ }
4135
+ }
4136
+ entries.push({
4137
+ urlPath: url.replace(/\/$/, "") || "/",
4138
+ routeName,
4139
+ concurrency,
4140
+ ...hasBuildVars ? { buildVars } : {},
4141
+ isPassthroughRoute
4142
+ });
4143
+ }
4144
+ resolvedRoutes++;
4145
+ } catch (err) {
4146
+ resolvedRoutes++;
4147
+ if (err.name === "Skip") {
4148
+ console.log(
4149
+ `[rsc-router] SKIP route "${routeName}" - ${err.message}`
4150
+ );
4151
+ notifyOnError(
4152
+ registry,
4153
+ err,
4154
+ "prerender",
4155
+ routeName,
4156
+ void 0,
4157
+ true
4158
+ );
4159
+ continue;
4160
+ }
4161
+ console.error(
4162
+ `[rsc-router] Failed to get params for prerender route "${routeName}": ${err.message}`
3485
4163
  );
3486
- continue;
4164
+ notifyOnError(registry, err, "prerender", routeName);
4165
+ throw err;
3487
4166
  }
3488
- console.error(
3489
- `[rsc-router] Failed to get params for prerender route "${routeName}": ${err.message}`
4167
+ } else {
4168
+ console.warn(
4169
+ `[rsc-router] Dynamic prerender route "${routeName}" has no getParams(), skipping`
3490
4170
  );
3491
- notifyOnError(registry, err, "prerender", routeName);
3492
- throw err;
3493
4171
  }
3494
- } else {
3495
- console.warn(
3496
- `[rsc-router] Dynamic prerender route "${routeName}" has no getParams(), skipping`
3497
- );
3498
4172
  }
3499
4173
  }
3500
4174
  }
4175
+ } finally {
4176
+ if (progressInterval) {
4177
+ clearInterval(progressInterval);
4178
+ const elapsed = ((performance.now() - paramsStart) / 1e3).toFixed(1);
4179
+ console.log(
4180
+ `[rsc-router] Resolved prerender params: ${resolvedRoutes}/${totalDynamic} routes (${elapsed}s)`
4181
+ );
4182
+ }
4183
+ }
4184
+ if (entries.length === 0) {
4185
+ debug9?.(
4186
+ "no prerender entries (done in %sms)",
4187
+ (performance.now() - overallStart).toFixed(1)
4188
+ );
4189
+ return;
3501
4190
  }
3502
- if (entries.length === 0) return;
3503
4191
  const maxConcurrency = Math.max(...entries.map((e) => e.concurrency));
3504
4192
  const concurrencyNote = maxConcurrency > 1 ? ` (concurrency: ${maxConcurrency})` : "";
3505
4193
  console.log(
3506
4194
  `[rsc-router] Pre-rendering ${entries.length} URL(s)${concurrencyNote}...`
3507
4195
  );
4196
+ debug9?.(
4197
+ "prerender loop: %d entries, max concurrency %d",
4198
+ entries.length,
4199
+ maxConcurrency
4200
+ );
3508
4201
  const { hashParams } = await rscEnv.runner.import("@rangojs/router/build");
3509
4202
  const manifestEntries = {};
3510
4203
  let doneCount = 0;
@@ -3524,7 +4217,8 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
3524
4217
  entry.urlPath,
3525
4218
  {},
3526
4219
  entry.buildVars,
3527
- entry.isPassthroughRoute
4220
+ entry.isPassthroughRoute,
4221
+ state.resolvedBuildEnv
3528
4222
  );
3529
4223
  if (!result) continue;
3530
4224
  if (result.passthrough) {
@@ -3610,10 +4304,22 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
3610
4304
  console.log(
3611
4305
  `[rsc-router] Pre-render complete: ${parts.join(", ")} (${totalElapsed}ms total)`
3612
4306
  );
4307
+ debug9?.(
4308
+ "expandPrerenderRoutes done: %d done, %d skipped, %sms (overall %sms)",
4309
+ doneCount,
4310
+ skipCount,
4311
+ totalElapsed,
4312
+ (performance.now() - overallStart).toFixed(1)
4313
+ );
3613
4314
  }
3614
4315
  async function renderStaticHandlers(state, rscEnv, registry) {
3615
4316
  if (!state.opts?.enableBuildPrerender || !state.isBuildMode || !state.resolvedStaticModules?.size)
3616
4317
  return;
4318
+ const overallStart = debug9 ? performance.now() : 0;
4319
+ debug9?.(
4320
+ "renderStaticHandlers: start (%d static module(s))",
4321
+ state.resolvedStaticModules.size
4322
+ );
3617
4323
  const manifestEntries = {};
3618
4324
  let staticDone = 0;
3619
4325
  let staticSkip = 0;
@@ -3648,7 +4354,9 @@ async function renderStaticHandlers(state, rscEnv, registry) {
3648
4354
  const result = await routerInstance.renderStaticSegment(
3649
4355
  def.handler,
3650
4356
  def.$$id,
3651
- def.$$routePrefix
4357
+ def.$$routePrefix,
4358
+ state.resolvedBuildEnv,
4359
+ !state.isBuildMode
3652
4360
  );
3653
4361
  if (result) {
3654
4362
  const hasHandles = Object.keys(result.handles).length > 0;
@@ -3701,13 +4409,29 @@ async function renderStaticHandlers(state, rscEnv, registry) {
3701
4409
  console.log(
3702
4410
  `[rsc-router] Static render complete: ${staticParts.join(", ")} (${totalStaticElapsed}ms total)`
3703
4411
  );
4412
+ debug9?.(
4413
+ "renderStaticHandlers done: %d done, %d skipped, %sms (overall %sms)",
4414
+ staticDone,
4415
+ staticSkip,
4416
+ totalStaticElapsed,
4417
+ (performance.now() - overallStart).toFixed(1)
4418
+ );
3704
4419
  }
3705
4420
 
3706
4421
  // src/vite/discovery/discover-routers.ts
4422
+ var debug10 = createRangoDebugger(NS.discovery);
3707
4423
  async function discoverRouters(state, rscEnv) {
3708
4424
  if (!state.resolvedEntryPath) return;
3709
- await rscEnv.runner.import(state.resolvedEntryPath);
3710
- const serverMod = await rscEnv.runner.import("@rangojs/router/server");
4425
+ await timed(
4426
+ debug10,
4427
+ "inner: import entry",
4428
+ () => rscEnv.runner.import(state.resolvedEntryPath)
4429
+ );
4430
+ const serverMod = await timed(
4431
+ debug10,
4432
+ "inner: import @rangojs/router/server",
4433
+ () => rscEnv.runner.import("@rangojs/router/server")
4434
+ );
3711
4435
  let registry = serverMod.RouterRegistry;
3712
4436
  if (!registry || registry.size === 0) {
3713
4437
  try {
@@ -3749,8 +4473,13 @@ async function discoverRouters(state, rscEnv) {
3749
4473
  );
3750
4474
  }
3751
4475
  }
3752
- const buildMod = await rscEnv.runner.import("@rangojs/router/build");
4476
+ const buildMod = await timed(
4477
+ debug10,
4478
+ "inner: import @rangojs/router/build",
4479
+ () => rscEnv.runner.import("@rangojs/router/build")
4480
+ );
3753
4481
  const generateManifestFull = buildMod.generateManifestFull;
4482
+ debug10?.("inner: found %d router(s) in registry", registry.size);
3754
4483
  const nestedRouterConflict = findNestedRouterConflict(
3755
4484
  [...registry.values()].map((router) => router.__sourceFile).filter(
3756
4485
  (sourceFile) => typeof sourceFile === "string"
@@ -3769,11 +4498,16 @@ async function discoverRouters(state, rscEnv) {
3769
4498
  let mergedRouteTrailingSlash = {};
3770
4499
  let routerMountIndex = 0;
3771
4500
  const allManifests = [];
4501
+ const manifestGenStart = debug10 ? performance.now() : 0;
3772
4502
  for (const [id, router] of registry) {
3773
4503
  if (!router.urlpatterns || !generateManifestFull) {
3774
4504
  continue;
3775
4505
  }
3776
- const manifest = generateManifestFull(router.urlpatterns, routerMountIndex);
4506
+ const manifest = generateManifestFull(
4507
+ router.urlpatterns,
4508
+ routerMountIndex,
4509
+ router.__basename ? { urlPrefix: router.__basename } : void 0
4510
+ );
3777
4511
  routerMountIndex++;
3778
4512
  allManifests.push({ id, manifest });
3779
4513
  const routeCount = Object.keys(manifest.routeManifest).length;
@@ -3839,7 +4573,13 @@ async function discoverRouters(state, rscEnv) {
3839
4573
  );
3840
4574
  }
3841
4575
  }
4576
+ debug10?.(
4577
+ "inner: generated manifests for %d router(s) (%sms)",
4578
+ allManifests.length,
4579
+ (performance.now() - manifestGenStart).toFixed(1)
4580
+ );
3842
4581
  let newMergedRouteTrie = null;
4582
+ const trieStart = debug10 ? performance.now() : 0;
3843
4583
  if (Object.keys(newMergedRouteManifest).length > 0) {
3844
4584
  const buildRouteTrie = buildMod.buildRouteTrie;
3845
4585
  if (buildRouteTrie && mergedRouteAncestry) {
@@ -3902,6 +4642,10 @@ async function discoverRouters(state, rscEnv) {
3902
4642
  }
3903
4643
  }
3904
4644
  }
4645
+ debug10?.(
4646
+ "inner: trie build done (%sms)",
4647
+ (performance.now() - trieStart).toFixed(1)
4648
+ );
3905
4649
  state.mergedRouteManifest = newMergedRouteManifest;
3906
4650
  state.mergedPrecomputedEntries = newMergedPrecomputedEntries;
3907
4651
  state.perRouterManifests = newPerRouterManifests;
@@ -4222,48 +4966,45 @@ function postprocessBundle(state) {
4222
4966
  );
4223
4967
  const evictionTargets = [
4224
4968
  {
4225
- info: state.handlerChunkInfo,
4969
+ infos: state.handlerChunkInfoMap.values(),
4226
4970
  fnName: "Prerender",
4227
4971
  brand: "prerenderHandler",
4228
4972
  label: "handler code from RSC bundle"
4229
4973
  },
4230
4974
  {
4231
- info: state.staticHandlerChunkInfo,
4975
+ infos: state.staticHandlerChunkInfoMap.values(),
4232
4976
  fnName: "Static",
4233
4977
  brand: "staticHandler",
4234
4978
  label: "static handler code"
4235
4979
  }
4236
4980
  ];
4237
4981
  for (const target of evictionTargets) {
4238
- if (!target.info) continue;
4239
- const chunkPath = resolve7(
4240
- state.projectRoot,
4241
- "dist/rsc",
4242
- target.info.fileName
4243
- );
4244
- try {
4245
- const code = readFileSync5(chunkPath, "utf-8");
4246
- const result = evictHandlerCode(
4247
- code,
4248
- target.info.exports,
4249
- target.fnName,
4250
- target.brand
4251
- );
4252
- if (result) {
4253
- writeFileSync4(chunkPath, result.code);
4254
- const savedKB = (result.savedBytes / 1024).toFixed(1);
4255
- console.log(
4256
- `[rsc-router] Evicted ${target.label} (${savedKB} KB saved): ${target.info.fileName}`
4982
+ for (const info of target.infos) {
4983
+ const chunkPath = resolve7(state.projectRoot, "dist/rsc", info.fileName);
4984
+ try {
4985
+ const code = readFileSync5(chunkPath, "utf-8");
4986
+ const result = evictHandlerCode(
4987
+ code,
4988
+ info.exports,
4989
+ target.fnName,
4990
+ target.brand
4991
+ );
4992
+ if (result) {
4993
+ writeFileSync4(chunkPath, result.code);
4994
+ const savedKB = (result.savedBytes / 1024).toFixed(1);
4995
+ console.log(
4996
+ `[rsc-router] Evicted ${target.label} (${savedKB} KB saved): ${info.fileName}`
4997
+ );
4998
+ }
4999
+ } catch (replaceErr) {
5000
+ console.warn(
5001
+ `[rsc-router] Failed to evict ${target.label}: ${replaceErr.message}`
4257
5002
  );
4258
5003
  }
4259
- } catch (replaceErr) {
4260
- console.warn(
4261
- `[rsc-router] Failed to evict ${target.label}: ${replaceErr.message}`
4262
- );
4263
5004
  }
4264
5005
  }
4265
- state.handlerChunkInfo = null;
4266
- state.staticHandlerChunkInfo = null;
5006
+ state.handlerChunkInfoMap.clear();
5007
+ state.staticHandlerChunkInfoMap.clear();
4267
5008
  if (hasPrerenderData && existsSync6(rscEntryPath)) {
4268
5009
  const rscCode = readFileSync5(rscEntryPath, "utf-8");
4269
5010
  if (!rscCode.includes("__prerender-manifest.js")) {
@@ -4306,7 +5047,7 @@ function postprocessBundle(state) {
4306
5047
  }
4307
5048
  if (hasStaticData && existsSync6(rscEntryPath)) {
4308
5049
  const rscCode = readFileSync5(rscEntryPath, "utf-8");
4309
- if (!rscCode.includes("__STATIC_MANIFEST")) {
5050
+ if (!rscCode.includes("__static-manifest.js")) {
4310
5051
  try {
4311
5052
  const manifestEntries = [];
4312
5053
  let totalBytes = copyStagedBuildAssets(
@@ -4344,8 +5085,101 @@ function postprocessBundle(state) {
4344
5085
  }
4345
5086
  }
4346
5087
 
5088
+ // src/vite/discovery/gate-state.ts
5089
+ function createDiscoveryGate(s, debug11) {
5090
+ let gatePending = false;
5091
+ let gateResolver = () => {
5092
+ };
5093
+ let inProgress = false;
5094
+ let queued = false;
5095
+ let pendingEvents = false;
5096
+ const beginGate = () => {
5097
+ if (gatePending) return;
5098
+ s.discoveryDone = new Promise((resolve10) => {
5099
+ gateResolver = resolve10;
5100
+ });
5101
+ gatePending = true;
5102
+ };
5103
+ const resolveGate = () => {
5104
+ if (!gatePending) return;
5105
+ if (inProgress || queued || pendingEvents) {
5106
+ debug11?.(
5107
+ "hmr: resolveGate deferred \u2014 work in flight (inProgress=%s queued=%s pendingEvents=%s)",
5108
+ inProgress,
5109
+ queued,
5110
+ pendingEvents
5111
+ );
5112
+ return;
5113
+ }
5114
+ gatePending = false;
5115
+ debug11?.("hmr: discoveryDone resolved");
5116
+ gateResolver();
5117
+ };
5118
+ const noteRouteEvent = () => {
5119
+ pendingEvents = true;
5120
+ beginGate();
5121
+ };
5122
+ const runRefreshCycle = async (work) => {
5123
+ if (inProgress) {
5124
+ queued = true;
5125
+ debug11?.("hmr: rediscovery in flight \u2014 queued for a follow-up cycle");
5126
+ return;
5127
+ }
5128
+ pendingEvents = false;
5129
+ inProgress = true;
5130
+ try {
5131
+ await work();
5132
+ } finally {
5133
+ inProgress = false;
5134
+ if (queued) {
5135
+ queued = false;
5136
+ debug11?.("hmr: consuming queued rediscovery");
5137
+ runRefreshCycle(work).catch((err) => {
5138
+ debug11?.(
5139
+ "hmr: queued cycle rejected \u2014 releasing gate (%s)",
5140
+ err instanceof Error ? err.message : String(err)
5141
+ );
5142
+ resolveGate();
5143
+ });
5144
+ } else if (pendingEvents) {
5145
+ debug11?.(
5146
+ "hmr: holding gate for pending events (debounce not yet fired)"
5147
+ );
5148
+ } else {
5149
+ resolveGate();
5150
+ }
5151
+ }
5152
+ };
5153
+ return {
5154
+ beginGate,
5155
+ resolveGate,
5156
+ noteRouteEvent,
5157
+ runRefreshCycle,
5158
+ state: () => ({ gatePending, inProgress, queued, pendingEvents })
5159
+ };
5160
+ }
5161
+
4347
5162
  // src/vite/router-discovery.ts
5163
+ var debugDiscovery = createRangoDebugger(NS.discovery);
5164
+ var debugRoutes = createRangoDebugger(NS.routes);
5165
+ var debugBuild = createRangoDebugger(NS.build);
5166
+ var debugDev = createRangoDebugger(NS.dev);
5167
+ var loaderHookRegistered = false;
5168
+ function ensureCloudflareProtocolLoaderRegistered() {
5169
+ if (loaderHookRegistered) return;
5170
+ loaderHookRegistered = true;
5171
+ try {
5172
+ register(
5173
+ new URL("./plugins/cloudflare-protocol-loader-hook.mjs", import.meta.url)
5174
+ );
5175
+ } catch (err) {
5176
+ console.warn(
5177
+ `[rsc-router] Could not register Node ESM loader hook for cloudflare:* imports (${err?.message ?? err}). Falling back to Vite transform only.`
5178
+ );
5179
+ }
5180
+ }
4348
5181
  async function createTempRscServer(state, options = {}) {
5182
+ ensureCloudflareProtocolLoaderRegistered();
4349
5183
  const { default: rsc } = await import("@vitejs/plugin-rsc");
4350
5184
  return createViteServer({
4351
5185
  root: state.projectRoot,
@@ -4368,6 +5202,7 @@ async function createTempRscServer(state, options = {}) {
4368
5202
  ...options.forceBuild ? [hashClientRefs(state.projectRoot)] : [],
4369
5203
  createVersionPlugin(),
4370
5204
  createVirtualStubPlugin(),
5205
+ createCloudflareProtocolStubPlugin(),
4371
5206
  // Dev prerender must use dev-mode IDs (path-based) to match the workerd
4372
5207
  // runtime. forceBuild produces hashed IDs for production bundle consistency.
4373
5208
  exposeInternalIds(options.forceBuild ? { forceBuild: true } : void 0),
@@ -4375,8 +5210,69 @@ async function createTempRscServer(state, options = {}) {
4375
5210
  ]
4376
5211
  });
4377
5212
  }
5213
+ async function resolveBuildEnv(option, factoryCtx) {
5214
+ if (!option) return null;
5215
+ if (option === "auto") {
5216
+ if (factoryCtx.preset !== "cloudflare") {
5217
+ throw new Error(
5218
+ '[rsc-router] buildEnv: "auto" is only supported with preset: "cloudflare". Use a factory function or plain object for other presets.'
5219
+ );
5220
+ }
5221
+ try {
5222
+ const userRequire = createRequire2(
5223
+ resolve8(factoryCtx.root, "package.json")
5224
+ );
5225
+ const wranglerPath = userRequire.resolve("wrangler");
5226
+ const { getPlatformProxy } = await import(pathToFileURL(wranglerPath).href);
5227
+ const proxy = await getPlatformProxy();
5228
+ return {
5229
+ env: proxy.env,
5230
+ dispose: proxy.dispose
5231
+ };
5232
+ } catch (err) {
5233
+ throw new Error(
5234
+ `[rsc-router] buildEnv: "auto" requires wrangler to be installed.
5235
+ Install it with: pnpm add -D wrangler
5236
+ ${err.message}`
5237
+ );
5238
+ }
5239
+ }
5240
+ if (typeof option === "function") {
5241
+ return await option(factoryCtx);
5242
+ }
5243
+ return { env: option };
5244
+ }
5245
+ async function acquireBuildEnv(s, command, mode) {
5246
+ const option = s.opts?.buildEnv;
5247
+ if (!option) return false;
5248
+ const result = await resolveBuildEnv(option, {
5249
+ root: s.projectRoot,
5250
+ mode,
5251
+ command,
5252
+ preset: s.opts?.preset ?? "node"
5253
+ });
5254
+ if (!result) return false;
5255
+ s.resolvedBuildEnv = result.env;
5256
+ s.buildEnvDispose = result.dispose ?? null;
5257
+ globalThis[BUILD_ENV_GLOBAL_KEY] = result.env;
5258
+ return true;
5259
+ }
5260
+ async function releaseBuildEnv(s) {
5261
+ if (s.buildEnvDispose) {
5262
+ try {
5263
+ await s.buildEnvDispose();
5264
+ } catch (err) {
5265
+ console.warn(`[rsc-router] buildEnv dispose failed: ${err.message}`);
5266
+ }
5267
+ s.buildEnvDispose = null;
5268
+ }
5269
+ s.resolvedBuildEnv = void 0;
5270
+ delete globalThis[BUILD_ENV_GLOBAL_KEY];
5271
+ }
4378
5272
  function createRouterDiscoveryPlugin(entryPath, opts) {
4379
5273
  const s = createDiscoveryState(entryPath, opts);
5274
+ let viteCommand = "build";
5275
+ let viteMode = "production";
4380
5276
  return {
4381
5277
  name: "@rangojs/router:discovery",
4382
5278
  config() {
@@ -4385,31 +5281,13 @@ function createRouterDiscoveryPlugin(entryPath, opts) {
4385
5281
  __RANGO_DEBUG__: JSON.stringify(!!process.env.INTERNAL_RANGO_DEBUG)
4386
5282
  }
4387
5283
  };
4388
- if (opts?.enableBuildPrerender) {
4389
- config.environments = {
4390
- rsc: {
4391
- build: {
4392
- rollupOptions: {
4393
- output: {
4394
- manualChunks(id) {
4395
- if (s.resolvedPrerenderModules?.has(id)) {
4396
- return "__prerender-handlers";
4397
- }
4398
- if (s.resolvedStaticModules?.has(id)) {
4399
- return "__static-handlers";
4400
- }
4401
- }
4402
- }
4403
- }
4404
- }
4405
- }
4406
- };
4407
- }
4408
5284
  return config;
4409
5285
  },
4410
5286
  configResolved(config) {
4411
5287
  s.projectRoot = config.root;
4412
5288
  s.isBuildMode = config.command === "build";
5289
+ viteCommand = config.command;
5290
+ viteMode = config.mode;
4413
5291
  s.userResolveAlias = config.resolve.alias;
4414
5292
  if (!s.resolvedEntryPath && opts?.routerPathRef?.path) {
4415
5293
  s.resolvedEntryPath = opts.routerPathRef.path;
@@ -4445,6 +5323,9 @@ function createRouterDiscoveryPlugin(entryPath, opts) {
4445
5323
  const discoveryPromise = new Promise((resolve10) => {
4446
5324
  resolveDiscovery = resolve10;
4447
5325
  });
5326
+ const gate = createDiscoveryGate(s, debugDiscovery);
5327
+ const beginDiscoveryGate = gate.beginGate;
5328
+ const resolveDiscoveryGate = gate.resolveGate;
4448
5329
  const getDevServerOrigin = () => server.resolvedUrls?.local?.[0]?.replace(/\/$/, "") || `http://localhost:${server.config.server.port || 5173}`;
4449
5330
  let prerenderTempServer = null;
4450
5331
  let prerenderNodeRegistry = null;
@@ -4454,40 +5335,183 @@ function createRouterDiscoveryPlugin(entryPath, opts) {
4454
5335
  });
4455
5336
  prerenderTempServer = null;
4456
5337
  }
5338
+ releaseBuildEnv(s).catch(() => {
5339
+ });
4457
5340
  });
5341
+ async function importEntryAndRegistry(tempRscEnv) {
5342
+ const flagAlreadySet = !!globalThis.__rscRouterDiscoveryActive;
5343
+ if (!flagAlreadySet) {
5344
+ globalThis.__rscRouterDiscoveryActive = true;
5345
+ }
5346
+ try {
5347
+ debugDiscovery?.(
5348
+ "importEntryAndRegistry: importing entry (flag=%s)",
5349
+ globalThis.__rscRouterDiscoveryActive ?? false
5350
+ );
5351
+ await tempRscEnv.runner.import(s.resolvedEntryPath);
5352
+ debugDiscovery?.(
5353
+ "importEntryAndRegistry: entry import OK, fetching RouterRegistry"
5354
+ );
5355
+ const serverMod = await tempRscEnv.runner.import(
5356
+ "@rangojs/router/server"
5357
+ );
5358
+ prerenderNodeRegistry = serverMod.RouterRegistry;
5359
+ debugDiscovery?.(
5360
+ "importEntryAndRegistry: registry size=%d",
5361
+ prerenderNodeRegistry?.size ?? 0
5362
+ );
5363
+ } finally {
5364
+ if (!flagAlreadySet) {
5365
+ delete globalThis.__rscRouterDiscoveryActive;
5366
+ debugDiscovery?.(
5367
+ "importEntryAndRegistry: cleared __rscRouterDiscoveryActive"
5368
+ );
5369
+ }
5370
+ }
5371
+ }
4458
5372
  async function getOrCreateTempServer() {
4459
- if (prerenderNodeRegistry) {
4460
- return prerenderTempServer.environments?.rsc ?? null;
5373
+ if (prerenderTempServer) {
5374
+ const existingEnv = prerenderTempServer.environments?.rsc;
5375
+ if (existingEnv?.runner) {
5376
+ if (prerenderNodeRegistry) {
5377
+ debugDiscovery?.(
5378
+ "getOrCreateTempServer: cached temp runner reused"
5379
+ );
5380
+ return existingEnv;
5381
+ }
5382
+ debugDiscovery?.(
5383
+ "getOrCreateTempServer: server alive but registry missing \u2014 re-importing"
5384
+ );
5385
+ try {
5386
+ await importEntryAndRegistry(existingEnv);
5387
+ return existingEnv;
5388
+ } catch (err) {
5389
+ debugDiscovery?.(
5390
+ "getOrCreateTempServer: reuse import failed (%s) \u2014 closing orphan and creating fresh",
5391
+ err?.message ?? String(err)
5392
+ );
5393
+ await prerenderTempServer.close().catch(() => {
5394
+ });
5395
+ prerenderTempServer = null;
5396
+ prerenderNodeRegistry = null;
5397
+ }
5398
+ } else {
5399
+ debugDiscovery?.(
5400
+ "getOrCreateTempServer: existing server has no rsc.runner \u2014 closing and recreating"
5401
+ );
5402
+ await prerenderTempServer.close().catch(() => {
5403
+ });
5404
+ prerenderTempServer = null;
5405
+ prerenderNodeRegistry = null;
5406
+ }
4461
5407
  }
5408
+ debugDiscovery?.(
5409
+ "getOrCreateTempServer: creating new temp server, entry=%s",
5410
+ s.resolvedEntryPath ?? "(unset)"
5411
+ );
4462
5412
  try {
4463
5413
  prerenderTempServer = await createTempRscServer(s, {
4464
5414
  cacheDir: "node_modules/.vite_prerender"
4465
5415
  });
4466
5416
  const tempRscEnv = prerenderTempServer.environments?.rsc;
4467
5417
  if (tempRscEnv?.runner) {
4468
- await tempRscEnv.runner.import(s.resolvedEntryPath);
4469
- const serverMod = await tempRscEnv.runner.import(
4470
- "@rangojs/router/server"
4471
- );
4472
- prerenderNodeRegistry = serverMod.RouterRegistry;
5418
+ await importEntryAndRegistry(tempRscEnv);
4473
5419
  return tempRscEnv;
4474
5420
  }
5421
+ debugDiscovery?.(
5422
+ "getOrCreateTempServer: tempRscEnv.runner unavailable"
5423
+ );
4475
5424
  } catch (err) {
5425
+ debugDiscovery?.(
5426
+ "getOrCreateTempServer: FAILED message=%s",
5427
+ err.message
5428
+ );
4476
5429
  console.warn(
4477
5430
  `[rsc-router] Failed to create temp runner: ${err.message}`
4478
5431
  );
4479
5432
  }
4480
5433
  return null;
4481
5434
  }
5435
+ async function clearTempRegistries(tempRscEnv) {
5436
+ try {
5437
+ const serverMod = await tempRscEnv.runner.import(
5438
+ "@rangojs/router/server"
5439
+ );
5440
+ if (typeof serverMod?.RouterRegistry?.clear === "function") {
5441
+ serverMod.RouterRegistry.clear();
5442
+ }
5443
+ if (typeof serverMod?.HostRouterRegistry?.clear === "function") {
5444
+ serverMod.HostRouterRegistry.clear();
5445
+ }
5446
+ debugDiscovery?.(
5447
+ "clearTempRegistries: cleared RouterRegistry + HostRouterRegistry"
5448
+ );
5449
+ } catch (err) {
5450
+ debugDiscovery?.(
5451
+ "clearTempRegistries: import @rangojs/router/server failed (%s)",
5452
+ err?.message ?? String(err)
5453
+ );
5454
+ }
5455
+ }
5456
+ async function refreshTempRscEnv() {
5457
+ let tempRscEnv = await getOrCreateTempServer();
5458
+ if (!tempRscEnv) return null;
5459
+ const envGraph = tempRscEnv.moduleGraph;
5460
+ const serverGraph = prerenderTempServer?.moduleGraph;
5461
+ const target = envGraph?.invalidateAll ? envGraph : serverGraph?.invalidateAll ? serverGraph : null;
5462
+ if (!target) {
5463
+ debugDiscovery?.(
5464
+ "refreshTempRscEnv: invalidateAll unavailable on env+server graphs, falling back to close+recreate"
5465
+ );
5466
+ if (prerenderTempServer) {
5467
+ await prerenderTempServer.close().catch(() => {
5468
+ });
5469
+ prerenderTempServer = null;
5470
+ prerenderNodeRegistry = null;
5471
+ }
5472
+ return await getOrCreateTempServer();
5473
+ }
5474
+ debugDiscovery?.(
5475
+ "refreshTempRscEnv: invalidating module graph (%s)",
5476
+ envGraph?.invalidateAll ? "env" : "server"
5477
+ );
5478
+ target.invalidateAll();
5479
+ prerenderNodeRegistry = null;
5480
+ await clearTempRegistries(tempRscEnv);
5481
+ await importEntryAndRegistry(tempRscEnv);
5482
+ return tempRscEnv;
5483
+ }
4482
5484
  const discover = async () => {
5485
+ const discoverStart = performance.now();
4483
5486
  const rscEnv = server.environments?.rsc;
4484
5487
  if (!rscEnv?.runner) {
5488
+ debugDiscovery?.(
5489
+ "dev: cloudflare path start, __rscRouterDiscoveryActive=%s",
5490
+ globalThis.__rscRouterDiscoveryActive ?? false
5491
+ );
4485
5492
  s.devServerOrigin = getDevServerOrigin();
4486
5493
  try {
4487
- const tempRscEnv = await getOrCreateTempServer();
5494
+ await timed(
5495
+ debugDiscovery,
5496
+ "acquireBuildEnv",
5497
+ () => acquireBuildEnv(s, viteCommand, viteMode)
5498
+ );
5499
+ const tempRscEnv = await timed(
5500
+ debugDiscovery,
5501
+ "getOrCreateTempServer",
5502
+ () => getOrCreateTempServer()
5503
+ );
4488
5504
  if (tempRscEnv) {
4489
- await discoverRouters(s, tempRscEnv);
4490
- writeRouteTypesFiles(s);
5505
+ await timed(
5506
+ debugDiscovery,
5507
+ "discoverRouters (cloudflare)",
5508
+ () => discoverRouters(s, tempRscEnv)
5509
+ );
5510
+ timedSync(
5511
+ debugDiscovery,
5512
+ "writeRouteTypesFiles",
5513
+ () => writeRouteTypesFiles(s)
5514
+ );
4491
5515
  }
4492
5516
  } catch (err) {
4493
5517
  console.warn(
@@ -4495,32 +5519,62 @@ function createRouterDiscoveryPlugin(entryPath, opts) {
4495
5519
  ${err.stack}`
4496
5520
  );
4497
5521
  }
5522
+ debugDiscovery?.(
5523
+ "dev discovery done (%sms)",
5524
+ (performance.now() - discoverStart).toFixed(1)
5525
+ );
4498
5526
  resolveDiscovery();
4499
5527
  return;
4500
5528
  }
4501
5529
  try {
4502
- const serverMod = await rscEnv.runner.import(
4503
- "@rangojs/router/server"
5530
+ debugDiscovery?.("dev: node path start");
5531
+ await timed(
5532
+ debugDiscovery,
5533
+ "acquireBuildEnv",
5534
+ () => acquireBuildEnv(s, viteCommand, viteMode)
5535
+ );
5536
+ const serverMod = await timed(
5537
+ debugDiscovery,
5538
+ "import @rangojs/router/server",
5539
+ () => rscEnv.runner.import("@rangojs/router/server")
4504
5540
  );
4505
5541
  if (serverMod?.setManifestReadyPromise) {
4506
5542
  serverMod.setManifestReadyPromise(discoveryPromise);
4507
5543
  }
4508
- await discoverRouters(s, rscEnv);
5544
+ await timed(
5545
+ debugDiscovery,
5546
+ "discoverRouters",
5547
+ () => discoverRouters(s, rscEnv)
5548
+ );
4509
5549
  s.devServerOrigin = getDevServerOrigin();
4510
- writeRouteTypesFiles(s);
4511
- await propagateDiscoveryState(rscEnv);
5550
+ timedSync(
5551
+ debugDiscovery,
5552
+ "writeRouteTypesFiles",
5553
+ () => writeRouteTypesFiles(s)
5554
+ );
5555
+ await timed(
5556
+ debugDiscovery,
5557
+ "propagateDiscoveryState",
5558
+ () => propagateDiscoveryState(rscEnv)
5559
+ );
4512
5560
  } catch (err) {
4513
5561
  console.warn(
4514
5562
  `[rsc-router] Router discovery failed: ${err.message}
4515
5563
  ${err.stack}`
4516
5564
  );
4517
5565
  } finally {
5566
+ debugDiscovery?.(
5567
+ "dev discovery done (%sms)",
5568
+ (performance.now() - discoverStart).toFixed(1)
5569
+ );
4518
5570
  resolveDiscovery();
4519
5571
  }
4520
5572
  };
4521
- s.discoveryDone = new Promise((resolve10) => {
4522
- setTimeout(() => discover().then(resolve10, resolve10), 0);
4523
- });
5573
+ beginDiscoveryGate();
5574
+ setTimeout(
5575
+ () => discover().then(resolveDiscoveryGate, resolveDiscoveryGate),
5576
+ 0
5577
+ );
4524
5578
  let mainRegistry = null;
4525
5579
  const propagateDiscoveryState = async (rscEnv) => {
4526
5580
  const serverMod = await rscEnv.runner.import("@rangojs/router/server");
@@ -4555,15 +5609,46 @@ ${err.stack}`
4555
5609
  }
4556
5610
  };
4557
5611
  server.middlewares.use("/__rsc_prerender", async (req, res) => {
5612
+ const reqStart = debugDev ? performance.now() : 0;
5613
+ const logResult = (status, note) => {
5614
+ debugDev?.(
5615
+ "/__rsc_prerender %s -> %d %s (%sms)",
5616
+ req.url,
5617
+ status,
5618
+ note,
5619
+ (performance.now() - reqStart).toFixed(1)
5620
+ );
5621
+ };
4558
5622
  if (s.discoveryDone) await s.discoveryDone;
4559
5623
  const url = new URL(req.url || "/", "http://localhost");
4560
5624
  const pathname = url.searchParams.get("pathname");
4561
5625
  if (!pathname) {
4562
5626
  res.statusCode = 400;
4563
5627
  res.end("Missing pathname");
5628
+ logResult(400, "missing pathname");
4564
5629
  return;
4565
5630
  }
4566
- let registry = mainRegistry;
5631
+ const rscEnv = server.environments?.rsc;
5632
+ let registry = null;
5633
+ if (rscEnv?.runner && s.resolvedEntryPath) {
5634
+ try {
5635
+ await rscEnv.runner.import(s.resolvedEntryPath);
5636
+ const serverMod = await rscEnv.runner.import(
5637
+ "@rangojs/router/server"
5638
+ );
5639
+ registry = serverMod.RouterRegistry ?? null;
5640
+ } catch (err) {
5641
+ console.warn(
5642
+ `[rsc-router] Dev prerender module refresh failed: ${err.message}`
5643
+ );
5644
+ res.statusCode = 500;
5645
+ res.end(`Prerender handler error: ${err.message}`);
5646
+ logResult(500, "module refresh failed");
5647
+ return;
5648
+ }
5649
+ } else {
5650
+ registry = mainRegistry;
5651
+ }
4567
5652
  if (!registry) {
4568
5653
  if (!prerenderNodeRegistry) {
4569
5654
  await getOrCreateTempServer();
@@ -4573,6 +5658,7 @@ ${err.stack}`
4573
5658
  if (!registry || registry.size === 0) {
4574
5659
  res.statusCode = 503;
4575
5660
  res.end("Prerender runner not available");
5661
+ logResult(503, "no registry");
4576
5662
  return;
4577
5663
  }
4578
5664
  const wantIntercept = url.searchParams.get("intercept") === "1";
@@ -4585,7 +5671,10 @@ ${err.stack}`
4585
5671
  pathname,
4586
5672
  {},
4587
5673
  void 0,
4588
- wantPassthrough
5674
+ wantPassthrough,
5675
+ s.resolvedBuildEnv,
5676
+ true
5677
+ // devMode: check getParams for passthrough routes
4589
5678
  );
4590
5679
  if (!result) continue;
4591
5680
  if (result.passthrough) continue;
@@ -4604,6 +5693,7 @@ ${err.stack}`
4604
5693
  payload = { segments: result.segments, handles: result.handles };
4605
5694
  }
4606
5695
  res.end(JSON.stringify(payload));
5696
+ logResult(200, `match ${result.routeName}`);
4607
5697
  return;
4608
5698
  } catch (err) {
4609
5699
  console.warn(
@@ -4613,6 +5703,7 @@ ${err.stack}`
4613
5703
  }
4614
5704
  res.statusCode = 404;
4615
5705
  res.end("No prerender match");
5706
+ logResult(404, "no match");
4616
5707
  });
4617
5708
  if (opts?.staticRouteTypesGeneration !== false) {
4618
5709
  const isGeneratedRouteFile = (filePath) => filePath.endsWith(".gen.ts") && (filePath.includes("named-routes.gen.ts") || filePath.includes("urls.gen.ts"));
@@ -4632,42 +5723,96 @@ ${err.stack}`
4632
5723
  return true;
4633
5724
  };
4634
5725
  let routeChangeTimer;
4635
- let runtimeRediscoveryInProgress = false;
4636
5726
  const refreshRuntimeDiscovery = async () => {
4637
5727
  const rscEnv = server.environments?.rsc;
4638
- if (!rscEnv?.runner || runtimeRediscoveryInProgress) return;
4639
- runtimeRediscoveryInProgress = true;
4640
- try {
4641
- await discoverRouters(s, rscEnv);
4642
- writeRouteTypesFiles(s);
4643
- await propagateDiscoveryState(rscEnv);
4644
- } catch (err) {
4645
- console.warn(
4646
- `[rsc-router] Runtime re-discovery failed: ${err.message}`
4647
- );
4648
- } finally {
4649
- runtimeRediscoveryInProgress = false;
4650
- }
5728
+ const hasMainRunner = !!rscEnv?.runner;
5729
+ if (!hasMainRunner && s.perRouterManifests.length === 0) return;
5730
+ await gate.runRefreshCycle(async () => {
5731
+ const hmrStart = performance.now();
5732
+ try {
5733
+ if (hasMainRunner) {
5734
+ await timed(
5735
+ debugDiscovery,
5736
+ "hmr discoverRouters",
5737
+ () => discoverRouters(s, rscEnv)
5738
+ );
5739
+ timedSync(
5740
+ debugDiscovery,
5741
+ "hmr writeRouteTypesFiles",
5742
+ () => writeRouteTypesFiles(s)
5743
+ );
5744
+ await timed(
5745
+ debugDiscovery,
5746
+ "hmr propagateDiscoveryState",
5747
+ () => propagateDiscoveryState(rscEnv)
5748
+ );
5749
+ } else {
5750
+ const tempRscEnv = await timed(
5751
+ debugDiscovery,
5752
+ "hmr refreshTempRscEnv (cloudflare)",
5753
+ () => refreshTempRscEnv()
5754
+ );
5755
+ if (!tempRscEnv) {
5756
+ throw new Error(
5757
+ "temp runner unavailable for cloudflare HMR rediscovery"
5758
+ );
5759
+ }
5760
+ await timed(
5761
+ debugDiscovery,
5762
+ "hmr discoverRouters (cloudflare)",
5763
+ () => discoverRouters(s, tempRscEnv)
5764
+ );
5765
+ timedSync(
5766
+ debugDiscovery,
5767
+ "hmr writeRouteTypesFiles",
5768
+ () => writeRouteTypesFiles(s)
5769
+ );
5770
+ }
5771
+ } catch (err) {
5772
+ console.warn(
5773
+ `[rsc-router] Runtime re-discovery failed: ${err.message}`
5774
+ );
5775
+ } finally {
5776
+ debugDiscovery?.(
5777
+ "hmr re-discovery done (%sms)",
5778
+ (performance.now() - hmrStart).toFixed(1)
5779
+ );
5780
+ }
5781
+ });
4651
5782
  };
4652
5783
  const scheduleRouteRegeneration = () => {
4653
5784
  clearTimeout(routeChangeTimer);
4654
5785
  routeChangeTimer = setTimeout(() => {
4655
5786
  routeChangeTimer = void 0;
5787
+ const regenStart = debugDiscovery ? performance.now() : 0;
5788
+ const rscEnv = server.environments?.rsc;
5789
+ const skipStaticWrite = !rscEnv?.runner && s.perRouterManifests.length > 0;
4656
5790
  try {
4657
- writeCombinedRouteTypesWithTracking(s);
4658
- if (s.perRouterManifests.length > 0) {
4659
- supplementGenFilesWithRuntimeRoutes(s);
5791
+ if (skipStaticWrite) {
5792
+ debugDiscovery?.(
5793
+ "watcher: skipping static write (cloudflare HMR \u2014 runtime rediscovery owns gen file)"
5794
+ );
5795
+ } else {
5796
+ writeCombinedRouteTypesWithTracking(s);
5797
+ if (s.perRouterManifests.length > 0) {
5798
+ supplementGenFilesWithRuntimeRoutes(s);
5799
+ }
4660
5800
  }
4661
5801
  } catch (err) {
4662
5802
  console.error(
4663
5803
  `[rsc-router] Route regeneration error: ${err.message}`
4664
5804
  );
4665
5805
  }
5806
+ debugDiscovery?.(
5807
+ "watcher: regenerated gen files (%sms)",
5808
+ (performance.now() - regenStart).toFixed(1)
5809
+ );
4666
5810
  if (s.perRouterManifests.length > 0) {
4667
5811
  refreshRuntimeDiscovery().catch((err) => {
4668
5812
  console.warn(
4669
5813
  `[rsc-router] Runtime re-discovery error: ${err.message}`
4670
5814
  );
5815
+ resolveDiscoveryGate();
4671
5816
  });
4672
5817
  }
4673
5818
  }, 100);
@@ -4685,6 +5830,12 @@ ${err.stack}`
4685
5830
  const hasUrls = source.includes("urls(");
4686
5831
  const hasCreateRouter = /\bcreateRouter\s*[<(]/.test(source);
4687
5832
  if (!hasUrls && !hasCreateRouter) return;
5833
+ debugDiscovery?.(
5834
+ "watcher: %s matches (urls=%s, router=%s)",
5835
+ filePath,
5836
+ hasUrls,
5837
+ hasCreateRouter
5838
+ );
4688
5839
  if (hasCreateRouter) {
4689
5840
  const nestedRouterConflict = findNestedRouterConflict([
4690
5841
  ...s.cachedRouterFiles ?? [],
@@ -4698,6 +5849,9 @@ ${err.stack}`
4698
5849
  }
4699
5850
  s.cachedRouterFiles = void 0;
4700
5851
  }
5852
+ if (s.perRouterManifests.length > 0) {
5853
+ gate.noteRouteEvent();
5854
+ }
4701
5855
  scheduleRouteRegeneration();
4702
5856
  } catch {
4703
5857
  }
@@ -4717,14 +5871,31 @@ ${err.stack}`
4717
5871
  // The manifest data is stored for the virtual module's load hook.
4718
5872
  async buildStart() {
4719
5873
  if (!s.isBuildMode) return;
4720
- if (s.mergedRouteManifest !== null) return;
5874
+ if (s.mergedRouteManifest !== null) {
5875
+ debugDiscovery?.(
5876
+ "build: skip (already discovered, env=%s)",
5877
+ this.environment?.name ?? "?"
5878
+ );
5879
+ return;
5880
+ }
5881
+ const buildStartTime = performance.now();
5882
+ debugDiscovery?.("build: start (env=%s)", this.environment?.name ?? "?");
4721
5883
  resetStagedBuildAssets(s.projectRoot);
4722
5884
  s.prerenderManifestEntries = null;
4723
5885
  s.staticManifestEntries = null;
5886
+ await timed(
5887
+ debugDiscovery,
5888
+ "build acquireBuildEnv",
5889
+ () => acquireBuildEnv(s, viteCommand, viteMode)
5890
+ );
4724
5891
  let tempServer = null;
4725
5892
  globalThis.__rscRouterDiscoveryActive = true;
4726
5893
  try {
4727
- tempServer = await createTempRscServer(s, { forceBuild: true });
5894
+ tempServer = await timed(
5895
+ debugDiscovery,
5896
+ "build createTempRscServer",
5897
+ () => createTempRscServer(s, { forceBuild: true })
5898
+ );
4728
5899
  const rscEnv = tempServer.environments?.rsc;
4729
5900
  if (!rscEnv?.runner) {
4730
5901
  console.warn(
@@ -4738,8 +5909,16 @@ ${err.stack}`
4738
5909
  if (tempIdsPlugin?.api?.staticHandlerModules) {
4739
5910
  s.resolvedStaticModules = tempIdsPlugin.api.staticHandlerModules;
4740
5911
  }
4741
- await discoverRouters(s, rscEnv);
4742
- writeRouteTypesFiles(s);
5912
+ await timed(
5913
+ debugDiscovery,
5914
+ "build discoverRouters",
5915
+ () => discoverRouters(s, rscEnv)
5916
+ );
5917
+ timedSync(
5918
+ debugDiscovery,
5919
+ "build writeRouteTypesFiles",
5920
+ () => writeRouteTypesFiles(s)
5921
+ );
4743
5922
  } catch (err) {
4744
5923
  const sourceFile = err.stack?.split("\n").find(
4745
5924
  (line) => line.includes(s.projectRoot) && !line.includes("node_modules")
@@ -4758,8 +5937,45 @@ ${details}`
4758
5937
  } finally {
4759
5938
  delete globalThis.__rscRouterDiscoveryActive;
4760
5939
  if (tempServer) {
4761
- await tempServer.close();
5940
+ await timed(
5941
+ debugDiscovery,
5942
+ "build tempServer.close",
5943
+ () => tempServer.close()
5944
+ );
4762
5945
  }
5946
+ await releaseBuildEnv(s);
5947
+ debugDiscovery?.(
5948
+ "build discovery done (%sms)",
5949
+ (performance.now() - buildStartTime).toFixed(1)
5950
+ );
5951
+ }
5952
+ },
5953
+ // Suppress vite's HMR cascade for our own gen-file writes.
5954
+ //
5955
+ // After every cf HMR cycle, refreshTempRscEnv → writeRouteTypesFiles
5956
+ // writes the configured gen files (default `router.named-routes.gen.ts`,
5957
+ // but the source filenames and gen suffix are user-configurable). The
5958
+ // chokidar watcher then fires twice independently: our
5959
+ // `handleRouteFileChange` (already short-circuited by
5960
+ // `consumeSelfGenWrite` inside `maybeHandleGeneratedRouteFileMutation`),
5961
+ // AND vite's own HMR pipeline (which invalidates the gen file's
5962
+ // importers and triggers a second workerd full reload — visible to the
5963
+ // user as a duplicate "[RSCRouter] HMR: version changed" on the client).
5964
+ //
5965
+ // `peekSelfGenWrite` is the authoritative filter: its map only contains
5966
+ // paths that `markSelfGenWrite` has registered, so it natively works
5967
+ // for any configured gen-file name. It is non-consuming so the chokidar
5968
+ // handler that fires later can still consume the same entry. Returning
5969
+ // [] tells vite "no modules invalidated by this change" — safe because
5970
+ // `s.perRouterManifests` is already up-to-date (the write that just
5971
+ // happened is the consequence of our just-completed rediscovery).
5972
+ handleHotUpdate(ctx) {
5973
+ if (peekSelfGenWrite(s, ctx.file)) {
5974
+ debugDiscovery?.(
5975
+ "handleHotUpdate: suppressing self-write HMR cascade for %s",
5976
+ ctx.file
5977
+ );
5978
+ return [];
4763
5979
  }
4764
5980
  },
4765
5981
  // Virtual module: provides the pre-generated route manifest as a JS module
@@ -4776,17 +5992,36 @@ ${details}`
4776
5992
  async load(id) {
4777
5993
  if (id === "\0" + VIRTUAL_ROUTES_MANIFEST_ID) {
4778
5994
  if (s.discoveryDone) {
4779
- await s.discoveryDone;
5995
+ await timed(
5996
+ debugRoutes,
5997
+ "await discoveryDone (manifest)",
5998
+ () => s.discoveryDone
5999
+ );
4780
6000
  }
4781
- return generateRoutesManifestModule(s);
6001
+ const code = await timed(
6002
+ debugRoutes,
6003
+ "generateRoutesManifestModule",
6004
+ () => generateRoutesManifestModule(s)
6005
+ );
6006
+ debugRoutes?.("manifest module emitted (%d bytes)", code?.length ?? 0);
6007
+ return code;
4782
6008
  }
4783
6009
  const perRouterPrefix = "\0" + VIRTUAL_ROUTES_MANIFEST_ID + "/";
4784
6010
  if (id.startsWith(perRouterPrefix)) {
4785
6011
  if (s.discoveryDone) {
4786
- await s.discoveryDone;
6012
+ await timed(
6013
+ debugRoutes,
6014
+ "await discoveryDone (per-router)",
6015
+ () => s.discoveryDone
6016
+ );
4787
6017
  }
4788
6018
  const routerId = id.slice(perRouterPrefix.length);
4789
- return generatePerRouterModule(s, routerId);
6019
+ const code = await timed(
6020
+ debugRoutes,
6021
+ `generatePerRouterModule ${routerId}`,
6022
+ () => generatePerRouterModule(s, routerId)
6023
+ );
6024
+ return code;
4790
6025
  }
4791
6026
  return null;
4792
6027
  },
@@ -4794,28 +6029,44 @@ ${details}`
4794
6029
  // Used by closeBundle for handler code eviction and prerender data injection.
4795
6030
  generateBundle(_options, bundle) {
4796
6031
  if (this.environment?.name !== "rsc") return;
6032
+ const genStart = debugBuild ? performance.now() : 0;
4797
6033
  for (const [fileName, chunk] of Object.entries(bundle)) {
4798
6034
  if (chunk.type === "chunk" && chunk.isEntry) {
4799
6035
  s.rscEntryFileName = fileName;
4800
6036
  break;
4801
6037
  }
4802
6038
  }
4803
- if (!s.resolvedPrerenderModules?.size && !s.resolvedStaticModules?.size)
6039
+ if (!s.resolvedPrerenderModules?.size && !s.resolvedStaticModules?.size) {
6040
+ debugBuild?.(
6041
+ "generateBundle (rsc): no handlers to scan (%sms)",
6042
+ (performance.now() - genStart).toFixed(1)
6043
+ );
4804
6044
  return;
6045
+ }
6046
+ s.handlerChunkInfoMap.clear();
6047
+ s.staticHandlerChunkInfoMap.clear();
4805
6048
  for (const [fileName, chunk] of Object.entries(bundle)) {
4806
6049
  if (chunk.type !== "chunk") continue;
4807
- if (fileName.includes("__prerender-handlers") && s.resolvedPrerenderModules?.size) {
6050
+ if (s.resolvedPrerenderModules?.size) {
4808
6051
  const handlers = extractHandlerExportsFromChunk(
4809
6052
  chunk.code,
4810
6053
  s.resolvedPrerenderModules,
4811
6054
  "Prerender",
4812
- true
6055
+ false
4813
6056
  );
4814
6057
  if (handlers.length > 0) {
4815
- s.handlerChunkInfo = { fileName, exports: handlers };
6058
+ const existing = s.handlerChunkInfoMap.get(fileName);
6059
+ if (existing) {
6060
+ existing.exports.push(...handlers);
6061
+ } else {
6062
+ s.handlerChunkInfoMap.set(fileName, {
6063
+ fileName,
6064
+ exports: handlers
6065
+ });
6066
+ }
4816
6067
  }
4817
6068
  }
4818
- if (fileName.includes("__static-handlers") && s.resolvedStaticModules?.size) {
6069
+ if (s.resolvedStaticModules?.size) {
4819
6070
  const handlers = extractHandlerExportsFromChunk(
4820
6071
  chunk.code,
4821
6072
  s.resolvedStaticModules,
@@ -4823,10 +6074,25 @@ ${details}`
4823
6074
  false
4824
6075
  );
4825
6076
  if (handlers.length > 0) {
4826
- s.staticHandlerChunkInfo = { fileName, exports: handlers };
6077
+ const existing = s.staticHandlerChunkInfoMap.get(fileName);
6078
+ if (existing) {
6079
+ existing.exports.push(...handlers);
6080
+ } else {
6081
+ s.staticHandlerChunkInfoMap.set(fileName, {
6082
+ fileName,
6083
+ exports: handlers
6084
+ });
6085
+ }
4827
6086
  }
4828
6087
  }
4829
6088
  }
6089
+ debugBuild?.(
6090
+ "generateBundle (rsc): scanned %d chunks, %d prerender chunk(s), %d static chunk(s) (%sms)",
6091
+ Object.keys(bundle).length,
6092
+ s.handlerChunkInfoMap.size,
6093
+ s.staticHandlerChunkInfoMap.size,
6094
+ (performance.now() - genStart).toFixed(1)
6095
+ );
4830
6096
  },
4831
6097
  // Build-time pre-rendering: evict handler code and inject collected prerender data.
4832
6098
  // Collection now happens in-process during discoverRouters() via RSC runner.
@@ -4837,20 +6103,41 @@ ${details}`
4837
6103
  async handler() {
4838
6104
  if (!s.isBuildMode) return;
4839
6105
  if (this.environment && this.environment.name !== "rsc") return;
4840
- postprocessBundle(s);
6106
+ timedSync(
6107
+ debugBuild,
6108
+ "closeBundle postprocessBundle",
6109
+ () => postprocessBundle(s)
6110
+ );
4841
6111
  }
4842
6112
  }
4843
6113
  };
4844
6114
  }
4845
6115
 
4846
6116
  // src/vite/rango.ts
6117
+ var debugConfig = createRangoDebugger(NS.config);
4847
6118
  async function rango(options) {
6119
+ const rangoStart = performance.now();
4848
6120
  const resolvedOptions = options ?? { preset: "node" };
4849
6121
  const preset = resolvedOptions.preset ?? "node";
4850
6122
  const showBanner = resolvedOptions.banner ?? true;
6123
+ debugConfig?.("rango(%s) setup start", preset);
4851
6124
  const plugins = [];
4852
- const rangoAliases = getPackageAliases();
4853
- const excludeDeps = getExcludeDeps();
6125
+ const rangoAliases = { ...getPackageAliases(), ...getVendorAliases() };
6126
+ const excludeDeps = [
6127
+ ...getExcludeDeps(),
6128
+ // plugin-rsc itself injects these into the client env's
6129
+ // optimizeDeps.include, which overrides exclude for the dep's own
6130
+ // pre-bundle entry. What exclude still controls is how *other*
6131
+ // pre-bundled deps treat imports of these specs (external vs inlined)
6132
+ // via esbuildCjsExternalPlugin. The cjs-to-esm transform in
6133
+ // plugins/cjs-to-esm.ts is the fallback for strict-pnpm consumers,
6134
+ // where client.browser's bare include fails to resolve and Vite ends up
6135
+ // serving the raw CJS file at dev-serve time.
6136
+ "@vitejs/plugin-rsc/browser",
6137
+ "@vitejs/plugin-rsc/vendor/react-server-dom/client.browser"
6138
+ ];
6139
+ const pkg = getPublishedPackageName();
6140
+ const nested = (spec) => `${pkg} > ${spec}`;
4854
6141
  const routerRef = { path: void 0 };
4855
6142
  const prerenderEnabled = true;
4856
6143
  if (preset === "cloudflare") {
@@ -4888,7 +6175,7 @@ async function rango(options) {
4888
6175
  // Pre-bundle rsc-html-stream to prevent discovery during first request
4889
6176
  // Exclude rsc-router modules to ensure same Context instance
4890
6177
  optimizeDeps: {
4891
- include: ["rsc-html-stream/client"],
6178
+ include: [nested("rsc-html-stream/client")],
4892
6179
  exclude: excludeDeps,
4893
6180
  esbuildOptions: sharedEsbuildOptions
4894
6181
  }
@@ -4913,8 +6200,10 @@ async function rango(options) {
4913
6200
  "react-dom/static.edge",
4914
6201
  "react/jsx-runtime",
4915
6202
  "react/jsx-dev-runtime",
4916
- "rsc-html-stream/server",
4917
- "@vitejs/plugin-rsc/vendor/react-server-dom/client.edge"
6203
+ nested("rsc-html-stream/server"),
6204
+ nested(
6205
+ "@vitejs/plugin-rsc/vendor/react-server-dom/client.edge"
6206
+ )
4918
6207
  ],
4919
6208
  exclude: excludeDeps,
4920
6209
  esbuildOptions: sharedEsbuildOptions
@@ -4929,7 +6218,9 @@ async function rango(options) {
4929
6218
  "react",
4930
6219
  "react/jsx-runtime",
4931
6220
  "react/jsx-dev-runtime",
4932
- "@vitejs/plugin-rsc/vendor/react-server-dom/server.edge"
6221
+ nested(
6222
+ "@vitejs/plugin-rsc/vendor/react-server-dom/server.edge"
6223
+ )
4933
6224
  ],
4934
6225
  exclude: excludeDeps,
4935
6226
  esbuildOptions: sharedEsbuildOptions
@@ -4946,6 +6237,7 @@ async function rango(options) {
4946
6237
  }
4947
6238
  });
4948
6239
  plugins.push(createVirtualEntriesPlugin(finalEntries));
6240
+ plugins.push(performanceTracksPlugin());
4949
6241
  plugins.push(
4950
6242
  rsc({
4951
6243
  entries: finalEntries,
@@ -5009,7 +6301,7 @@ ${list}`);
5009
6301
  "react-dom",
5010
6302
  "react/jsx-runtime",
5011
6303
  "react/jsx-dev-runtime",
5012
- "rsc-html-stream/client"
6304
+ nested("rsc-html-stream/client")
5013
6305
  ],
5014
6306
  exclude: excludeDeps,
5015
6307
  esbuildOptions: sharedEsbuildOptions,
@@ -5026,7 +6318,9 @@ ${list}`);
5026
6318
  "react-dom/static.edge",
5027
6319
  "react/jsx-runtime",
5028
6320
  "react/jsx-dev-runtime",
5029
- "@vitejs/plugin-rsc/vendor/react-server-dom/client.edge"
6321
+ nested(
6322
+ "@vitejs/plugin-rsc/vendor/react-server-dom/client.edge"
6323
+ )
5030
6324
  ],
5031
6325
  exclude: excludeDeps,
5032
6326
  esbuildOptions: sharedEsbuildOptions
@@ -5039,7 +6333,9 @@ ${list}`);
5039
6333
  "react",
5040
6334
  "react/jsx-runtime",
5041
6335
  "react/jsx-dev-runtime",
5042
- "@vitejs/plugin-rsc/vendor/react-server-dom/server.edge"
6336
+ nested(
6337
+ "@vitejs/plugin-rsc/vendor/react-server-dom/server.edge"
6338
+ )
5043
6339
  ],
5044
6340
  esbuildOptions: sharedEsbuildOptions
5045
6341
  }
@@ -5064,6 +6360,7 @@ ${list}`);
5064
6360
  }
5065
6361
  });
5066
6362
  plugins.push(createVirtualEntriesPlugin(finalEntries, routerRef));
6363
+ plugins.push(performanceTracksPlugin());
5067
6364
  plugins.push(
5068
6365
  rsc({
5069
6366
  entries: finalEntries
@@ -5104,9 +6401,16 @@ ${list}`);
5104
6401
  createRouterDiscoveryPlugin(discoveryEntryPath, {
5105
6402
  routerPathRef: discoveryRouterRef,
5106
6403
  enableBuildPrerender: prerenderEnabled,
5107
- staticRouteTypesGeneration: resolvedOptions.staticRouteTypesGeneration
6404
+ buildEnv: options?.buildEnv,
6405
+ preset
5108
6406
  })
5109
6407
  );
6408
+ debugConfig?.(
6409
+ "rango(%s) setup done: %d plugin(s) (%sms)",
6410
+ preset,
6411
+ plugins.length,
6412
+ (performance.now() - rangoStart).toFixed(1)
6413
+ );
5110
6414
  return plugins;
5111
6415
  }
5112
6416
 
@@ -5117,29 +6421,75 @@ function poke() {
5117
6421
  apply: "serve",
5118
6422
  configureServer(server) {
5119
6423
  const stdin = process.stdin;
5120
- const previousRawMode = stdin.isTTY ? stdin.isRaw : null;
6424
+ const debug11 = process.env.RANGO_POKE_DEBUG === "1";
6425
+ const triggerReload = (source) => {
6426
+ server.hot.send({ type: "full-reload", path: "*" });
6427
+ server.config.logger.info(` browser reload (${source})`, {
6428
+ timestamp: true
6429
+ });
6430
+ };
6431
+ const toBuffer = (chunk) => {
6432
+ return typeof chunk === "string" ? Buffer.from(chunk, "utf8") : chunk;
6433
+ };
6434
+ const formatChunk = (chunk) => {
6435
+ const data = toBuffer(chunk);
6436
+ const hex = Array.from(data).map((byte) => `0x${byte.toString(16).padStart(2, "0")}`).join(" ");
6437
+ const ascii = Array.from(data).map((byte) => {
6438
+ if (byte >= 32 && byte <= 126) return String.fromCharCode(byte);
6439
+ if (byte === 10) return "\\n";
6440
+ if (byte === 13) return "\\r";
6441
+ if (byte === 9) return "\\t";
6442
+ return ".";
6443
+ }).join("");
6444
+ return `len=${data.length} hex=[${hex}] ascii="${ascii}"`;
6445
+ };
6446
+ const readCtrlR = (chunk) => {
6447
+ const data = typeof chunk === "string" ? Buffer.from(chunk, "utf8") : chunk;
6448
+ return data.length === 1 && data[0] === 18;
6449
+ };
6450
+ const readSubmittedCommands = (chunk) => {
6451
+ const text = toBuffer(chunk).toString("utf8").replace(/\r\n/g, "\n").replace(/\r/g, "\n");
6452
+ if (!text.includes("\n")) return [];
6453
+ const lines = text.split("\n");
6454
+ lines.pop();
6455
+ return lines;
6456
+ };
6457
+ if (debug11) {
6458
+ server.config.logger.info(
6459
+ ` poke debug enabled (isTTY=${stdin.isTTY ? "yes" : "no"}, isRaw=${stdin.isTTY ? stdin.isRaw ? "yes" : "no" : "n/a"})`,
6460
+ { timestamp: true }
6461
+ );
6462
+ }
5121
6463
  if (stdin.isTTY) {
5122
- stdin.setRawMode(true);
6464
+ server.config.logger.info(
6465
+ " poke ready: press e + enter to reload browser (ctrl+r also works when available)",
6466
+ { timestamp: true }
6467
+ );
5123
6468
  }
5124
6469
  const onData = (data) => {
5125
- if (data.length !== 1) return;
5126
- if (data[0] === 3) {
5127
- process.emit("SIGINT", "SIGINT");
5128
- return;
5129
- }
5130
- if (data[0] === 18) {
5131
- server.hot.send({ type: "full-reload", path: "*" });
5132
- server.config.logger.info(" browser reload (ctrl+r)", {
6470
+ if (debug11) {
6471
+ server.config.logger.info(` poke stdin ${formatChunk(data)}`, {
5133
6472
  timestamp: true
5134
6473
  });
5135
6474
  }
6475
+ if (readCtrlR(data)) {
6476
+ triggerReload("ctrl+r");
6477
+ return;
6478
+ }
6479
+ for (const command of readSubmittedCommands(data)) {
6480
+ if (command === "e") {
6481
+ triggerReload("e+enter");
6482
+ return;
6483
+ }
6484
+ if (command === "\x1Br") {
6485
+ triggerReload("option+r+enter");
6486
+ return;
6487
+ }
6488
+ }
5136
6489
  };
5137
6490
  stdin.on("data", onData);
5138
6491
  server.httpServer?.on("close", () => {
5139
6492
  stdin.off("data", onData);
5140
- if (stdin.isTTY && previousRawMode !== null) {
5141
- stdin.setRawMode(previousRawMode);
5142
- }
5143
6493
  });
5144
6494
  }
5145
6495
  };