-
Notifications
You must be signed in to change notification settings - Fork 168
Open
Description
Currently, ReadableStream.prototype.tee() performs ReadableStreamTee() with cloneForBranch2 always set to false. This means that both branches always see identical chunks (chunk1 === chunk2).
However, in some cases, web authors may want to clone each chunk before it is enqueued to the second branch:
- In MSTP's VideoFrame lifetime management model assumes a single consumer w3c/mediacapture-transform#56, each chunk is a
VideoFramewhich has an explicit.close()method to clean up it underlying media resource. A web author may want to process each frame with two parallelTransformStreams, while still allowing each branch to close their received frames. Therefore, the frames should be cloned first. - A polyfill for the Fetch API wants to implement
Response.clone(). This must replicate the behavior of "tee aReadableStream", which setscloneForBranch2totrue.
While it is technically possible to implement this in author code, the solution is not pretty:
- You could re-implement
ReadableStreamTee()yourself and callVideoFrame.clone()(orstructuredClone()when Expose structuredClone html#3414 ships in browsers). - You could use a bunch of
TransformStreams to turnchunkinto[chunk, clonedChunk], then tee the stream, then pick the first or second element in the two branches. See this comment for an example. (Note that this also increases the total queue size by 2, since theTransformStreams have a writable HWM of 1 chunk.)
Therefore, we may want to expose the cloneForBranch2 functionality to web authors. Some suggestions:
readable.tee({ structuredClone: true }): performsReadableStreamTee(readable, true). Works only with transferable platform objects.readable.tee({ cloneCallback: (chunk) => chunk.clone() }): calls the givencloneCallbackwhereReadableStreamDefaultTeecurrently callsStructuredClone(chunk2). Works with any object.
Or perhaps we can combine both into one option?
callback ReadableStreamTeeCloneCallback = any (any chunk);
dictionary ReadableStreamTeeOptions {
clone: (boolean or ReadableStreamTeeCloneCallback);
}
interface ReadableStream {
sequence<ReadableStream> tee(optional ReadableStreamTeeOptions options);
}
- If
cloneis a function, then tee calls it whenever it needs to clone a chunk. - If
cloneis a boolean, then tee callsStructuredClone()if it's set totrue. This acts as a shorthand forreadable.tee({ clone: structuredClone }).
(This issue was split from #1155.)
jan-ivar and eligrey
Metadata
Metadata
Assignees
Labels
No labels