Skip to content

Allow web authors to tee() with cloned chunks #1156

@MattiasBuelens

Description

@MattiasBuelens

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:

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 Expose structuredClone html#3414 ships in browsers).
  • You could use a bunch of TransformStreams to turn chunk into [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 the TransformStreams 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.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions