1
0
mirror of https://github.com/SerenityOS/serenity synced 2024-07-09 03:50:45 +00:00

LibWeb: Expose the ReadableStream tee IDL interface

This just sets up the plumbing to the underlying ReadableStreamTee AO,
which as of this commit, will just throw a NotImplemented exception.
This commit is contained in:
Timothy Flynn 2024-01-28 10:28:59 -05:00 committed by Andreas Kling
parent 5ccd1ff1bf
commit d8413774df
5 changed files with 43 additions and 1 deletions

View File

@ -238,6 +238,21 @@ bool readable_stream_has_default_reader(ReadableStream const& stream)
return false;
}
// https://streams.spec.whatwg.org/#readable-stream-tee
WebIDL::ExceptionOr<ReadableStreamPair> readable_stream_tee(JS::Realm& realm, ReadableStream& stream, bool)
{
// 1. Assert: stream implements ReadableStream.
// 2. Assert: cloneForBranch2 is a boolean.
// 3. If stream.[[controller]] implements ReadableByteStreamController, return ? ReadableByteStreamTee(stream).
if (stream.controller()->has<JS::NonnullGCPtr<Streams::ReadableByteStreamController>>()) {
return realm.vm().throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "Byte stream teeing");
}
// 4. Return ? ReadableStreamDefaultTee(stream, cloneForBranch2).
return realm.vm().throw_completion<JS::InternalError>(JS::ErrorType::NotImplemented, "Default stream teeing");
}
// https://streams.spec.whatwg.org/#make-size-algorithm-from-size-function
JS::NonnullGCPtr<SizeAlgorithm> extract_size_algorithm(JS::VM& vm, QueuingStrategy const& strategy)
{

View File

@ -47,6 +47,8 @@ size_t readable_stream_get_num_read_requests(ReadableStream const&);
bool readable_stream_has_byob_reader(ReadableStream const&);
bool readable_stream_has_default_reader(ReadableStream const&);
WebIDL::ExceptionOr<ReadableStreamPair> readable_stream_tee(JS::Realm&, ReadableStream&, bool clone_for_branch2);
WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> readable_stream_reader_generic_cancel(ReadableStreamGenericReaderMixin&, JS::Value reason);
void readable_stream_reader_generic_initialize(ReadableStreamReader, ReadableStream&);
WebIDL::ExceptionOr<void> readable_stream_reader_generic_release(ReadableStreamGenericReaderMixin&);

View File

@ -108,6 +108,13 @@ WebIDL::ExceptionOr<ReadableStreamReader> ReadableStream::get_reader(ReadableStr
return ReadableStreamReader { TRY(acquire_readable_stream_byob_reader(*this)) };
}
// https://streams.spec.whatwg.org/#readablestream-tee
WebIDL::ExceptionOr<ReadableStreamPair> ReadableStream::tee()
{
// To tee a ReadableStream stream, return ? ReadableStreamTee(stream, true).
return TRY(readable_stream_tee(realm(), *this, true));
}
void ReadableStream::initialize(JS::Realm& realm)
{
Base::initialize(realm);

View File

@ -26,6 +26,23 @@ struct ReadableStreamGetReaderOptions {
Optional<Bindings::ReadableStreamReaderMode> mode;
};
struct ReadableStreamPair {
// Define a couple container-like methods so this type may be used as the return type of the IDL `tee` implementation.
size_t size() const { return 2; }
JS::NonnullGCPtr<ReadableStream>& at(size_t index)
{
if (index == 0)
return first;
if (index == 1)
return second;
VERIFY_NOT_REACHED();
}
JS::NonnullGCPtr<ReadableStream> first;
JS::NonnullGCPtr<ReadableStream> second;
};
// https://streams.spec.whatwg.org/#readablestream
class ReadableStream final : public Bindings::PlatformObject {
WEB_PLATFORM_OBJECT(ReadableStream, Bindings::PlatformObject);
@ -45,6 +62,7 @@ public:
bool locked() const;
WebIDL::ExceptionOr<JS::GCPtr<JS::Object>> cancel(JS::Value reason);
WebIDL::ExceptionOr<ReadableStreamReader> get_reader(ReadableStreamGetReaderOptions const& = {});
WebIDL::ExceptionOr<ReadableStreamPair> tee();
Optional<ReadableStreamController>& controller() { return m_controller; }
void set_controller(Optional<ReadableStreamController> value) { m_controller = move(value); }

View File

@ -23,7 +23,7 @@ interface ReadableStream {
ReadableStreamReader getReader(optional ReadableStreamGetReaderOptions options = {});
// FIXME: ReadableStream pipeThrough(ReadableWritablePair transform, optional StreamPipeOptions options = {});
// FIXME: Promise<undefined> pipeTo(WritableStream destination, optional StreamPipeOptions options = {});
// FIXME: sequence<ReadableStream> tee();
sequence<ReadableStream> tee();
// FIXME: async iterable<any>(optional ReadableStreamIteratorOptions options = {});
};