mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-17 05:07:37 +08:00
fix(react-router): read route tables another file hands the router (#2400)
A route table kept in a file of its own produced no routes: the ASP.NET
Core React template's AppRoutes array, which App.js maps into
<Route {...rest}>, a routes array imported into useRoutes(routes) or
createBrowserRouter(routes), and codedthemes' one-object-per-file
[MainRoutes, LoginRoutes]. Route objects were read only from a file that
itself names a data router, so these apps had no routes and their
navigate()/<Link to> navigation reached nothing.
The table's own file cannot tell it from a menu's { path, element } list,
so the evidence is the file that hands it over: a useRoutes /
create*Router argument, or a .map whose callback renders a <Route> from
the item's own fields ({...route}, {...rest}, path={route.path}). A new
FrameworkResolver.crossFileNodes hook keeps those routes, reconciled in
runPostExtract on every index and sync (removal-only syncs included):
new ones are inserted with pending references, ones no longer wanted are
removed with their incoming resolution edges resurrected, unchanged ones
keep their edges. The React pass starts from the files that import React
Router, follows the import to the table and the tables it names
(...ApiAuthorizationRoutes, children: x), each under its mount, and owns
its routes by id (route:<file>:<line>:table:<path>).
Route objects (tables and data routers alike): an index: true route is
the page at its parent's address; a route object around others is their
layout (a references edge marked layout: true, as Angular's), and is not
a page of its own where a child claims its address. A route renders past
a *Wrapper or *Route guard, and through a same-file
lazy(() => import(...)) to the module it loads, never a same-named
component in another app. useRoutes joins the file-level gate.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Framework & language coverage — what is done, what is left
|
||||
|
||||
**Last verified: 2026-08-29** (Angular row: 2026-10-06) against the build at that date. Re-verify with the
|
||||
**Last verified: 2026-08-29** (Angular row: 2026-10-06; React Router row: 2026-10-06) against the build at that date. Re-verify with the
|
||||
queries in [Checking this file is still true](#checking-this-file-is-still-true)
|
||||
before trusting a row; this is a snapshot, not a live view.
|
||||
|
||||
@@ -38,7 +38,7 @@ guessed.
|
||||
|---|---|---|---|---|
|
||||
| Expo Router | `frameworks/expo-router.ts` | `expo-router-synthesizer.ts` | `expo-router.test.ts` | — |
|
||||
| Next.js | `frameworks/nextjs.ts` | `next-router-synthesizer.ts` | `nextjs.test.ts` | next-saas-starter |
|
||||
| React Router | `frameworks/react-router.ts` | `react-router-synthesizer.ts` | `react-router.test.ts` | proshop (44 edges), proshop-v2 (28), react-redux-realworld (22), react-boilerplate (`styled(Link)`), takenote (v5 `<Redirect>`), bulletproof-react (nested `children`, `lazy` routes, `paths.x.path` constants through an app's own tsconfig alias: 0 → 9 named, linked routes), and its `paths.x.getHref(id)` links and `navigate(paths.x.getHref())` calls (0 → 11 navigates) |
|
||||
| React Router | `frameworks/react-router.ts` | `react-router-synthesizer.ts` | `react-router.test.ts` | proshop (44 edges), proshop-v2 (28), react-redux-realworld (22), react-boilerplate (`styled(Link)`), takenote (v5 `<Redirect>`), bulletproof-react (nested `children`, `lazy` routes, `paths.x.path` constants through an app's own tsconfig alias: 0 → 9 named, linked routes), and its `paths.x.getHref(id)` links and `navigate(paths.x.getHref())` calls (0 → 11 navigates). Route tables another file hands the router (`tableRoutes` in `frameworks/react.ts`, trap 13): the ASP.NET Core React template's `AppRoutes.map(… <Route {...rest}>)` on jasontaylordev/CleanArchitecture's `ClientApp-React` (0 → 6 routes, 11 navigates), replaysMike/Binner (0 → 46, 87), GavinLonDigital/RankingApp, GarrettHays/PaydirtPickem, charlessolar/eShopOnContainersDDD; `useRoutes(routes)` from another file and `[...sessionRoutes]` on uilibrary/matx-react (0 → 7, 16); codedthemes' `createBrowserRouter([MainRoutes, LoginRoutes])` on berry and mantis (9 and 8 routes, no navigation they can resolve); a table `.map`ped inside `<Route path="/dashboard">` on RADeveloping/chickadeeinvest; `useRoutes([...])` in place on minimal-ui-kit/material-kit-react (0 → 7, bound through `lazy(() => import(…))` to each page) |
|
||||
| TanStack Router | `frameworks/tanstack-router.ts` | `tanstack-router-synthesizer.ts` | `tanstack-router.test.ts` | TanStack examples, fastapi-template frontend |
|
||||
| Vue Router / Nuxt | `frameworks/vue-router.ts` (Nuxt file routes: `nuxtResolver` in `frameworks/vue.ts`) | `vue-router-synthesizer.ts` | `vue-router.test.ts` | vue-realworld (23 edges); vue-element-admin (62 routes), vue-admin-template (14), vben (192), halo console (34) — named tables, module files, `children` + layouts; Nuxt: mealie, elk, nuxt/movies |
|
||||
| SvelteKit | `frameworks/sveltekit-router.ts` | `sveltekit-synthesizer.ts` | `sveltekit-router.test.ts`, `sveltekit-route-names.test.ts` | sveltekit-realworld (31 edges); shadcn-svelte and skeleton (`(group)` layouts: 13 and 23 edges), svelte.dev (74), kit's test apps (47) |
|
||||
@@ -263,6 +263,26 @@ Each of these cost real debugging time; they are not hypothetical.
|
||||
template-bound handler there was listed as dead code. A new detector that
|
||||
gates on a dependency should ask `dependsOn`, not read a `package.json`
|
||||
itself, so it sees the same manifests every other detector does.
|
||||
13. **A route table can be named only by another file.** The ASP.NET Core
|
||||
React template keeps its routes in `AppRoutes.js`, a file that never names
|
||||
the router, and renders them from `App.js` with `AppRoutes.map(({ element,
|
||||
...rest }) => <Route {...rest} element={element} />)`; codedthemes' admin
|
||||
kits put one route object per file and list them in
|
||||
`createBrowserRouter([MainRoutes, LoginRoutes])`. Read on its own, such a
|
||||
file cannot be told from a menu's `{ path, element }` list, and per-file
|
||||
extraction cannot see the file that hands it over, nor run again when that
|
||||
file changes. So React keeps those routes in the cross-file pass
|
||||
(`FrameworkResolver.crossFileNodes`, reconciled in `runPostExtract` on every
|
||||
index and sync, removals included): it starts from the files that import
|
||||
React Router, takes only a `useRoutes` / `create*Router` argument or a
|
||||
`.map` whose callback renders a `<Route>` from the item's own fields
|
||||
(`{...route}`, `{...rest}`, `path={route.path}` — never
|
||||
`path={r.layout + r.path}`), follows the import to the table and the tables
|
||||
it names in turn, and owns its routes by id (`…:table:<path>`). Two limits
|
||||
it shares with every router: a table rendered by a component that is
|
||||
itself mounted under another file's `<Route path="/admin/*">` reads as if
|
||||
at the root, and a navigation that failed while its route was gone is not
|
||||
retried until a full index.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -141,6 +141,8 @@ These describe `codegraph ui` and its screens. They were taken out of `## [Unrel
|
||||
|
||||
- **A server action written through a wrapper starts its transition on the right page.** `export const signIn = validatedAction(schema, async (data) => { … redirect('/dashboard') })` — the arrow inside is no symbol of its own — now belongs to `signIn` on the Screens tab, and `signIn` is attributed to the page whose component hands it to `useActionState(signIn, …)`, read from the source when the graph holds no such edge.
|
||||
|
||||
- **React Router apps that keep their routes in a table get a Screens picture.** The ASP.NET Core React template's `AppRoutes` array, a `routes` array handed to `useRoutes` or `createBrowserRouter` from another file, and admin kits' `[MainRoutes, LoginRoutes]` route objects drew no screens, because their routes were never read. They are now, with the links and `navigate(…)` calls between them. A parent route object's component is drawn as the layout around the screens inside it: its own links count from each of those screens, and when an `index: true` child claims its address, that child is the screen there. Re-index React projects after upgrading.
|
||||
|
||||
## Fixes — Steps — what a call does, and when
|
||||
|
||||
- **A Steps picture with nothing past its anchor says why.** Starting Steps from a helper that only computes drew one box and no explanation. The panel now says that nothing it sets in motion is a step the picture draws, explains that calls between plain functions fold into the lines, and links to the symbol's callers and callees.
|
||||
|
||||
Reference in New Issue
Block a user