@rangojs/router 0.0.0-experimental.14 → 0.0.0-experimental.140

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 (460) hide show
  1. package/AGENTS.md +17 -0
  2. package/README.md +432 -7
  3. package/dist/bin/rango.js +2073 -213
  4. package/dist/testing/vitest.js +82 -0
  5. package/dist/vite/index.js +7258 -2714
  6. package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  7. package/package.json +140 -67
  8. package/skills/api-client/SKILL.md +211 -0
  9. package/skills/breadcrumbs/SKILL.md +329 -0
  10. package/skills/bundle-analysis/SKILL.md +159 -0
  11. package/skills/cache-guide/SKILL.md +487 -0
  12. package/skills/caching/SKILL.md +357 -25
  13. package/skills/comparison/SKILL.md +50 -0
  14. package/skills/comparison/agents/openai.yaml +4 -0
  15. package/skills/comparison/references/framework-comparison.md +837 -0
  16. package/skills/composability/SKILL.md +246 -0
  17. package/skills/css/SKILL.md +76 -0
  18. package/skills/debug-manifest/SKILL.md +16 -10
  19. package/skills/document-cache/SKILL.md +87 -62
  20. package/skills/fonts/SKILL.md +6 -4
  21. package/skills/handler-use/SKILL.md +364 -0
  22. package/skills/hooks/SKILL.md +557 -79
  23. package/skills/host-router/SKILL.md +320 -0
  24. package/skills/i18n/SKILL.md +276 -0
  25. package/skills/intercept/SKILL.md +207 -15
  26. package/skills/layout/SKILL.md +146 -6
  27. package/skills/links/SKILL.md +304 -25
  28. package/skills/loader/SKILL.md +616 -54
  29. package/skills/middleware/SKILL.md +217 -37
  30. package/skills/migrate-nextjs/SKILL.md +611 -0
  31. package/skills/migrate-react-router/SKILL.md +927 -0
  32. package/skills/mime-routes/SKILL.md +42 -11
  33. package/skills/observability/SKILL.md +194 -0
  34. package/skills/parallel/SKILL.md +284 -3
  35. package/skills/ppr/SKILL.md +426 -0
  36. package/skills/prerender/SKILL.md +437 -52
  37. package/skills/rango/SKILL.md +369 -22
  38. package/skills/react-compiler/SKILL.md +168 -0
  39. package/skills/response-routes/SKILL.md +263 -121
  40. package/skills/route/SKILL.md +350 -21
  41. package/skills/router-setup/SKILL.md +246 -33
  42. package/skills/scripts/SKILL.md +179 -0
  43. package/skills/server-actions/SKILL.md +775 -0
  44. package/skills/shell-manifest/SKILL.md +185 -0
  45. package/skills/streams-and-websockets/SKILL.md +283 -0
  46. package/skills/tailwind/SKILL.md +27 -3
  47. package/skills/testing/SKILL.md +126 -222
  48. package/skills/testing/bindings.md +103 -0
  49. package/skills/testing/cache-prerender.md +127 -0
  50. package/skills/testing/client-components.md +124 -0
  51. package/skills/testing/e2e-parity.md +125 -0
  52. package/skills/testing/flight.md +91 -0
  53. package/skills/testing/handles.md +131 -0
  54. package/skills/testing/loader.md +128 -0
  55. package/skills/testing/middleware.md +99 -0
  56. package/skills/testing/render-handler.md +122 -0
  57. package/skills/testing/response-routes.md +95 -0
  58. package/skills/testing/reverse-and-types.md +85 -0
  59. package/skills/testing/server-actions.md +107 -0
  60. package/skills/testing/server-tree.md +128 -0
  61. package/skills/testing/setup.md +123 -0
  62. package/skills/theme/SKILL.md +9 -8
  63. package/skills/typesafety/SKILL.md +532 -103
  64. package/skills/use-cache/SKILL.md +367 -0
  65. package/skills/vercel/SKILL.md +128 -0
  66. package/skills/view-transitions/SKILL.md +337 -0
  67. package/src/__augment-tests__/augment.ts +81 -0
  68. package/src/__augment-tests__/augmented.check.ts +116 -0
  69. package/src/__internal.ts +77 -44
  70. package/src/bin/rango.ts +312 -15
  71. package/src/browser/action-coordinator.ts +114 -0
  72. package/src/browser/action-fence.ts +47 -0
  73. package/src/browser/app-shell.ts +39 -0
  74. package/src/browser/app-version.ts +14 -0
  75. package/src/browser/connection-warmup.ts +134 -0
  76. package/src/browser/cookie-name.ts +140 -0
  77. package/src/browser/event-controller.ts +293 -202
  78. package/src/browser/history-state.ts +101 -0
  79. package/src/browser/index.ts +3 -3
  80. package/src/browser/intercept-utils.ts +52 -0
  81. package/src/browser/invalidate-client-cache.ts +52 -0
  82. package/src/browser/link-interceptor.ts +24 -4
  83. package/src/browser/logging.ts +11 -0
  84. package/src/browser/merge-segment-loaders.ts +20 -12
  85. package/src/browser/navigation-bridge.ts +385 -576
  86. package/src/browser/navigation-client.ts +245 -75
  87. package/src/browser/navigation-store-handle.ts +38 -0
  88. package/src/browser/navigation-store.ts +184 -118
  89. package/src/browser/navigation-transaction.ts +247 -0
  90. package/src/browser/network-error-handler.ts +88 -0
  91. package/src/browser/partial-update.ts +412 -364
  92. package/src/browser/prefetch/cache.ts +359 -0
  93. package/src/browser/prefetch/fetch.ts +452 -0
  94. package/src/browser/prefetch/observer.ts +65 -0
  95. package/src/browser/prefetch/policy.ts +48 -0
  96. package/src/browser/prefetch/queue.ts +209 -0
  97. package/src/browser/prefetch/resource-ready.ts +77 -0
  98. package/src/browser/rango-state.ts +194 -0
  99. package/src/browser/react/Link.tsx +275 -68
  100. package/src/browser/react/NavigationProvider.tsx +265 -109
  101. package/src/browser/react/ScrollRestoration.tsx +10 -6
  102. package/src/browser/react/context.ts +11 -0
  103. package/src/browser/react/filter-segment-order.ts +70 -0
  104. package/src/browser/react/index.ts +0 -48
  105. package/src/browser/react/location-state-shared.ts +272 -60
  106. package/src/browser/react/location-state.ts +90 -20
  107. package/src/browser/react/mount-context.ts +6 -1
  108. package/src/browser/react/nonce-context.ts +23 -0
  109. package/src/browser/react/shallow-equal.ts +27 -0
  110. package/src/browser/react/use-action.ts +35 -66
  111. package/src/browser/react/use-handle.ts +39 -126
  112. package/src/browser/react/use-href.tsx +8 -1
  113. package/src/browser/react/use-link-status.ts +39 -13
  114. package/src/browser/react/use-navigation.ts +53 -69
  115. package/src/browser/react/use-params.ts +75 -0
  116. package/src/browser/react/use-pathname.ts +47 -0
  117. package/src/browser/react/use-reverse.ts +106 -0
  118. package/src/browser/react/use-router.ts +98 -0
  119. package/src/browser/react/use-search-params.ts +51 -0
  120. package/src/browser/react/use-segments.ts +72 -99
  121. package/src/browser/response-adapter.ts +164 -0
  122. package/src/browser/rsc-router.tsx +300 -72
  123. package/src/browser/scroll-restoration.ts +138 -50
  124. package/src/browser/segment-reconciler.ts +243 -0
  125. package/src/browser/segment-structure-assert.ts +17 -1
  126. package/src/browser/server-action-bridge.ts +668 -613
  127. package/src/browser/types.ts +223 -51
  128. package/src/browser/validate-redirect-origin.ts +56 -0
  129. package/src/build/collect-fallback-refs.ts +107 -0
  130. package/src/build/generate-manifest.ts +252 -161
  131. package/src/build/generate-route-types.ts +41 -1038
  132. package/src/build/index.ts +12 -7
  133. package/src/build/prefix-tree-utils.ts +123 -0
  134. package/src/build/route-trie.ts +225 -42
  135. package/src/build/route-types/ast-helpers.ts +25 -0
  136. package/src/build/route-types/ast-route-extraction.ts +105 -0
  137. package/src/build/route-types/codegen.ts +113 -0
  138. package/src/build/route-types/include-resolution.ts +812 -0
  139. package/src/build/route-types/param-extraction.ts +51 -0
  140. package/src/build/route-types/per-module-writer.ts +144 -0
  141. package/src/build/route-types/router-processing.ts +695 -0
  142. package/src/build/route-types/scan-filter.ts +85 -0
  143. package/src/build/route-types/source-scan.ts +216 -0
  144. package/src/build/runtime-discovery.ts +223 -0
  145. package/src/cache/background-task.ts +34 -0
  146. package/src/cache/cache-error.ts +104 -0
  147. package/src/cache/cache-key-utils.ts +60 -0
  148. package/src/cache/cache-policy.ts +199 -0
  149. package/src/cache/cache-runtime.ts +525 -0
  150. package/src/cache/cache-scope.ts +298 -332
  151. package/src/cache/cache-tag.ts +103 -0
  152. package/src/cache/cf/cf-base64.ts +33 -0
  153. package/src/cache/cf/cf-cache-constants.ts +127 -0
  154. package/src/cache/cf/cf-cache-store.ts +2500 -158
  155. package/src/cache/cf/cf-cache-types.ts +349 -0
  156. package/src/cache/cf/cf-kv-utils.ts +46 -0
  157. package/src/cache/cf/cf-tag-marker-memo.ts +105 -0
  158. package/src/cache/cf/index.ts +17 -17
  159. package/src/cache/document-cache.ts +199 -92
  160. package/src/cache/handle-capture.ts +81 -0
  161. package/src/cache/handle-snapshot.ts +111 -0
  162. package/src/cache/index.ts +29 -35
  163. package/src/cache/memory-segment-store.ts +363 -30
  164. package/src/cache/profile-registry.ts +88 -0
  165. package/src/cache/read-through-swr.ts +178 -0
  166. package/src/cache/segment-codec.ts +248 -0
  167. package/src/cache/shell-cache.ts +386 -0
  168. package/src/cache/tag-invalidation.ts +230 -0
  169. package/src/cache/taint.ts +153 -0
  170. package/src/cache/types.ts +156 -211
  171. package/src/cache/vercel/index.ts +11 -0
  172. package/src/cache/vercel/vercel-cache-store.ts +1102 -0
  173. package/src/client.rsc.tsx +43 -21
  174. package/src/client.tsx +131 -347
  175. package/src/cloudflare/index.ts +11 -0
  176. package/src/cloudflare/tracing.ts +109 -0
  177. package/src/component-utils.ts +23 -4
  178. package/src/components/DefaultDocument.tsx +13 -3
  179. package/src/context-var.ts +168 -0
  180. package/src/debug.ts +19 -9
  181. package/src/decode-loader-results.ts +52 -0
  182. package/src/defer.ts +185 -0
  183. package/src/deps/ssr.ts +0 -1
  184. package/src/encode-kv.ts +49 -0
  185. package/src/errors.ts +106 -10
  186. package/src/escape-script.ts +52 -0
  187. package/src/handle.ts +110 -35
  188. package/src/handles/MetaTags.tsx +83 -59
  189. package/src/handles/Scripts.tsx +183 -0
  190. package/src/handles/breadcrumbs.ts +93 -0
  191. package/src/handles/deferred-resolution.ts +127 -0
  192. package/src/handles/is-thenable.ts +18 -0
  193. package/src/handles/meta.ts +44 -53
  194. package/src/handles/script.ts +244 -0
  195. package/src/host/cookie-handler.ts +20 -65
  196. package/src/host/errors.ts +21 -30
  197. package/src/host/index.ts +13 -9
  198. package/src/host/pattern-matcher.ts +50 -79
  199. package/src/host/router.ts +151 -121
  200. package/src/host/testing.ts +45 -32
  201. package/src/host/types.ts +52 -11
  202. package/src/host/utils.ts +2 -2
  203. package/src/href-client.ts +192 -57
  204. package/src/index.rsc.ts +177 -35
  205. package/src/index.ts +255 -71
  206. package/src/internal-debug.ts +9 -2
  207. package/src/loader-store.ts +500 -0
  208. package/src/loader.rsc.ts +31 -99
  209. package/src/loader.ts +30 -12
  210. package/src/missing-id-error.ts +68 -0
  211. package/src/outlet-context.ts +1 -1
  212. package/src/outlet-provider.tsx +41 -0
  213. package/src/prerender/param-hash.ts +16 -14
  214. package/src/prerender/store.ts +121 -21
  215. package/src/prerender.ts +460 -26
  216. package/src/redirect-origin.ts +100 -0
  217. package/src/regex-escape.ts +8 -0
  218. package/src/render-error-thrower.tsx +20 -0
  219. package/src/response-utils.ts +62 -0
  220. package/src/reverse.ts +198 -128
  221. package/src/root-error-boundary.tsx +42 -48
  222. package/src/route-content-wrapper.tsx +22 -77
  223. package/src/route-definition/dsl-helpers.ts +1116 -0
  224. package/src/route-definition/helper-factories.ts +88 -0
  225. package/src/route-definition/helpers-types.ts +505 -0
  226. package/src/route-definition/index.ts +54 -0
  227. package/src/route-definition/redirect.ts +134 -0
  228. package/src/route-definition/resolve-handler-use.ts +160 -0
  229. package/src/route-definition/use-item-types.ts +29 -0
  230. package/src/route-definition.ts +1 -1481
  231. package/src/route-map-builder.ts +82 -144
  232. package/src/route-name.ts +53 -0
  233. package/src/route-types.ts +71 -45
  234. package/src/router/basename.ts +14 -0
  235. package/src/router/content-negotiation.ts +263 -0
  236. package/src/router/debug-manifest.ts +72 -0
  237. package/src/router/error-handling.ts +54 -27
  238. package/src/router/find-match.ts +245 -0
  239. package/src/router/handler-context.ts +377 -125
  240. package/src/router/instrument.ts +350 -0
  241. package/src/router/intercept-resolution.ts +59 -28
  242. package/src/router/lazy-includes.ts +254 -0
  243. package/src/router/loader-resolution.ts +421 -157
  244. package/src/router/logging.ts +106 -6
  245. package/src/router/manifest.ts +131 -57
  246. package/src/router/match-api.ts +167 -246
  247. package/src/router/match-context.ts +4 -24
  248. package/src/router/match-handlers.ts +440 -0
  249. package/src/router/match-middleware/background-revalidation.ts +117 -93
  250. package/src/router/match-middleware/cache-lookup.ts +297 -150
  251. package/src/router/match-middleware/cache-store.ts +123 -51
  252. package/src/router/match-middleware/intercept-resolution.ts +44 -43
  253. package/src/router/match-middleware/segment-resolution.ts +64 -22
  254. package/src/router/match-pipelines.ts +11 -87
  255. package/src/router/match-result.ts +121 -50
  256. package/src/router/metrics.ts +219 -28
  257. package/src/router/middleware-types.ts +93 -0
  258. package/src/router/middleware.ts +505 -441
  259. package/src/router/navigation-snapshot.ts +133 -0
  260. package/src/router/params-util.ts +23 -0
  261. package/src/router/parse-pattern.ts +115 -0
  262. package/src/router/pattern-matching.ts +311 -142
  263. package/src/router/prefetch-cache-ttl.ts +51 -0
  264. package/src/router/prefetch-limits.ts +37 -0
  265. package/src/router/prerender-match.ts +547 -0
  266. package/src/router/preview-match.ts +102 -0
  267. package/src/router/request-classification.ts +278 -0
  268. package/src/router/revalidation.ts +203 -62
  269. package/src/router/route-snapshot.ts +246 -0
  270. package/src/router/router-context.ts +45 -48
  271. package/src/router/router-interfaces.ts +554 -0
  272. package/src/router/router-options.ts +779 -0
  273. package/src/router/router-registry.ts +21 -0
  274. package/src/router/segment-resolution/fresh.ts +772 -0
  275. package/src/router/segment-resolution/helpers.ts +348 -0
  276. package/src/router/segment-resolution/loader-cache.ts +250 -0
  277. package/src/router/segment-resolution/loader-mask.ts +44 -0
  278. package/src/router/segment-resolution/revalidation.ts +1331 -0
  279. package/src/router/segment-resolution/static-store.ts +81 -0
  280. package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
  281. package/src/router/segment-resolution/view-transition-default.ts +56 -0
  282. package/src/router/segment-resolution.ts +25 -1354
  283. package/src/router/segment-wrappers.ts +292 -0
  284. package/src/router/state-cookie-name.ts +33 -0
  285. package/src/router/substitute-pattern-params.ts +75 -0
  286. package/src/router/telemetry-otel.ts +261 -0
  287. package/src/router/telemetry.ts +377 -0
  288. package/src/router/timeout.ts +128 -0
  289. package/src/router/tracing.ts +206 -0
  290. package/src/router/trie-matching.ts +240 -61
  291. package/src/router/types.ts +23 -70
  292. package/src/router/url-params.ts +57 -0
  293. package/src/router.ts +781 -2378
  294. package/src/rsc/full-payload.ts +70 -0
  295. package/src/rsc/handler-context.ts +46 -0
  296. package/src/rsc/handler.ts +905 -1142
  297. package/src/rsc/helpers.ts +275 -19
  298. package/src/rsc/index.ts +2 -25
  299. package/src/rsc/json-route-result.ts +38 -0
  300. package/src/rsc/loader-fetch.ts +305 -0
  301. package/src/rsc/manifest-init.ts +77 -0
  302. package/src/rsc/nonce.ts +14 -0
  303. package/src/rsc/origin-guard.ts +155 -0
  304. package/src/rsc/progressive-enhancement.ts +502 -0
  305. package/src/rsc/redirect-guard.ts +99 -0
  306. package/src/rsc/response-cache-serve.ts +238 -0
  307. package/src/rsc/response-error.ts +104 -0
  308. package/src/rsc/response-route-handler.ts +257 -0
  309. package/src/rsc/rsc-rendering.ts +337 -0
  310. package/src/rsc/runtime-warnings.ts +55 -0
  311. package/src/rsc/server-action.ts +522 -0
  312. package/src/rsc/shell-capture.ts +439 -0
  313. package/src/rsc/ssr-setup.ts +144 -0
  314. package/src/rsc/transition-gate.ts +89 -0
  315. package/src/rsc/types.ts +95 -12
  316. package/src/runtime-env.ts +18 -0
  317. package/src/search-params.ts +99 -82
  318. package/src/segment-content-promise.ts +67 -0
  319. package/src/segment-loader-promise.ts +149 -0
  320. package/src/segment-system.tsx +349 -134
  321. package/src/serialize.ts +243 -0
  322. package/src/server/context.ts +452 -85
  323. package/src/server/cookie-parse.ts +32 -0
  324. package/src/server/cookie-store.ts +310 -0
  325. package/src/server/fetchable-loader-store.ts +11 -6
  326. package/src/server/handle-store.ts +123 -42
  327. package/src/server/live.ts +130 -0
  328. package/src/server/loader-registry.ts +51 -100
  329. package/src/server/request-context.ts +842 -157
  330. package/src/server.ts +15 -8
  331. package/src/ssr/index.tsx +412 -136
  332. package/src/ssr/ssr-root.tsx +228 -0
  333. package/src/static-handler.ts +45 -18
  334. package/src/testing/cache-status.ts +162 -0
  335. package/src/testing/collect-handle.ts +46 -0
  336. package/src/testing/dispatch.ts +701 -0
  337. package/src/testing/dom.entry.ts +22 -0
  338. package/src/testing/e2e/fixture.ts +188 -0
  339. package/src/testing/e2e/index.ts +128 -0
  340. package/src/testing/e2e/matchers.ts +35 -0
  341. package/src/testing/e2e/page-helpers.ts +272 -0
  342. package/src/testing/e2e/parity.ts +387 -0
  343. package/src/testing/e2e/server.ts +195 -0
  344. package/src/testing/flight-matchers.ts +97 -0
  345. package/src/testing/flight-normalize.ts +11 -0
  346. package/src/testing/flight-runtime.d.ts +57 -0
  347. package/src/testing/flight-tree.ts +682 -0
  348. package/src/testing/flight.entry.ts +52 -0
  349. package/src/testing/flight.ts +257 -0
  350. package/src/testing/generated-routes.ts +199 -0
  351. package/src/testing/index.ts +105 -0
  352. package/src/testing/internal/context.ts +371 -0
  353. package/src/testing/internal/flight-client-globals.ts +30 -0
  354. package/src/testing/internal/seed-vars.ts +54 -0
  355. package/src/testing/render-handler.ts +357 -0
  356. package/src/testing/render-route.tsx +584 -0
  357. package/src/testing/run-loader.ts +385 -0
  358. package/src/testing/run-middleware.ts +205 -0
  359. package/src/testing/run-transition-when.ts +164 -0
  360. package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
  361. package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
  362. package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
  363. package/src/testing/vitest-stubs/version.ts +5 -0
  364. package/src/testing/vitest.ts +305 -0
  365. package/src/theme/ThemeProvider.tsx +40 -72
  366. package/src/theme/ThemeScript.tsx +12 -14
  367. package/src/theme/constants.ts +57 -15
  368. package/src/theme/index.ts +3 -20
  369. package/src/theme/theme-context.ts +5 -35
  370. package/src/theme/theme-script.ts +43 -39
  371. package/src/theme/use-theme.ts +0 -3
  372. package/src/types/boundaries.ts +123 -0
  373. package/src/types/cache-types.ts +207 -0
  374. package/src/types/error-types.ts +132 -0
  375. package/src/types/global-namespace.ts +113 -0
  376. package/src/types/handler-context.ts +839 -0
  377. package/src/types/index.ts +81 -0
  378. package/src/types/loader-types.ts +212 -0
  379. package/src/types/request-scope.ts +112 -0
  380. package/src/types/route-config.ts +138 -0
  381. package/src/types/route-entry.ts +114 -0
  382. package/src/types/segments.ts +271 -0
  383. package/src/types.ts +1 -1795
  384. package/src/urls/include-helper.ts +162 -0
  385. package/src/urls/include-provider.ts +71 -0
  386. package/src/urls/index.ts +43 -0
  387. package/src/urls/path-helper-types.ts +413 -0
  388. package/src/urls/path-helper.ts +275 -0
  389. package/src/urls/pattern-types.ts +124 -0
  390. package/src/urls/response-types.ts +109 -0
  391. package/src/urls/type-extraction.ts +316 -0
  392. package/src/urls/urls-function.ts +80 -0
  393. package/src/urls.ts +1 -1341
  394. package/src/use-loader.tsx +406 -141
  395. package/src/vercel/index.ts +11 -0
  396. package/src/vercel/tracing.ts +88 -0
  397. package/src/vite/debug.ts +185 -0
  398. package/src/vite/discovery/bundle-postprocess.ts +182 -0
  399. package/src/vite/discovery/discover-routers.ts +389 -0
  400. package/src/vite/discovery/discovery-errors.ts +255 -0
  401. package/src/vite/discovery/gate-state.ts +171 -0
  402. package/src/vite/discovery/prerender-collection.ts +467 -0
  403. package/src/vite/discovery/route-types-writer.ts +214 -0
  404. package/src/vite/discovery/self-gen-tracking.ts +73 -0
  405. package/src/vite/discovery/state.ts +161 -0
  406. package/src/vite/discovery/virtual-module-codegen.ts +183 -0
  407. package/src/vite/index.ts +23 -2255
  408. package/src/vite/inject-client-debug.ts +36 -0
  409. package/src/vite/plugin-types.ts +303 -0
  410. package/src/vite/plugins/cjs-to-esm.ts +90 -0
  411. package/src/vite/plugins/client-ref-dedup.ts +120 -0
  412. package/src/vite/plugins/client-ref-hashing.ts +118 -0
  413. package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
  414. package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  415. package/src/vite/plugins/cloudflare-protocol-stub.ts +194 -0
  416. package/src/vite/{expose-action-id.ts → plugins/expose-action-id.ts} +88 -110
  417. package/src/vite/{expose-id-utils.ts → plugins/expose-id-utils.ts} +89 -79
  418. package/src/vite/plugins/expose-ids/export-analysis.ts +363 -0
  419. package/src/vite/plugins/expose-ids/handler-transform.ts +130 -0
  420. package/src/vite/plugins/expose-ids/loader-transform.ts +64 -0
  421. package/src/vite/plugins/expose-ids/router-transform.ts +199 -0
  422. package/src/vite/plugins/expose-ids/types.ts +45 -0
  423. package/src/vite/plugins/expose-internal-ids.ts +805 -0
  424. package/src/vite/plugins/performance-tracks.ts +89 -0
  425. package/src/vite/plugins/refresh-cmd.ts +127 -0
  426. package/src/vite/plugins/use-cache-transform.ts +313 -0
  427. package/src/vite/plugins/vercel-output.ts +384 -0
  428. package/src/vite/plugins/version-injector.ts +94 -0
  429. package/src/vite/plugins/version-plugin.ts +263 -0
  430. package/src/vite/plugins/virtual-entries.ts +234 -0
  431. package/src/vite/plugins/virtual-stub-plugin.ts +29 -0
  432. package/src/vite/rango.ts +560 -0
  433. package/src/vite/router-discovery.ts +1638 -0
  434. package/src/vite/{ast-handler-extract.ts → utils/ast-handler-extract.ts} +200 -37
  435. package/src/vite/utils/banner.ts +36 -0
  436. package/src/vite/utils/bundle-analysis.ts +132 -0
  437. package/src/vite/utils/client-chunks.ts +184 -0
  438. package/src/vite/utils/directive-prologue.ts +40 -0
  439. package/src/vite/utils/forward-user-plugins.ts +171 -0
  440. package/src/vite/utils/manifest-utils.ts +15 -0
  441. package/src/vite/utils/package-resolution.ts +89 -0
  442. package/src/vite/utils/prerender-utils.ts +249 -0
  443. package/src/vite/utils/shared-utils.ts +269 -0
  444. package/CLAUDE.md +0 -43
  445. package/dist/vite/index.named-routes.gen.ts +0 -103
  446. package/src/browser/lru-cache.ts +0 -69
  447. package/src/browser/react/use-client-cache.ts +0 -56
  448. package/src/browser/request-controller.ts +0 -164
  449. package/src/browser/shallow.ts +0 -35
  450. package/src/cache/memory-store.ts +0 -253
  451. package/src/handles/index.ts +0 -6
  452. package/src/href-context.ts +0 -33
  453. package/src/network-error-thrower.tsx +0 -21
  454. package/src/router.gen.ts +0 -6
  455. package/src/static-handler.gen.ts +0 -5
  456. package/src/urls.gen.ts +0 -8
  457. package/src/vite/expose-internal-ids.ts +0 -1167
  458. package/src/vite/package-resolution.ts +0 -125
  459. package/src/vite/virtual-entries.ts +0 -114
  460. /package/src/vite/{version.d.ts → plugins/version.d.ts} +0 -0
