/* * Copyright (c) 2024-2025, stelar7 * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include #include #include #include namespace Web::IndexedDB { // https://w3c.github.io/IndexedDB/#transaction class IDBTransaction : public DOM::EventTarget { WEB_PLATFORM_OBJECT(IDBTransaction, DOM::EventTarget); GC_DECLARE_ALLOCATOR(IDBTransaction); enum TransactionState { Active, Inactive, Committing, Finished }; public: virtual ~IDBTransaction() override; [[nodiscard]] static GC::Ref create(JS::Realm&, GC::Ref, Bindings::IDBTransactionMode, Bindings::IDBTransactionDurability, Vector>); [[nodiscard]] Bindings::IDBTransactionMode mode() const { return m_mode; } [[nodiscard]] TransactionState state() const { return m_state; } [[nodiscard]] GC::Ptr error() const { return m_error; } [[nodiscard]] GC::Ref connection() const { return m_connection; } [[nodiscard]] Bindings::IDBTransactionDurability durability() const { return m_durability; } [[nodiscard]] GC::Ptr associated_request() const { return m_associated_request; } [[nodiscard]] bool aborted() const { return m_aborted; } [[nodiscard]] GC::Ref object_store_names(); [[nodiscard]] RequestList& request_list() { return m_request_list; } [[nodiscard]] ReadonlySpan> scope() const { return m_scope; } [[nodiscard]] String uuid() const { return m_uuid; } void set_mode(Bindings::IDBTransactionMode mode) { m_mode = mode; } void set_error(GC::Ptr error) { m_error = error; } void set_associated_request(GC::Ptr request) { m_associated_request = request; } void set_aborted(bool aborted) { m_aborted = aborted; } void set_cleanup_event_loop(GC::Ptr event_loop) { m_cleanup_event_loop = event_loop; } void set_state(TransactionState state) { m_state = state; } [[nodiscard]] bool is_upgrade_transaction() const { return m_mode == Bindings::IDBTransactionMode::Versionchange; } [[nodiscard]] bool is_readonly() const { return m_mode == Bindings::IDBTransactionMode::Readonly; } [[nodiscard]] bool is_readwrite() const { return m_mode == Bindings::IDBTransactionMode::Readwrite; } [[nodiscard]] bool is_finished() const { return m_state == TransactionState::Finished; } GC::Ptr object_store_named(String const& name) const; void add_to_scope(GC::Ref object_store) { m_scope.append(object_store); } WebIDL::ExceptionOr abort(); WebIDL::ExceptionOr commit(); WebIDL::ExceptionOr> object_store(String const& name); void set_onabort(WebIDL::CallbackType*); WebIDL::CallbackType* onabort(); void set_oncomplete(WebIDL::CallbackType*); WebIDL::CallbackType* oncomplete(); void set_onerror(WebIDL::CallbackType*); WebIDL::CallbackType* onerror(); protected: explicit IDBTransaction(JS::Realm&, GC::Ref, Bindings::IDBTransactionMode, Bindings::IDBTransactionDurability, Vector>); virtual void initialize(JS::Realm&) override; virtual void visit_edges(Visitor& visitor) override; private: // AD-HOC: The transaction has a connection GC::Ref m_connection; // A transaction has a mode that determines which types of interactions can be performed upon that transaction. Bindings::IDBTransactionMode m_mode; // A transaction has a durability hint. This is a hint to the user agent of whether to prioritize performance or durability when committing the transaction. Bindings::IDBTransactionDurability m_durability { Bindings::IDBTransactionDurability::Default }; // A transaction has a state TransactionState m_state; // A transaction has a error which is set if the transaction is aborted. GC::Ptr m_error; // A transaction has an associated upgrade request GC::Ptr m_associated_request; // AD-HOC: We need to track abort state separately, since we cannot rely on only the error. bool m_aborted { false }; // A transaction has a scope which is a set of object stores that the transaction may interact with. Vector> m_scope; // A transaction has a request list of pending requests which have been made against the transaction. RequestList m_request_list; // A transaction optionally has a cleanup event loop which is an event loop. GC::Ptr m_cleanup_event_loop; // NOTE: Used for debug purposes String m_uuid; }; }