- From: Mattias Buelens <notifications@github.com>
- Date: Wed, 04 Aug 2021 02:01:42 -0700
- To: whatwg/streams <streams@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/streams/issues/1156@github.com>
Currently, [`ReadableStream.prototype.tee()`](https://streams.spec.whatwg.org/commit-snapshots/5d86b65e45e0d56fcb8fbbff52fbbf2394918154/#rs-tee) performs [`ReadableStreamTee()`](https://streams.spec.whatwg.org/commit-snapshots/5d86b65e45e0d56fcb8fbbff52fbbf2394918154/#readable-stream-tee) 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 w3c/mediacapture-transform#56, each chunk is a `VideoFrame` which has an explicit `.close()` method to clean up it underlying media resource. A web author may want to process each frame with two parallel `TransformStream`s, 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 a `ReadableStream`"](https://streams.spec.whatwg.org/commit-snapshots/5d86b65e45e0d56fcb8fbbff52fbbf2394918154/#readablestream-tee), which sets `cloneForBranch2` to `true`. While it is *technically* possible to implement this in author code, the solution is not pretty: * You could re-implement `ReadableStreamTee()` yourself and call `VideoFrame.clone()` (or `structuredClone()` when whatwg/html#3414 ships in browsers). * You could use a bunch of `TransformStream`s to turn `chunk` into `[chunk, clonedChunk]`, then tee the stream, then pick the first or second element in the two branches. See [this comment](https://github.com/whatwg/streams/issues/1155#issuecomment-892184703) for an example. (Note that this also increases the total queue size by 2, since the `TransformStream`s 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 })`: performs `ReadableStreamTee(readable, true)`. Works only with transferable platform objects. * `readable.tee({ cloneCallback: (chunk) => chunk.clone() })`: calls the given `cloneCallback` where `ReadableStreamDefaultTee` currently calls `StructuredClone(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 `clone` is a function, then tee calls it whenever it needs to clone a chunk. * If `clone` is a boolean, then tee calls `StructuredClone()` if it's set to `true`. This acts as a shorthand for `readable.tee({ clone: structuredClone })`. (This issue was split from [#1155](https://github.com/whatwg/streams/issues/1155#issuecomment-892194167).) -- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/whatwg/streams/issues/1156
Received on Wednesday, 4 August 2021 09:01:57 UTC