@@ -11,11 +11,17 @@
11
11
  import type { UrlPatterns } from "../urls.js";
12
12
  import type { AllUseItems } from "../route-types.js";
13
13
  import { extractStaticPrefix } from "../router/pattern-matching.js";
14
- import { RSCRouterContext, runWithPrefixes } from "../server/context.js";
14
+ import { RangoContext, runWithPrefixes } from "../server/context.js";
15
15
  import type { EntryData, TrackedInclude } from "../server/context.js";
16
16
  import type { TrailingSlashMode } from "../types.js";
17
17
  import { createRouteHelpers } from "../route-definition.js";
18
18
  import MapRootLayout from "../server/root-layout.js";
19
+ import { collectFallbackClientRefs } from "./collect-fallback-refs.js";
20
+ import {
21
+ isIncludeProvider,
22
+ resolveIncludeModule,
23
+ type IncludeProvider,
24
+ } from "../urls/include-provider.js";
19
25
 
20
26
  /**
21
27
  * Node in the prefix tree
@@ -45,26 +51,63 @@ export interface GeneratedManifest {
45
51
  routeTrailingSlash?: Record<string, string>;
46
52
  /** Route names using Prerender (for dev-mode Node.js delegation) */
47
53
  prerenderRoutes?: string[];
48
- /** Route names with passthrough: true (handler kept in bundle for live fallback) */
54
+ /** Route names wrapped with Passthrough() (live handler for runtime fallback) */
49
55
  passthroughRoutes?: string[];
