@rangojs/router 0.0.0-experimental.9 → 0.0.0-experimental.91

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 (1125) hide show
  1. package/AGENTS.md +9 -0
  2. package/README.md +972 -4
  3. package/dist/__internal.d.ts +83 -0
  4. package/dist/__internal.d.ts.map +1 -0
  5. package/dist/__internal.js +19 -0
  6. package/dist/__internal.js.map +1 -0
  7. package/dist/__mocks__/version.d.ts +7 -0
  8. package/dist/__mocks__/version.d.ts.map +1 -0
  9. package/dist/__mocks__/version.js +7 -0
  10. package/dist/__mocks__/version.js.map +1 -0
  11. package/dist/__tests__/client-href.test.d.ts +2 -0
  12. package/dist/__tests__/client-href.test.d.ts.map +1 -0
  13. package/dist/__tests__/client-href.test.js +74 -0
  14. package/dist/__tests__/client-href.test.js.map +1 -0
  15. package/dist/__tests__/component-utils.test.d.ts +2 -0
  16. package/dist/__tests__/component-utils.test.d.ts.map +1 -0
  17. package/dist/__tests__/component-utils.test.js +51 -0
  18. package/dist/__tests__/component-utils.test.js.map +1 -0
  19. package/dist/__tests__/event-controller.test.d.ts +2 -0
  20. package/dist/__tests__/event-controller.test.d.ts.map +1 -0
  21. package/dist/__tests__/event-controller.test.js +538 -0
  22. package/dist/__tests__/event-controller.test.js.map +1 -0
  23. package/dist/__tests__/helpers/route-tree.d.ts +118 -0
  24. package/dist/__tests__/helpers/route-tree.d.ts.map +1 -0
  25. package/dist/__tests__/helpers/route-tree.js +374 -0
  26. package/dist/__tests__/helpers/route-tree.js.map +1 -0
  27. package/dist/__tests__/match-result.test.d.ts +2 -0
  28. package/dist/__tests__/match-result.test.d.ts.map +1 -0
  29. package/dist/__tests__/match-result.test.js +154 -0
  30. package/dist/__tests__/match-result.test.js.map +1 -0
  31. package/dist/__tests__/navigation-store.test.d.ts +2 -0
  32. package/dist/__tests__/navigation-store.test.d.ts.map +1 -0
  33. package/dist/__tests__/navigation-store.test.js +440 -0
  34. package/dist/__tests__/navigation-store.test.js.map +1 -0
  35. package/dist/__tests__/partial-update.test.d.ts +2 -0
  36. package/dist/__tests__/partial-update.test.d.ts.map +1 -0
  37. package/dist/__tests__/partial-update.test.js +1009 -0
  38. package/dist/__tests__/partial-update.test.js.map +1 -0
  39. package/dist/__tests__/reverse-types.test.d.ts +8 -0
  40. package/dist/__tests__/reverse-types.test.d.ts.map +1 -0
  41. package/dist/__tests__/reverse-types.test.js +656 -0
  42. package/dist/__tests__/reverse-types.test.js.map +1 -0
  43. package/dist/__tests__/route-definition.test.d.ts +2 -0
  44. package/dist/__tests__/route-definition.test.d.ts.map +1 -0
  45. package/dist/__tests__/route-definition.test.js +55 -0
  46. package/dist/__tests__/route-definition.test.js.map +1 -0
  47. package/dist/__tests__/router-helpers.test.d.ts +2 -0
  48. package/dist/__tests__/router-helpers.test.d.ts.map +1 -0
  49. package/dist/__tests__/router-helpers.test.js +377 -0
  50. package/dist/__tests__/router-helpers.test.js.map +1 -0
  51. package/dist/__tests__/router-integration-2.test.d.ts +2 -0
  52. package/dist/__tests__/router-integration-2.test.d.ts.map +1 -0
  53. package/dist/__tests__/router-integration-2.test.js +426 -0
  54. package/dist/__tests__/router-integration-2.test.js.map +1 -0
  55. package/dist/__tests__/router-integration.test.d.ts +2 -0
  56. package/dist/__tests__/router-integration.test.d.ts.map +1 -0
  57. package/dist/__tests__/router-integration.test.js +1051 -0
  58. package/dist/__tests__/router-integration.test.js.map +1 -0
  59. package/dist/__tests__/search-params.test.d.ts +5 -0
  60. package/dist/__tests__/search-params.test.d.ts.map +1 -0
  61. package/dist/__tests__/search-params.test.js +306 -0
  62. package/dist/__tests__/search-params.test.js.map +1 -0
  63. package/dist/__tests__/segment-system.test.d.ts +2 -0
  64. package/dist/__tests__/segment-system.test.d.ts.map +1 -0
  65. package/dist/__tests__/segment-system.test.js +627 -0
  66. package/dist/__tests__/segment-system.test.js.map +1 -0
  67. package/dist/__tests__/static-handler-types.test.d.ts +8 -0
  68. package/dist/__tests__/static-handler-types.test.d.ts.map +1 -0
  69. package/dist/__tests__/static-handler-types.test.js +63 -0
  70. package/dist/__tests__/static-handler-types.test.js.map +1 -0
  71. package/dist/__tests__/urls.test.d.ts +2 -0
  72. package/dist/__tests__/urls.test.d.ts.map +1 -0
  73. package/dist/__tests__/urls.test.js +421 -0
  74. package/dist/__tests__/urls.test.js.map +1 -0
  75. package/dist/__tests__/use-mount.test.d.ts +2 -0
  76. package/dist/__tests__/use-mount.test.d.ts.map +1 -0
  77. package/dist/__tests__/use-mount.test.js +35 -0
  78. package/dist/__tests__/use-mount.test.js.map +1 -0
  79. package/dist/bin/rango.d.ts +2 -0
  80. package/dist/bin/rango.d.ts.map +1 -0
  81. package/dist/bin/rango.js +1619 -155
  82. package/dist/bin/rango.js.map +1 -0
  83. package/dist/browser/event-controller.d.ts +191 -0
  84. package/dist/browser/event-controller.d.ts.map +1 -0
  85. package/dist/browser/event-controller.js +559 -0
  86. package/dist/browser/event-controller.js.map +1 -0
  87. package/dist/browser/index.d.ts +2 -0
  88. package/dist/browser/index.d.ts.map +1 -0
  89. package/dist/browser/index.js +14 -0
  90. package/dist/browser/index.js.map +1 -0
  91. package/dist/browser/link-interceptor.d.ts +38 -0
  92. package/dist/browser/link-interceptor.d.ts.map +1 -0
  93. package/dist/browser/link-interceptor.js +99 -0
  94. package/dist/browser/link-interceptor.js.map +1 -0
  95. package/dist/browser/logging.d.ts +10 -0
  96. package/dist/browser/logging.d.ts.map +1 -0
  97. package/dist/browser/logging.js +29 -0
  98. package/dist/browser/logging.js.map +1 -0
  99. package/dist/browser/lru-cache.d.ts +17 -0
  100. package/dist/browser/lru-cache.d.ts.map +1 -0
  101. package/dist/browser/lru-cache.js +50 -0
  102. package/dist/browser/lru-cache.js.map +1 -0
  103. package/dist/browser/merge-segment-loaders.d.ts +39 -0
  104. package/dist/browser/merge-segment-loaders.d.ts.map +1 -0
  105. package/dist/browser/merge-segment-loaders.js +102 -0
  106. package/dist/browser/merge-segment-loaders.js.map +1 -0
  107. package/dist/browser/navigation-bridge.d.ts +102 -0
  108. package/dist/browser/navigation-bridge.d.ts.map +1 -0
  109. package/dist/browser/navigation-bridge.js +708 -0
  110. package/dist/browser/navigation-bridge.js.map +1 -0
  111. package/dist/browser/navigation-client.d.ts +25 -0
  112. package/dist/browser/navigation-client.d.ts.map +1 -0
  113. package/dist/browser/navigation-client.js +157 -0
  114. package/dist/browser/navigation-client.js.map +1 -0
  115. package/dist/browser/navigation-store.d.ts +101 -0
  116. package/dist/browser/navigation-store.d.ts.map +1 -0
  117. package/dist/browser/navigation-store.js +625 -0
  118. package/dist/browser/navigation-store.js.map +1 -0
  119. package/dist/browser/partial-update.d.ts +75 -0
  120. package/dist/browser/partial-update.d.ts.map +1 -0
  121. package/dist/browser/partial-update.js +426 -0
  122. package/dist/browser/partial-update.js.map +1 -0
  123. package/dist/browser/react/Link.d.ts +86 -0
  124. package/dist/browser/react/Link.d.ts.map +1 -0
  125. package/dist/browser/react/Link.js +128 -0
  126. package/dist/browser/react/Link.js.map +1 -0
  127. package/dist/browser/react/NavigationProvider.d.ts +63 -0
  128. package/dist/browser/react/NavigationProvider.d.ts.map +1 -0
  129. package/dist/browser/react/NavigationProvider.js +216 -0
  130. package/dist/browser/react/NavigationProvider.js.map +1 -0
  131. package/dist/browser/react/ScrollRestoration.d.ts +75 -0
  132. package/dist/browser/react/ScrollRestoration.d.ts.map +1 -0
  133. package/dist/browser/react/ScrollRestoration.js +57 -0
  134. package/dist/browser/react/ScrollRestoration.js.map +1 -0
  135. package/dist/browser/react/context.d.ts +46 -0
  136. package/dist/browser/react/context.d.ts.map +1 -0
  137. package/dist/browser/react/context.js +10 -0
  138. package/dist/browser/react/context.js.map +1 -0
  139. package/dist/browser/react/index.d.ts +11 -0
  140. package/dist/browser/react/index.d.ts.map +1 -0
  141. package/dist/browser/react/index.js +22 -0
  142. package/dist/browser/react/index.js.map +1 -0
  143. package/dist/browser/react/location-state-shared.d.ts +63 -0
  144. package/dist/browser/react/location-state-shared.d.ts.map +1 -0
  145. package/dist/browser/react/location-state-shared.js +81 -0
  146. package/dist/browser/react/location-state-shared.js.map +1 -0
  147. package/dist/browser/react/location-state.d.ts +23 -0
  148. package/dist/browser/react/location-state.d.ts.map +1 -0
  149. package/dist/browser/react/location-state.js +29 -0
  150. package/dist/browser/react/location-state.js.map +1 -0
  151. package/dist/browser/react/mount-context.d.ts +24 -0
  152. package/dist/browser/react/mount-context.d.ts.map +1 -0
  153. package/dist/browser/react/mount-context.js +24 -0
  154. package/dist/browser/react/mount-context.js.map +1 -0
  155. package/dist/browser/react/use-action.d.ts +64 -0
  156. package/dist/browser/react/use-action.d.ts.map +1 -0
  157. package/dist/browser/react/use-action.js +134 -0
  158. package/dist/browser/react/use-action.js.map +1 -0
  159. package/dist/browser/react/use-client-cache.d.ts +41 -0
  160. package/dist/browser/react/use-client-cache.d.ts.map +1 -0
  161. package/dist/browser/react/use-client-cache.js +39 -0
  162. package/dist/browser/react/use-client-cache.js.map +1 -0
  163. package/dist/browser/react/use-handle.d.ts +31 -0
  164. package/dist/browser/react/use-handle.d.ts.map +1 -0
  165. package/dist/browser/react/use-handle.js +144 -0
  166. package/dist/browser/react/use-handle.js.map +1 -0
  167. package/dist/browser/react/use-href.d.ts +33 -0
  168. package/dist/browser/react/use-href.d.ts.map +1 -0
  169. package/dist/browser/react/use-href.js +39 -0
  170. package/dist/browser/react/use-href.js.map +1 -0
  171. package/dist/browser/react/use-link-status.d.ts +37 -0
  172. package/dist/browser/react/use-link-status.d.ts.map +1 -0
  173. package/dist/browser/react/use-link-status.js +99 -0
  174. package/dist/browser/react/use-link-status.js.map +1 -0
  175. package/dist/browser/react/use-mount.d.ts +25 -0
  176. package/dist/browser/react/use-mount.d.ts.map +1 -0
  177. package/dist/browser/react/use-mount.js +30 -0
  178. package/dist/browser/react/use-mount.js.map +1 -0
  179. package/dist/browser/react/use-navigation.d.ts +27 -0
  180. package/dist/browser/react/use-navigation.d.ts.map +1 -0
  181. package/dist/browser/react/use-navigation.js +87 -0
  182. package/dist/browser/react/use-navigation.js.map +1 -0
  183. package/dist/browser/react/use-segments.d.ts +38 -0
  184. package/dist/browser/react/use-segments.d.ts.map +1 -0
  185. package/dist/browser/react/use-segments.js +130 -0
  186. package/dist/browser/react/use-segments.js.map +1 -0
  187. package/dist/browser/request-controller.d.ts +26 -0
  188. package/dist/browser/request-controller.d.ts.map +1 -0
  189. package/dist/browser/request-controller.js +147 -0
  190. package/dist/browser/request-controller.js.map +1 -0
  191. package/dist/browser/rsc-router.d.ts +129 -0
  192. package/dist/browser/rsc-router.d.ts.map +1 -0
  193. package/dist/browser/rsc-router.js +195 -0
  194. package/dist/browser/rsc-router.js.map +1 -0
  195. package/dist/browser/scroll-restoration.d.ts +93 -0
  196. package/dist/browser/scroll-restoration.d.ts.map +1 -0
  197. package/dist/browser/scroll-restoration.js +321 -0
  198. package/dist/browser/scroll-restoration.js.map +1 -0
  199. package/dist/browser/segment-structure-assert.d.ts +17 -0
  200. package/dist/browser/segment-structure-assert.d.ts.map +1 -0
  201. package/dist/browser/segment-structure-assert.js +59 -0
  202. package/dist/browser/segment-structure-assert.js.map +1 -0
  203. package/dist/browser/server-action-bridge.d.ts +26 -0
  204. package/dist/browser/server-action-bridge.d.ts.map +1 -0
  205. package/dist/browser/server-action-bridge.js +668 -0
  206. package/dist/browser/server-action-bridge.js.map +1 -0
  207. package/dist/browser/shallow.d.ts +12 -0
  208. package/dist/browser/shallow.d.ts.map +1 -0
  209. package/dist/browser/shallow.js +34 -0
  210. package/dist/browser/shallow.js.map +1 -0
  211. package/dist/browser/types.d.ts +369 -0
  212. package/dist/browser/types.d.ts.map +1 -0
  213. package/dist/browser/types.js +2 -0
  214. package/dist/browser/types.js.map +1 -0
  215. package/dist/build/__tests__/generate-cli.test.d.ts +2 -0
  216. package/dist/build/__tests__/generate-cli.test.d.ts.map +1 -0
  217. package/dist/build/__tests__/generate-cli.test.js +237 -0
  218. package/dist/build/__tests__/generate-cli.test.js.map +1 -0
  219. package/dist/build/__tests__/generate-manifest.test.d.ts +2 -0
  220. package/dist/build/__tests__/generate-manifest.test.d.ts.map +1 -0
  221. package/dist/build/__tests__/generate-manifest.test.js +119 -0
  222. package/dist/build/__tests__/generate-manifest.test.js.map +1 -0
  223. package/dist/build/__tests__/generate-route-types.test.d.ts +2 -0
  224. package/dist/build/__tests__/generate-route-types.test.d.ts.map +1 -0
  225. package/dist/build/__tests__/generate-route-types.test.js +620 -0
  226. package/dist/build/__tests__/generate-route-types.test.js.map +1 -0
  227. package/dist/build/__tests__/per-router-manifest.test.d.ts +2 -0
  228. package/dist/build/__tests__/per-router-manifest.test.d.ts.map +1 -0
  229. package/dist/build/__tests__/per-router-manifest.test.js +308 -0
  230. package/dist/build/__tests__/per-router-manifest.test.js.map +1 -0
  231. package/dist/build/generate-manifest.d.ts +81 -0
  232. package/dist/build/generate-manifest.d.ts.map +1 -0
  233. package/dist/build/generate-manifest.js +276 -0
  234. package/dist/build/generate-manifest.js.map +1 -0
  235. package/dist/build/generate-route-types.d.ts +115 -0
  236. package/dist/build/generate-route-types.d.ts.map +1 -0
  237. package/dist/build/generate-route-types.js +740 -0
  238. package/dist/build/generate-route-types.js.map +1 -0
  239. package/dist/build/index.d.ts +21 -0
  240. package/dist/build/index.d.ts.map +1 -0
  241. package/dist/build/index.js +21 -0
  242. package/dist/build/index.js.map +1 -0
  243. package/dist/build/route-trie.d.ts +71 -0
  244. package/dist/build/route-trie.d.ts.map +1 -0
  245. package/dist/build/route-trie.js +175 -0
  246. package/dist/build/route-trie.js.map +1 -0
  247. package/dist/cache/__tests__/cache-scope.test.d.ts +2 -0
  248. package/dist/cache/__tests__/cache-scope.test.d.ts.map +1 -0
  249. package/dist/cache/__tests__/cache-scope.test.js +208 -0
  250. package/dist/cache/__tests__/cache-scope.test.js.map +1 -0
  251. package/dist/cache/__tests__/document-cache.test.d.ts +2 -0
  252. package/dist/cache/__tests__/document-cache.test.d.ts.map +1 -0
  253. package/dist/cache/__tests__/document-cache.test.js +345 -0
  254. package/dist/cache/__tests__/document-cache.test.js.map +1 -0
  255. package/dist/cache/__tests__/memory-segment-store.test.d.ts +2 -0
  256. package/dist/cache/__tests__/memory-segment-store.test.d.ts.map +1 -0
  257. package/dist/cache/__tests__/memory-segment-store.test.js +425 -0
  258. package/dist/cache/__tests__/memory-segment-store.test.js.map +1 -0
  259. package/dist/cache/__tests__/memory-store.test.d.ts +2 -0
  260. package/dist/cache/__tests__/memory-store.test.d.ts.map +1 -0
  261. package/dist/cache/__tests__/memory-store.test.js +367 -0
  262. package/dist/cache/__tests__/memory-store.test.js.map +1 -0
  263. package/dist/cache/cache-scope.d.ts +102 -0
  264. package/dist/cache/cache-scope.d.ts.map +1 -0
  265. package/dist/cache/cache-scope.js +440 -0
  266. package/dist/cache/cache-scope.js.map +1 -0
  267. package/dist/cache/cf/__tests__/cf-cache-store.test.d.ts +2 -0
  268. package/dist/cache/cf/__tests__/cf-cache-store.test.d.ts.map +1 -0
  269. package/dist/cache/cf/__tests__/cf-cache-store.test.js +330 -0
  270. package/dist/cache/cf/__tests__/cf-cache-store.test.js.map +1 -0
  271. package/dist/cache/cf/cf-cache-store.d.ts +165 -0
  272. package/dist/cache/cf/cf-cache-store.d.ts.map +1 -0
  273. package/dist/cache/cf/cf-cache-store.js +242 -0
  274. package/dist/cache/cf/cf-cache-store.js.map +1 -0
  275. package/dist/cache/cf/index.d.ts +14 -0
  276. package/dist/cache/cf/index.d.ts.map +1 -0
  277. package/dist/cache/cf/index.js +17 -0
  278. package/dist/cache/cf/index.js.map +1 -0
  279. package/dist/cache/document-cache.d.ts +64 -0
  280. package/dist/cache/document-cache.d.ts.map +1 -0
  281. package/dist/cache/document-cache.js +228 -0
  282. package/dist/cache/document-cache.js.map +1 -0
  283. package/dist/cache/index.d.ts +19 -0
  284. package/dist/cache/index.d.ts.map +1 -0
  285. package/dist/cache/index.js +21 -0
  286. package/dist/cache/index.js.map +1 -0
  287. package/dist/cache/memory-segment-store.d.ts +110 -0
  288. package/dist/cache/memory-segment-store.d.ts.map +1 -0
  289. package/dist/cache/memory-segment-store.js +117 -0
  290. package/dist/cache/memory-segment-store.js.map +1 -0
  291. package/dist/cache/memory-store.d.ts +41 -0
  292. package/dist/cache/memory-store.d.ts.map +1 -0
  293. package/dist/cache/memory-store.js +191 -0
  294. package/dist/cache/memory-store.js.map +1 -0
  295. package/dist/cache/types.d.ts +317 -0
  296. package/dist/cache/types.d.ts.map +1 -0
  297. package/dist/cache/types.js +12 -0
  298. package/dist/cache/types.js.map +1 -0
  299. package/dist/client.d.ts +248 -0
  300. package/dist/client.d.ts.map +1 -0
  301. package/dist/client.js +367 -0
  302. package/dist/client.js.map +1 -0
  303. package/dist/client.rsc.d.ts +26 -0
  304. package/dist/client.rsc.d.ts.map +1 -0
  305. package/dist/client.rsc.js +46 -0
  306. package/dist/client.rsc.js.map +1 -0
  307. package/dist/component-utils.d.ts +36 -0
  308. package/dist/component-utils.d.ts.map +1 -0
  309. package/dist/component-utils.js +61 -0
  310. package/dist/component-utils.js.map +1 -0
  311. package/dist/components/DefaultDocument.d.ts +13 -0
  312. package/dist/components/DefaultDocument.d.ts.map +1 -0
  313. package/dist/components/DefaultDocument.js +15 -0
  314. package/dist/components/DefaultDocument.js.map +1 -0
  315. package/dist/debug.d.ts +58 -0
  316. package/dist/debug.d.ts.map +1 -0
  317. package/dist/debug.js +157 -0
  318. package/dist/debug.js.map +1 -0
  319. package/dist/default-error-boundary.d.ts +11 -0
  320. package/dist/default-error-boundary.d.ts.map +1 -0
  321. package/dist/default-error-boundary.js +45 -0
  322. package/dist/default-error-boundary.js.map +1 -0
  323. package/dist/deps/browser.d.ts +2 -0
  324. package/dist/deps/browser.d.ts.map +1 -0
  325. package/dist/deps/browser.js +3 -0
  326. package/dist/deps/browser.js.map +1 -0
  327. package/dist/deps/html-stream-client.d.ts +2 -0
  328. package/dist/deps/html-stream-client.d.ts.map +1 -0
  329. package/dist/deps/html-stream-client.js +3 -0
  330. package/dist/deps/html-stream-client.js.map +1 -0
  331. package/dist/deps/html-stream-server.d.ts +2 -0
  332. package/dist/deps/html-stream-server.d.ts.map +1 -0
  333. package/dist/deps/html-stream-server.js +3 -0
  334. package/dist/deps/html-stream-server.js.map +1 -0
  335. package/dist/deps/rsc.d.ts +2 -0
  336. package/dist/deps/rsc.d.ts.map +1 -0
  337. package/dist/deps/rsc.js +4 -0
  338. package/dist/deps/rsc.js.map +1 -0
  339. package/dist/deps/ssr.d.ts +2 -0
  340. package/dist/deps/ssr.d.ts.map +1 -0
  341. package/dist/deps/ssr.js +3 -0
  342. package/dist/deps/ssr.js.map +1 -0
  343. package/dist/errors.d.ts +174 -0
  344. package/dist/errors.d.ts.map +1 -0
  345. package/dist/errors.js +241 -0
  346. package/dist/errors.js.map +1 -0
  347. package/dist/handle.d.ts +78 -0
  348. package/dist/handle.d.ts.map +1 -0
  349. package/dist/handle.js +82 -0
  350. package/dist/handle.js.map +1 -0
  351. package/dist/handles/MetaTags.d.ts +14 -0
  352. package/dist/handles/MetaTags.d.ts.map +1 -0
  353. package/dist/handles/MetaTags.js +136 -0
  354. package/dist/handles/MetaTags.js.map +1 -0
  355. package/dist/handles/index.d.ts +6 -0
  356. package/dist/handles/index.d.ts.map +1 -0
  357. package/dist/handles/index.js +6 -0
  358. package/dist/handles/index.js.map +1 -0
  359. package/dist/handles/meta.d.ts +39 -0
  360. package/dist/handles/meta.d.ts.map +1 -0
  361. package/dist/handles/meta.js +202 -0
  362. package/dist/handles/meta.js.map +1 -0
  363. package/dist/host/__tests__/errors.test.d.ts +2 -0
  364. package/dist/host/__tests__/errors.test.d.ts.map +1 -0
  365. package/dist/host/__tests__/errors.test.js +76 -0
  366. package/dist/host/__tests__/errors.test.js.map +1 -0
  367. package/dist/host/__tests__/pattern-comprehensive.test.d.ts +2 -0
  368. package/dist/host/__tests__/pattern-comprehensive.test.d.ts.map +1 -0
  369. package/dist/host/__tests__/pattern-comprehensive.test.js +732 -0
  370. package/dist/host/__tests__/pattern-comprehensive.test.js.map +1 -0
  371. package/dist/host/__tests__/pattern-matcher.test.d.ts +2 -0
  372. package/dist/host/__tests__/pattern-matcher.test.d.ts.map +1 -0
  373. package/dist/host/__tests__/pattern-matcher.test.js +251 -0
  374. package/dist/host/__tests__/pattern-matcher.test.js.map +1 -0
  375. package/dist/host/__tests__/router.test.d.ts +2 -0
  376. package/dist/host/__tests__/router.test.d.ts.map +1 -0
  377. package/dist/host/__tests__/router.test.js +241 -0
  378. package/dist/host/__tests__/router.test.js.map +1 -0
  379. package/dist/host/__tests__/testing.test.d.ts +2 -0
  380. package/dist/host/__tests__/testing.test.d.ts.map +1 -0
  381. package/dist/host/__tests__/testing.test.js +64 -0
  382. package/dist/host/__tests__/testing.test.js.map +1 -0
  383. package/dist/host/__tests__/utils.test.d.ts +2 -0
  384. package/dist/host/__tests__/utils.test.d.ts.map +1 -0
  385. package/dist/host/__tests__/utils.test.js +29 -0
  386. package/dist/host/__tests__/utils.test.js.map +1 -0
  387. package/dist/host/cookie-handler.d.ts +34 -0
  388. package/dist/host/cookie-handler.d.ts.map +1 -0
  389. package/dist/host/cookie-handler.js +124 -0
  390. package/dist/host/cookie-handler.js.map +1 -0
  391. package/dist/host/errors.d.ts +56 -0
  392. package/dist/host/errors.d.ts.map +1 -0
  393. package/dist/host/errors.js +79 -0
  394. package/dist/host/errors.js.map +1 -0
  395. package/dist/host/index.d.ts +29 -0
  396. package/dist/host/index.d.ts.map +1 -0
  397. package/dist/host/index.js +32 -0
  398. package/dist/host/index.js.map +1 -0
  399. package/dist/host/pattern-matcher.d.ts +36 -0
  400. package/dist/host/pattern-matcher.d.ts.map +1 -0
  401. package/dist/host/pattern-matcher.js +172 -0
  402. package/dist/host/pattern-matcher.js.map +1 -0
  403. package/dist/host/router.d.ts +26 -0
  404. package/dist/host/router.d.ts.map +1 -0
  405. package/dist/host/router.js +218 -0
  406. package/dist/host/router.js.map +1 -0
  407. package/dist/host/testing.d.ts +36 -0
  408. package/dist/host/testing.d.ts.map +1 -0
  409. package/dist/host/testing.js +55 -0
  410. package/dist/host/testing.js.map +1 -0
  411. package/dist/host/types.d.ts +115 -0
  412. package/dist/host/types.d.ts.map +1 -0
  413. package/dist/host/types.js +7 -0
  414. package/dist/host/types.js.map +1 -0
  415. package/dist/host/utils.d.ts +21 -0
  416. package/dist/host/utils.d.ts.map +1 -0
  417. package/dist/host/utils.js +23 -0
  418. package/dist/host/utils.js.map +1 -0
  419. package/dist/href-client.d.ts +131 -0
  420. package/dist/href-client.d.ts.map +1 -0
  421. package/dist/href-client.js +64 -0
  422. package/dist/href-client.js.map +1 -0
  423. package/{src/href-context.ts → dist/href-context.d.ts} +7 -11
  424. package/dist/href-context.d.ts.map +1 -0
  425. package/dist/href-context.js +21 -0
  426. package/dist/href-context.js.map +1 -0
  427. package/dist/index.d.ts +73 -0
  428. package/dist/index.d.ts.map +1 -0
  429. package/dist/index.js +91 -0
  430. package/dist/index.js.map +1 -0
  431. package/dist/index.rsc.d.ts +32 -0
  432. package/dist/index.rsc.d.ts.map +1 -0
  433. package/dist/index.rsc.js +40 -0
  434. package/dist/index.rsc.js.map +1 -0
  435. package/dist/internal-debug.d.ts +2 -0
  436. package/dist/internal-debug.d.ts.map +1 -0
  437. package/dist/internal-debug.js +5 -0
  438. package/dist/internal-debug.js.map +1 -0
  439. package/dist/loader.d.ts +14 -0
  440. package/dist/loader.d.ts.map +1 -0
  441. package/dist/loader.js +20 -0
  442. package/dist/loader.js.map +1 -0
  443. package/dist/loader.rsc.d.ts +19 -0
  444. package/dist/loader.rsc.d.ts.map +1 -0
  445. package/dist/loader.rsc.js +99 -0
  446. package/dist/loader.rsc.js.map +1 -0
  447. package/dist/network-error-thrower.d.ts +17 -0
  448. package/dist/network-error-thrower.d.ts.map +1 -0
  449. package/dist/network-error-thrower.js +14 -0
  450. package/dist/network-error-thrower.js.map +1 -0
  451. package/dist/outlet-context.d.ts +13 -0
  452. package/dist/outlet-context.d.ts.map +1 -0
  453. package/dist/outlet-context.js +3 -0
  454. package/dist/outlet-context.js.map +1 -0
  455. package/dist/prerender/__tests__/param-hash.test.d.ts +2 -0
  456. package/dist/prerender/__tests__/param-hash.test.d.ts.map +1 -0
  457. package/dist/prerender/__tests__/param-hash.test.js +148 -0
  458. package/dist/prerender/__tests__/param-hash.test.js.map +1 -0
  459. package/dist/prerender/param-hash.d.ts +16 -0
  460. package/dist/prerender/param-hash.d.ts.map +1 -0
  461. package/dist/prerender/param-hash.js +36 -0
  462. package/dist/prerender/param-hash.js.map +1 -0
  463. package/dist/prerender/store.d.ts +38 -0
  464. package/dist/prerender/store.d.ts.map +1 -0
  465. package/dist/prerender/store.js +61 -0
  466. package/dist/prerender/store.js.map +1 -0
  467. package/dist/prerender.d.ts +66 -0
  468. package/dist/prerender.d.ts.map +1 -0
  469. package/dist/prerender.js +57 -0
  470. package/dist/prerender.js.map +1 -0
  471. package/dist/reverse.d.ts +196 -0
  472. package/dist/reverse.d.ts.map +1 -0
  473. package/dist/reverse.js +78 -0
  474. package/dist/reverse.js.map +1 -0
  475. package/dist/root-error-boundary.d.ts +33 -0
  476. package/dist/root-error-boundary.d.ts.map +1 -0
  477. package/dist/root-error-boundary.js +165 -0
  478. package/dist/root-error-boundary.js.map +1 -0
  479. package/dist/route-content-wrapper.d.ts +46 -0
  480. package/dist/route-content-wrapper.d.ts.map +1 -0
  481. package/dist/route-content-wrapper.js +77 -0
  482. package/dist/route-content-wrapper.js.map +1 -0
  483. package/dist/route-definition.d.ts +421 -0
  484. package/dist/route-definition.d.ts.map +1 -0
  485. package/dist/route-definition.js +868 -0
  486. package/dist/route-definition.js.map +1 -0
  487. package/dist/route-map-builder.d.ts +155 -0
  488. package/dist/route-map-builder.d.ts.map +1 -0
  489. package/dist/route-map-builder.js +237 -0
  490. package/dist/route-map-builder.js.map +1 -0
  491. package/dist/route-types.d.ts +165 -0
  492. package/dist/route-types.d.ts.map +1 -0
  493. package/dist/route-types.js +7 -0
  494. package/dist/route-types.js.map +1 -0
  495. package/dist/router/__tests__/handler-context.test.d.ts +2 -0
  496. package/dist/router/__tests__/handler-context.test.d.ts.map +1 -0
  497. package/dist/router/__tests__/handler-context.test.js +65 -0
  498. package/dist/router/__tests__/handler-context.test.js.map +1 -0
  499. package/dist/router/__tests__/loader-cycle-detection.test.d.ts +2 -0
  500. package/dist/router/__tests__/loader-cycle-detection.test.d.ts.map +1 -0
  501. package/dist/router/__tests__/loader-cycle-detection.test.js +221 -0
  502. package/dist/router/__tests__/loader-cycle-detection.test.js.map +1 -0
  503. package/dist/router/__tests__/match-context.test.d.ts +2 -0
  504. package/dist/router/__tests__/match-context.test.d.ts.map +1 -0
  505. package/dist/router/__tests__/match-context.test.js +92 -0
  506. package/dist/router/__tests__/match-context.test.js.map +1 -0
  507. package/dist/router/__tests__/match-pipelines.test.d.ts +2 -0
  508. package/dist/router/__tests__/match-pipelines.test.d.ts.map +1 -0
  509. package/dist/router/__tests__/match-pipelines.test.js +417 -0
  510. package/dist/router/__tests__/match-pipelines.test.js.map +1 -0
  511. package/dist/router/__tests__/match-result.test.d.ts +2 -0
  512. package/dist/router/__tests__/match-result.test.d.ts.map +1 -0
  513. package/dist/router/__tests__/match-result.test.js +457 -0
  514. package/dist/router/__tests__/match-result.test.js.map +1 -0
  515. package/dist/router/__tests__/on-error.test.d.ts +2 -0
  516. package/dist/router/__tests__/on-error.test.d.ts.map +1 -0
  517. package/dist/router/__tests__/on-error.test.js +678 -0
  518. package/dist/router/__tests__/on-error.test.js.map +1 -0
  519. package/dist/router/__tests__/pattern-matching.test.d.ts +2 -0
  520. package/dist/router/__tests__/pattern-matching.test.d.ts.map +1 -0
  521. package/dist/router/__tests__/pattern-matching.test.js +629 -0
  522. package/dist/router/__tests__/pattern-matching.test.js.map +1 -0
  523. package/dist/router/__tests__/segment-resolution-parallel-loading.test.d.ts +2 -0
  524. package/dist/router/__tests__/segment-resolution-parallel-loading.test.d.ts.map +1 -0
  525. package/dist/router/__tests__/segment-resolution-parallel-loading.test.js +155 -0
  526. package/dist/router/__tests__/segment-resolution-parallel-loading.test.js.map +1 -0
  527. package/dist/router/error-handling.d.ts +77 -0
  528. package/dist/router/error-handling.d.ts.map +1 -0
  529. package/dist/router/error-handling.js +202 -0
  530. package/dist/router/error-handling.js.map +1 -0
  531. package/dist/router/handler-context.d.ts +20 -0
  532. package/dist/router/handler-context.d.ts.map +1 -0
  533. package/dist/router/handler-context.js +198 -0
  534. package/dist/router/handler-context.js.map +1 -0
  535. package/dist/router/intercept-resolution.d.ts +66 -0
  536. package/dist/router/intercept-resolution.d.ts.map +1 -0
  537. package/dist/router/intercept-resolution.js +246 -0
  538. package/dist/router/intercept-resolution.js.map +1 -0
  539. package/dist/router/loader-resolution.d.ts +64 -0
  540. package/dist/router/loader-resolution.d.ts.map +1 -0
  541. package/dist/router/loader-resolution.js +284 -0
  542. package/dist/router/loader-resolution.js.map +1 -0
  543. package/dist/router/logging.d.ts +15 -0
  544. package/dist/router/logging.d.ts.map +1 -0
  545. package/dist/router/logging.js +99 -0
  546. package/dist/router/logging.js.map +1 -0
  547. package/dist/router/manifest.d.ts +22 -0
  548. package/dist/router/manifest.d.ts.map +1 -0
  549. package/dist/router/manifest.js +181 -0
  550. package/dist/router/manifest.js.map +1 -0
  551. package/dist/router/match-api.d.ts +35 -0
  552. package/dist/router/match-api.d.ts.map +1 -0
  553. package/dist/router/match-api.js +406 -0
  554. package/dist/router/match-api.js.map +1 -0
  555. package/dist/router/match-context.d.ts +206 -0
  556. package/dist/router/match-context.d.ts.map +1 -0
  557. package/dist/router/match-context.js +17 -0
  558. package/dist/router/match-context.js.map +1 -0
  559. package/dist/router/match-middleware/background-revalidation.d.ts +127 -0
  560. package/dist/router/match-middleware/background-revalidation.d.ts.map +1 -0
  561. package/dist/router/match-middleware/background-revalidation.js +75 -0
  562. package/dist/router/match-middleware/background-revalidation.js.map +1 -0
  563. package/dist/router/match-middleware/cache-lookup.d.ts +112 -0
  564. package/dist/router/match-middleware/cache-lookup.d.ts.map +1 -0
  565. package/dist/router/match-middleware/cache-lookup.js +257 -0
  566. package/dist/router/match-middleware/cache-lookup.js.map +1 -0
  567. package/dist/router/match-middleware/cache-store.d.ts +113 -0
  568. package/dist/router/match-middleware/cache-store.d.ts.map +1 -0
  569. package/dist/router/match-middleware/cache-store.js +108 -0
  570. package/dist/router/match-middleware/cache-store.js.map +1 -0
  571. package/dist/router/match-middleware/index.d.ts +81 -0
  572. package/dist/router/match-middleware/index.d.ts.map +1 -0
  573. package/dist/router/match-middleware/index.js +80 -0
  574. package/dist/router/match-middleware/index.js.map +1 -0
  575. package/dist/router/match-middleware/intercept-resolution.d.ts +117 -0
  576. package/dist/router/match-middleware/intercept-resolution.d.ts.map +1 -0
  577. package/dist/router/match-middleware/intercept-resolution.js +134 -0
  578. package/dist/router/match-middleware/intercept-resolution.js.map +1 -0
  579. package/dist/router/match-middleware/segment-resolution.d.ts +99 -0
  580. package/dist/router/match-middleware/segment-resolution.d.ts.map +1 -0
  581. package/dist/router/match-middleware/segment-resolution.js +53 -0
  582. package/dist/router/match-middleware/segment-resolution.js.map +1 -0
  583. package/dist/router/match-pipelines.d.ts +147 -0
  584. package/dist/router/match-pipelines.d.ts.map +1 -0
  585. package/dist/router/match-pipelines.js +82 -0
  586. package/dist/router/match-pipelines.js.map +1 -0
  587. package/dist/router/match-result.d.ts +126 -0
  588. package/dist/router/match-result.d.ts.map +1 -0
  589. package/dist/router/match-result.js +93 -0
  590. package/dist/router/match-result.js.map +1 -0
  591. package/dist/router/metrics.d.ts +20 -0
  592. package/dist/router/metrics.d.ts.map +1 -0
  593. package/dist/router/metrics.js +47 -0
  594. package/dist/router/metrics.js.map +1 -0
  595. package/dist/router/middleware.d.ts +249 -0
  596. package/dist/router/middleware.d.ts.map +1 -0
  597. package/dist/router/middleware.js +434 -0
  598. package/dist/router/middleware.js.map +1 -0
  599. package/dist/router/middleware.test.d.ts +2 -0
  600. package/dist/router/middleware.test.d.ts.map +1 -0
  601. package/dist/router/middleware.test.js +816 -0
  602. package/dist/router/middleware.test.js.map +1 -0
  603. package/dist/router/pattern-matching.d.ts +149 -0
  604. package/dist/router/pattern-matching.d.ts.map +1 -0
  605. package/dist/router/pattern-matching.js +349 -0
  606. package/dist/router/pattern-matching.js.map +1 -0
  607. package/dist/router/revalidation.d.ts +44 -0
  608. package/dist/router/revalidation.d.ts.map +1 -0
  609. package/dist/router/revalidation.js +147 -0
  610. package/dist/router/revalidation.js.map +1 -0
  611. package/dist/router/router-context.d.ts +135 -0
  612. package/dist/router/router-context.d.ts.map +1 -0
  613. package/dist/router/router-context.js +36 -0
  614. package/dist/router/router-context.js.map +1 -0
  615. package/dist/router/segment-resolution.d.ts +127 -0
  616. package/dist/router/segment-resolution.d.ts.map +1 -0
  617. package/dist/router/segment-resolution.js +919 -0
  618. package/dist/router/segment-resolution.js.map +1 -0
  619. package/dist/router/trie-matching.d.ts +40 -0
  620. package/dist/router/trie-matching.d.ts.map +1 -0
  621. package/dist/router/trie-matching.js +127 -0
  622. package/dist/router/trie-matching.js.map +1 -0
  623. package/dist/router/types.d.ts +136 -0
  624. package/dist/router/types.d.ts.map +1 -0
  625. package/dist/router/types.js +7 -0
  626. package/dist/router/types.js.map +1 -0
  627. package/dist/router.d.ts +753 -0
  628. package/dist/router.d.ts.map +1 -0
  629. package/dist/router.gen.d.ts +6 -0
  630. package/dist/router.gen.d.ts.map +1 -0
  631. package/dist/router.gen.js +6 -0
  632. package/dist/router.gen.js.map +1 -0
  633. package/dist/router.js +1304 -0
  634. package/dist/router.js.map +1 -0
  635. package/dist/rsc/__tests__/helpers.test.d.ts +2 -0
  636. package/dist/rsc/__tests__/helpers.test.d.ts.map +1 -0
  637. package/dist/rsc/__tests__/helpers.test.js +140 -0
  638. package/dist/rsc/__tests__/helpers.test.js.map +1 -0
  639. package/dist/rsc/handler.d.ts +45 -0
  640. package/dist/rsc/handler.d.ts.map +1 -0
  641. package/dist/rsc/handler.js +1172 -0
  642. package/dist/rsc/handler.js.map +1 -0
  643. package/dist/rsc/helpers.d.ts +16 -0
  644. package/dist/rsc/helpers.d.ts.map +1 -0
  645. package/dist/rsc/helpers.js +55 -0
  646. package/dist/rsc/helpers.js.map +1 -0
  647. package/dist/rsc/index.d.ts +22 -0
  648. package/dist/rsc/index.d.ts.map +1 -0
  649. package/dist/rsc/index.js +23 -0
  650. package/dist/rsc/index.js.map +1 -0
  651. package/dist/rsc/nonce.d.ts +9 -0
  652. package/dist/rsc/nonce.d.ts.map +1 -0
  653. package/dist/rsc/nonce.js +18 -0
  654. package/dist/rsc/nonce.js.map +1 -0
  655. package/dist/rsc/types.d.ts +206 -0
  656. package/dist/rsc/types.d.ts.map +1 -0
  657. package/dist/rsc/types.js +8 -0
  658. package/dist/rsc/types.js.map +1 -0
  659. package/dist/search-params.d.ts +103 -0
  660. package/dist/search-params.d.ts.map +1 -0
  661. package/dist/search-params.js +74 -0
  662. package/dist/search-params.js.map +1 -0
  663. package/dist/segment-system.d.ts +75 -0
  664. package/dist/segment-system.d.ts.map +1 -0
  665. package/dist/segment-system.js +336 -0
  666. package/dist/segment-system.js.map +1 -0
  667. package/dist/server/context.d.ts +245 -0
  668. package/dist/server/context.d.ts.map +1 -0
  669. package/dist/server/context.js +197 -0
  670. package/dist/server/context.js.map +1 -0
  671. package/dist/server/fetchable-loader-store.d.ts +18 -0
  672. package/dist/server/fetchable-loader-store.d.ts.map +1 -0
  673. package/dist/server/fetchable-loader-store.js +18 -0
  674. package/dist/server/fetchable-loader-store.js.map +1 -0
  675. package/dist/server/handle-store.d.ts +85 -0
  676. package/dist/server/handle-store.d.ts.map +1 -0
  677. package/dist/server/handle-store.js +142 -0
  678. package/dist/server/handle-store.js.map +1 -0
  679. package/dist/server/loader-registry.d.ts +55 -0
  680. package/dist/server/loader-registry.d.ts.map +1 -0
  681. package/dist/server/loader-registry.js +132 -0
  682. package/dist/server/loader-registry.js.map +1 -0
  683. package/dist/server/request-context.d.ts +226 -0
  684. package/dist/server/request-context.d.ts.map +1 -0
  685. package/dist/server/request-context.js +290 -0
  686. package/dist/server/request-context.js.map +1 -0
  687. package/dist/server/root-layout.d.ts +4 -0
  688. package/dist/server/root-layout.d.ts.map +1 -0
  689. package/dist/server/root-layout.js +5 -0
  690. package/dist/server/root-layout.js.map +1 -0
  691. package/dist/server.d.ts +15 -0
  692. package/dist/server.d.ts.map +1 -0
  693. package/dist/server.js +20 -0
  694. package/dist/server.js.map +1 -0
  695. package/dist/ssr/__tests__/ssr-handler.test.d.ts +2 -0
  696. package/dist/ssr/__tests__/ssr-handler.test.d.ts.map +1 -0
  697. package/dist/ssr/__tests__/ssr-handler.test.js +132 -0
  698. package/dist/ssr/__tests__/ssr-handler.test.js.map +1 -0
  699. package/dist/ssr/index.d.ts +98 -0
  700. package/dist/ssr/index.d.ts.map +1 -0
  701. package/dist/ssr/index.js +158 -0
  702. package/dist/ssr/index.js.map +1 -0
  703. package/dist/static-handler.d.ts +50 -0
  704. package/dist/static-handler.d.ts.map +1 -0
  705. package/dist/static-handler.gen.d.ts +5 -0
  706. package/dist/static-handler.gen.d.ts.map +1 -0
  707. package/dist/static-handler.gen.js +5 -0
  708. package/dist/static-handler.gen.js.map +1 -0
  709. package/dist/static-handler.js +29 -0
  710. package/dist/static-handler.js.map +1 -0
  711. package/dist/theme/ThemeProvider.d.ts +20 -0
  712. package/dist/theme/ThemeProvider.d.ts.map +1 -0
  713. package/dist/theme/ThemeProvider.js +240 -0
  714. package/dist/theme/ThemeProvider.js.map +1 -0
  715. package/dist/theme/ThemeScript.d.ts +48 -0
  716. package/dist/theme/ThemeScript.d.ts.map +1 -0
  717. package/dist/theme/ThemeScript.js +13 -0
  718. package/dist/theme/ThemeScript.js.map +1 -0
  719. package/dist/theme/__tests__/theme.test.d.ts +2 -0
  720. package/dist/theme/__tests__/theme.test.d.ts.map +1 -0
  721. package/dist/theme/__tests__/theme.test.js +103 -0
  722. package/dist/theme/__tests__/theme.test.js.map +1 -0
  723. package/dist/theme/constants.d.ts +29 -0
  724. package/dist/theme/constants.d.ts.map +1 -0
  725. package/dist/theme/constants.js +48 -0
  726. package/dist/theme/constants.js.map +1 -0
  727. package/dist/theme/index.d.ts +31 -0
  728. package/dist/theme/index.d.ts.map +1 -0
  729. package/dist/theme/index.js +36 -0
  730. package/dist/theme/index.js.map +1 -0
  731. package/dist/theme/theme-context.d.ts +40 -0
  732. package/dist/theme/theme-context.d.ts.map +1 -0
  733. package/dist/theme/theme-context.js +60 -0
  734. package/dist/theme/theme-context.js.map +1 -0
  735. package/dist/theme/theme-script.d.ts +27 -0
  736. package/dist/theme/theme-script.d.ts.map +1 -0
  737. package/dist/theme/theme-script.js +147 -0
  738. package/dist/theme/theme-script.js.map +1 -0
  739. package/dist/theme/types.d.ts +163 -0
  740. package/dist/theme/types.d.ts.map +1 -0
  741. package/dist/theme/types.js +11 -0
  742. package/dist/theme/types.js.map +1 -0
  743. package/dist/theme/use-theme.d.ts +12 -0
  744. package/dist/theme/use-theme.d.ts.map +1 -0
  745. package/dist/theme/use-theme.js +40 -0
  746. package/dist/theme/use-theme.js.map +1 -0
  747. package/dist/types.d.ts +1479 -0
  748. package/dist/types.d.ts.map +1 -0
  749. package/dist/types.js +10 -0
  750. package/dist/types.js.map +1 -0
  751. package/dist/urls.d.ts +441 -0
  752. package/dist/urls.d.ts.map +1 -0
  753. package/dist/urls.gen.d.ts +8 -0
  754. package/dist/urls.gen.d.ts.map +1 -0
  755. package/dist/urls.gen.js +8 -0
  756. package/dist/urls.gen.js.map +1 -0
  757. package/dist/urls.js +443 -0
  758. package/dist/urls.js.map +1 -0
  759. package/dist/use-loader.d.ts +127 -0
  760. package/dist/use-loader.d.ts.map +1 -0
  761. package/dist/use-loader.js +237 -0
  762. package/dist/use-loader.js.map +1 -0
  763. package/dist/vite/__tests__/ast-handler-extract.test.d.ts +2 -0
  764. package/dist/vite/__tests__/ast-handler-extract.test.d.ts.map +1 -0
  765. package/dist/vite/__tests__/ast-handler-extract.test.js +294 -0
  766. package/dist/vite/__tests__/ast-handler-extract.test.js.map +1 -0
  767. package/dist/vite/__tests__/expose-id-utils.test.d.ts +2 -0
  768. package/dist/vite/__tests__/expose-id-utils.test.d.ts.map +1 -0
  769. package/dist/vite/__tests__/expose-id-utils.test.js +224 -0
  770. package/dist/vite/__tests__/expose-id-utils.test.js.map +1 -0
  771. package/dist/vite/__tests__/expose-internal-ids.test.d.ts +2 -0
  772. package/dist/vite/__tests__/expose-internal-ids.test.d.ts.map +1 -0
  773. package/dist/vite/__tests__/expose-internal-ids.test.js +647 -0
  774. package/dist/vite/__tests__/expose-internal-ids.test.js.map +1 -0
  775. package/dist/vite/__tests__/expose-router-id.test.d.ts +2 -0
  776. package/dist/vite/__tests__/expose-router-id.test.d.ts.map +1 -0
  777. package/dist/vite/__tests__/expose-router-id.test.js +39 -0
  778. package/dist/vite/__tests__/expose-router-id.test.js.map +1 -0
  779. package/dist/vite/ast-handler-extract.d.ts +49 -0
  780. package/dist/vite/ast-handler-extract.d.ts.map +1 -0
  781. package/dist/vite/ast-handler-extract.js +249 -0
  782. package/dist/vite/ast-handler-extract.js.map +1 -0
  783. package/dist/vite/expose-action-id.d.ts +19 -0
  784. package/dist/vite/expose-action-id.d.ts.map +1 -0
  785. package/dist/vite/expose-action-id.js +250 -0
  786. package/dist/vite/expose-action-id.js.map +1 -0
  787. package/dist/vite/expose-id-utils.d.ts +69 -0
  788. package/dist/vite/expose-id-utils.d.ts.map +1 -0
  789. package/dist/vite/expose-id-utils.js +289 -0
  790. package/dist/vite/expose-id-utils.js.map +1 -0
  791. package/dist/vite/expose-internal-ids.d.ts +22 -0
  792. package/dist/vite/expose-internal-ids.d.ts.map +1 -0
  793. package/dist/vite/expose-internal-ids.js +886 -0
  794. package/dist/vite/expose-internal-ids.js.map +1 -0
  795. package/dist/vite/index.d.ts +149 -0
  796. package/dist/vite/index.d.ts.map +1 -0
  797. package/dist/vite/index.js +5565 -2291
  798. package/dist/vite/index.js.bak +5448 -0
  799. package/dist/vite/index.js.map +1 -0
  800. package/dist/vite/index.named-routes.gen.ts +103 -0
  801. package/dist/vite/package-resolution.d.ts +43 -0
  802. package/dist/vite/package-resolution.d.ts.map +1 -0
  803. package/{src/vite/package-resolution.ts → dist/vite/package-resolution.js} +53 -66
  804. package/dist/vite/package-resolution.js.map +1 -0
  805. package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  806. package/dist/vite/virtual-entries.d.ts +25 -0
  807. package/dist/vite/virtual-entries.d.ts.map +1 -0
  808. package/{src/vite/virtual-entries.ts → dist/vite/virtual-entries.js} +12 -16
  809. package/dist/vite/virtual-entries.js.map +1 -0
  810. package/package.json +72 -63
  811. package/skills/breadcrumbs/SKILL.md +252 -0
  812. package/skills/cache-guide/SKILL.md +294 -0
  813. package/skills/caching/SKILL.md +93 -23
  814. package/skills/composability/SKILL.md +172 -0
  815. package/skills/debug-manifest/SKILL.md +12 -8
  816. package/skills/document-cache/SKILL.md +18 -16
  817. package/skills/fonts/SKILL.md +6 -4
  818. package/skills/handler-use/SKILL.md +362 -0
  819. package/skills/hooks/SKILL.md +341 -71
  820. package/skills/host-router/SKILL.md +218 -0
  821. package/skills/intercept/SKILL.md +151 -8
  822. package/skills/layout/SKILL.md +122 -3
  823. package/skills/links/SKILL.md +158 -25
  824. package/skills/loader/SKILL.md +439 -46
  825. package/skills/middleware/SKILL.md +205 -37
  826. package/skills/migrate-nextjs/SKILL.md +560 -0
  827. package/skills/migrate-react-router/SKILL.md +765 -0
  828. package/skills/mime-routes/SKILL.md +15 -11
  829. package/skills/parallel/SKILL.md +263 -1
  830. package/skills/prerender/SKILL.md +467 -65
  831. package/skills/rango/SKILL.md +87 -21
  832. package/skills/response-routes/SKILL.md +152 -91
  833. package/skills/route/SKILL.md +281 -14
  834. package/skills/router-setup/SKILL.md +210 -32
  835. package/skills/streams-and-websockets/SKILL.md +283 -0
  836. package/skills/theme/SKILL.md +9 -8
  837. package/skills/typesafety/SKILL.md +327 -86
  838. package/skills/use-cache/SKILL.md +324 -0
  839. package/src/__internal.ts +102 -4
  840. package/src/bin/rango.ts +312 -15
  841. package/src/browser/action-coordinator.ts +97 -0
  842. package/src/browser/action-response-classifier.ts +99 -0
  843. package/src/browser/app-shell.ts +52 -0
  844. package/src/browser/app-version.ts +14 -0
  845. package/src/browser/event-controller.ts +92 -64
  846. package/src/browser/history-state.ts +80 -0
  847. package/src/browser/intercept-utils.ts +52 -0
  848. package/src/browser/link-interceptor.ts +24 -4
  849. package/src/browser/logging.ts +55 -0
  850. package/src/browser/merge-segment-loaders.ts +20 -12
  851. package/src/browser/navigation-bridge.ts +367 -561
  852. package/src/browser/navigation-client.ts +228 -70
  853. package/src/browser/navigation-store.ts +97 -55
  854. package/src/browser/navigation-transaction.ts +297 -0
  855. package/src/browser/network-error-handler.ts +61 -0
  856. package/src/browser/partial-update.ts +362 -316
  857. package/src/browser/prefetch/cache.ts +314 -0
  858. package/src/browser/prefetch/fetch.ts +282 -0
  859. package/src/browser/prefetch/observer.ts +65 -0
  860. package/src/browser/prefetch/policy.ts +48 -0
  861. package/src/browser/prefetch/queue.ts +191 -0
  862. package/src/browser/prefetch/resource-ready.ts +77 -0
  863. package/src/browser/rango-state.ts +152 -0
  864. package/src/browser/react/Link.tsx +255 -71
  865. package/src/browser/react/NavigationProvider.tsx +132 -17
  866. package/src/browser/react/context.ts +11 -0
  867. package/src/browser/react/filter-segment-order.ts +11 -0
  868. package/src/browser/react/index.ts +12 -12
  869. package/src/browser/react/location-state-shared.ts +95 -53
  870. package/src/browser/react/location-state.ts +60 -15
  871. package/src/browser/react/mount-context.ts +6 -1
  872. package/src/browser/react/nonce-context.ts +23 -0
  873. package/src/browser/react/shallow-equal.ts +27 -0
  874. package/src/browser/react/use-action.ts +29 -51
  875. package/src/browser/react/use-client-cache.ts +5 -3
  876. package/src/browser/react/use-handle.ts +30 -120
  877. package/src/browser/react/use-link-status.ts +6 -5
  878. package/src/browser/react/use-navigation.ts +44 -65
  879. package/src/browser/react/use-params.ts +75 -0
  880. package/src/browser/react/use-pathname.ts +47 -0
  881. package/src/browser/react/use-router.ts +83 -0
  882. package/src/browser/react/use-search-params.ts +56 -0
  883. package/src/browser/react/use-segments.ts +80 -97
  884. package/src/browser/response-adapter.ts +73 -0
  885. package/src/browser/rsc-router.tsx +246 -64
  886. package/src/browser/scroll-restoration.ts +127 -52
  887. package/src/browser/segment-reconciler.ts +243 -0
  888. package/src/browser/segment-structure-assert.ts +16 -0
  889. package/src/browser/server-action-bridge.ts +510 -603
  890. package/src/browser/shallow.ts +6 -1
  891. package/src/browser/types.ts +152 -48
  892. package/src/browser/validate-redirect-origin.ts +29 -0
  893. package/src/build/generate-manifest.ts +84 -23
  894. package/src/build/generate-route-types.ts +39 -752
  895. package/src/build/index.ts +6 -5
  896. package/src/build/route-trie.ts +83 -31
  897. package/src/build/route-types/ast-helpers.ts +25 -0
  898. package/src/build/route-types/ast-route-extraction.ts +98 -0
  899. package/src/build/route-types/codegen.ts +102 -0
  900. package/src/build/route-types/include-resolution.ts +418 -0
  901. package/src/build/route-types/param-extraction.ts +48 -0
  902. package/src/build/route-types/per-module-writer.ts +128 -0
  903. package/src/build/route-types/router-processing.ts +618 -0
  904. package/src/build/route-types/scan-filter.ts +85 -0
  905. package/src/build/runtime-discovery.ts +231 -0
  906. package/src/cache/background-task.ts +34 -0
  907. package/src/cache/cache-key-utils.ts +44 -0
  908. package/src/cache/cache-policy.ts +125 -0
  909. package/src/cache/cache-runtime.ts +342 -0
  910. package/src/cache/cache-scope.ts +167 -307
  911. package/src/cache/cf/cf-cache-store.ts +573 -21
  912. package/src/cache/cf/index.ts +13 -3
  913. package/src/cache/document-cache.ts +116 -77
  914. package/src/cache/handle-capture.ts +81 -0
  915. package/src/cache/handle-snapshot.ts +41 -0
  916. package/src/cache/index.ts +1 -15
  917. package/src/cache/memory-segment-store.ts +191 -13
  918. package/src/cache/profile-registry.ts +73 -0
  919. package/src/cache/read-through-swr.ts +134 -0
  920. package/src/cache/segment-codec.ts +256 -0
  921. package/src/cache/taint.ts +153 -0
  922. package/src/cache/types.ts +72 -122
  923. package/src/client.rsc.tsx +3 -1
  924. package/src/client.tsx +113 -301
  925. package/src/component-utils.ts +4 -4
  926. package/src/components/DefaultDocument.tsx +5 -1
  927. package/src/context-var.ts +156 -0
  928. package/src/debug.ts +19 -9
  929. package/src/errors.ts +77 -7
  930. package/src/handle.ts +55 -10
  931. package/src/handles/MetaTags.tsx +73 -20
  932. package/src/handles/breadcrumbs.ts +66 -0
  933. package/src/handles/index.ts +1 -0
  934. package/src/handles/meta.ts +30 -13
  935. package/src/host/cookie-handler.ts +21 -15
  936. package/src/host/errors.ts +8 -8
  937. package/src/host/index.ts +4 -7
  938. package/src/host/pattern-matcher.ts +27 -27
  939. package/src/host/router.ts +61 -39
  940. package/src/host/testing.ts +8 -8
  941. package/src/host/types.ts +15 -7
  942. package/src/host/utils.ts +1 -1
  943. package/src/href-client.ts +65 -45
  944. package/src/index.rsc.ts +138 -21
  945. package/src/index.ts +206 -51
  946. package/src/internal-debug.ts +11 -0
  947. package/src/loader.rsc.ts +25 -143
  948. package/src/loader.ts +27 -10
  949. package/src/network-error-thrower.tsx +3 -1
  950. package/src/outlet-context.ts +1 -1
  951. package/src/outlet-provider.tsx +45 -0
  952. package/src/prerender/param-hash.ts +4 -2
  953. package/src/prerender/store.ts +159 -13
  954. package/src/prerender.ts +397 -29
  955. package/src/response-utils.ts +28 -0
  956. package/src/reverse.ts +209 -121
  957. package/src/root-error-boundary.tsx +41 -29
  958. package/src/route-content-wrapper.tsx +7 -4
  959. package/src/route-definition/dsl-helpers.ts +1134 -0
  960. package/src/route-definition/helper-factories.ts +200 -0
  961. package/src/route-definition/helpers-types.ts +478 -0
  962. package/src/route-definition/index.ts +55 -0
  963. package/src/route-definition/redirect.ts +101 -0
  964. package/src/route-definition/resolve-handler-use.ts +155 -0
  965. package/src/route-definition.ts +1 -1431
  966. package/src/route-map-builder.ts +162 -123
  967. package/src/route-name.ts +53 -0
  968. package/src/route-types.ts +66 -9
  969. package/src/router/content-negotiation.ts +215 -0
  970. package/src/router/debug-manifest.ts +72 -0
  971. package/src/router/error-handling.ts +9 -9
  972. package/src/router/find-match.ts +160 -0
  973. package/src/router/handler-context.ts +455 -86
  974. package/src/router/intercept-resolution.ts +35 -20
  975. package/src/router/lazy-includes.ts +237 -0
  976. package/src/router/loader-resolution.ts +359 -128
  977. package/src/router/logging.ts +251 -0
  978. package/src/router/manifest.ts +98 -32
  979. package/src/router/match-api.ts +195 -261
  980. package/src/router/match-context.ts +4 -2
  981. package/src/router/match-handlers.ts +440 -0
  982. package/src/router/match-middleware/background-revalidation.ts +108 -93
  983. package/src/router/match-middleware/cache-lookup.ts +415 -86
  984. package/src/router/match-middleware/cache-store.ts +91 -29
  985. package/src/router/match-middleware/intercept-resolution.ts +48 -21
  986. package/src/router/match-middleware/segment-resolution.ts +73 -9
  987. package/src/router/match-pipelines.ts +10 -45
  988. package/src/router/match-result.ts +135 -35
  989. package/src/router/metrics.ts +240 -15
  990. package/src/router/middleware-cookies.ts +55 -0
  991. package/src/router/middleware-types.ts +200 -0
  992. package/src/router/middleware.ts +373 -371
  993. package/src/router/navigation-snapshot.ts +182 -0
  994. package/src/router/pattern-matching.ts +251 -44
  995. package/src/router/prerender-match.ts +502 -0
  996. package/src/router/preview-match.ts +98 -0
  997. package/src/router/request-classification.ts +310 -0
  998. package/src/router/revalidation.ts +152 -39
  999. package/src/router/route-snapshot.ts +245 -0
  1000. package/src/router/router-context.ts +41 -21
  1001. package/src/router/router-interfaces.ts +484 -0
  1002. package/src/router/router-options.ts +618 -0
  1003. package/src/router/router-registry.ts +24 -0
  1004. package/src/router/segment-resolution/fresh.ts +748 -0
  1005. package/src/router/segment-resolution/helpers.ts +268 -0
  1006. package/src/router/segment-resolution/loader-cache.ts +199 -0
  1007. package/src/router/segment-resolution/revalidation.ts +1384 -0
  1008. package/src/router/segment-resolution/static-store.ts +67 -0
  1009. package/src/router/segment-resolution.ts +21 -1315
  1010. package/src/router/segment-wrappers.ts +291 -0
  1011. package/src/router/telemetry-otel.ts +299 -0
  1012. package/src/router/telemetry.ts +300 -0
  1013. package/src/router/timeout.ts +148 -0
  1014. package/src/router/trie-matching.ts +103 -30
  1015. package/src/router/types.ts +17 -9
  1016. package/src/router/url-params.ts +49 -0
  1017. package/src/router.ts +647 -1988
  1018. package/src/rsc/handler-context.ts +45 -0
  1019. package/src/rsc/handler.ts +864 -1114
  1020. package/src/rsc/helpers.ts +181 -19
  1021. package/src/rsc/index.ts +0 -20
  1022. package/src/rsc/loader-fetch.ts +229 -0
  1023. package/src/rsc/manifest-init.ts +90 -0
  1024. package/src/rsc/nonce.ts +14 -0
  1025. package/src/rsc/origin-guard.ts +141 -0
  1026. package/src/rsc/progressive-enhancement.ts +393 -0
  1027. package/src/rsc/response-error.ts +37 -0
  1028. package/src/rsc/response-route-handler.ts +360 -0
  1029. package/src/rsc/rsc-rendering.ts +253 -0
  1030. package/src/rsc/runtime-warnings.ts +42 -0
  1031. package/src/rsc/server-action.ts +358 -0
  1032. package/src/rsc/ssr-setup.ts +128 -0
  1033. package/src/rsc/types.ts +46 -11
  1034. package/src/search-params.ts +230 -0
  1035. package/src/segment-content-promise.ts +67 -0
  1036. package/src/segment-loader-promise.ts +122 -0
  1037. package/src/segment-system.tsx +134 -36
  1038. package/src/server/context.ts +333 -59
  1039. package/src/server/cookie-store.ts +190 -0
  1040. package/src/server/fetchable-loader-store.ts +37 -0
  1041. package/src/server/handle-store.ts +113 -15
  1042. package/src/server/loader-registry.ts +24 -64
  1043. package/src/server/request-context.ts +603 -109
  1044. package/src/server.ts +35 -155
  1045. package/src/ssr/index.tsx +103 -30
  1046. package/src/static-handler.ts +126 -0
  1047. package/src/theme/ThemeProvider.tsx +21 -15
  1048. package/src/theme/ThemeScript.tsx +5 -5
  1049. package/src/theme/constants.ts +5 -2
  1050. package/src/theme/index.ts +4 -14
  1051. package/src/theme/theme-context.ts +4 -30
  1052. package/src/theme/theme-script.ts +21 -18
  1053. package/src/types/boundaries.ts +158 -0
  1054. package/src/types/cache-types.ts +198 -0
  1055. package/src/types/error-types.ts +192 -0
  1056. package/src/types/global-namespace.ts +100 -0
  1057. package/src/types/handler-context.ts +759 -0
  1058. package/src/types/index.ts +88 -0
  1059. package/src/types/loader-types.ts +209 -0
  1060. package/src/types/request-scope.ts +126 -0
  1061. package/src/types/route-config.ts +170 -0
  1062. package/src/types/route-entry.ts +120 -0
  1063. package/src/types/segments.ts +150 -0
  1064. package/src/types.ts +1 -1757
  1065. package/src/urls/include-helper.ts +207 -0
  1066. package/src/urls/index.ts +53 -0
  1067. package/src/urls/path-helper-types.ts +372 -0
  1068. package/src/urls/path-helper.ts +364 -0
  1069. package/src/urls/pattern-types.ts +107 -0
  1070. package/src/urls/response-types.ts +108 -0
  1071. package/src/urls/type-extraction.ts +372 -0
  1072. package/src/urls/urls-function.ts +98 -0
  1073. package/src/urls.ts +1 -1282
  1074. package/src/use-loader.tsx +161 -81
  1075. package/src/vite/debug.ts +184 -0
  1076. package/src/vite/discovery/bundle-postprocess.ts +181 -0
  1077. package/src/vite/discovery/discover-routers.ts +376 -0
  1078. package/src/vite/discovery/prerender-collection.ts +486 -0
  1079. package/src/vite/discovery/route-types-writer.ts +258 -0
  1080. package/src/vite/discovery/self-gen-tracking.ts +47 -0
  1081. package/src/vite/discovery/state.ts +117 -0
  1082. package/src/vite/discovery/virtual-module-codegen.ts +203 -0
  1083. package/src/vite/index.ts +15 -1963
  1084. package/src/vite/plugin-types.ts +103 -0
  1085. package/src/vite/plugins/cjs-to-esm.ts +98 -0
  1086. package/src/vite/plugins/client-ref-dedup.ts +131 -0
  1087. package/src/vite/plugins/client-ref-hashing.ts +117 -0
  1088. package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
  1089. package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  1090. package/src/vite/plugins/cloudflare-protocol-stub.ts +214 -0
  1091. package/src/vite/{expose-action-id.ts → plugins/expose-action-id.ts} +107 -64
  1092. package/src/vite/plugins/expose-id-utils.ts +299 -0
  1093. package/src/vite/plugins/expose-ids/export-analysis.ts +296 -0
  1094. package/src/vite/plugins/expose-ids/handler-transform.ts +209 -0
  1095. package/src/vite/plugins/expose-ids/loader-transform.ts +74 -0
  1096. package/src/vite/plugins/expose-ids/router-transform.ts +127 -0
  1097. package/src/vite/plugins/expose-ids/types.ts +45 -0
  1098. package/src/vite/plugins/expose-internal-ids.ts +816 -0
  1099. package/src/vite/plugins/performance-tracks.ts +96 -0
  1100. package/src/vite/plugins/refresh-cmd.ts +127 -0
  1101. package/src/vite/plugins/use-cache-transform.ts +336 -0
  1102. package/src/vite/plugins/version-injector.ts +83 -0
  1103. package/src/vite/plugins/version-plugin.ts +266 -0
  1104. package/src/vite/plugins/virtual-entries.ts +123 -0
  1105. package/src/vite/plugins/virtual-stub-plugin.ts +29 -0
  1106. package/src/vite/rango.ts +497 -0
  1107. package/src/vite/router-discovery.ts +1111 -0
  1108. package/src/vite/utils/ast-handler-extract.ts +517 -0
  1109. package/src/vite/utils/banner.ts +36 -0
  1110. package/src/vite/utils/bundle-analysis.ts +137 -0
  1111. package/src/vite/utils/manifest-utils.ts +70 -0
  1112. package/src/vite/utils/package-resolution.ts +161 -0
  1113. package/src/vite/utils/prerender-utils.ts +221 -0
  1114. package/src/vite/utils/shared-utils.ts +170 -0
  1115. package/CLAUDE.md +0 -43
  1116. package/src/browser/lru-cache.ts +0 -69
  1117. package/src/browser/request-controller.ts +0 -164
  1118. package/src/cache/memory-store.ts +0 -253
  1119. package/src/router.gen.ts +0 -6
  1120. package/src/urls.gen.ts +0 -8
  1121. package/src/vite/expose-handle-id.ts +0 -209
  1122. package/src/vite/expose-loader-id.ts +0 -426
  1123. package/src/vite/expose-location-state-id.ts +0 -177
  1124. package/src/vite/expose-prerender-handler-id.ts +0 -429
  1125. /package/src/vite/{version.d.ts → plugins/version.d.ts} +0 -0
