glindex/transaction
Build and start IndexedDB transactions over one or more object stores.
All database operations run inside a transaction. Build one with
prepare, register the stores you need with store, then await the
Promise returned by begin. Store and index operations are then
performed via the glindex/store and
glindex/index modules.
Example
import gleam/javascript/promise
import glindex
import glindex/store
import glindex/transaction
pub fn get_track(db, id) {
let tx = transaction.prepare(db, transaction.read_only)
let #(tx, s) = transaction.store(tx, track_store())
use tx <- promise.await(transaction.begin(tx))
case tx {
Ok(tx) -> store.get(tx, s, glindex.Only(id))
Error(e) -> promise.resolve(Error(e))
}
}
Transaction lifetime
IndexedDB auto-commits a transaction as soon as it has no pending requests
and all microtasks have been processed. Do not await anything unrelated
to the database inside a transaction - for example, an HTTP request or a
timer. If the event loop goes idle between two database operations, the
transaction will have already committed and the next operation will fail
with TransactionInactiveError.
You generally do not need to call commit explicitly. Call abort to
roll back all changes made in the transaction.
Types
Handle to an active transaction.
pub type Transaction(readonly, upgrade)
Builder used to declare which stores a transaction will access before it is
started. Obtain one from prepare, add stores with store, then call
begin to open the transaction.
pub type TransactionBuilder(readonly)
Durability hint passed to the browser when creating the transaction.
DurabilityDefault- let the browser choose.DurabilityStrict- guarantee writes are flushed to disk beforeon_completefires (slower, safer).DurabilityRelaxed- allow the OS to decide when to flush (faster, risks data loss on power failure).
pub type TransactionDurability {
DurabilityDefault
DurabilityStrict
DurabilityRelaxed
}
Constructors
-
DurabilityDefault -
DurabilityStrict -
DurabilityRelaxed
Errors returned by store and index operations.
ConstraintError- a uniqueness constraint was violated.DataError- the key or value was invalid for the operation.InvalidStateError- the transaction or store is in an unexpected state.NotFoundError- no record matched the query.QuotaExceededError- the browser’s storage quota has been reached.TransactionInactiveError- the transaction has already committed or aborted.UnableToDecode- the record was found but the decoder failed.UnknownError- an unexpected browser error occurred.
pub type TransactionError {
ConstraintError
DataError
InvalidStateError
NotFoundError
QuotaExceededError
TransactionInactiveError
UnableToDecode(List(decode.DecodeError))
UnknownError(String)
}
Constructors
-
ConstraintError -
DataError -
InvalidStateError -
NotFoundError -
QuotaExceededError -
TransactionInactiveError -
UnableToDecode(List(decode.DecodeError)) -
UnknownError(String)
Handle to an index obtained via transaction.index.
pub type TransactionIndex(t, k, i)
The access mode of a transaction, carried as a phantom type.
Use the pre-built constants read_only and read_write instead of
constructing these directly.
pub type TransactionMode(readonly) {
TransactionReadOnly
TransactionReadWrite
}
Constructors
-
TransactionReadOnly -
TransactionReadWrite
Handle to an object store obtained after store is called on a builder.
The phantom type store_type must match the Store used to obtain it,
preventing indexes from one store being used with another store’s handle.
pub type TransactionStore(store_type, key_mode, t, k)
Values
pub fn abort(tx: Transaction(rw, upgrade)) -> Nil
Abort the transaction, rolling back all writes made so far.
pub fn begin(
builder: TransactionBuilder(readonly),
) -> promise.Promise(
Result(
Transaction(readonly, @internal Normal),
TransactionError,
),
)
Start the transaction and return a Promise resolving to the active handle.
Resolves to Ok(transaction) if the transaction was opened successfully,
or Error(TransactionError) if it could not be started.
pub fn commit(tx: Transaction(rw, upgrade)) -> Nil
Commit the transaction immediately without waiting for all pending requests to settle.
In most cases you do not need to call this - IndexedDB commits automatically once there are no more pending requests.
pub fn index(
store: TransactionStore(store_type, key_mode, t, k),
name: glindex.Index(store_type, t, k, i),
) -> TransactionIndex(t, k, i)
Obtain an index handle from a store handle.
The Index(store_type) and TransactionStore(store_type) must share the
same phantom type.
pub fn on_abort(
builder: TransactionBuilder(readonly),
handler: fn(option.Option(String)) -> Nil,
) -> TransactionBuilder(readonly)
Register a handler called when the transaction is aborted.
The handler receives Some(error_name) if the abort was triggered by an
error, or None if it was triggered by abort.
pub fn on_complete(
builder: TransactionBuilder(readonly),
handler: fn() -> Nil,
) -> TransactionBuilder(readonly)
Register a handler called when the transaction completes successfully.
pub fn on_error(
builder: TransactionBuilder(readonly),
handler: fn(String) -> Nil,
) -> TransactionBuilder(readonly)
Register a handler called when the transaction fails with an error.
The handler receives the browser error name as a string.
pub fn prepare(
db: glindex.Database,
mode: TransactionMode(readonly),
) -> TransactionBuilder(readonly)
Create a transaction builder for the given database and access mode.
Chain store calls to register every store you will access, then call
begin to start the transaction.
pub const read_only: TransactionMode(@internal ReadOnly)
Pre-built constant for a read-only transaction.
Multiple read-only transactions can run concurrently; prefer this mode whenever you do not need to write.
pub const read_write: TransactionMode(@internal ReadWrite)
Pre-built constant for a read-write transaction.
pub fn store(
builder: TransactionBuilder(readonly),
store: glindex.Store(store_type, key_mode, t, k),
) -> #(
TransactionBuilder(readonly),
TransactionStore(store_type, key_mode, t, k),
)
Register an object store on the builder and receive a typed handle.
Returns a tuple of #(updated_builder, store_handle). Chain multiple calls
to register all stores the transaction will access before calling begin.
let tx = transaction.prepare(db, transaction.read_write)
let #(tx, tracks) = transaction.store(tx, track_store())
let #(tx, artists) = transaction.store(tx, artist_store())
use tx <- promise.await(transaction.begin(tx))
pub fn with_durability(
builder: TransactionBuilder(readonly),
durability: TransactionDurability,
) -> TransactionBuilder(readonly)
Set the durability hint for the transaction.