50
56
  /** Route name → response type for non-RSC routes */
51
57
  responseTypeRoutes?: Record<string, string>;
52
58
  /** Route name -> search schema descriptor for typed URL helpers */
53
59
  routeSearchSchemas?: Record<string, Record<string, string>>;
54
- /** Generation timestamp */
55
- generatedAt: string;
56
60
  }
57
61
 
58
62
  /**
59
63
  * Build prefix tree node by running the patterns with proper context.
60
64
  * Uses a visited set to detect circular includes and prevent infinite recursion.
61
65
  */
62
- function buildPrefixTreeNode(
66
+ // Merge tracked nested includes into `target`. Multiple includes can share a
67
+ // fullPrefix (e.g. include("/", a), include("/", b)) — concat their routes and
68
+ // Object.assign children rather than overwrite.
69
+ async function mergeIncludeNodes(
70
+ target: Record<string, PrefixTreeNode>,
71
+ includes: TrackedInclude[],
72
+ buildChild: (include: TrackedInclude) => Promise<PrefixTreeNode>,
73
+ ): Promise<void> {
74
+ for (const include of includes) {
75
+ let node: PrefixTreeNode;
76
+ try {
77
+ node = await buildChild(include);
78
+ } catch (err) {
79
+ // Discovery (build-time, and the dev trie-rebuild) populates the
80
+ // manifest / trie / generated types for the WHOLE app. A failing async
81
+ // include provider here — a broken import, a module that throws at eval —
82
+ // must HARD-FAIL, not be swallowed: swallowing produces a green build with
83
+ // the entire route group silently absent from the manifest/trie/types, so
84
+ // CI passes, the deploy ships, and every one of that group's URLs then
85
+ // 404s/500s in production. On main an eager include that threw failed the
86
+ // build loudly; the async form must keep that contract. Rethrow with the
87
+ // offending prefix so the failure is actionable. (Sibling isolation
88
+ // belongs at PER-REQUEST runtime — see find-match.ts — not at discovery.)
89
+ throw new Error(
90
+ `[@rangojs/router] Failed to resolve include at prefix "${include.fullPrefix}" ` +
91
+ `during route discovery: ${(err as Error)?.message ?? String(err)}`,
92
+ { cause: err },
93
+ );
94
+ }
95
+ const existing = target[include.fullPrefix];
96
+ if (existing) {
97
+ existing.routes.push(...node.routes);
98
+ Object.assign(existing.children, node.children);
99
+ } else {
100
+ target[include.fullPrefix] = node;
101
+ }
102
+ }
103
+ }
104
+
105
+ async function buildPrefixTreeNode(
63
106
  urlPrefix: string,
64
107
  namePrefix: string | undefined,
65
- patterns: UrlPatterns<any>,
108
+ patternsOrProvider: UrlPatterns<any> | IncludeProvider<any>,
66
109
  routeManifest: Record<string, string>,
67
- routeAncestry: Record<string, string[]>, // internal: feeds trie building, not exported
110
+ routeAncestry: Record<string, string[]>, // internal: feeds trie building, not exported
68
111
  mountIndex: number,
69
112
  visited: Set<unknown> = new Set(),
70
113
  routeTrailingSlash?: Record<string, string>,
@@ -73,10 +116,17 @@ function buildPrefixTreeNode(
73
116
  passthroughRoutes?: string[],
74
117
  responseTypeRoutes?: Record<string, string>,
75
118
  routeSearchSchemas?: Record<string, Record<string, string>>,
76
- ): PrefixTreeNode {
119
+ ): Promise<PrefixTreeNode> {
120
+ // Resolve an async include provider (`() => import("./routes")`) so its routes
121
+ // are walked into the build-time manifest/types/href. Runtime matching still
122
+ // defers the import via lazy-includes; this only runs during build/dev
123
+ // discovery, which is async.
124
+ const patterns: UrlPatterns<any> = isIncludeProvider(patternsOrProvider)
125
+ ? resolveIncludeModule(await patternsOrProvider(), urlPrefix)
126
+ : patternsOrProvider;
77
127
  if (visited.has(patterns)) {
78
128
  console.warn(
79
- `[@rangojs/router] Circular include detected at prefix "${urlPrefix}". Skipping.`
129
+ `[@rangojs/router] Circular include detected at prefix "${urlPrefix}". Skipping.`,
80
130
  );
81
131
  return {
82
132
  staticPrefix: extractStaticPrefix(urlPrefix),
@@ -87,125 +137,117 @@ function buildPrefixTreeNode(
87
137
  };
88
138
  }
89
139
  visited.add(patterns);
90
- // Create context for running patterns with include tracking
91
- const manifest = new Map<string, EntryData>();
92
- const patternsMap = new Map<string, string>();
93
- const patternsByPrefix = new Map<string, Map<string, string>>();
94
- const trailingSlashMap = new Map<string, TrailingSlashMode>();
95
- const searchSchemasMap = new Map<string, Record<string, string>>();
96
- const trackedIncludes: TrackedInclude[] = [];
140
+ try {
141
+ // Create context for running patterns with include tracking
142
+ const manifest = new Map<string, EntryData>();
143
+ const patternsMap = new Map<string, string>();
144
+ const patternsByPrefix = new Map<string, Map<string, string>>();
145
+ const trailingSlashMap = new Map<string, TrailingSlashMode>();
146
+ const searchSchemasMap = new Map<string, Record<string, string>>();
147
+ const trackedIncludes: TrackedInclude[] = [];
97
148
 
98
- RSCRouterContext.run(
99
- {
100
- manifest,
101
- patterns: patternsMap,
102
- patternsByPrefix,
103
- trailingSlash: trailingSlashMap,
104
- searchSchemas: searchSchemasMap,
105
- namespace: "build",
106
- parent: null,
107
- counters: {},
108
- mountIndex,
109
- trackedIncludes, // Enable nested include tracking
110
- },
111
- () => {
112
- const helpers = createRouteHelpers();
113
- // Wrap in root layout for correct parent hierarchy (matches runtime)
114
- helpers.layout(MapRootLayout, () => {
115
- if (urlPrefix || namePrefix) {
116
- return runWithPrefixes(urlPrefix, namePrefix, () => {
117
- return patterns.handler() as AllUseItems[];
118
- });
119
- }
120
- return patterns.handler() as AllUseItems[];
121
- });
122
- }
123
- );
149
+ RangoContext.run(
150
+ {
151
+ manifest,
152
+ patterns: patternsMap,
153
+ patternsByPrefix,
154
+ trailingSlash: trailingSlashMap,
155
+ searchSchemas: searchSchemasMap,
156
+ namespace: "build",
157
+ parent: null,
158
+ counters: {},
159
+ mountIndex,
160
+ trackedIncludes, // Enable nested include tracking
161
+ },
162
+ () => {
163
+ const helpers = createRouteHelpers();
164
+ // Wrap in root layout for correct parent hierarchy (matches runtime)
165
+ helpers.layout(MapRootLayout, () => {
166
+ if (urlPrefix || namePrefix) {
167
+ return runWithPrefixes(urlPrefix, namePrefix, () => {
168
+ return patterns.handler() as AllUseItems[];
169
+ });
170
+ }
171
+ return patterns.handler() as AllUseItems[];
172
+ });
173
+ },
174
+ );
124
175
 
125
- // Collect route names defined in this include (routes have prefixes applied)
126
- const routes: string[] = [];
127
- for (const [name, pattern] of patternsMap.entries()) {
128
- routes.push(name);
129
- routeManifest[name] = pattern;
130
- }
176
+ // Collect route names defined in this include (routes have prefixes applied)
177
+ const routes = [...patternsMap.keys()];
178
+ Object.assign(routeManifest, Object.fromEntries(patternsMap));
131
179
 
132
- // Collect trailing slash config
133
- if (routeTrailingSlash) {
134
- for (const [name, mode] of trailingSlashMap.entries()) {
135
- routeTrailingSlash[name] = mode;
180
+ // Collect trailing slash config
181
+ if (routeTrailingSlash) {
182
+ for (const [name, mode] of trailingSlashMap.entries()) {
183
+ routeTrailingSlash[name] = mode;
184
+ }
136
185
  }
137
- }
138
- if (routeSearchSchemas) {
139
- for (const [name, schema] of searchSchemasMap.entries()) {
140
- routeSearchSchemas[name] = schema;
186
+ if (routeSearchSchemas) {
187
+ for (const [name, schema] of searchSchemasMap.entries()) {
188
+ routeSearchSchemas[name] = schema;
189
+ }
141
190
  }
142
- }
143
191
 
144
- // Capture ancestry from manifest entries' parent chains
145
- captureAncestry(manifest, routeAncestry);
192
+ // Capture ancestry from manifest entries' parent chains
193
+ captureAncestry(manifest, routeAncestry);
146
194
 
147
- // Collect prerender route names and handler definitions from manifest entries
148
- if (prerenderRoutes) {
149
- for (const [name, entry] of manifest) {
150
- if (entry.type === "route" && entry.isPrerender) {
151
- prerenderRoutes.push(name);
152
- if (prerenderDefs && entry.prerenderDef) {
153
- prerenderDefs[name] = entry.prerenderDef;
154
- }
155
- if (passthroughRoutes && entry.prerenderDef?.options?.passthrough === true) {
156
- passthroughRoutes.push(name);
195
+ // Collect prerender route names and handler definitions from manifest entries
196
+ if (prerenderRoutes) {
197
+ for (const [name, entry] of manifest) {
198
+ if (entry.type === "route" && entry.isPrerender) {
199
+ prerenderRoutes.push(name);
200
+ if (prerenderDefs && entry.prerenderDef) {
201
+ prerenderDefs[name] = entry.prerenderDef;
202
+ }
203
+ if (passthroughRoutes && entry.isPassthrough === true) {
204
+ passthroughRoutes.push(name);
205
+ }
157
206
  }
158
207
  }
159
208
  }
160
- }
161
209
 
162
- // Collect response type routes from manifest entries
163
- if (responseTypeRoutes) {
164
- for (const [name, entry] of manifest) {
165
- if (entry.type === "route" && entry.responseType) {
166
- responseTypeRoutes[name] = entry.responseType;
210
+ // Collect response type routes from manifest entries
211
+ if (responseTypeRoutes) {
212
+ for (const [name, entry] of manifest) {
213
+ if (entry.type === "route" && entry.responseType) {
214
+ responseTypeRoutes[name] = entry.responseType;
215
+ }
167
216
  }
168
217
  }
169
- }
170
-
171
- // Build children from tracked nested includes.
172
- // Multiple includes can share the same fullPrefix (e.g., include("/", patternsA),
173
- // include("/", patternsB)). Merge their routes instead of overwriting.
174
- const children: Record<string, PrefixTreeNode> = {};
175
218
 
176
- for (const include of trackedIncludes) {
177
- const childNode = buildPrefixTreeNode(
178
- include.fullPrefix,
179
- include.namePrefix,
180
- include.patterns as UrlPatterns<any>,
181
- routeManifest,
182
- routeAncestry,
183
- mountIndex,
184
- visited,
185
- routeTrailingSlash,
186
- prerenderRoutes,
187
- prerenderDefs,
188
- passthroughRoutes,
189
- responseTypeRoutes,
190
- routeSearchSchemas,
219
+ const children: Record<string, PrefixTreeNode> = {};
220
+ await mergeIncludeNodes(children, trackedIncludes, (include) =>
221
+ buildPrefixTreeNode(
222
+ include.fullPrefix,
223
+ include.namePrefix,
224
+ include.patterns as UrlPatterns<any> | IncludeProvider<any>,
225
+ routeManifest,
226
+ routeAncestry,
227
+ mountIndex,
228
+ visited,
229
+ routeTrailingSlash,
230
+ prerenderRoutes,
231
+ prerenderDefs,
232
+ passthroughRoutes,
233
+ responseTypeRoutes,
234
+ routeSearchSchemas,
235
+ ),
191
236
  );
192
237
 
193
- const existing = children[include.fullPrefix];
194
- if (existing) {
195
- existing.routes.push(...childNode.routes);
196
- Object.assign(existing.children, childNode.children);
197
- } else {
198
- children[include.fullPrefix] = childNode;
199
- }
238
+ return {
239
+ staticPrefix: extractStaticPrefix(urlPrefix),
240
+ fullPrefix: urlPrefix,
241
+ namePrefix: namePrefix || undefined,
242
+ children,
243
+ routes,
244
+ };
245
+ } finally {
246
+ // Remove from visited so sibling branches can reuse the same patterns without
247
+ // false circular-include detection — and so a throwing handler (caught by the
248
+ // parent mergeIncludeNodes) does not leak this entry into the shared set.
249
+ visited.delete(patterns);
200
250
  }
201
-
202
- return {
203
- staticPrefix: extractStaticPrefix(urlPrefix),
204
- fullPrefix: urlPrefix,
205
- namePrefix: namePrefix || undefined,
206
- children,
207
- routes,
208
- };
209
251
  }
210
252
 
211
253
  /**
@@ -229,18 +271,28 @@ function captureAncestry(
229
271
  }
230
272
 
231
273
  /**
232
- * Generate manifest from UrlPatterns
274
+ * Internal manifest result including build-pipeline-only fields.
275
+ * Not part of the public API — use generateManifest() for the public surface.
276
+ */
277
+ export interface FullManifest extends GeneratedManifest {
278
+ _routeAncestry: Record<string, string[]>;
279
+ _prerenderDefs?: Record<string, any>;
280
+ }
281
+
282
+ /**
283
+ * Generate manifest from UrlPatterns (public API).
233
284
  *
234
- * This runs all patterns (including lazy ones) at build time to extract:
235
- * - The complete prefix tree for short-circuit optimization
236
- * - The complete route manifest for href()
285
+ * Returns only the public GeneratedManifest fields. Internal build pipeline
286
+ * consumers that need _routeAncestry or _prerenderDefs should use
287
+ * generateManifestFull() instead.
237
288
  *
238
289
  * @example
239
290
  * ```typescript
240
291
  * import { generateManifest } from "@rangojs/router/build";
241
292
  * import { urlpatterns } from "./urls";
242
293
  *
243
- * const manifest = generateManifest(urlpatterns);
294
+ * // Async: awaits async include() providers (`() => import("./routes")`).
295
+ * const manifest = await generateManifest(urlpatterns);
244
296
  * // Write to file for runtime use
245
297
  * fs.writeFileSync(
246
298
  * "src/generated/route-manifest.json",
@@ -248,10 +300,37 @@ function captureAncestry(
248
300
  * );
249
301
  * ```
250
302
  */
251
- export function generateManifest<TEnv>(
303
+ export async function generateManifest<TEnv>(
304
+ urlpatterns: UrlPatterns<TEnv, any>,
305
+ mountIndex: number = 0,
306
+ ): Promise<GeneratedManifest> {
307
+ const { _routeAncestry, _prerenderDefs, ...publicManifest } =
308
+ await generateManifestFull(urlpatterns, mountIndex);
309
+ return publicManifest;
310
+ }
311
+
312
+ /**
313
+ * Generate manifest with internal build-pipeline fields.
314
+ *
315
+ * Used by the Vite plugin (discover-routers via dynamic import through
316
+ * @rangojs/router/build), manifest-init (direct import), and trie
317
+ * building. Not intended for external use.
318
+ */
319
+ export async function generateManifestFull<TEnv>(
252
320
  urlpatterns: UrlPatterns<TEnv, any>,
253
321
  mountIndex: number = 0,
254
- ): GeneratedManifest & { _routeAncestry: Record<string, string[]>; _prerenderDefs?: Record<string, any> } {
322
+ options?: {
323
+ urlPrefix?: string;
324
+ /**
325
+ * Called once per `"use client"` component registered as an
326
+ * errorBoundary/notFoundBoundary fallback, with its client-reference key
327
+ * (`$$id`). Lets the build collect fallback module ids for dedicated
328
+ * chunking without exposing the otherwise-discarded EntryData tree. The
329
+ * EntryData map built below is local; this is the only seam that surfaces it.
330
+ */
331
+ collectClientFallbackRef?: (refKey: string) => void;
332
+ },
333
+ ): Promise<FullManifest> {
255
334
  const routeManifest: Record<string, string> = {};
256
335
  const routeAncestry: Record<string, string[]> = {};
257
336
  const prefixTree: Record<string, PrefixTreeNode> = {};
@@ -264,7 +343,7 @@ export function generateManifest<TEnv>(
264
343
  const searchSchemasMap = new Map<string, Record<string, string>>();
265
344
  const trackedIncludes: TrackedInclude[] = [];
266
345
 
267
- RSCRouterContext.run(
346
+ RangoContext.run(
268
347
  {
269
348
  manifest,
270
349
  patterns: patternsMap,
@@ -276,6 +355,8 @@ export function generateManifest<TEnv>(
276
355
  counters: {},
277
356
  mountIndex,
278
357
  trackedIncludes, // Enable include tracking
358
+ // basename sets the initial URL prefix for all path() registrations
359
+ ...(options?.urlPrefix ? { urlPrefix: options.urlPrefix } : {}),
279
360
  },
280
361
  () => {
281
362
  const helpers = createRouteHelpers();
@@ -283,22 +364,34 @@ export function generateManifest<TEnv>(
283
364
  helpers.layout(MapRootLayout, () => {
284
365
  return urlpatterns.handler() as AllUseItems[];
285
366
  });
286
- }
367
+ },
287
368
  );
288
369
 
289
- // Collect root-level routes and trailing slash config
290
- const routeTrailingSlash: Record<string, string> = {};
291
- for (const [name, pattern] of patternsMap.entries()) {
292
- routeManifest[name] = pattern;
293
- }
294
- for (const [name, mode] of trailingSlashMap.entries()) {
295
- routeTrailingSlash[name] = mode;
296
- }
297
- const routeSearchSchemas: Record<string, Record<string, string>> = {};
298
- for (const [name, schema] of searchSchemasMap.entries()) {
299
- routeSearchSchemas[name] = schema;
370
+ // Surface the "use client" components registered as error/notFound fallbacks
371
+ // (route-tree errorBoundary()/notFoundBoundary() helpers, stored on EntryData).
372
+ // The boundary may be a handler function and/or wrap the client boundary in
373
+ // server providers, so walk the whole tree (see collectFallbackClientRefs).
374
+ if (options?.collectClientFallbackRef) {
375
+ const report = options.collectClientFallbackRef;
376
+ const collect = (boundary: unknown[] | undefined) => {
377
+ for (const item of boundary ?? [])
378
+ collectFallbackClientRefs(item, report);
379
+ };
380
+ for (const entry of manifest.values()) {
381
+ collect(entry.errorBoundary);
382
+ collect(entry.notFoundBoundary);
383
+ }
300
384
  }
301
385
 
386
+ // Collect root-level routes and trailing slash config
387
+ Object.assign(routeManifest, Object.fromEntries(patternsMap));
388
+ const routeTrailingSlash: Record<string, string> =
389
+ Object.fromEntries(trailingSlashMap);
390
+ const routeSearchSchemas: Record<
391
+ string,
392
+ Record<string, string>
393
+ > = Object.fromEntries(searchSchemasMap);
394
+
302
395
  // Capture ancestry from manifest entries' parent chains
303
396
  captureAncestry(manifest, routeAncestry);
304
397
 
@@ -313,7 +406,7 @@ export function generateManifest<TEnv>(
313
406
  if (entry.prerenderDef) {
314
407
  prerenderDefs[name] = entry.prerenderDef;
315
408
  }
316
- if (entry.prerenderDef?.options?.passthrough === true) {
409
+ if (entry.isPassthrough === true) {
317
410
  passthroughRoutes.push(name);
318
411
  }
319
412
  }
@@ -322,15 +415,13 @@ export function generateManifest<TEnv>(
322
415
  }
323
416
  }
324
417
 
325
- // Build prefix tree from tracked includes (shared visited set for cycle detection).
326
- // Multiple includes can share the same fullPrefix (e.g., include("/", patternsA),
327
- // include("/", patternsB)). Merge their routes instead of overwriting.
418
+ // Shared visited set for cycle detection across all root-level includes.
328
419
  const visited = new Set<unknown>();
329
- for (const include of trackedIncludes) {
330
- const node = buildPrefixTreeNode(
420
+ await mergeIncludeNodes(prefixTree, trackedIncludes, (include) =>
421
+ buildPrefixTreeNode(
331
422
  include.fullPrefix,
332
423
  include.namePrefix,
333
- include.patterns as UrlPatterns<any>,
424
+ include.patterns as UrlPatterns<any> | IncludeProvider<any>,
334
425
  routeManifest,
335
426
  routeAncestry,
336
427
  mountIndex,
@@ -341,30 +432,31 @@ export function generateManifest<TEnv>(
341
432
  passthroughRoutes,
342
433
  responseTypeRoutes,
343
434
  routeSearchSchemas,
344
- );
345
-
346
- const existing = prefixTree[include.fullPrefix];
347
- if (existing) {
348
- existing.routes.push(...node.routes);
349
- Object.assign(existing.children, node.children);
350
- } else {
351
- prefixTree[include.fullPrefix] = node;
352
- }
353
- }
435
+ ),
436
+ );
354
437
 
355
438
  return {
356
439
  prefixTree,
357
440
  routeManifest,
358
- routeTrailingSlash: Object.keys(routeTrailingSlash).length > 0 ? routeTrailingSlash : undefined,
441
+ routeTrailingSlash:
442
+ Object.keys(routeTrailingSlash).length > 0
443
+ ? routeTrailingSlash
444
+ : undefined,
359
445
  prerenderRoutes: prerenderRoutes.length > 0 ? prerenderRoutes : undefined,
360
- passthroughRoutes: passthroughRoutes.length > 0 ? passthroughRoutes : undefined,
361
- responseTypeRoutes: Object.keys(responseTypeRoutes).length > 0 ? responseTypeRoutes : undefined,
362
- routeSearchSchemas: Object.keys(routeSearchSchemas).length > 0 ? routeSearchSchemas : undefined,
363
- generatedAt: new Date().toISOString(),
364
- // Internal: routeAncestry is used only for trie building, not exported
446
+ passthroughRoutes:
447
+ passthroughRoutes.length > 0 ? passthroughRoutes : undefined,
448
+ responseTypeRoutes:
449
+ Object.keys(responseTypeRoutes).length > 0
450
+ ? responseTypeRoutes
451
+ : undefined,
452
+ routeSearchSchemas:
453
+ Object.keys(routeSearchSchemas).length > 0
454
+ ? routeSearchSchemas
455
+ : undefined,
365
456
  _routeAncestry: routeAncestry,
366
457
  // Internal: prerender handler definitions for build-time getParams() access
367
- _prerenderDefs: Object.keys(prerenderDefs).length > 0 ? prerenderDefs : undefined,
458
+ _prerenderDefs:
459
+ Object.keys(prerenderDefs).length > 0 ? prerenderDefs : undefined,
368
460
  };
369
461
  }
370
462
 
@@ -373,18 +465,17 @@ export function generateManifest<TEnv>(
373
465
  *
374
466
  * @example
375
467
  * ```typescript
376
- * const code = generateManifestCode(urlpatterns);
468
+ * const code = await generateManifestCode(urlpatterns);
377
469
  * fs.writeFileSync("src/generated/route-manifest.ts", code);
378
470
  * ```
379
471
  */
380
- export function generateManifestCode<TEnv>(
381
- urlpatterns: UrlPatterns<TEnv, any>
382
- ): string {
383
- const manifest = generateManifest(urlpatterns);
472
+ export async function generateManifestCode<TEnv>(
473
+ urlpatterns: UrlPatterns<TEnv, any>,
474
+ ): Promise<string> {
475
+ const manifest = await generateManifest(urlpatterns);
384
476
 
385
477
  return `/**
386
478
  * Auto-generated route manifest
387
- * Generated at: ${manifest.generatedAt}
388
479
  *
389
480
  * DO NOT EDIT - This file is generated by @rangojs/router
390
481
  */