Separate route structure comparison from param comparison (#98974)
Changing a page’s search params doesn’t change which page it is, but it
may change the data that page needs. The router currently mixes these
concerns by appending search params to `__PAGE__` segments. Remove that
encoding so we can compare which route is being rendered separately from
the param values used to render it.
Param values are now compared through the existing VaryPath data
structure, while route structure is compared during the existing tree
traversals. Each traversal can decide which comparisons matter for the
work it’s doing.
Client-side comparisons and history restoration still need the search
params, so store them in a separate FlightRouterState slot for now. As
before, previous-page search params are stripped from normal request
headers. This is a temporary step that lets us migrate incrementally.
Eventually, FlightRouterState will be replaced by a type that represents
the route and its params more directly.
This is mostly a refactor, though it fixes an accidental inconsistency
in search-param handling compared with regular route params, avoiding
some redundant prefetch work.
Fully cached pages already track their vary params correctly. This
separation prepares us to do the same for partially dynamic segments
during navigation, so changing an unrelated param won’t require
rendering their dynamic content again.