Keep HMR instructions typed until serialization (#96569)
Stacked on #96686.
## What?
Keep HMR update instructions as typed Rust values until they cross the
client protocol serialization boundary. The JSON wire format remains
unchanged.
## Why?
HMR aggregation currently operates on `serde_json::Value`, so it has to
inspect serialized `type` fields and clone values out of JSON objects.
This loses type information before aggregation and makes unsupported
instruction variants easy to overlook.
Keeping instructions typed lets aggregation use concrete equality and
hashing, preserves stable ordering while deduplicating updates, and
falls back to a total update when it encounters an instruction type it
cannot aggregate.
## How?
- Add `UpdateInstructionValue`, a type-erased serializable value with
typed downcasting and equality.
- Represent chunk-list and merged ECMAScript updates with owned,
hashable values backed by frozen collections.
- Aggregate typed instructions with first-seen ordering for merged
updates and last-writer-wins values for chunk updates.
- Serialize instructions only when producing the HMR protocol message.
- Add unit coverage for downcasting, equality, hashing, aggregation
behavior, and the existing JSON protocol shape.
## Verification
- Unit tests cover the new typed values and aggregation behavior.
- Serialization tests confirm the client-facing HMR messages are
unchanged.
- CI
<!-- NEXT_JS_LLM -->