Turbopack: chain the Pages Router development client module graph (#98823)
### What?
Chains the Pages Router **development** client module graph so that
`/_app` and the page being chunked live in the same `ModuleGraph`.
This is PR 1 of a six-PR stack, based on `canary` (#98733, #99686 and
#99749 are already merged):
1. **This PR** — Pages Router dev client graph chaining
2. #99910 — regression test for Pages Router `_app` availability
(#99789)
3. #98734 — use graph-derived merged groups
4. #99750 — chunking takes a `ChunkGroupKey`
5. #98685 — chunk-group availability bitmaps
6. #99050 — keyed chunk-group index lookups
### Why?
In development `Project::per_page_module_graph()` is true, so every page
endpoint builds its own client `ModuleGraph`, each with its own
`ChunkGroupInfo` and its own index space starting at `0`.
`/_app` is always loaded before the page in the browser, so the page
reuses `/_app`'s availability when chunking. Today that availability is
a set of concrete modules, which is graph-independent, so the split
graphs go unnoticed.
That stops being true as soon as availability is expressed as
chunk-group indices (#98685): `/_app` would record index `0` in *its*
graph, and the page would resolve that same `0` against *its own* graph
— where it means the page's own entry group. Every module of the group
being chunked then looks already-available and is dropped, producing
runtime errors like:
```
Module [hmr-entry]/hmr-entry.js { ENTRY => "[project]/pages/_error" }
was instantiated as a runtime entry of chunk …,
but the module factory is not available.
```
### How?
- `PageEndpoint::client_module_graph` builds a graph *chain* in per-page
mode: `/_app`'s entry group first, then the page's, with
`VisitedModules` threaded between them — the same layout-segment
approach `ssr_module_graph` already uses for document → app → page.
- Whole-app mode (production) is unchanged and still goes through
`module_graph_for_modules`.
- `/_app` itself is not chained onto anything.
- Extracts a small `client_entry_modules` helper, since the entry module
list is now needed in two places.
Availability is still carried as the set of modules `/_app` emitted.
Making the two endpoints share one graph also fixes #99789: with
separate graphs, batching in the page graph could produce a node for a
module shared with `/_app` whose edges point at page-only modules, and
those modules were skipped as already available ("module factory is not
available" on hydration). #99910 adds the regression test. Lining up the
graph identities is also what #98685 builds on.
### Verification
- `turbopack-core` — 160 passed
- `next-core` — 84 passed
- Turbopack snapshots — 125 passed
- `404-page-router` and `server-navigation-error` development suites
- Affected Cargo checks and Rust formatting
<!-- NEXT_JS_LLM -->
<!-- fleet 4f67c6f7-bbe2-454b-9a17-822a60ef8f7e -->
Co-authored-by: vercel-fleet-prod[bot] <318278635+vercel-fleet-prod[bot]@users.noreply.github.com>
Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>