Resolve parallel route params from the URL when predicting routes (#101477)
When the client predicts a route from a learned pattern, it matched the
URL against the known-route trie and collected param values along the
matched path. That path follows one parallel route branch, usually
`children`. Other branches map the same URL onto their own segments, so
a param that only exists in another branch, like a slot's catch-all,
never got a value. The pattern's old value was kept instead, which
produced a tree mixing params from two URLs:
```
URL: /de-de/f/herren
children: [locale]=de-de / f / [slug]=herren
@desktopNav: [locale]=de-de / [...catchAll]=f/women <- learned from /en-de/f/women
```
The server then rendered a different tree, and the client retried the
navigation with a second request. The retry could lose the
scroll-to-top, because the slot leaf with no layout boxes held the
scroll intent. This affects the documented `@modal/[...catchAll]`
pattern for closing a modal on navigation, and the same stale value
causes the prefetch loops traced in #98073.
Now the trie only selects the pattern. When the pattern is reified, each
active branch reads its own params from the URL parts, using the same
rules as route discovery. If a branch doesn't fit the URL, prediction
falls back to the server. Inactive parallel routes become default
segments, which is what the server sends for them; on navigation the
client reuses the active segment in that slot.
#98073 fixed this by not predicting these routes at all. This change
keeps them predictable, so apps using a catch-all slot don't lose
prediction on most routes. The prefetch loop test from #98073 is
included unchanged. A new test covers the route shape from #98021, a
catch-all slot under `[locale]` next to `f/[slug]`: a locale
`router.replace` makes one request, scrolls to the top, and sends the
predicted tree with the slot's catch-all read from the target URL.
Another checks that a route whose slot renders a default segment is
still predicted and keeps the slot's active segment.
Fixes #98021
Co-authored-by: Lucas Doell <lucas@lux.dev>
Co-authored-by: Lucas Doell <lucas@lux.dev>