package/src/vite/index.ts CHANGED
@@ -1,1968 +1,20 @@
1
- import type { Plugin, PluginOption } from "vite";
2
- import { createServer as createViteServer } from "vite";
3
- import * as Vite from "vite";
4
- import { resolve, join, dirname } from "node:path";
5
- import { createHash } from "node:crypto";
6
- import { createRequire } from "node:module";
7
- import { mkdirSync, writeFileSync, readFileSync, existsSync, readdirSync } from "node:fs";
8
- import { generateRouteTypesSource, writePerModuleRouteTypes, writePerModuleRouteTypesForFile, writeCombinedRouteTypes } from "../build/generate-route-types.ts";
9
- import { exposeActionId } from "./expose-action-id.ts";
10
- import { exposeLoaderId } from "./expose-loader-id.ts";
11
- import { exposeHandleId } from "./expose-handle-id.ts";
12
- import { exposeLocationStateId } from "./expose-location-state-id.ts";
13
- import { exposePrerenderHandlerId } from "./expose-prerender-handler-id.ts";
14
- import type { ExposePrerenderHandlerIdApi } from "./expose-prerender-handler-id.ts";
15
- import {
16
- VIRTUAL_ENTRY_BROWSER,
17
- VIRTUAL_ENTRY_SSR,
18
- getVirtualEntryRSC,
19
- getVirtualVersionContent,
20
- VIRTUAL_IDS,
21
- } from "./virtual-entries.ts";
22
- import {
23
- getExcludeDeps,
24
- getPackageAliases,
25
- getPublishedPackageName,
26
- isWorkspaceDevelopment,
27
- } from "./package-resolution.ts";
28
-
29
- /** Plugin API type for cloudflare-integration: shares handler chunk metadata. */
30
- interface CloudflareIntegrationApi {
31
- handlerChunkInfo: {
32
- fileName: string;
33
- exports: Array<{ name: string; handlerId: string; passthrough: boolean }>;
34
- } | null;
35
- }
36
-
37
- // Re-export plugins
38
- export { exposeActionId } from "./expose-action-id.ts";
39
- export { exposeLoaderId } from "./expose-loader-id.ts";
40
- export { exposeHandleId } from "./expose-handle-id.ts";
41
- export { exposeLocationStateId } from "./expose-location-state-id.ts";
42
- export { exposePrerenderHandlerId } from "./expose-prerender-handler-id.ts";
43
-
44
- // Virtual module type declarations in ./version.d.ts
45
-
46
- /**
47
- * esbuild plugin to provide rsc-router:version virtual module during optimization.
48
- * This is needed because esbuild runs during Vite's dependency optimization phase,
49
- * before Vite's plugin system can handle virtual modules.
50
- */
51
- const versionEsbuildPlugin = {
52
- name: "@rangojs/router-version",
53
- setup(build: any) {
54
- build.onResolve({ filter: /^rsc-router:version$/ }, (args: any) => ({
55
- path: args.path,
56
- namespace: "@rangojs/router-virtual",
57
- }));
58
- build.onLoad({ filter: /.*/, namespace: "@rangojs/router-virtual" }, () => ({
59
- contents: `export const VERSION = "dev";`,
60
- loader: "js",
61
- }));
62
- },
63
- };
64
-
65
- /**
66
- * Shared esbuild options for dependency optimization.
67
- * Includes the version stub plugin for all environments.
68
- */
69
- const sharedEsbuildOptions = {
70
- plugins: [versionEsbuildPlugin],
71
- };
72
-
73
- /**
74
- * RSC plugin entry points configuration.
75
- * All entries use virtual modules by default. Specify a path to use a custom entry file.
76
- */
77
- export interface RscEntries {
78
- /**
79
- * Path to a custom browser/client entry file.
80
- * If not specified, a default virtual entry is used.
81
- */
82
- client?: string;
83
-
84
- /**
85
- * Path to a custom SSR entry file.
86
- * If not specified, a default virtual entry is used.
87
- */
88
- ssr?: string;
89
-
90
- /**
91
- * Path to a custom RSC entry file.
92
- * If not specified, a default virtual entry is used that imports the router from the `entry` option.
93
- */
94
- rsc?: string;
95
- }
96
-
97
- /**
98
- * Options for @vitejs/plugin-rsc integration
99
- */
100
- export interface RscPluginOptions {
101
- /**
102
- * Entry points for client, ssr, and rsc environments.
103
- * All entries use virtual modules by default.
104
- * Specify paths only when you need custom entry files.
105
- */
106
- entries?: RscEntries;
107
- }
108
-
109
- /**
110
- * Base options shared by all presets
111
- */
112
- interface RangoBaseOptions {
113
- /**
114
- * Show startup banner. Set to false to disable.
115
- * @default true
116
- */
117
- banner?: boolean;
118
-
119
- /**
120
- * Generate static route type files (.gen.ts) by parsing url modules at startup.
121
- * Creates per-module route maps and a combined named-routes.gen.ts for type-safe
122
- * Handler<"name", routes> and href() without executing router code.
123
- * Set to `false` to disable (run `npx rango extract-names` manually instead).
124
- * @default true
125
- */
126
- staticRouteTypesGeneration?: boolean;
127
- }
128
-
129
- /**
130
- * Options for Node.js deployment (default)
131
- */
132
- export interface RangoNodeOptions extends RangoBaseOptions {
133
- /**
134
- * Deployment preset. Defaults to 'node' when not specified.
135
- */
136
- preset?: "node";
137
-
138
- /**
139
- * Path to your router configuration file that exports the route tree.
140
- * This file must export a `router` object created with `createRouter()`.
141
- *
142
- * @example
143
- * ```ts
144
- * rango({ router: './src/router.tsx' })
145
- * ```
146
- */
147
- router: string;
148
-
149
- /**
150
- * RSC plugin configuration. By default, rsc-router includes @vitejs/plugin-rsc
151
- * with sensible defaults.
152
- *
153
- * Entry files (browser, ssr, rsc) are optional - if they don't exist,
154
- * virtual defaults are used.
155
- *
156
- * - Omit or pass `true`/`{}` to use defaults (recommended)
157
- * - Pass `{ entries: {...} }` to customize entry paths
158
- * - Pass `false` to disable (for manual @vitejs/plugin-rsc configuration)
159
- *
160
- * @default true
161
- */
162
- rsc?: boolean | RscPluginOptions;
163
- }
164
-
165
- /**
166
- * Options for Cloudflare Workers deployment
167
- */
168
- export interface RangoCloudflareOptions extends RangoBaseOptions {
169
- /**
170
- * Deployment preset for Cloudflare Workers.
171
- * When using cloudflare preset:
172
- * - @vitejs/plugin-rsc is NOT added (cloudflare plugin adds it)
173
- * - Your worker entry (e.g., worker.rsc.tsx) imports the router directly
174
- * - Browser and SSR use virtual entries
175
- * - Build-time manifest generation is auto-detected from wrangler.json main entry
176
- */
177
- preset: "cloudflare";
178
- }
179
-
180
- /**
181
- * Options for rango() Vite plugin
182
- */
183
- export type RangoOptions = RangoNodeOptions | RangoCloudflareOptions;
184
-
185
- /**
186
- * Create a virtual modules plugin for default entry files.
187
- * Provides virtual module content when entries use VIRTUAL_IDS (no custom entry configured).
188
- */
189
- function createVirtualEntriesPlugin(
190
- entries: { client: string; ssr: string; rsc?: string },
191
- routerPath?: string
192
- ): Plugin {
193
-
194
- // Build virtual modules map based on which entries use virtual IDs
195
- const virtualModules: Record<string, string> = {};
196
-
197
- if (entries.client === VIRTUAL_IDS.browser) {
198
- virtualModules[VIRTUAL_IDS.browser] = VIRTUAL_ENTRY_BROWSER;
199
- }
200
- if (entries.ssr === VIRTUAL_IDS.ssr) {
201
- virtualModules[VIRTUAL_IDS.ssr] = VIRTUAL_ENTRY_SSR;
202
- }
203
- if (entries.rsc === VIRTUAL_IDS.rsc && routerPath) {
204
- // Convert relative path to absolute for virtual module imports
205
- const absoluteRouterPath = routerPath.startsWith(".")
206
- ? "/" + routerPath.slice(2) // ./src/router.tsx -> /src/router.tsx
207
- : routerPath;
208
- virtualModules[VIRTUAL_IDS.rsc] = getVirtualEntryRSC(absoluteRouterPath);
209
- }
210
-
211
- return {
212
- name: "@rangojs/router:virtual-entries",
213
- enforce: "pre",
214
-
215
- resolveId(id) {
216
- if (id in virtualModules) {
217
- return "\0" + id;
218
- }
219
- // Handle if the id already has the null prefix (RSC plugin wrapper imports)
220
- if (id.startsWith("\0") && id.slice(1) in virtualModules) {
221
- return id;
222
- }
223
- return null;
224
- },
225
-
226
- load(id) {
227
- if (id.startsWith("\0virtual:rsc-router/")) {
228
- const virtualId = id.slice(1);
229
- if (virtualId in virtualModules) {
230
- return virtualModules[virtualId];
231
- }
232
- }
233
- return null;
234
- },
235
- };
236
- }
237
-
238
- /**
239
- * Manual chunks configuration for client build.
240
- * Splits React and router packages into separate chunks for better caching.
241
- */
242
- function getManualChunks(id: string): string | undefined {
243
- const normalized = Vite.normalizePath(id);
244
-
245
- if (
246
- normalized.includes("node_modules/react/") ||
247
- normalized.includes("node_modules/react-dom/") ||
248
- normalized.includes("node_modules/react-server-dom-webpack/") ||
249
- normalized.includes("node_modules/@vitejs/plugin-rsc/")
250
- ) {
251
- return "react";
252
- }
253
- // Use dynamic package name from package.json
254
- // Check both npm install path and workspace symlink resolved path
255
- const packageName = getPublishedPackageName();
256
- if (
257
- normalized.includes(`node_modules/${packageName}/`) ||
258
- normalized.includes("packages/rsc-router/") ||
259
- normalized.includes("packages/rangojs-router/")
260
- ) {
261
- return "router";
262
- }
263
- return undefined;
264
- }
265
-
266
- /**
267
- * Plugin providing rsc-router:version virtual module.
268
- * Exports VERSION that changes when RSC modules change (dev) or at build time (production).
269
- *
270
- * The version is used for:
271
- * 1. Cache invalidation - CFCacheStore uses VERSION to invalidate stale cache
272
- * 2. Version mismatch detection - client sends version, server reloads on mismatch
273
- *
274
- * In dev mode, the version updates when:
275
- * - Server starts (initial version)
276
- * - RSC modules change via HMR (triggers version module invalidation)
277
- *
278
- * Client-only HMR changes don't update the version since they don't affect
279
- * server-rendered content or cached RSC payloads.
280
- * @internal
281
- */
282
- function createVersionPlugin(): Plugin {
283
- // Generate version at plugin creation time (build/server start)
284
- const buildVersion = Date.now().toString(16);
285
- let currentVersion = buildVersion;
286
- let isDev = false;
287
- let server: any = null;
288
-
289
- return {
290
- name: "@rangojs/router:version",
291
- enforce: "pre",
292
-
293
- configResolved(config) {
294
- isDev = config.command === "serve";
295
- },
296
-
297
- configureServer(devServer) {
298
- server = devServer;
299
- },
300
-
301
- resolveId(id) {
302
- if (id === VIRTUAL_IDS.version) {
303
- return "\0" + id;
304
- }
305
- return null;
306
- },
307
-
308
- load(id) {
309
- if (id === "\0" + VIRTUAL_IDS.version) {
310
- return getVirtualVersionContent(currentVersion);
311
- }
312
- return null;
313
- },
314
-
315
- // Track RSC module changes and update version
316
- hotUpdate(ctx) {
317
- if (!isDev) return;
318
-
319
- // Check if this is an RSC environment update (not client/ssr)
320
- // RSC modules affect server-rendered content and cached payloads
321
- // In Vite 6, environment is accessed via `this.environment`
322
- const isRscModule = this.environment?.name === "rsc";
323
-
324
- if (isRscModule && ctx.modules.length > 0) {
325
- // Update version when RSC modules change
326
- currentVersion = Date.now().toString(16);
327
- console.log(
328
- `[rsc-router] RSC module changed, version updated: ${currentVersion}`
329
- );
330
-
331
- // Invalidate the version module so it gets reloaded with new version
332
- if (server) {
333
- const rscEnv = server.environments?.rsc;
334
- if (rscEnv?.moduleGraph) {
335
- const versionMod = rscEnv.moduleGraph.getModuleById(
336
- "\0" + VIRTUAL_IDS.version
337
- );
338
- if (versionMod) {
339
- rscEnv.moduleGraph.invalidateModule(versionMod);
340
- }
341
- }
342
- }
343
- }
344
- },
345
- };
346
- }
347
-
348
- /**
349
- * Flatten prefix tree leaf nodes into precomputed route entries.
350
- * Leaf nodes have no children (no nested includes), so their routes can be
351
- * used directly by evaluateLazyEntry() without running the handler.
352
- * Non-leaf nodes are skipped because they have nested lazy includes that
353
- * require the handler to run for discovery.
354
- */
355
- function flattenLeafEntries(
356
- prefixTree: Record<string, any>,
357
- routeManifest: Record<string, string>,
358
- result: Array<{ staticPrefix: string; routes: Record<string, string> }>,
359
- ): void {
360
- function visit(node: any): void {
361
- const children = node.children || {};
362
- if (Object.keys(children).length === 0 && node.routes && node.routes.length > 0) {
363
- // Leaf node: collect its routes from the manifest
364
- const routes: Record<string, string> = {};
365
- for (const name of node.routes) {
366
- if (name in routeManifest) {
367
- routes[name] = routeManifest[name];
368
- }
369
- }
370
- result.push({ staticPrefix: node.staticPrefix, routes });
371
- } else {
372
- // Non-leaf: recurse into children
373
- for (const child of Object.values(children)) {
374
- visit(child);
375
- }
376
- }
377
- }
378
- for (const node of Object.values(prefixTree)) {
379
- visit(node);
380
- }
381
- }
382
-
383
- /**
384
- * Walk prefix tree to map each route name to its scope's staticPrefix.
385
- */
386
- function buildRouteToStaticPrefix(
387
- prefixTree: Record<string, any>,
388
- result: Record<string, string>,
389
- ): void {
390
- function visit(node: any): void {
391
- const sp = node.staticPrefix || "";
392
- for (const name of (node.routes || [])) {
393
- result[name] = sp;
394
- }
395
- for (const child of Object.values(node.children || {})) {
396
- visit(child);
397
- }
398
- }
399
- for (const node of Object.values(prefixTree)) {
400
- visit(node);
401
- }
402
- }
403
-
404
- /**
405
- * Plugin that discovers router instances at dev/build time via the RSC environment.
406
- *
407
- * Uses `server.environments.rsc.runner.import()` to load the user's router file
408
- * with full TS/TSX compilation. This triggers `createRouter()` which populates
409
- * the `RouterRegistry`. The plugin then generates manifests for each router.
410
- *
411
- * In dev mode, this runs in `configureServer` (post-middleware setup).
412
- * In build mode, this will run in `buildStart` (future).
413
- *
414
- * @internal
415
- */
416
- function createRouterDiscoveryPlugin(
417
- entryPath: string,
418
- opts?: { enableBuildPrerender?: boolean; staticRouteTypesGeneration?: boolean },
419
- ): Plugin {
420
- let projectRoot = "";
421
- let isBuildMode = false;
422
- let userResolveAlias: any = undefined;
423
-
424
- // Merged route manifest from all discovered routers.
425
- // Populated during discovery (dev: configureServer, build: buildStart).
426
- // Read by the virtual module's load hook to emit setCachedManifest() call.
427
- let mergedRouteManifest: Record<string, string> | null = null;
428
-
429
- // Per-router route manifests for generating typed route files.
430
- let perRouterManifests: Array<{ id: string; routeManifest: Record<string, string> }> = [];
431
-
432
- // Concrete URLs to pre-render at build time (populated during buildStart).
433
- // Only used when enableBuildPrerender is true.
434
- let prerenderBuildUrls: string[] | null = null;
435
- // Maps route name -> router hash for prerender storage keys
436
- let prerenderRouteHashMap: Record<string, string> = {};
437
-
438
- // Reference to @vitejs/plugin-rsc's RscPluginManager for early manifest writes.
439
- // Populated during configResolved, used in closeBundle to write the assets
440
- // manifest before the child prerender process starts.
441
- let rscPluginManager: any = null;
442
- let cfIntegrationApi: CloudflareIntegrationApi | null = null;
443
-
444
- // Promise that resolves when dev-mode discovery completes.
445
- // The virtual module's load hook awaits this to ensure data is available.
446
- let discoveryDone: Promise<void> | null = null;
447
-
448
- // Pre-computed route entries from prefix tree leaf nodes.
449
- // Leaf nodes have no nested includes, so their routes can be used directly
450
- // by evaluateLazyEntry() without running the handler.
451
- let mergedPrecomputedEntries: Array<{
452
- staticPrefix: string;
453
- routes: Record<string, string>;
454
- }> | null = null;
455
-
456
- // Route trie for O(path_length) matching at runtime.
457
- let mergedRouteTrie: any = null;
458
-
459
- // Shared discovery logic: import entry via RSC runner, generate manifests,
460
- // write static files, and populate mergedRouteManifest.
461
- async function discoverRouters(rscEnv: any) {
462
- // Import the entry file via RSC environment.
463
- // For node preset: this is the router file (createRouter() registers in RouterRegistry).
464
- // For cloudflare preset: this is the worker entry (which imports the router).
465
- await rscEnv.runner.import(entryPath);
466
-
467
- // Import the router package to access the registry
468
- const serverMod = await rscEnv.runner.import("@rangojs/router/server");
469
- let registry: Map<string, any> = serverMod.RouterRegistry;
470
-
471
- if (!registry || registry.size === 0) {
472
- // No RSC routers found directly. Check for host routers with lazy handlers
473
- // that need to be resolved to trigger sub-app createRouter() calls.
474
- try {
475
- const hostMod = await rscEnv.runner.import("@rangojs/router/host");
476
- const hostRegistry: Map<string, any> | undefined = hostMod.HostRouterRegistry;
477
-
478
- if (hostRegistry && hostRegistry.size > 0) {
479
- console.log(
480
- `[rsc-router] Found ${hostRegistry.size} host router(s), resolving lazy handlers...`
481
- );
482
-
483
- for (const [, entry] of hostRegistry) {
484
- for (const route of entry.routes) {
485
- if (typeof route.handler === 'function') {
486
- try {
487
- await route.handler();
488
- } catch {
489
- // Lazy handler may fail in temp server context, that's OK
490
- }
491
- }
492
- }
493
- if (entry.fallback && typeof entry.fallback.handler === 'function') {
494
- try {
495
- await entry.fallback.handler();
496
- } catch {
497
- // Fallback handler may fail in temp server context
498
- }
499
- }
500
- }
501
-
502
- // Re-read RouterRegistry - sub-app createRouter() calls should have populated it
503
- const freshServerMod = await rscEnv.runner.import("@rangojs/router/server");
504
- const freshRegistry: Map<string, any> = freshServerMod.RouterRegistry;
505
-
506
- if (freshRegistry && freshRegistry.size > 0) {
507
- // Update references so the manifest generation below uses the fresh data
508
- Object.assign(serverMod, freshServerMod);
509
- registry = freshRegistry;
510
- }
511
- }
512
- } catch {
513
- // @rangojs/router/host not available or import failed, skip
514
- }
515
-
516
- // If still no routers after host router resolution, fail
517
- if (!registry || registry.size === 0) {
518
- throw new Error(
519
- `[rsc-router] No routers found in registry after importing ${entryPath}`
520
- );
521
- }
522
- }
523
-
524
- // Import build utilities for manifest generation
525
- const buildMod = await rscEnv.runner.import("@rangojs/router/build");
526
- const generateManifest = buildMod.generateManifest;
527
-
528
- mergedRouteManifest = {};
529
- mergedPrecomputedEntries = [];
530
- perRouterManifests = [];
531
- let mergedRouteAncestry: Record<string, string[]> = {};
532
- let mergedRouteTrailingSlash: Record<string, string> = {};
533
-
534
- let routerMountIndex = 0;
535
- // Collect all manifests for trie building (avoid re-running generateManifest)
536
- const allManifests: Array<{ id: string; manifest: any }> = [];
537
-
538
- for (const [id, router] of registry) {
539
- if (!router.urlpatterns || !generateManifest) {
540
- continue;
541
- }
542
-
543
- const manifest = generateManifest(router.urlpatterns, routerMountIndex);
544
- routerMountIndex++;
545
- allManifests.push({ id, manifest });
546
- const routeCount = Object.keys(manifest.routeManifest).length;
547
- const staticRoutes = Object.values(manifest.routeManifest).filter(
548
- (p: any) => !p.includes(":") && !p.includes("*")
549
- ).length;
550
- const dynamicRoutes = routeCount - staticRoutes;
551
-
552
- // Merge into the combined manifest
553
- Object.assign(mergedRouteManifest, manifest.routeManifest);
554
- perRouterManifests.push({ id, routeManifest: manifest.routeManifest });
555
-
556
- // Merge ancestry (internal field, used only for trie building)
557
- if (manifest._routeAncestry) {
558
- Object.assign(mergedRouteAncestry, manifest._routeAncestry);
559
- }
560
- // Merge trailing slash config
561
- if (manifest.routeTrailingSlash) {
562
- Object.assign(mergedRouteTrailingSlash, manifest.routeTrailingSlash);
563
- }
564
-
565
- // Flatten prefix tree leaf nodes into precomputed entries.
566
- // Leaf nodes (no children) can have their routes used directly by
567
- // evaluateLazyEntry() without running the handler at runtime.
568
- flattenLeafEntries(manifest.prefixTree, manifest.routeManifest, mergedPrecomputedEntries);
569
-
570
- // Write static files for this router
571
- const hash = hashRouterId(id);
572
- const outDir = join(projectRoot, "dist", "static", `__${hash}`);
573
- mkdirSync(outDir, { recursive: true });
574
-
575
- writeFileSync(
576
- join(outDir, "routes.json"),
577
- JSON.stringify(manifest.routeManifest, null, 2) + "\n"
578
- );
579
-
580
- writeFileSync(
581
- join(outDir, "prefixes.json"),
582
- JSON.stringify(manifest.prefixTree, null, 2) + "\n"
583
- );
584
-
585
- console.log(
586
- `[rsc-router] Router "${id}" -> ${routeCount} routes ` +
587
- `(${staticRoutes} static, ${dynamicRoutes} dynamic) ` +
588
- `-> dist/static/__${hash}/`
589
- );
590
- }
591
-
592
- // Build route trie from merged manifest + ancestry
593
- if (mergedRouteManifest && Object.keys(mergedRouteManifest).length > 0) {
594
- const buildRouteTrie = buildMod.buildRouteTrie;
595
- if (buildRouteTrie && mergedRouteAncestry) {
596
- // Build routeToStaticPrefix from saved manifests
597
- const routeToStaticPrefix: Record<string, string> = {};
598
- for (const { manifest } of allManifests) {
599
- // Root-level routes have empty static prefix
600
- for (const name of Object.keys(manifest.routeManifest)) {
601
- if (!(name in routeToStaticPrefix)) {
602
- routeToStaticPrefix[name] = "";
603
- }
604
- }
605
- buildRouteToStaticPrefix(manifest.prefixTree, routeToStaticPrefix);
606
- }
607
-
608
- // Collect prerender route names and response type routes from all manifests
609
- const prerenderRouteNames = new Set<string>();
610
- const passthroughRouteNames = new Set<string>();
611
- const mergedResponseTypeRoutes: Record<string, string> = {};
612
- for (const { manifest } of allManifests) {
613
- if (manifest.prerenderRoutes) {
614
- for (const name of manifest.prerenderRoutes) {
615
- prerenderRouteNames.add(name);
616
- }
617
- }
618
- if (manifest.passthroughRoutes) {
619
- for (const name of manifest.passthroughRoutes) {
620
- passthroughRouteNames.add(name);
621
- }
622
- }
623
- if (manifest.responseTypeRoutes) {
624
- Object.assign(mergedResponseTypeRoutes, manifest.responseTypeRoutes);
625
- }
626
- }
627
-
628
- mergedRouteTrie = buildRouteTrie(
629
- mergedRouteManifest,
630
- mergedRouteAncestry,
631
- routeToStaticPrefix,
632
- Object.keys(mergedRouteTrailingSlash).length > 0 ? mergedRouteTrailingSlash : undefined,
633
- prerenderRouteNames.size > 0 ? prerenderRouteNames : undefined,
634
- passthroughRouteNames.size > 0 ? passthroughRouteNames : undefined,
635
- Object.keys(mergedResponseTypeRoutes).length > 0 ? mergedResponseTypeRoutes : undefined,
636
- );
637
- // Trie built successfully
638
- }
639
- }
640
-
641
- // Expand prerender routes into concrete URLs for build-time rendering.
642
- // Static routes use pattern as-is; dynamic routes call getParams() to enumerate.
643
- if (opts?.enableBuildPrerender) {
644
- const urls: string[] = [];
645
- const routeHashMap: Record<string, string> = {};
646
- for (const { id, manifest } of allManifests) {
647
- if (!manifest.prerenderRoutes) continue;
648
- const rHash = hashRouterId(id);
649
- const defs = manifest._prerenderDefs || {};
650
- for (const routeName of manifest.prerenderRoutes) {
651
- routeHashMap[routeName] = rHash;
652
- const pattern = manifest.routeManifest[routeName];
653
- if (!pattern) continue;
654
- const hasDynamic = pattern.includes(":") || pattern.includes("*");
655
- if (!hasDynamic) {
656
- // Static route: use pattern directly (strip trailing slash for URL)
657
- urls.push(pattern.replace(/\/$/, "") || "/");
658
- } else {
659
- // Dynamic route: call getParams() to enumerate param combinations
660
- const def = defs[routeName];
661
- if (def?.getParams) {
662
- try {
663
- const paramsList = await def.getParams();
664
- for (const params of paramsList) {
665
- let url = pattern;
666
- for (const [key, value] of Object.entries(params as Record<string, string>)) {
667
- url = url.replace(`:${key}`, encodeURIComponent(String(value)));
668
- }
669
- urls.push(url.replace(/\/$/, "") || "/");
670
- }
671
- } catch (err: any) {
672
- console.warn(
673
- `[rsc-router] Failed to get params for prerender route "${routeName}": ${err.message}`
674
- );
675
- }
676
- } else {
677
- console.warn(
678
- `[rsc-router] Dynamic prerender route "${routeName}" has no getParams(), skipping`
679
- );
680
- }
681
- }
682
- }
683
- }
684
- if (urls.length > 0) {
685
- prerenderBuildUrls = urls;
686
- prerenderRouteHashMap = routeHashMap;
687
- console.log(
688
- `[rsc-router] Pre-render URLs: ${urls.join(", ")}`
689
- );
690
- }
691
- }
692
-
693
- return serverMod;
694
- }
695
-
696
- // Write named-routes type file next to the router entry file.
697
- // Only writes when content has changed to avoid triggering HMR loops.
698
- function writeRouteTypesFiles() {
699
- if (perRouterManifests.length === 0) return;
700
- try {
701
- const entryDir = dirname(resolve(projectRoot, entryPath));
702
- // Merge all router manifests into a single route map
703
- const mergedManifest: Record<string, string> = {};
704
- for (const { routeManifest } of perRouterManifests) {
705
- Object.assign(mergedManifest, routeManifest);
706
- }
707
- const outPath = join(entryDir, "named-routes.gen.ts");
708
- const source = generateRouteTypesSource(mergedManifest);
709
- const existing = existsSync(outPath) ? readFileSync(outPath, "utf-8") : null;
710
- if (existing !== source) {
711
- writeFileSync(outPath, source);
712
- console.log(`[rsc-router] Generated route types -> ${outPath}`);
713
- }
714
- } catch (err) {
715
- console.warn(`[rsc-router] Failed to write named-routes.gen.ts: ${(err as Error).message}`);
716
- }
717
- }
718
-
719
- return {
720
- name: "@rangojs/router:discovery",
721
-
722
- configResolved(config) {
723
- projectRoot = config.root;
724
- isBuildMode = config.command === "build";
725
- // Capture user's resolve aliases for the temp server
726
- userResolveAlias = config.resolve.alias;
727
- // Generate per-module route types from static source parsing.
728
- // Runs before the dev server starts so .gen.ts files exist immediately for IDE.
729
- if (opts?.staticRouteTypesGeneration !== false) {
730
- writePerModuleRouteTypes(projectRoot, entryPath);
731
- writeCombinedRouteTypes(projectRoot, entryPath);
732
- }
733
- // Capture @vitejs/plugin-rsc manager for early manifest writes during prerender.
734
- // The manager's buildAssetsManifest is populated during client generateBundle,
735
- // but writeAssetsManifest is called after all closeBundle hooks complete.
736
- // We call it early in our closeBundle so the child process can import it.
737
- if (opts?.enableBuildPrerender) {
738
- const rscPlugin = config.plugins.find((p: any) => p.name === "rsc:minimal");
739
- if (rscPlugin?.api?.manager) {
740
- rscPluginManager = rscPlugin.api.manager;
741
- }
742
- // Look up cloudflare-integration plugin API for handler chunk metadata
743
- const cfPlugin = config.plugins.find(
744
- (p: any) => p.name === "@rangojs/router:cloudflare-integration",
745
- );
746
- if (cfPlugin?.api) {
747
- cfIntegrationApi = cfPlugin.api as CloudflareIntegrationApi;
748
- }
749
- }
750
- },
751
-
752
- // Dev mode: discover routers and populate manifest in memory.
753
- // Skipped in build mode (buildStart handles it).
754
- configureServer(server) {
755
- if (isBuildMode) return;
756
- // Skip if this is a temp server created by buildStart
757
- if ((globalThis as any).__rscRouterDiscoveryActive) return;
758
-
759
- // Discovery promise that the handler can await if requests arrive
760
- // before discovery completes
761
- let resolveDiscovery: () => void;
762
- const discoveryPromise = new Promise<void>((resolve) => {
763
- resolveDiscovery = resolve;
764
- });
765
-
766
- const discover = async () => {
767
- const rscEnv = (server.environments as any)?.rsc;
768
- if (!rscEnv?.runner) {
769
- resolveDiscovery!();
770
- return;
771
- }
772
-
773
- try {
774
- // Set the readiness gate BEFORE discovery so early requests
775
- // block until manifest is populated
776
- const serverMod = await rscEnv.runner.import("@rangojs/router/server");
777
- if (serverMod?.setManifestReadyPromise) {
778
- serverMod.setManifestReadyPromise(discoveryPromise);
779
- }
780
-
781
- await discoverRouters(rscEnv);
782
- writeRouteTypesFiles();
783
-
784
- // Populate the route map in the RSC env
785
- if (mergedRouteManifest && serverMod?.setCachedManifest) {
786
- serverMod.setCachedManifest(mergedRouteManifest);
787
- }
788
- if (mergedPrecomputedEntries && mergedPrecomputedEntries.length > 0 && serverMod?.setPrecomputedEntries) {
789
- serverMod.setPrecomputedEntries(mergedPrecomputedEntries);
790
- }
791
- if (mergedRouteTrie && serverMod?.setRouteTrie) {
792
- serverMod.setRouteTrie(mergedRouteTrie);
793
- }
794
- } catch (err: any) {
795
- console.warn(
796
- `[rsc-router] Router discovery failed: ${err.message}\n${err.stack}`
797
- );
798
- } finally {
799
- resolveDiscovery!();
800
- }
801
- };
802
-
803
- // Schedule after all plugins have finished configureServer.
804
- // Store the promise so the virtual module's load hook can await it.
805
- discoveryDone = new Promise<void>((resolve) => {
806
- setTimeout(() => discover().then(resolve, resolve), 0);
807
- });
808
-
809
- // Watch url module files for changes and regenerate route types.
810
- // Only process files that contain urls( — skip components, actions, etc.
811
- if (opts?.staticRouteTypesGeneration !== false) {
812
- server.watcher.on("change", (filePath) => {
813
- if (filePath.endsWith(".gen.ts")) return;
814
- if (!filePath.endsWith(".ts") && !filePath.endsWith(".tsx")) return;
815
- try {
816
- const source = readFileSync(filePath, "utf-8");
817
- const trimmed = source.trimStart();
818
- if (trimmed.startsWith('"use client"') || trimmed.startsWith("'use client'")) return;
819
- if (!source.includes("urls(")) return;
820
- writePerModuleRouteTypesForFile(filePath);
821
- writeCombinedRouteTypes(projectRoot, entryPath);
822
- } catch {
823
- // Ignore read errors for deleted/moved files
824
- }
825
- });
826
- }
827
- },
828
-
829
- // Build mode: create a temporary Vite dev server to access the RSC
830
- // environment's module runner, then discover routers and generate manifests.
831
- // The manifest data is stored for the virtual module's load hook.
832
- async buildStart() {
833
- if (!isBuildMode) return;
834
- // Only run once across environment builds
835
- if (mergedRouteManifest !== null) return;
836
-
837
- let tempServer: any = null;
838
- try {
839
- // Prevent the temp server's plugin instances from running discovery
840
- (globalThis as any).__rscRouterDiscoveryActive = true;
841
-
842
- // Create a minimal Vite server with just the RSC plugin.
843
- // We bypass the user's config file because:
844
- // - Custom environments (e.g., CloudflareDevEnvironment) may not expose
845
- // a module runner compatible with runner.import()
846
- // - The temp server only needs RSC conditions to import the router
847
- const { default: rsc } = await import("@vitejs/plugin-rsc");
848
- tempServer = await createViteServer({
849
- root: projectRoot,
850
- configFile: false,
851
- server: { middlewareMode: true },
852
- appType: "custom",
853
- logLevel: "silent",
854
- // Use the resolved aliases from the real config (includes user's path aliases
855
- // like @/ -> src/ AND package aliases from rsc-router)
856
- resolve: { alias: userResolveAlias },
857
- // Enable automatic JSX runtime so .tsx files don't need `import React`.
858
- // Without this, esbuild defaults to classic mode (React.createElement)
859
- // which fails when lazy host-router handlers load sub-app modules with JSX.
860
- esbuild: { jsx: "automatic", jsxImportSource: "react" },
861
- plugins: [
862
- rsc({ entries: { client: "virtual:entry-client", ssr: "virtual:entry-ssr", rsc: entryPath } }),
863
- createVersionPlugin(),
864
- // Stub virtual modules that the RSC entry may import
865
- // (e.g., virtual:rsc-router/routes-manifest, virtual:rsc-router/loader-manifest)
866
- createVirtualStubPlugin(),
867
- ],
868
- });
869
-
870
- const rscEnv = (tempServer.environments as any)?.rsc;
871
- if (!rscEnv?.runner) {
872
- console.warn(
873
- "[rsc-router] RSC environment runner not available during build, skipping manifest generation"
874
- );
875
- return;
876
- }
877
-
878
- await discoverRouters(rscEnv);
879
- writeRouteTypesFiles();
880
- } catch (err: any) {
881
- // Clean up before re-throwing so the temp server doesn't leak
882
- delete (globalThis as any).__rscRouterDiscoveryActive;
883
- if (tempServer) {
884
- await tempServer.close();
885
- }
886
- throw new Error(
887
- `[rsc-router] Build-time router discovery failed: ${err.message}`
888
- );
889
- } finally {
890
- delete (globalThis as any).__rscRouterDiscoveryActive;
891
- if (tempServer) {
892
- await tempServer.close();
893
- }
894
- }
895
- },
896
-
897
- // Virtual module: provides the pre-generated route manifest as a JS module
898
- // that calls setCachedManifest() at import time.
899
- resolveId(id) {
900
- if (id === VIRTUAL_ROUTES_MANIFEST_ID) {
901
- return "\0" + VIRTUAL_ROUTES_MANIFEST_ID;
902
- }
903
- // virtual:rsc-router/prerender-paths removed: prerender data is served through the worker
904
- return null;
905
- },
906
-
907
- async load(id) {
908
- if (id === "\0" + VIRTUAL_ROUTES_MANIFEST_ID) {
909
- // In dev mode, wait for discovery to complete before emitting module content.
910
- // This is critical for Cloudflare dev where the worker runs in a separate
911
- // Miniflare process and can only receive manifest data via the virtual module.
912
- if (discoveryDone) {
913
- await discoveryDone;
914
- console.log(`[rsc-router] Virtual module loaded after discovery (${mergedRouteManifest ? Object.keys(mergedRouteManifest).length + ' routes' : 'no data'})`);
915
- }
916
- const hasManifest = mergedRouteManifest && Object.keys(mergedRouteManifest).length > 0;
917
- if (hasManifest) {
918
- const lines = [
919
- `import { setCachedManifest, setPrecomputedEntries, setRouteTrie } from "@rangojs/router/server";`,
920
- `setCachedManifest(${JSON.stringify(mergedRouteManifest)});`,
921
- ];
922
- if (mergedPrecomputedEntries && mergedPrecomputedEntries.length > 0) {
923
- lines.push(`setPrecomputedEntries(${JSON.stringify(mergedPrecomputedEntries)});`);
924
- }
925
- if (mergedRouteTrie) {
926
- lines.push(`setRouteTrie(${JSON.stringify(mergedRouteTrie)});`);
927
- }
928
- return lines.join("\n");
929
- }
930
- // No manifest available yet (dev mode: discovery hasn't completed)
931
- return `// Route manifest will be populated at runtime`;
932
- }
933
- // virtual:rsc-router/prerender-paths load handler removed
934
- return null;
935
- },
936
-
937
- // Build-time pre-rendering: spawn a child Node.js process to import the
938
- // built worker and render each prerender URL to static HTML.
939
- // A separate process is needed because Vite registers module resolution
940
- // hooks that interfere with importing the bundled worker.
941
- //
942
- // RETRY SEMANTICS:
943
- // Vite's environment-aware builder calls closeBundle once per environment
944
- // build (rsc -> client -> ssr). Pre-rendering requires BOTH the client
945
- // assets manifest AND the SSR bundle, so early calls bail out silently.
946
- // The `order: "post"` ensures this runs after other plugins' closeBundle
947
- // hooks. `sequential: true` prevents concurrent closeBundle execution
948
- // across environments, avoiding race conditions on shared state like
949
- // prerenderBuildUrls. The null-guard on prerenderBuildUrls ensures we
950
- // run at most once even if closeBundle fires again after the SSR build.
951
- closeBundle: {
952
- order: "post" as const,
953
- sequential: true,
954
- async handler() {
955
- if (!isBuildMode || !prerenderBuildUrls?.length) return;
956
-
957
- // The assets manifest is populated during the client build (step 4/5).
958
- // If it's not set yet, we're in an earlier build step — bail out without
959
- // consuming prerenderBuildUrls so we can retry on the next closeBundle call.
960
- if (!rscPluginManager?.buildAssetsManifest) return;
961
-
962
- // The SSR bundle must exist (written during step 5/5). Without it the
963
- // worker import will fail. Bail without consuming urls so the next
964
- // closeBundle call (after SSR build) can proceed.
965
- const ssrPath = resolve(projectRoot, "dist/rsc/ssr/index.js");
966
- if (!existsSync(ssrPath)) return;
967
-
968
- // Guard: only run once across environment builds
969
- if (prerenderBuildUrls === null) return;
970
- const urlsToRender = prerenderBuildUrls;
971
- prerenderBuildUrls = null;
972
-
973
- // Write the assets manifest early. @vitejs/plugin-rsc populates
974
- // buildAssetsManifest during the client build's generateBundle hook,
975
- // but calls writeAssetsManifest() AFTER builder.build(ssr) returns.
976
- // Since closeBundle fires DURING builder.build(ssr), the file doesn't
977
- // exist yet. We call writeAssetsManifest ourselves so the child
978
- // prerender process can import it. The RSC plugin overwrites it
979
- // with identical data later.
980
- try {
981
- rscPluginManager.writeAssetsManifest(["ssr", "rsc"]);
982
- } catch (err: any) {
983
- console.warn(
984
- `[rsc-router] Failed to write assets manifest early: ${err.message}`
985
- );
986
- }
987
-
988
- console.log(
989
- `[rsc-router] Pre-rendering ${urlsToRender.length} route(s)...`
990
- );
991
-
992
- // Generate a temporary script that runs in a clean Node.js process.
993
- // This avoids Vite's module resolution hooks interfering with imports.
994
- const scriptPath = resolve(projectRoot, "dist/.prerender.mjs");
995
- const scriptContent = generatePrerenderScript(projectRoot, urlsToRender, prerenderRouteHashMap);
996
- writeFileSync(scriptPath, scriptContent);
997
-
998
- try {
999
- const { execFileSync } = await import("node:child_process");
1000
- // Clear NODE_OPTIONS and tsx loader flags to prevent Vite's module
1001
- // resolution hooks from being inherited by the child process.
1002
- const cleanEnv = { ...process.env };
1003
- delete cleanEnv.NODE_OPTIONS;
1004
- delete cleanEnv.TSX;
1005
- execFileSync(process.execPath, ["--no-warnings", scriptPath], {
1006
- stdio: "inherit",
1007
- cwd: projectRoot,
1008
- env: cleanEnv,
1009
- });
1010
-
1011
- // Surgically replace handler function bodies with stubs in the chunk.
1012
- // The chunk also contains framework code (shared deps) that must stay intact.
1013
- // We replace each createPrerenderHandler(...) call with a stub object and
1014
- // remove the $$id assignment line.
1015
- const chunkInfo = cfIntegrationApi?.handlerChunkInfo;
1016
- if (chunkInfo) {
1017
- const chunkPath = resolve(projectRoot, "dist/rsc", chunkInfo.fileName);
1018
- try {
1019
- let code = readFileSync(chunkPath, "utf-8");
1020
- const originalSize = Buffer.byteLength(code);
1021
-
1022
- for (const { name, handlerId, passthrough } of chunkInfo.exports) {
1023
- // Passthrough handlers stay in the bundle for live fallback
1024
- if (passthrough) continue;
1025
- // Find start: "const Name = createPrerenderHandler"
1026
- // \s* handles both minified and readable output
1027
- const callStartRe = new RegExp(
1028
- `const\\s+${name}\\s*=\\s*createPrerenderHandler\\s*(?:<[^>]*>)?\\s*\\(`,
1029
- );
1030
- const startMatch = callStartRe.exec(code);
1031
- if (!startMatch) continue;
1032
-
1033
- // Use paren-depth counting to find the matching close paren.
1034
- // This is more robust than searching for the handlerId string,
1035
- // which could appear elsewhere in the chunk.
1036
- const openParenPos = startMatch.index + startMatch[0].length;
1037
- let depth = 1;
1038
- let pos = openParenPos;
1039
- while (pos < code.length && depth > 0) {
1040
- const ch = code[pos];
1041
- if (ch === '"' || ch === "'" || ch === "`") {
1042
- pos++;
1043
- while (pos < code.length && code[pos] !== ch) {
1044
- if (code[pos] === "\\") pos++;
1045
- pos++;
1046
- }
1047
- } else if (ch === "(") {
1048
- depth++;
1049
- } else if (ch === ")") {
1050
- depth--;
1051
- }
1052
- pos++;
1053
- }
1054
- if (depth !== 0) continue;
1055
-
1056
- // pos is now after the closing paren. Skip trailing semicolon.
1057
- let rangeEnd = pos;
1058
- while (rangeEnd < code.length && /\s/.test(code[rangeEnd])) rangeEnd++;
1059
- if (code[rangeEnd] === ";") rangeEnd++;
1060
-
1061
- // Validate: the matched range should contain the expected handlerId
1062
- const matched = code.slice(startMatch.index, rangeEnd);
1063
- if (!matched.includes(handlerId)) continue;
1064
-
1065
- const stub = `const ${name} = { __brand: "prerenderHandler", $$id: "${handlerId}" };`;
1066
- code = code.slice(0, startMatch.index) + stub + code.slice(rangeEnd);
1067
-
1068
- // Remove the $$id assignment line (now redundant)
1069
- code = code.replace(
1070
- new RegExp(`\\n${name}\\.\\$\\$id\\s*=\\s*"[^"]+";`),
1071
- "",
1072
- );
1073
- }
1074
-
1075
- writeFileSync(chunkPath, code);
1076
- const newSize = Buffer.byteLength(code);
1077
- const savedKB = ((originalSize - newSize) / 1024).toFixed(1);
1078
- console.log(
1079
- `[rsc-router] Evicted handler code from RSC bundle (${savedKB} KB saved): ${chunkInfo.fileName}`,
1080
- );
1081
- } catch (replaceErr: any) {
1082
- console.warn(
1083
- `[rsc-router] Failed to evict handler code: ${replaceErr.message}`,
1084
- );
1085
- }
1086
- }
1087
- // Inject pre-rendered data into the RSC worker bundle.
1088
- // Read all .flight files written by the child process and embed them
1089
- // as globalThis.__PRERENDER_DATA so the worker can serve them at runtime.
1090
- try {
1091
- const { readdirSync: readDir } = await import("node:fs");
1092
- const prerenderData: Record<string, any> = {};
1093
- const staticDir = resolve(projectRoot, "dist/static");
1094
- for (const hashDir of readDir(staticDir).filter((d: string) => d.startsWith("__"))) {
1095
- const prerenderDir = resolve(staticDir, hashDir, "prerender");
1096
- if (!existsSync(prerenderDir)) continue;
1097
- for (const routeDir of readDir(prerenderDir)) {
1098
- const routePath = resolve(prerenderDir, routeDir);
1099
- for (const file of readDir(routePath).filter((f: string) => f.endsWith(".flight"))) {
1100
- const paramHash = file.slice(0, -7); // strip ".flight"
1101
- const key = `${routeDir}/${paramHash}`;
1102
- const content = readFileSync(resolve(routePath, file), "utf-8");
1103
- prerenderData[key] = JSON.parse(content);
1104
- }
1105
- }
1106
- }
1107
-
1108
- if (Object.keys(prerenderData).length > 0) {
1109
- const rscEntryPath = resolve(projectRoot, "dist/rsc/index.js");
1110
- if (existsSync(rscEntryPath)) {
1111
- let rscCode = readFileSync(rscEntryPath, "utf-8");
1112
- const injection = `globalThis.__PRERENDER_DATA = ${JSON.stringify(prerenderData)};\n`;
1113
- rscCode = injection + rscCode;
1114
- writeFileSync(rscEntryPath, rscCode);
1115
- const dataSize = (Buffer.byteLength(injection) / 1024).toFixed(1);
1116
- console.log(
1117
- `[rsc-router] Injected prerender data into RSC bundle (${dataSize} KB, ${Object.keys(prerenderData).length} entries)`,
1118
- );
1119
- }
1120
- }
1121
- } catch (injectErr: any) {
1122
- console.warn(
1123
- `[rsc-router] Failed to inject prerender data: ${injectErr.message}`,
1124
- );
1125
- }
1126
- } catch (err: any) {
1127
- console.warn(
1128
- `[rsc-router] Build-time pre-rendering failed: ${err.message}`
1129
- );
1130
- } finally {
1131
- // Clean up the temporary script
1132
- try {
1133
- const { rmSync } = await import("node:fs");
1134
- rmSync(scriptPath, { force: true });
1135
- } catch {}
1136
- }
1137
- },
1138
- },
1139
- };
1140
- }
1141
-
1142
- /**
1143
- * Generate a standalone Node.js script that collects serialized segment data
1144
- * for pre-rendered routes. Writes .flight JSON files to dist/static/.
1145
- * The script runs in a separate process to avoid Vite's module resolution hooks.
1146
- */
1147
- function generatePrerenderScript(
1148
- projectRoot: string,
1149
- urls: string[],
1150
- routeHashMap: Record<string, string>,
1151
- ): string {
1152
- return `
1153
- import { mkdirSync, writeFileSync, symlinkSync, existsSync, readdirSync, statSync, lstatSync, rmSync } from "node:fs";
1154
- import { resolve } from "node:path";
1155
-
1156
- const projectRoot = ${JSON.stringify(projectRoot)};
1157
- const urls = ${JSON.stringify(urls)};
1158
- const routeHashMap = ${JSON.stringify(routeHashMap)};
1159
-
1160
- // DJB2 hash matching the runtime param-hash utility
1161
- function djb2Hex(str) {
1162
- let hash = 5381;
1163
- for (let i = 0; i < str.length; i++) {
1164
- hash = ((hash << 5) + hash + str.charCodeAt(i)) >>> 0;
1165
- }
1166
- return hash.toString(16).padStart(8, "0");
1167
- }
1168
-
1169
- function hashParams(params) {
1170
- const entries = Object.entries(params);
1171
- if (entries.length === 0) return "_";
1172
- const sorted = entries.sort(([a], [b]) => a.localeCompare(b));
1173
- const str = sorted.map(([k, v]) => k + "=" + v).join("&");
1174
- return djb2Hex(str);
1175
- }
1176
-
1177
- // Extract params from a URL by matching against the route pattern.
1178
- // The route pattern uses :paramName syntax.
1179
- function extractParams(urlPath, pattern) {
1180
- const urlParts = urlPath.split("/").filter(Boolean);
1181
- const patternParts = pattern.split("/").filter(Boolean);
1182
- const params = {};
1183
- for (let i = 0; i < patternParts.length; i++) {
1184
- if (patternParts[i].startsWith(":")) {
1185
- const paramName = patternParts[i].slice(1);
1186
- params[paramName] = decodeURIComponent(urlParts[i] || "");
1187
- }
1188
- }
1189
- return params;
1190
- }
1191
-
1192
- // Mock workerd globals (bundled worker accesses globalThis.Cloudflare.compatibilityFlags)
1193
- globalThis.Cloudflare = { compatibilityFlags: { enable_nodejs_process_v2: false } };
1194
-
1195
- // Create symlinks for project root directories under dist/ so that relative
1196
- // paths from import.meta.dirname (dist/rsc/assets/) resolve correctly.
1197
- const symlinks = [];
1198
- try {
1199
- for (const entry of readdirSync(projectRoot)) {
1200
- if (entry === "dist" || entry === "node_modules" || entry.startsWith(".")) continue;
1201
- const target = resolve(projectRoot, entry);
1202
- const link = resolve(projectRoot, "dist", entry);
1203
- try {
1204
- if (!existsSync(link) && statSync(target).isDirectory()) {
1205
- symlinkSync(target, link);
1206
- symlinks.push(link);
1207
- }
1208
- } catch {}
1209
- }
1210
- } catch {}
1211
-
1212
- const mockEnv = new Proxy({}, {
1213
- get(_, prop) {
1214
- if (prop === "toString" || prop === Symbol.toPrimitive) return () => "[PrerenderEnv]";
1215
- if (prop === Symbol.toStringTag) return "PrerenderEnv";
1216
- if (prop === "Variables") return {};
1217
- if (prop === "ASSETS") return { fetch: () => new Response("", { status: 404 }) };
1218
- throw new Error("Cloudflare binding \\"" + String(prop) + "\\" not available in prerender");
1219
- },
1220
- });
1221
- const mockCtx = { waitUntil: () => {}, passThroughOnException: () => {} };
1222
-
1223
- try {
1224
- const mod = await import(resolve(projectRoot, "dist/rsc/index.js"));
1225
- const worker = mod.default;
1226
- if (!worker?.fetch) {
1227
- console.warn("[rsc-router] Built worker has no fetch handler, skipping pre-render");
1228
- process.exit(0);
1229
- }
1230
-
1231
- let rendered = 0;
1232
- for (const urlPath of urls) {
1233
- try {
1234
- // Collect serialized segments for this route
1235
- const response = await worker.fetch(
1236
- new Request("http://localhost" + urlPath + "?__no_cache&__prerender_collect", {
1237
- headers: { Accept: "text/html" },
1238
- }),
1239
- mockEnv,
1240
- mockCtx,
1241
- );
1242
- if (response.status !== 200) {
1243
- console.warn("[rsc-router] Pre-render collect " + urlPath + " returned " + response.status + ", skipping");
1244
- continue;
1245
- }
1246
- const data = await response.json();
1247
- const { segments, handles, routeName } = data;
1248
- if (!routeName || !segments) {
1249
- console.warn("[rsc-router] Pre-render collect " + urlPath + " missing routeName or segments, skipping");
1250
- continue;
1251
- }
1252
-
1253
- const routerHash = routeHashMap[routeName];
1254
- if (!routerHash) {
1255
- console.warn("[rsc-router] No router hash for route " + routeName + ", skipping");
1256
- continue;
1257
- }
1258
-
1259
- // Compute param hash from the matched route params
1260
- // The response carries routeName; we compute params from the URL
1261
- // using the route manifest pattern. For static routes, paramHash is "_".
1262
- const paramHash = hashParams(data.params || {});
1263
-
1264
- // Write .flight file
1265
- const flightDir = resolve(projectRoot, "dist", "static",
1266
- "__" + routerHash, "prerender", routeName);
1267
- mkdirSync(flightDir, { recursive: true });
1268
- const flightPath = resolve(flightDir, paramHash + ".flight");
1269
- writeFileSync(flightPath, JSON.stringify({ segments, handles }));
1270
-
1271
- rendered++;
1272
- console.log("[rsc-router] Pre-rendered: " + routeName + " (" + urlPath + ") -> " + paramHash + ".flight");
1273
- } catch (err) {
1274
- console.warn("[rsc-router] Pre-render failed for " + urlPath + ": " + err.message);
1275
- }
1276
- }
1277
-
1278
- if (rendered > 0) {
1279
- console.log("[rsc-router] Pre-rendered " + rendered + "/" + urls.length + " route(s) to dist/static/");
1280
- }
1281
- } finally {
1282
- for (const link of symlinks) {
1283
- try { if (lstatSync(link).isSymbolicLink()) rmSync(link); } catch {}
1284
- }
1285
- }
1286
- `.trim();
1287
- }
1288
-
1289
- const VIRTUAL_ROUTES_MANIFEST_ID = "virtual:rsc-router/routes-manifest";
1290
- // VIRTUAL_PRERENDER_PATHS_ID removed: prerender data is served through the worker
1291
-
1292
- /**
1293
- * Resolve the entry path for build-time router discovery.
1294
- * - Node preset: uses the required `router` option.
1295
- * - Cloudflare preset: reads the `main` field from wrangler.json.
1296
- */
1297
- function resolveDiscoveryEntryPath(options: RangoOptions): string | undefined {
1298
- if (options.preset === "cloudflare") {
1299
- // Auto-detect from wrangler.json
1300
- const wranglerPaths = ["wrangler.json", "wrangler.jsonc"];
1301
- for (const filename of wranglerPaths) {
1302
- if (existsSync(filename)) {
1303
- try {
1304
- const raw = readFileSync(filename, "utf-8");
1305
- // Strip JSON comments for .jsonc
1306
- const cleaned = raw.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
1307
- const config = JSON.parse(cleaned);
1308
- if (config.main) {
1309
- return config.main;
1310
- }
1311
- } catch {
1312
- // Ignore parse errors
1313
- }
1314
- }
1315
- }
1316
- return undefined;
1317
- }
1318
- // Node preset: router is required
1319
- return (options as RangoNodeOptions).router;
1320
- }
1321
-
1322
- /**
1323
- * Stub plugin for virtual modules in the temp discovery server.
1324
- * The RSC entry may import virtual modules (routes-manifest, loader-manifest)
1325
- * that aren't available in the temp server. The RSC plugin also requires
1326
- * client/ssr entries which don't need real content for discovery.
1327
- */
1328
- function createVirtualStubPlugin(): Plugin {
1329
- const STUB_PREFIXES = [
1330
- "virtual:rsc-router/",
1331
- "virtual:entry-",
1332
- "virtual:vite-rsc/",
1333
- ];
1334
- return {
1335
- name: "@rangojs/router:virtual-stubs",
1336
- resolveId(id) {
1337
- if (STUB_PREFIXES.some((p) => id.startsWith(p))) {
1338
- return "\0stub:" + id;
1339
- }
1340
- return null;
1341
- },
1342
- load(id) {
1343
- if (id.startsWith("\0stub:")) {
1344
- return "export default {}";
1345
- }
1346
- return null;
1347
- },
1348
- };
1349
- }
1350
-
1351
- /**
1352
- * Generate a deterministic 12-char hex hash from a router id.
1353
- * Used to create collision-free directory names for per-router static output.
1354
- */
1355
- function hashRouterId(id: string): string {
1356
- return createHash("sha256").update(id).digest("hex").slice(0, 12);
1357
- }
1358
-
1359
- /**
1360
- * Plugin that auto-injects VERSION and routes-manifest into custom entry.rsc files.
1361
- * If a custom entry.rsc file uses createRSCHandler but doesn't pass version,
1362
- * this transform adds the import and property automatically.
1363
- * Also ensures the routes-manifest virtual module is always imported.
1364
- * @internal
1365
- */
1366
- function createVersionInjectorPlugin(rscEntryPath: string): Plugin {
1367
- let projectRoot = "";
1368
- let resolvedEntryPath = "";
1369
-
1370
- return {
1371
- name: "@rangojs/router:version-injector",
1372
- enforce: "pre",
1373
-
1374
- configResolved(config) {
1375
- projectRoot = config.root;
1376
- resolvedEntryPath = resolve(projectRoot, rscEntryPath);
1377
- },
1378
-
1379
- transform(code, id) {
1380
- // Only transform the RSC entry file
1381
- const normalizedId = Vite.normalizePath(id);
1382
- const normalizedEntry = Vite.normalizePath(resolvedEntryPath);
1383
-
1384
- if (normalizedId !== normalizedEntry) {
1385
- return null;
1386
- }
1387
-
1388
- // Prepend imports at the top of the file. ES imports are hoisted
1389
- // by the module system, so source position is irrelevant.
1390
- const prepend: string[] = [];
1391
- let newCode = code;
1392
-
1393
- if (!code.includes("virtual:rsc-router/routes-manifest")) {
1394
- prepend.push(`import "virtual:rsc-router/routes-manifest";`);
1395
- }
1396
-
1397
- // Auto-inject VERSION if file uses createRSCHandler without version
1398
- const needsVersion =
1399
- code.includes("createRSCHandler") &&
1400
- !code.includes("@rangojs/router:version") &&
1401
- /createRSCHandler\s*\(\s*\{/.test(code);
1402
-
1403
- if (needsVersion) {
1404
- prepend.push(`import { VERSION } from "@rangojs/router:version";`);
1405
- newCode = newCode.replace(
1406
- /createRSCHandler\s*\(\s*\{/,
1407
- "createRSCHandler({\n version: VERSION,"
1408
- );
1409
- }
1410
-
1411
- if (prepend.length === 0 && newCode === code) return null;
1412
-
1413
- newCode = prepend.join("\n") + (prepend.length > 0 ? "\n" : "") + newCode;
1414
-
1415
- return {
1416
- code: newCode,
1417
- map: null,
1418
- };
1419
- },
1420
- };
1421
- }
1422
-
1423
- const _require = createRequire(import.meta.url);
1424
- const _rangoVersion: string = _require("../../package.json").version;
1425
-
1426
- let _bannerPrinted = false;
1427
-
1428
- function printBanner(
1429
- mode: "dev" | "build" | "preview",
1430
- preset: string,
1431
- version: string
1432
- ): void {
1433
- if (_bannerPrinted) return;
1434
- _bannerPrinted = true;
1435
-
1436
- // ANSI codes
1437
- const dim = "\x1b[2m";
1438
- const bold = "\x1b[1m";
1439
- const reset = "\x1b[0m";
1440
-
1441
- const banner = `
1442
- ${dim} ✦ ✦ ✧. . .${reset}
1443
- ${dim} ╱${reset} ${bold}╔═╗${reset}${dim} * ╱ ✦ *${reset}
1444
- ${dim} ${reset}${bold}║ ║${reset} ${bold}╔═╗${reset}${dim} * ✧. ╱${reset}
1445
- ${dim} ${reset}${bold}╔╗ ║ ║ ║ ║${reset}${dim} * ╱${reset}
1446
- ${dim} ${reset}${bold}║║ ║ ║ ║ ║ ╦═╗╔═╗╔╗╔╔═╗╔═╗${reset}${dim} ✧ ✦${reset}
1447
- ${dim} ${reset}${bold}═╣║ ║ ╠═╝ ║ ╠╦╝╠═╣║║║║ ╦║ ║${reset}${dim} * ✧${reset}
1448
- ${dim} ${reset}${bold}║╚═╝ ╔═══╝ ╩╚═╩ ╩╝╚╝╚═╝╚═╝${reset}${dim} ✦ . *${reset}
1449
- ${dim} ${reset}${bold}╚══╗ ║${reset}${dim} * RSC Wrangler ✧ ✦${reset}
1450
- ${dim} * ${reset}${bold}║ ╠═${reset}${dim} * ✧. ╱${reset}
1451
- ${bold}══════╝ ╚═════════╩═══${reset}${dim} ✦ *${reset}
1452
-
1453
- v${version} · ${preset} · ${mode}
1454
- `;
1455
-
1456
- console.log(banner);
1457
- }
1458
-
1459
1
  /**
1460
- * Vite plugin for @rangojs/router.
1461
- *
1462
- * Includes @vitejs/plugin-rsc and all necessary transforms for the router
1463
- * to function correctly with React Server Components.
2
+ * Public API for @rangojs/router/vite
1464
3
  *
1465
- * @example Node.js (default)
1466
- * ```ts
1467
- * export default defineConfig({
1468
- * plugins: [react(), rango({ router: './src/router.tsx' })],
1469
- * });
1470
- * ```
1471
- *
1472
- * @example Cloudflare Workers
1473
- * ```ts
1474
- * export default defineConfig({
1475
- * plugins: [
1476
- * react(),
1477
- * rango({ preset: 'cloudflare' }),
1478
- * cloudflare({ viteEnvironment: { name: 'rsc' } }),
1479
- * ],
1480
- * });
1481
- * ```
1482
- */
1483
- export async function rango(
1484
- options: RangoOptions
1485
- ): Promise<PluginOption[]> {
1486
- const preset = options.preset ?? "node";
1487
- const showBanner = options.banner ?? true;
1488
-
1489
- const plugins: PluginOption[] = [];
1490
-
1491
- // Get package resolution info (workspace vs npm install)
1492
- const rangoAliases = getPackageAliases();
1493
- const excludeDeps = getExcludeDeps();
1494
-
1495
- // Track RSC entry path for version injection
1496
- let rscEntryPath: string | null = null;
1497
-
1498
- // Build-time prerendering is always enabled for cloudflare preset.
1499
- // Handlers now run in the RSC env directly (no separate Node.js server needed).
1500
- const prerenderEnabled = preset === "cloudflare";
1501
-
1502
- if (preset === "cloudflare") {
1503
- // Cloudflare preset: configure entries for cloudflare worker setup
1504
- // Router is not needed here - worker.rsc.tsx imports it directly
1505
-
1506
- // Dynamically import @vitejs/plugin-rsc
1507
- const { default: rsc } = await import("@vitejs/plugin-rsc");
1508
-
1509
- // Only client and ssr entries - rsc entry is handled by cloudflare plugin
1510
- // Always use virtual modules for cloudflare preset
1511
- const finalEntries: { client: string; ssr: string } = {
1512
- client: VIRTUAL_IDS.browser,
1513
- ssr: VIRTUAL_IDS.ssr,
1514
- };
1515
-
1516
- const cfApi: CloudflareIntegrationApi = { handlerChunkInfo: null };
1517
- let resolvedPrerenderModules: Map<string, string[]> | undefined;
1518
-
1519
- plugins.push({
1520
- name: "@rangojs/router:cloudflare-integration",
1521
- enforce: "pre",
1522
-
1523
- api: cfApi,
1524
-
1525
- config() {
1526
- // Configure environments for cloudflare deployment
1527
- return {
1528
- // Exclude rsc-router modules from optimization to prevent module duplication
1529
- // This ensures the same Context instance is used by both browser entry and RSC proxy modules
1530
- optimizeDeps: {
1531
- exclude: excludeDeps,
1532
- esbuildOptions: sharedEsbuildOptions,
1533
- },
1534
- resolve: {
1535
- alias: rangoAliases,
1536
- },
1537
- environments: {
1538
- client: {
1539
- build: {
1540
- rollupOptions: {
1541
- output: {
1542
- manualChunks: getManualChunks,
1543
- },
1544
- },
1545
- },
1546
- // Pre-bundle rsc-html-stream to prevent discovery during first request
1547
- // Exclude rsc-router modules to ensure same Context instance
1548
- optimizeDeps: {
1549
- include: ["rsc-html-stream/client"],
1550
- exclude: excludeDeps,
1551
- esbuildOptions: sharedEsbuildOptions,
1552
- },
1553
- },
1554
- ssr: {
1555
- // Build SSR inside RSC directory so wrangler can deploy self-contained dist/rsc
1556
- build: {
1557
- outDir: "./dist/rsc/ssr",
1558
- },
1559
- resolve: {
1560
- // Ensure single React instance in SSR child environment
1561
- dedupe: ["react", "react-dom"],
1562
- },
1563
- // Pre-bundle SSR entry and React for proper module linking with childEnvironments
1564
- // All deps must be listed to avoid late discovery triggering ERR_OUTDATED_OPTIMIZED_DEP
1565
- optimizeDeps: {
1566
- entries: [finalEntries.ssr],
1567
- include: [
1568
- "react",
1569
- "react-dom",
1570
- "react-dom/server.edge",
1571
- "react-dom/static.edge",
1572
- "react/jsx-runtime",
1573
- "react/jsx-dev-runtime",
1574
- "rsc-html-stream/server",
1575
- "@vitejs/plugin-rsc/vendor/react-server-dom/client.edge",
1576
- ],
1577
- exclude: excludeDeps,
1578
- esbuildOptions: sharedEsbuildOptions,
1579
- },
1580
- },
1581
- rsc: {
1582
- build: {
1583
- rollupOptions: {
1584
- output: {
1585
- manualChunks(id) {
1586
- if (resolvedPrerenderModules?.has(id)) {
1587
- return "__prerender-handlers";
1588
- }
1589
- },
1590
- },
1591
- },
1592
- },
1593
- // RSC environment needs exclude list and esbuild options
1594
- // Exclude rsc-router modules to prevent createContext in RSC environment
1595
- optimizeDeps: {
1596
- exclude: excludeDeps,
1597
- esbuildOptions: sharedEsbuildOptions,
1598
- },
1599
- },
1600
- },
1601
- };
1602
- },
1603
-
1604
- configResolved(config) {
1605
- if (showBanner) {
1606
- const mode = config.command === "serve" ? (process.argv.includes("preview") ? "preview" : "dev") : "build";
1607
- printBanner(mode, "cloudflare", _rangoVersion);
1608
- }
1609
- // Resolve prerenderHandlerModules from the prerender handler plugin's API.
1610
- // This avoids module-level shared state between plugins.
1611
- const prerenderPlugin = config.plugins.find(
1612
- (p) => p.name === "@rangojs/router:expose-prerender-handler-id",
1613
- );
1614
- resolvedPrerenderModules =
1615
- (prerenderPlugin?.api as ExposePrerenderHandlerIdApi | undefined)?.prerenderHandlerModules;
1616
- },
1617
-
1618
- // Record handler chunk metadata during RSC build for post-prerender replacement.
1619
- // Rollup minifies EXPORT names (e.g. ArticlesIndex -> r) but keeps internal
1620
- // variable names intact. We search for original names from prerenderHandlerModules.
1621
- generateBundle(_options, bundle) {
1622
- if (this.environment?.name !== "rsc") return;
1623
- if (!resolvedPrerenderModules?.size) return;
1624
-
1625
- for (const [fileName, chunk] of Object.entries(bundle)) {
1626
- if (chunk.type !== "chunk") continue;
1627
- if (!fileName.includes("__prerender-handlers")) continue;
1628
-
1629
- const handlers: Array<{ name: string; handlerId: string; passthrough: boolean }> = [];
1630
- for (const [, handlerNames] of resolvedPrerenderModules) {
1631
- for (const name of handlerNames) {
1632
- const idPattern = new RegExp(
1633
- `\\b${name}\\.\\$\\$id\\s*=\\s*"([^"]+)"`,
1634
- );
1635
- const match = chunk.code.match(idPattern);
1636
- if (match) {
1637
- // Detect passthrough option in the createPrerenderHandler call.
1638
- // Find the call range for this handler and check for passthrough within it.
1639
- const callStartRe = new RegExp(
1640
- `const\\s+${name}\\s*=\\s*createPrerenderHandler\\s*(?:<[^>]*>)?\\s*\\(`,
1641
- );
1642
- const callStart = callStartRe.exec(chunk.code);
1643
- let isPassthrough = false;
1644
- if (callStart) {
1645
- // Use paren-depth counting to find the call range
1646
- const openPos = callStart.index + callStart[0].length;
1647
- let depth = 1;
1648
- let p = openPos;
1649
- while (p < chunk.code.length && depth > 0) {
1650
- const ch = chunk.code[p];
1651
- if (ch === '"' || ch === "'" || ch === "`") {
1652
- p++;
1653
- while (p < chunk.code.length && chunk.code[p] !== ch) {
1654
- if (chunk.code[p] === "\\") p++;
1655
- p++;
1656
- }
1657
- } else if (ch === "(") {
1658
- depth++;
1659
- } else if (ch === ")") {
1660
- depth--;
1661
- }
1662
- p++;
1663
- }
1664
- if (depth === 0) {
1665
- const callBody = chunk.code.slice(callStart.index, p);
1666
- isPassthrough = /passthrough\s*:\s*(!0|true)/.test(callBody);
1667
- }
1668
- }
1669
- handlers.push({ name, handlerId: match[1], passthrough: isPassthrough });
1670
- }
1671
- }
1672
- }
1673
-
1674
- if (handlers.length > 0) {
1675
- cfApi.handlerChunkInfo = { fileName, exports: handlers };
1676
- }
1677
- break;
1678
- }
1679
- },
1680
-
1681
- });
1682
-
1683
- plugins.push(createVirtualEntriesPlugin(finalEntries));
1684
-
1685
- // Add RSC plugin with cloudflare-specific options
1686
- // Note: loadModuleDevProxy should NOT be used with childEnvironments
1687
- // since SSR runs in workerd alongside RSC
1688
- plugins.push(
1689
- rsc({
1690
- get entries() {
1691
- return finalEntries;
1692
- },
1693
- serverHandler: false,
1694
- }) as PluginOption
1695
- );
1696
- } else {
1697
- // Node preset: full RSC plugin integration
1698
- const nodeOptions = options as RangoNodeOptions;
1699
- const routerPath = nodeOptions.router;
1700
- const rscOption = nodeOptions.rsc ?? true;
1701
-
1702
- // Add RSC plugin by default (can be disabled with rsc: false)
1703
- if (rscOption !== false) {
1704
- // Dynamically import @vitejs/plugin-rsc
1705
- const { default: rsc } = await import("@vitejs/plugin-rsc");
1706
-
1707
- // Resolve entry paths: use explicit config or virtual modules
1708
- const userEntries =
1709
- typeof rscOption === "boolean" ? {} : rscOption.entries || {};
1710
- const finalEntries = {
1711
- client: userEntries.client ?? VIRTUAL_IDS.browser,
1712
- ssr: userEntries.ssr ?? VIRTUAL_IDS.ssr,
1713
- rsc: userEntries.rsc ?? VIRTUAL_IDS.rsc,
1714
- };
1715
-
1716
- // Track RSC entry for version injection (only if custom entry provided)
1717
- rscEntryPath = userEntries.rsc ?? null;
1718
-
1719
- // Create wrapper plugin that checks for duplicates
1720
- let hasWarnedDuplicate = false;
1721
-
1722
- plugins.push({
1723
- name: "@rangojs/router:rsc-integration",
1724
- enforce: "pre",
1725
-
1726
- config() {
1727
- // Configure environments for RSC
1728
- // When using virtual entries, we need to explicitly configure optimizeDeps
1729
- // so Vite pre-bundles React before processing the virtual modules.
1730
- // Without this, the dep optimizer may run multiple times with different hashes,
1731
- // causing React instance mismatches.
1732
- const useVirtualClient = finalEntries.client === VIRTUAL_IDS.browser;
1733
- const useVirtualSSR = finalEntries.ssr === VIRTUAL_IDS.ssr;
1734
- const useVirtualRSC = finalEntries.rsc === VIRTUAL_IDS.rsc;
1735
-
1736
- return {
1737
- // Exclude rsc-router modules from optimization to prevent module duplication
1738
- // This ensures the same Context instance is used by both browser entry and RSC proxy modules
1739
- optimizeDeps: {
1740
- exclude: excludeDeps,
1741
- esbuildOptions: sharedEsbuildOptions,
1742
- },
1743
- resolve: {
1744
- alias: rangoAliases,
1745
- },
1746
- environments: {
1747
- client: {
1748
- build: {
1749
- rollupOptions: {
1750
- output: {
1751
- manualChunks: getManualChunks,
1752
- },
1753
- },
1754
- },
1755
- // Always exclude rsc-router modules, conditionally add virtual entry
1756
- optimizeDeps: {
1757
- exclude: excludeDeps,
1758
- esbuildOptions: sharedEsbuildOptions,
1759
- ...(useVirtualClient && {
1760
- // Tell Vite to scan the virtual entry for dependencies
1761
- entries: [VIRTUAL_IDS.browser],
1762
- }),
1763
- },
1764
- },
1765
- ...(useVirtualSSR && {
1766
- ssr: {
1767
- optimizeDeps: {
1768
- entries: [VIRTUAL_IDS.ssr],
1769
- // Pre-bundle all SSR deps to prevent late discovery triggering ERR_OUTDATED_OPTIMIZED_DEP
1770
- include: [
1771
- "react",
1772
- "react-dom",
1773
- "react-dom/server.edge",
1774
- "react-dom/static.edge",
1775
- "react/jsx-runtime",
1776
- "react/jsx-dev-runtime",
1777
- "@vitejs/plugin-rsc/vendor/react-server-dom/client.edge",
1778
- ],
1779
- exclude: excludeDeps,
1780
- esbuildOptions: sharedEsbuildOptions,
1781
- },
1782
- },
1783
- }),
1784
- ...(useVirtualRSC && {
1785
- rsc: {
1786
- optimizeDeps: {
1787
- entries: [VIRTUAL_IDS.rsc],
1788
- // Pre-bundle React for RSC to ensure single instance
1789
- include: ["react", "react/jsx-runtime"],
1790
- esbuildOptions: sharedEsbuildOptions,
1791
- },
1792
- },
1793
- }),
1794
- },
1795
- };
1796
- },
1797
-
1798
- configResolved(config) {
1799
- if (showBanner) {
1800
- const mode = config.command === "serve" ? (process.argv.includes("preview") ? "preview" : "dev") : "build";
1801
- printBanner(mode, "node", _rangoVersion);
1802
- }
1803
-
1804
- // Count how many RSC base plugins there are (rsc:minimal is the main one)
1805
- const rscMinimalCount = config.plugins.filter(
1806
- (p) => p.name === "rsc:minimal"
1807
- ).length;
1808
-
1809
- if (rscMinimalCount > 1 && !hasWarnedDuplicate) {
1810
- hasWarnedDuplicate = true;
1811
- console.warn(
1812
- "[rsc-router] Duplicate @vitejs/plugin-rsc detected. " +
1813
- "Remove rsc() from your config or use rango({ rsc: false }) for manual configuration."
1814
- );
1815
- }
1816
- },
1817
- });
1818
-
1819
- // Add virtual entries plugin
1820
- plugins.push(createVirtualEntriesPlugin(finalEntries, routerPath));
1821
-
1822
- // Add the RSC plugin directly
1823
- // Cast to PluginOption to handle type differences between bundled vite types
1824
- plugins.push(
1825
- rsc({
1826
- entries: finalEntries,
1827
- }) as PluginOption
1828
- );
1829
- }
1830
- }
1831
-
1832
- plugins.push(exposeActionId());
1833
-
1834
- // Always add exposeLoaderId for GET-based loader fetching with useFetchLoader
1835
- plugins.push(exposeLoaderId());
1836
-
1837
- // Always add exposeHandleId for auto-generated handle IDs
1838
- plugins.push(exposeHandleId());
1839
-
1840
- // Always add exposeLocationStateId for auto-generated location state keys
1841
- plugins.push(exposeLocationStateId());
1842
-
1843
- // Always add exposePrerenderHandlerId for auto-generated prerender handler IDs
1844
- plugins.push(exposePrerenderHandlerId());
1845
-
1846
- // Add version virtual module plugin for cache invalidation
1847
- plugins.push(createVersionPlugin());
1848
-
1849
- // Resolve discovery entry path (used for both discovery and version injection).
1850
- // Node preset: uses the required router path.
1851
- // Cloudflare preset: auto-detects RSC entry from wrangler.json main field.
1852
- const discoveryEntryPath = resolveDiscoveryEntryPath(options);
1853
-
1854
- // Add version injector for custom entry.rsc files.
1855
- // For Cloudflare preset, the RSC entry is the worker file (from wrangler.json).
1856
- const injectorEntryPath = rscEntryPath ?? (preset === "cloudflare" ? discoveryEntryPath : null);
1857
- if (injectorEntryPath) {
1858
- plugins.push(createVersionInjectorPlugin(injectorEntryPath));
1859
- }
1860
-
1861
- // Transform CJS vendor files to ESM for browser compatibility
1862
- // optimizeDeps.include doesn't work because the file is loaded after initial optimization
1863
- plugins.push(createCjsToEsmPlugin());
1864
-
1865
- // Add router discovery plugin for build-time manifest generation.
1866
- if (discoveryEntryPath) {
1867
- plugins.push(createRouterDiscoveryPlugin(discoveryEntryPath, {
1868
- enableBuildPrerender: prerenderEnabled,
1869
- staticRouteTypesGeneration: options.staticRouteTypesGeneration,
1870
- }));
1871
- }
1872
-
1873
- return plugins;
1874
- }
1875
-
1876
-
1877
- /**
1878
- * Transform CJS vendor files from @vitejs/plugin-rsc to ESM for browser compatibility.
1879
- * The react-server-dom vendor files are shipped as CJS which doesn't work in browsers.
4
+ * Exports: rango() plugin factory, poke() dev utility plugin,
5
+ * and related option types. All other utilities are internal implementation
6
+ * details consumed via direct imports within the package.
1880
7
  */
1881
- function createCjsToEsmPlugin(): Plugin {
1882
- return {
1883
- name: "@rangojs/router:cjs-to-esm",
1884
- enforce: "pre",
1885
- transform(code, id) {
1886
- const cleanId = id.split("?")[0];
1887
-
1888
- // Transform the client.browser.js entry point to re-export from CJS
1889
- if (
1890
- cleanId.includes("vendor/react-server-dom/client.browser.js") ||
1891
- cleanId.includes("vendor\\react-server-dom\\client.browser.js")
1892
- ) {
1893
- const isProd = process.env.NODE_ENV === "production";
1894
- const cjsFile = isProd
1895
- ? "./cjs/react-server-dom-webpack-client.browser.production.js"
1896
- : "./cjs/react-server-dom-webpack-client.browser.development.js";
1897
-
1898
- return {
1899
- code: `export * from "${cjsFile}";`,
1900
- map: null,
1901
- };
1902
- }
1903
-
1904
- // Transform the actual CJS files to ESM
1905
- if (
1906
- (cleanId.includes("vendor/react-server-dom/cjs/") ||
1907
- cleanId.includes("vendor\\react-server-dom\\cjs\\")) &&
1908
- cleanId.includes("client.browser")
1909
- ) {
1910
- let transformed = code;
1911
-
1912
- // Extract the license comment to preserve it
1913
- const licenseMatch = transformed.match(/^\/\*\*[\s\S]*?\*\//);
1914
- const license = licenseMatch ? licenseMatch[0] : "";
1915
- if (license) {
1916
- transformed = transformed.slice(license.length);
1917
- }
1918
-
1919
- // Remove "use strict" (both dev and prod have this)
1920
- transformed = transformed.replace(/^\s*["']use strict["'];\s*/, "");
1921
-
1922
- // Remove the conditional IIFE wrapper (development only)
1923
- transformed = transformed.replace(
1924
- /^\s*["']production["']\s*!==\s*process\.env\.NODE_ENV\s*&&\s*\(function\s*\(\)\s*\{/,
1925
- ""
1926
- );
1927
-
1928
- // Remove the closing of the conditional IIFE at the end (development only)
1929
- transformed = transformed.replace(/\}\)\(\);?\s*$/, "");
1930
-
1931
- // Replace require('react') and require('react-dom') with imports (development)
1932
- transformed = transformed.replace(
1933
- /var\s+React\s*=\s*require\s*\(\s*["']react["']\s*\)\s*,[\s\n]+ReactDOM\s*=\s*require\s*\(\s*["']react-dom["']\s*\)\s*,/g,
1934
- 'import React from "react";\nimport ReactDOM from "react-dom";\nvar '
1935
- );
1936
-
1937
- // Replace require('react-dom') only (production - doesn't import React)
1938
- transformed = transformed.replace(
1939
- /var\s+ReactDOM\s*=\s*require\s*\(\s*["']react-dom["']\s*\)\s*,/g,
1940
- 'import ReactDOM from "react-dom";\nvar '
1941
- );
1942
-
1943
- // Transform exports.xyz = function() to export function xyz()
1944
- transformed = transformed.replace(
1945
- /exports\.(\w+)\s*=\s*function\s*\(/g,
1946
- "export function $1("
1947
- );
1948
-
1949
- // Transform exports.xyz = value to export const xyz = value
1950
- transformed = transformed.replace(
1951
- /exports\.(\w+)\s*=/g,
1952
- "export const $1 ="
1953
- );
1954
-
1955
- // Reconstruct with license at the top
1956
- transformed = license + "\n" + transformed;
1957
-
1958
- return {
1959
- code: transformed,
1960
- map: null,
1961
- };
1962
- }
1963
8
 
1964
- return null;
1965
- },
1966
- };
1967
- }
9
+ export { rango } from "./rango.js";
10
+ export { poke } from "./plugins/refresh-cmd.js";
1968
11
 
12
+ export type {
13
+ RangoNodeOptions,
14
+ RangoCloudflareOptions,
15
+ RangoOptions,
16
+ BuildEnvOption,
17
+ BuildEnvFactory,
18
+ BuildEnvFactoryContext,
19
+ BuildEnvResult,
20
+ } from "./plugin-types.js";