WritableStream.cpp 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /*
  2. * Copyright (c) 2023, Matthew Olsson <mattco@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibJS/Runtime/PromiseCapability.h>
  7. #include <LibWeb/Bindings/Intrinsics.h>
  8. #include <LibWeb/Bindings/WritableStreamPrototype.h>
  9. #include <LibWeb/Streams/AbstractOperations.h>
  10. #include <LibWeb/Streams/UnderlyingSink.h>
  11. #include <LibWeb/Streams/WritableStream.h>
  12. #include <LibWeb/Streams/WritableStreamDefaultController.h>
  13. #include <LibWeb/Streams/WritableStreamDefaultWriter.h>
  14. #include <LibWeb/WebIDL/ExceptionOr.h>
  15. namespace Web::Streams {
  16. // https://streams.spec.whatwg.org/#ws-constructor
  17. WebIDL::ExceptionOr<JS::NonnullGCPtr<WritableStream>> WritableStream::construct_impl(JS::Realm& realm, Optional<JS::Handle<JS::Object>> const& underlying_sink_object)
  18. {
  19. auto& vm = realm.vm();
  20. auto writable_stream = MUST_OR_THROW_OOM(realm.heap().allocate<WritableStream>(realm, realm));
  21. // 1. If underlyingSink is missing, set it to null.
  22. auto underlying_sink = underlying_sink_object.has_value() ? JS::Value(underlying_sink_object.value().ptr()) : JS::js_null();
  23. // 2. Let underlyingSinkDict be underlyingSink, converted to an IDL value of type UnderlyingSink.
  24. auto underlying_sink_dict = TRY(UnderlyingSink::from_value(vm, underlying_sink));
  25. // 3. If underlyingSinkDict["type"] exists, throw a RangeError exception.
  26. if (!underlying_sink_dict.type.has_value())
  27. return WebIDL::SimpleException { WebIDL::SimpleExceptionType::RangeError, "Invalid use of reserved key 'type'"sv };
  28. // 4. Perform ! InitializeWritableStream(this).
  29. // Note: This AO configures slot values which are already specified in the class's field initializers.
  30. // FIXME: 5. Let sizeAlgorithm be ! ExtractSizeAlgorithm(strategy).
  31. SizeAlgorithm size_algorithm = [](auto const&) { return JS::normal_completion(JS::Value(1)); };
  32. // FIXME: 6. Let highWaterMark be ? ExtractHighWaterMark(strategy, 1).
  33. auto high_water_mark = 1.0;
  34. // FIXME: 7. Perform ? SetUpWritableStreamDefaultControllerFromUnderlyingSink(this, underlyingSink, underlyingSinkDict, highWaterMark, sizeAlgorithm).
  35. (void)high_water_mark;
  36. return writable_stream;
  37. }
  38. // https://streams.spec.whatwg.org/#ws-locked
  39. bool WritableStream::locked() const
  40. {
  41. // 1. Return ! IsWritableStreamLocked(this).
  42. return is_writable_stream_locked(*this);
  43. }
  44. WritableStream::WritableStream(JS::Realm& realm)
  45. : Bindings::PlatformObject(realm)
  46. {
  47. }
  48. JS::ThrowCompletionOr<void> WritableStream::initialize(JS::Realm& realm)
  49. {
  50. MUST_OR_THROW_OOM(Base::initialize(realm));
  51. set_prototype(&Bindings::ensure_web_prototype<Bindings::WritableStreamPrototype>(realm, "WritableStream"));
  52. return {};
  53. }
  54. void WritableStream::visit_edges(Cell::Visitor& visitor)
  55. {
  56. Base::visit_edges(visitor);
  57. visitor.visit(m_close_request);
  58. visitor.visit(m_controller);
  59. visitor.visit(m_in_flight_write_request);
  60. visitor.visit(m_in_flight_close_request);
  61. if (m_pending_abort_request.has_value()) {
  62. visitor.visit(m_pending_abort_request->promise);
  63. visitor.visit(m_pending_abort_request->reason);
  64. }
  65. visitor.visit(m_stored_error);
  66. visitor.visit(m_writer);
  67. for (auto& write_request : m_write_requests)
  68. visitor.visit(write_request);
  69. }
  70. }