1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 19:17:44 +00:00

LibWeb: Add the ReadableStreamGenericReader mixin interface

This commit is contained in:
Matthew Olsson 2023-03-28 17:43:34 -07:00 committed by Linus Groh
parent f409f68a9a
commit fe69d66a4e
9 changed files with 189 additions and 3 deletions

View file

@ -1,11 +1,14 @@
/*
* Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2023, Matthew Olsson <mattco@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/Streams/AbstractOperations.h>
#include <LibWeb/Streams/ReadableStream.h>
#include <LibWeb/Streams/ReadableStreamGenericReader.h>
#include <LibWeb/WebIDL/ExceptionOr.h>
namespace Web::Streams {
@ -20,4 +23,82 @@ bool is_readable_stream_locked(ReadableStream const& stream)
return true;
}
// https://streams.spec.whatwg.org/#readable-stream-cancel
WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> readable_stream_cancel(ReadableStream& stream, JS::Value reason)
{
auto& realm = stream.realm();
// 1. Set stream.[[disturbed]] to true.
stream.set_disturbed(true);
// 2. If stream.[[state]] is "closed", return a promise resolved with undefined.
if (stream.is_closed())
return WebIDL::create_resolved_promise(realm, JS::js_undefined());
// 3. If stream.[[state]] is "errored", return a promise rejected with stream.[[storedError]].
if (stream.is_errored())
return WebIDL::create_rejected_promise(realm, stream.stored_error());
// 4. Perform ! ReadableStreamClose(stream).
readable_stream_close(stream);
// 5. Let reader be stream.[[reader]].
auto reader = stream.reader();
// FIXME:
// 6. If reader is not undefined and reader implements ReadableStreamBYOBReader,
// 1. Let readIntoRequests be reader.[[readIntoRequests]].
// 2. Set reader.[[readIntoRequests]] to an empty list.
// 3. For each readIntoRequest of readIntoRequests,
// 1. Perform readIntoRequests close steps, given undefined.
// 7. Let sourceCancelPromise be ! stream.[[controller]].[[CancelSteps]](reason).
// 8. Return the result of reacting to sourceCancelPromise with a fulfillment step that returns undefined.
(void)reader;
(void)reason;
return WebIDL::create_resolved_promise(realm, JS::js_undefined());
}
// https://streams.spec.whatwg.org/#readable-stream-close
void readable_stream_close(ReadableStream& stream)
{
auto& realm = stream.realm();
// 1. Assert: stream.[[state]] is "readable".
VERIFY(stream.is_readable());
// 2. Set stream.[[state]] to "closed".
stream.set_stream_state(ReadableStream::State::Closed);
// 3. Let reader be stream.[[reader]].
auto reader = stream.reader();
// 4. If reader is undefined, return.
if (!reader)
return;
// 5. Resolve reader.[[closedPromise]] with undefined.
WebIDL::resolve_promise(realm, *reader->closed_promise_capability());
// FIXME:
// 6. If reader implements ReadableStreamDefaultReader,
// 1. Let readRequests be reader.[[readRequests]].
// 2. Set reader.[[readRequests]] to an empty list.
// 3. For each readRequest of readRequests,
// 1. Perform readRequests close steps.
}
// https://streams.spec.whatwg.org/#readable-stream-reader-generic-cancel
JS::NonnullGCPtr<WebIDL::Promise> readable_stream_reader_generic_cancel(ReadableStreamGenericReaderMixin& reader, JS::Value reason)
{
// 1. Let stream be reader.[[stream]]
auto stream = reader.stream();
// 2. Assert: stream is not undefined
VERIFY(stream);
// 3. Return ! ReadableStreamCancel(stream, reason)
return MUST(readable_stream_cancel(*stream, reason));
}
}