Observes ProtocolEvents during a graph run and builds typed derived projections (secondary event logs, promises, etc.).
Data is surfaced to consumers through projections returned from
init(). Projections are merged into GraphRunStream.extensions for
in-process consumers. Use StreamChannel.local for local streaming
values, StreamChannel.remote for values that should also be visible
to remote clients, or Promise<T> for final values.
To make projection data available to remote clients (SDK consumers
over WebSocket / SSE), create a named channel with
StreamChannel.remote(name). The StreamMux detects named
StreamChannel instances in the init() return and auto-forwards every
push() as a ProtocolEvent on custom:<name>. Remote clients
subscribe via session.subscribe("custom:<name>").
finalize and fail are optional. When a transformer uses
StreamChannel, the mux auto-closes/fails the channels on run
completion — no manual lifecycle management needed. Implement
finalize/fail only for non-channel teardown (e.g. resolving a
Promise).