v158 · network · webtransport
WebTransportReceiveStream
Incoming WebTransport streams in Chromium have historically been plain ReadableStream objects. Chrome 158 gives them the type the spec has named all along: WebTransportReceiveStream, a ReadableStream subclass whose one addition is getStats() — per-stream byte counters separating what the network delivered (bytesReceived) from what your code has actually consumed (bytesRead).
concepts
-
The subclass, member by member
Interrogate the real interface object: the prototype chain down to
ReadableStream,getStatsas the subclass's own single addition, the illegal-constructor rule, and where instances actually come from on a live session. -
bytesReceived vs bytesRead
The diagnosis the two counters exist for: is the network slow, or is your consumer? Probe the real stats surface, then drive a real
ReadableStreamproducer/consumer rig — clearly labelled as a local stand-in — where the gap between the two counters is the backlog you can watch grow and drain. -
Migration: what old code sees
A subclass is the compatible way to change a runtime type. Run the
instanceofand own-property matrix that proves plain-ReadableStreamcode keeps working, and see the feature-detect branches new code should use — including Firefox's shipped-but-rejectinggetStats.
why it shipped
Two reasons, one practical and one structural. Practically: an application receiving a large or latency-sensitive stream cannot tell browser-side buffering from network stall. getStats() splits the question — bytesReceived counts contiguous application bytes the browser has taken off the network for this stream, bytesRead counts what JavaScript has pulled out; a growing gap means your consumer is the bottleneck, not the connection. Structurally: the spec says incoming unidirectional streams and the readable half of bidirectional streams are WebTransportReceiveStreams, and Firefox and Safari already ship the type — exposing it aligns Chromium's runtime types with the spec and the other engines.
the API
interface WebTransportReceiveStream : ReadableStream {
Promise<WebTransportReceiveStreamStats> getStats();
};
// stats: { bytesReceived, bytesRead } — bytesRead ≤ bytesReceived
const reader = transport.incomingUnidirectionalStreams.getReader();
const { value: stream } = await reader.read(); // a WebTransportReceiveStream
const { bytesReceived, bytesRead } = await stream.getStats();
const bufferedInBrowser = bytesReceived - bytesRead;