Packages

Gleam bindings for the IndexedDB API

Current section

Files

Jump to
idb src idb.gleam
Raw

src/idb.gleam

import gleam/dynamic.{type Dynamic}
import gleam/json.{type Json}
import gleam/list
import gleam/option.{type Option, None, Some}
import gleam/result
import gleam/string
import idb/event.{type ConnectEventHandler}
import idb/index.{type IndexKey}
import idb/internals/internal
import idb/range.{type KeyRange}
import idb/store.{type ObjectStoreKey}
// ---- Types -----------------------------------------------------------------
/// Type to represent a [connection](https://developer.mozilla.org/docs/Web/API/IndexedDB_API/Basic_Terminology#database_connection)
/// to an IndexedDB [database](https://developer.mozilla.org/docs/Web/API/IndexedDB_API/Basic_Terminology#database).
///
/// Use [`connect`](#connect) to create an instance of `Connection`.
///
pub type Connection
/// Type to represent an IndexedDB error.
///
pub type IdbError
/// Type to represent an IndexedDB [index](https://developer.mozilla.org/docs/Web/API/IndexedDB_API/Basic_Terminology#index).
///
/// Use [`create_index`](#create_index) to create an instance of `Index`.
///
pub type Index
/// Type to represent the [key](https://developer.mozilla.org/docs/Web/API/IndexedDB_API/Basic_Terminology#key)
/// used on an IndexedDB object store or index.
///
pub type Key =
internal.Key
/// Type to represent an IndexedDB [object store](https://developer.mozilla.org/docs/Web/API/IndexedDB_API/Basic_Terminology#object_store).
///
/// Use [`create_store`](#create_store) to create an instance of `ObjectStore`.
///
pub type ObjectStore
/// Type to represent an IndexedDB [transaction](https://developer.mozilla.org/docs/Web/API/IndexedDB_API/Basic_Terminology#transaction).
///
/// Use [`start_transaction`](#start_transaction) to create an instance of `Transaction`.
///
pub type Transaction =
internal.Transaction
/// Type to represent an IndexedDB [transaction](https://developer.mozilla.org/docs/Web/API/IndexedDB_API/Basic_Terminology#transaction)
/// access [mode](https://developer.mozilla.org/docs/Web/API/IDBTransaction/mode).
///
pub type TransactionMode {
ReadOnly
ReadWrite
}
// ---- Key Constructors -----------------------------------------------------
/// Creates a new `Key` from `String`.
///
@external(javascript, "./idb_ffi.ts", "key")
pub fn key_string(value: String) -> Key
/// Creates a new `Key` from `Int`.
///
@external(javascript, "./idb_ffi.ts", "key")
pub fn key_int(value: Int) -> Key
/// Creates a new `Key` from `Float`.
///
@external(javascript, "./idb_ffi.ts", "key")
pub fn key_float(value: Float) -> Key
/// Creates a new `Key` from a list of `Key`.
///
@external(javascript, "./idb_ffi.ts", "key")
pub fn key_list(value: List(Key)) -> Key
// ---- Database Functions ----------------------------------------------------
/// Retrieves a list of available databases, returning its name and version.
///
/// The last argument is executed when the list is available
/// or when the attempt is failed.
///
@external(javascript, "./idb_ffi.ts", "getDatabases")
pub fn get_databases(
next: fn(Result(List(#(String, Int)), IdbError)) -> a,
) -> Nil
/// Creates a connection to an IndexedDB database with the specified name and version.
///
/// If the specified version is zero or negative value, then it will be treated as 1.
///
/// If the database does not exist, then it will be created.
///
/// The last argument is executed when the connection is created
/// or when the attempt is failed.
/// The returned value is discarded.
///
/// Similar to the [`IDBFactory.open`](https://developer.mozilla.org/docs/Web/API/IDBFactory/open)
/// on the IndexedDB API.
///
pub fn connect(
name: String,
version: Int,
event_handlers: List(ConnectEventHandler(a, b, c, d)),
next: fn(Result(Connection, IdbError)) -> e,
) -> Nil {
let #(on_upgrade_needed, on_blocked, on_version_change, on_close) = {
event_handlers
|> list.fold(#(None, None, None, None), fn(acc, handler) {
case handler {
event.OnUpgrade(x) -> #(Some(x), acc.1, acc.2, acc.3)
event.OnBlocked(x) -> #(acc.0, Some(x), acc.2, acc.3)
event.OnBlocking(x) -> #(acc.0, acc.1, Some(x), acc.3)
event.OnTerminated(x) -> #(acc.0, acc.1, acc.2, Some(x))
}
})
}
do_connect(
name,
case version {
v if v <= 0 -> 1
v -> v
},
on_upgrade_needed,
on_blocked,
on_version_change,
on_close,
next,
)
}
@external(javascript, "./idb_ffi.ts", "connect")
fn do_connect(
name: String,
version: Int,
on_upgrade_needed: Option(fn(Transaction, Int, Int) -> a),
on_blocked: Option(fn(Int, Int) -> b),
on_version_change: Option(fn(Int, Int) -> c),
on_close: Option(fn() -> d),
next: fn(Result(Connection, IdbError)) -> e,
) -> Nil
/// This is an utility function that combines
/// [`connect`](#connect) with `result.try`.
///
pub fn try_connect(
name: String,
version: Int,
event_handlers: List(ConnectEventHandler(a, b, c, d)),
apply fun: fn(Connection) -> Result(e, IdbError),
) -> Nil {
use db <- connect(name, version, event_handlers)
result.try(db, fun)
}
/// Deletes an IndexedDB database with the specified name.
///
/// The last argument is executed when the database is deleted
/// or when the attempt is failed.
/// The returned value is discarded.
///
/// Similar to the [`IDBFactory.deleteDatabase`](https://developer.mozilla.org/docs/Web/API/IDBFactory/deleteDatabase)
/// on the IndexedDB API.
///
@external(javascript, "./idb_ffi.ts", "deleteDatabase")
pub fn delete_database(
name: String,
next: fn(Result(Nil, IdbError)) -> a,
) -> Nil
/// Starts a new transaction that can be used to access the specified object stores.
///
/// The last argument is executed when the transaction is completed or errored.
/// The returned value is discarded.
///
/// Similar to the [`IDBDatabase.transaction`](https://developer.mozilla.org/docs/Web/API/IDBDatabase/transaction)
/// on the IndexedDB API.
///
pub fn start_transaction(
db: Connection,
store_names: List(String),
mode: TransactionMode,
on_close: fn(Result(Nil, IdbError)) -> a,
) -> Result(Transaction, IdbError) {
do_start_transaction(
db,
store_names,
case mode {
ReadOnly -> "readonly"
ReadWrite -> "readwrite"
},
on_close,
)
}
@external(javascript, "./idb_ffi.ts", "startTransaction")
fn do_start_transaction(
db: Connection,
store_names: List(String),
mode: String,
on_close: fn(Result(Nil, IdbError)) -> a,
) -> Result(Transaction, IdbError)
/// Starts a new transaction with only a single object store.
///
/// The last argument is executed when the transaction is completed or errored.
/// The returned value is discarded.
///
/// This is an utility function that combines
/// [`start_transaction`](#start_transaction) with [`get_store`](#get_store).
///
pub fn start_store_transaction(
db: Connection,
store_name: String,
mode: TransactionMode,
on_close: fn(Result(Nil, IdbError)) -> a,
) -> Result(ObjectStore, IdbError) {
use tx <- result.try(start_transaction(db, [store_name], mode, on_close))
get_store(tx, store_name)
}
/// Starts a new transaction with only a single index.
///
/// The last argument is executed when the transaction is completed or errored.
/// The returned value is discarded.
///
/// This is an utility function that combines
/// [`start_transaction`](#start_transaction) with [`get_store`](#get_store)
/// and [`get_index`](#get_index).
///
pub fn start_index_transaction(
db: Connection,
store_index_name: #(String, String),
on_close: fn(Result(Nil, IdbError)) -> a,
) -> Result(Index, IdbError) {
use tx <- result.try(start_transaction(
db,
[store_index_name.0],
ReadOnly,
on_close,
))
use store <- result.try(get_store(tx, store_index_name.0))
get_index(store, store_index_name.1)
}
// ---- ObjectStore Functions -------------------------------------------------
/// Retrieves a list of the names of the object stores
/// currently in the connected database.
///
@external(javascript, "./idb_ffi.ts", "getStoreNames")
pub fn get_store_names(db: Connection) -> List(String)
/// Retrieves a list of the names of the object stores
/// currently available in the transaction.
///
@external(javascript, "./idb_ffi.ts", "getTransactionStoreNames")
pub fn get_transaction_store_names(tx: Transaction) -> List(String)
/// Retrieves an object store to be used for operations.
///
@external(javascript, "./idb_ffi.ts", "getStore")
pub fn get_store(tx: Transaction, name: String) -> Result(ObjectStore, IdbError)
/// Creates a new object store with the specified name and key.
///
/// Can only be called using `versionchange` transaction, will return an `Error` otherwise.
/// Use [`connect`](#connect) with [`on_upgrade`](#on_upgrade)
/// to initialize a `versionchange` transaction.
///
/// Similar to the [`IDBDatabase.createObjectStore`](https://developer.mozilla.org/docs/Web/API/IDBDatabase/createObjectStore)
/// on the IndexedDB API.
///
pub fn create_store(
tx: Transaction,
name: String,
key: ObjectStoreKey,
) -> Result(ObjectStore, IdbError) {
do_create_store(tx, name, case key {
store.OutOfLineKey -> json.null()
store.AutoIncrementedOutOfLineKey ->
json.object([#("autoIncrement", json.bool(True))])
store.InLineKey("") -> json.null()
store.InLineKey(key) -> json.object([#("keyPath", json.string(key))])
store.AutoIncrementedInLineKey("") -> json.null()
store.AutoIncrementedInLineKey(key) ->
json.object([
#("keyPath", json.string(key)),
#("autoIncrement", json.bool(True)),
])
store.CompoundInLineKey([]) -> json.null()
store.CompoundInLineKey(keys) ->
case keys |> list.filter(fn(k) { !string.is_empty(k) }) {
[] -> json.null()
_ -> json.object([#("keyPath", json.array(keys, json.string))])
}
})
}
@external(javascript, "./idb_ffi.ts", "createStore")
fn do_create_store(
tx: Transaction,
name: String,
key: Json,
) -> Result(ObjectStore, IdbError)
/// Deletes an [object store](https://developer.mozilla.org/docs/Web/API/IndexedDB_API/Basic_Terminology#object_store)
/// with the specified name, along with any indexes that reference it.
///
/// Can only be called using `versionchange` transaction, will return an `Error` otherwise.
/// Use [`connect`](#connect) with [`on_upgrade`](#on_upgrade)
/// to initialize a `versionchange` transaction.
///
/// Similar to the [`IDBDatabase.deleteObjectStore`](https://developer.mozilla.org/docs/Web/API/IDBDatabase/deleteObjectStore)
/// on the IndexedDB API.
///
@external(javascript, "./idb_ffi.ts", "deleteStore")
pub fn delete_store(tx: Transaction, name: String) -> Result(Nil, IdbError)
// ---- ObjectStore Operation Functions ---------------------------------------
fn quick_operation(
db: Connection,
store_name: String,
mode: TransactionMode,
operation: fn(ObjectStore) -> Nil,
next: fn(Result(a, IdbError)) -> b,
) -> Nil {
{
use store <- result.map(
start_store_transaction(db, store_name, mode, fn(_) { Nil }),
)
operation(store)
}
|> result.map_error(fn(e) {
next(Error(e))
Nil
})
|> result_unwrap()
}
/// Inserts a new record
/// to an object store.
///
/// The last argument is executed with the key or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// Similar to the [`IDBObjectStore.add`](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/add)
/// on the IndexedDB API.
///
@external(javascript, "./idb_ffi.ts", "add")
pub fn add(
store: ObjectStore,
value: Json,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil
/// Inserts a new record
/// to an object store inside a new transaction.
///
/// The last argument is executed with the key or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// This is an utility function that combines
/// [`start_store_transaction`](#start_store_transaction) with [`add`](#add).
///
pub fn quick_add(
db: Connection,
store_name: String,
value: Json,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil {
{ add(_, value, next) }
|> quick_operation(db, store_name, ReadWrite, _, next)
}
/// Inserts a new record using a specified key
/// to an object store.
///
/// The last argument is executed with the key or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// Similar to the [`IDBObjectStore.add`](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/add)
/// on the IndexedDB API.
///
@external(javascript, "./idb_ffi.ts", "addTo")
pub fn add_to(
store: ObjectStore,
key: Key,
value: Json,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil
/// Inserts a new record using a specified key
/// to an object store inside a new transaction.
///
/// The last argument is executed with the key or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// This is an utility function that combines
/// [`start_store_transaction`](#start_store_transaction) with [`add_to`](#add_to).
///
pub fn quick_add_to(
db: Connection,
store_name: String,
key: Key,
value: Json,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil {
{ add_to(_, key, value, next) }
|> quick_operation(db, store_name, ReadWrite, _, next)
}
/// Retrieves the total number of records within the range
/// in an object store.
///
/// The last argument is executed with the result or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// Similar to the [`IDBObjectStore.count`](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/count)
/// on the IndexedDB API.
///
@external(javascript, "./idb_ffi.ts", "count")
pub fn count(
store: ObjectStore,
query: KeyRange,
next: fn(Result(Int, IdbError)) -> a,
) -> Nil
/// Retrieves the total number of records within the range
/// in an object store inside a new transaction.
///
/// The last argument is executed with the result or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// This is an utility function that combines
/// [`start_store_transaction`](#start_store_transaction) with [`count`](#count).
///
pub fn quick_count(
db: Connection,
store_name: String,
query: KeyRange,
next: fn(Result(Int, IdbError)) -> a,
) -> Nil {
{ count(_, query, next) }
|> quick_operation(db, store_name, ReadOnly, _, next)
}
/// Deletes all records within the range
/// from an object store.
///
/// The last argument is executed
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// Similar to the [`IDBObjectStore.delete`](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/delete)
/// and [`IDBObjectStore.clear`](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/clear)
/// on the IndexedDB API.
///
@external(javascript, "./idb_ffi.ts", "delete_")
pub fn delete(
store: ObjectStore,
query: KeyRange,
next: fn(Result(Nil, IdbError)) -> a,
) -> Nil
/// Deletes all records within the range
/// from an object store inside a new transaction.
///
/// The last argument is executed
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// This is an utility function that combines
/// [`start_store_transaction`](#start_store_transaction) with [`delete`](#delete).
///
pub fn quick_delete(
db: Connection,
store_name: String,
query: KeyRange,
next: fn(Result(Nil, IdbError)) -> a,
) -> Nil {
{ delete(_, query, next) }
|> quick_operation(db, store_name, ReadWrite, _, next)
}
/// Retrieves the first record within the range
/// from an object store.
///
/// The last argument is executed with the record value or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// Similar to the [`IDBObjectStore.get`](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/get)
/// on the IndexedDB API.
///
@external(javascript, "./idb_ffi.ts", "getOne")
pub fn get_one(
store: ObjectStore,
query: KeyRange,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil
/// Retrieves the first record within the range
/// from an object store inside a new transaction.
///
/// The last argument is executed with the record value or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// This is an utility function that combines
/// [`start_store_transaction`](#start_store_transaction) with [`get_one`](#get_one).
///
pub fn quick_get_one(
db: Connection,
store_name: String,
query: KeyRange,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil {
{ get_one(_, query, next) }
|> quick_operation(db, store_name, ReadOnly, _, next)
}
/// Retrieves all records within the range
/// from an object store.
///
/// The last argument is executed with the record values or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// Similar to the [`IDBObjectStore.getAll`](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/getAll)
/// on the IndexedDB API.
///
@external(javascript, "./idb_ffi.ts", "get")
pub fn get(
store: ObjectStore,
query: KeyRange,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil
/// Retrieves all records within the range
/// from an object store inside a new transaction.
///
/// The last argument is executed with the record values or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// This is an utility function that combines
/// [`start_store_transaction`](#start_store_transaction) with [`get`](#get).
///
pub fn quick_get(
db: Connection,
store_name: String,
query: KeyRange,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil {
{ get(_, query, next) }
|> quick_operation(db, store_name, ReadOnly, _, next)
}
/// Retrieves some records within the range
/// from an object store.
///
/// Limits the retrieved records to the amount specified on the third argument.
/// If the limit is a negative `Int`, then it will be treated as no limit.
///
/// The last argument is executed with the record values or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// Similar to the [`IDBObjectStore.getAll`](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/getAll)
/// on the IndexedDB API.
///
@external(javascript, "./idb_ffi.ts", "getWithLimit")
pub fn get_with_limit(
store: ObjectStore,
query: KeyRange,
limit: Int,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil
/// Retrieves some records within the range
/// from an object store inside a new transaction.
///
/// Limits the retrieved records to the amount specified on the fourth argument.
/// If the limit is a negative `Int`, then it will be treated as no limit.
///
/// The last argument is executed with the record values or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// This is an utility function that combines
/// [`start_store_transaction`](#start_store_transaction) with [`get_with_limit`](#get_with_limit).
///
pub fn quick_get_with_limit(
db: Connection,
store_name: String,
query: KeyRange,
limit: Int,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil {
{ get_with_limit(_, query, limit, next) }
|> quick_operation(db, store_name, ReadOnly, _, next)
}
/// Retrieves the first key within the range
/// from an object store.
///
/// The last argument is executed with the record key or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// Similar to the [`IDBObjectStore.getKey`](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/getKey)
/// on the IndexedDB API.
///
@external(javascript, "./idb_ffi.ts", "getOneKey")
pub fn get_one_key(
store: ObjectStore,
query: KeyRange,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil
/// Retrieves the first key within the range
/// from an object store inside a new transaction.
///
/// The last argument is executed with the record key or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// This is an utility function that combines
/// [`start_store_transaction`](#start_store_transaction) with [`get_one_key`](#get_one_key).
///
pub fn quick_get_one_key(
db: Connection,
store_name: String,
query: KeyRange,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil {
{ get_one_key(_, query, next) }
|> quick_operation(db, store_name, ReadOnly, _, next)
}
/// Retrieves all keys within the range
/// from an object store.
///
/// The last argument is executed with the record keys or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// Similar to the [`IDBObjectStore.getAllKeys`](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/getAllKeys)
/// on the IndexedDB API.
///
@external(javascript, "./idb_ffi.ts", "getKeys")
pub fn get_keys(
store: ObjectStore,
query: KeyRange,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil
/// Retrieves all keys within the range
/// from an object store inside a new transaction.
///
/// The last argument is executed with the record keys or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// This is an utility function that combines
/// [`start_store_transaction`](#start_store_transaction) with [`get_keys`](#get_keys).
///
pub fn quick_get_keys(
db: Connection,
store_name: String,
query: KeyRange,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil {
{ get_keys(_, query, next) }
|> quick_operation(db, store_name, ReadOnly, _, next)
}
/// Retrieves some keys within the range
/// from an object store.
///
/// Limits the retrieved keys to the amount specified on the third argument.
/// If the limit is a negative `Int`, then it will be treated as no limit.
///
/// The last argument is executed with the record keys or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// Similar to the [`IDBObjectStore.getAllKeys`](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/getAllKeys)
/// on the IndexedDB API.
///
@external(javascript, "./idb_ffi.ts", "getKeysWithLimit")
pub fn get_keys_with_limit(
store: ObjectStore,
query: KeyRange,
limit: Int,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil
/// Retrieves some keys within the range
/// from an object store inside a new transaction.
///
/// Limits the retrieved keys to the amount specified on the fourth argument.
/// If the limit is a negative `Int`, then it will be treated as no limit.
///
/// The last argument is executed with the record keys or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// This is an utility function that combines
/// [`start_store_transaction`](#start_store_transaction) with [`get_keys_with_limit`](#get_keys_with_limit).
///
pub fn quick_get_keys_with_limit(
db: Connection,
store_name: String,
query: KeyRange,
limit: Int,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil {
{ get_keys_with_limit(_, query, limit, next) }
|> quick_operation(db, store_name, ReadOnly, _, next)
}
/// Updates a record in an object store
/// or inserts a new record if it does not already exist.
///
/// The last argument is executed with the key or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// Similar to the [`IDBObjectStore.put`](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/put)
/// on the IndexedDB API.
///
@external(javascript, "./idb_ffi.ts", "put")
pub fn put(
store: ObjectStore,
value: Json,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil
/// Updates a record in an object store
/// or inserts a new record if it does not already exist
/// inside a new transaction.
///
/// The last argument is executed with the key or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// This is an utility function that combines
/// [`start_store_transaction`](#start_store_transaction) with [`put`](#put).
///
pub fn quick_put(
db: Connection,
store_name: String,
value: Json,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil {
{ put(_, value, next) }
|> quick_operation(db, store_name, ReadWrite, _, next)
}
/// Updates a record using a specified key in an object store
/// or inserts a new record if it does not already exist.
///
/// The last argument is executed with the key or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// Similar to the [`IDBObjectStore.put`](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/put)
/// on the IndexedDB API.
///
@external(javascript, "./idb_ffi.ts", "putTo")
pub fn put_to(
store: ObjectStore,
key: Key,
value: Json,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil
/// Updates a record using a specified key in an object store
/// or inserts a new record if it does not already exist
/// inside a new transaction.
///
/// The last argument is executed with the key or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// This is an utility function that combines
/// [`start_store_transaction`](#start_store_transaction) with [`put_to`](#put_to).
///
pub fn quick_put_to(
db: Connection,
store_name: String,
key: Key,
value: Json,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil {
{ put_to(_, key, value, next) }
|> quick_operation(db, store_name, ReadWrite, _, next)
}
// ---- Index Functions -------------------------------------------------------
/// Retrieves a list of the names of the indexes
/// currently referencing the object store.
///
@external(javascript, "./idb_ffi.ts", "getIndexNames")
pub fn get_index_names(store: ObjectStore) -> List(String)
/// Retrieves an index to be used for operations.
///
@external(javascript, "./idb_ffi.ts", "getIndex")
pub fn get_index(store: ObjectStore, name: String) -> Result(Index, IdbError)
/// Creates an index that referenced the specified
/// object store with the specified name.
///
/// Can only be called using `ObjectStore` inside a `versionchange` transaction,
/// will return an `Error` otherwise.
/// Use [`connect`](#connect) with [`on_upgrade`](#on_upgrade)
/// to initialize a `versionchange` transaction.
///
/// Similar to the [`IDBObjectStore.createIndex`](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/createIndex)
/// on the IndexedDB API.
///
pub fn create_index(
store: ObjectStore,
name: String,
key: IndexKey,
) -> Result(Index, IdbError) {
do_create_index(
store,
name,
case key {
index.Key(key)
| index.UniqueKey(key)
| index.MultiEntryKey(key)
| index.MultiEntryUniqueKey(key) -> json.string(key)
index.CompoundKey([]) | index.UniqueCompoundKey([]) -> json.string("")
index.CompoundKey(keys) | index.UniqueCompoundKey(keys) ->
case keys |> list.filter(fn(key) { !string.is_empty(key) }) {
[] -> json.string("")
keys -> json.array(keys, json.string)
}
},
case key {
index.Key(_) | index.CompoundKey(_) -> json.null()
index.UniqueKey(_) | index.UniqueCompoundKey(_) ->
json.object([
#("unique", json.bool(True)),
])
index.MultiEntryKey(_) ->
json.object([
#("multiEntry", json.bool(True)),
])
index.MultiEntryUniqueKey(_) ->
json.object([
#("unique", json.bool(True)),
#("multiEntry", json.bool(True)),
])
},
)
}
@external(javascript, "./idb_ffi.ts", "createIndex")
fn do_create_index(
store: ObjectStore,
name: String,
key: Json,
options: Json,
) -> Result(Index, IdbError)
/// Deletes an [index](https://developer.mozilla.org/docs/Web/API/IndexedDB_API/Basic_Terminology#index)
/// that referenced the specified object store with the specified name.
///
/// Can only be called using `ObjectStore` inside a `versionchange` transaction,
/// will return an `Error` otherwise.
/// Use [`connect`](#connect) with [`on_upgrade`](#on_upgrade)
/// to initialize a `versionchange` transaction.
///
/// Similar to the [`IDBObjectStore.deleteIndex`](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/deleteIndex)
/// on the IndexedDB API.
///
@external(javascript, "./idb_ffi.ts", "deleteIndex")
pub fn delete_index(store: ObjectStore, name: String) -> Result(Nil, IdbError)
// ---- Index Operation Functions ---------------------------------------------
fn quick_index_operation(
db: Connection,
store_index_name: #(String, String),
operation: fn(Index) -> Nil,
next: fn(Result(a, IdbError)) -> b,
) -> Nil {
{
use store <- result.map(
start_index_transaction(db, store_index_name, fn(_) { Nil }),
)
operation(store)
}
|> result.map_error(fn(e) {
next(Error(e))
Nil
})
|> result_unwrap()
}
/// Retrieves the total number of records within the range
/// in an index.
///
/// The last argument is executed with the result or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// Similar to the [`IDBIndex.count`](https://developer.mozilla.org/docs/Web/API/IDBIndex/count)
/// on the IndexedDB API.
///
@external(javascript, "./idb_ffi.ts", "indexCount")
pub fn index_count(
index: Index,
query: KeyRange,
next: fn(Result(Int, IdbError)) -> a,
) -> Nil
/// Retrieves the total number of records within the range
/// in an index inside a new transaction.
///
/// The last argument is executed with the result or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// This is an utility function that combines
/// [`start_index_transaction`](#start_index_transaction) with [`index_count`](#index_count).
///
pub fn quick_index_count(
db: Connection,
store_index_name: #(String, String),
query: KeyRange,
next: fn(Result(Int, IdbError)) -> a,
) -> Nil {
{ index_count(_, query, next) }
|> quick_index_operation(db, store_index_name, _, next)
}
/// Retrieves the first record within the range
/// from an index.
///
/// The last argument is executed with the record value or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// Similar to the [`IDBIndex.get`](https://developer.mozilla.org/docs/Web/API/IDBIndex/get)
/// on the IndexedDB API.
///
@external(javascript, "./idb_ffi.ts", "indexGetOne")
pub fn index_get_one(
index: Index,
query: KeyRange,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil
/// Retrieves the first record within the range
/// from an index inside a new transaction.
///
/// The last argument is executed with the record value or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// This is an utility function that combines
/// [`start_index_transaction`](#start_index_transaction) with [`index_get_one`](#index_get_one).
///
pub fn quick_index_get_one(
db: Connection,
store_index_name: #(String, String),
query: KeyRange,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil {
{ index_get_one(_, query, next) }
|> quick_index_operation(db, store_index_name, _, next)
}
/// Retrieves all records within the range
/// from an index.
///
/// The last argument is executed with the record values or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// Similar to the [`IDBIndex.getAll`](https://developer.mozilla.org/docs/Web/API/IDBIndex/getAll)
/// on the IndexedDB API.
///
@external(javascript, "./idb_ffi.ts", "indexGet")
pub fn index_get(
index: Index,
query: KeyRange,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil
/// Retrieves all records within the range
/// from an index inside a new transaction.
///
/// The last argument is executed with the record values or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// This is an utility function that combines
/// [`start_index_transaction`](#start_index_transaction) with [`index_get`](#index_get).
///
pub fn quick_index_get(
db: Connection,
store_index_name: #(String, String),
query: KeyRange,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil {
{ index_get(_, query, next) }
|> quick_index_operation(db, store_index_name, _, next)
}
/// Retrieves some records within the range
/// from an index.
///
/// Limits the retrieved records to the amount specified on the third argument.
/// If the limit is a negative `Int`, then it will be treated as no limit.
///
/// The last argument is executed with the record values or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// Similar to the [`IDBIndex.getAll`](https://developer.mozilla.org/docs/Web/API/IDBIndex/getAll)
/// on the IndexedDB API.
///
@external(javascript, "./idb_ffi.ts", "indexGetWithLimit")
pub fn index_get_with_limit(
index: Index,
query: KeyRange,
limit: Int,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil
/// Retrieves some records within the range
/// from an index inside a new transaction.
///
/// Limits the retrieved records to the amount specified on the fourth argument.
/// If the limit is a negative `Int`, then it will be treated as no limit.
///
/// The last argument is executed with the record values or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// This is an utility function that combines
/// [`start_index_transaction`](#start_index_transaction) with [`index_get_with_limit`](#index_get_with_limit).
///
pub fn quick_index_get_with_limit(
db: Connection,
store_index_name: #(String, String),
query: KeyRange,
limit: Int,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil {
{ index_get_with_limit(_, query, limit, next) }
|> quick_index_operation(db, store_index_name, _, next)
}
/// Retrieves the first key within the range
/// from an index.
///
/// The last argument is executed with the index key or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// Similar to the [`IDBIndex.getKey`](https://developer.mozilla.org/docs/Web/API/IDBIndex/getKey)
/// on the IndexedDB API.
///
@external(javascript, "./idb_ffi.ts", "indexGetOneKey")
pub fn index_get_one_key(
index: Index,
query: KeyRange,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil
/// Retrieves the first key within the range
/// from an index inside a new transaction.
///
/// The last argument is executed with the index key or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// This is an utility function that combines
/// [`start_index_transaction`](#start_index_transaction) with [`index_get_one_key`](#index_get_one_key).
///
pub fn quick_index_get_one_key(
db: Connection,
store_index_name: #(String, String),
query: KeyRange,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil {
{ index_get_one_key(_, query, next) }
|> quick_index_operation(db, store_index_name, _, next)
}
/// Retrieves all keys within the range
/// from an index.
///
/// The last argument is executed with the index keys or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// Similar to the [`IDBIndex.getAllKeys`](https://developer.mozilla.org/docs/Web/API/IDBIndex/getAllKeys)
/// on the IndexedDB API.
///
@external(javascript, "./idb_ffi.ts", "indexGetKeys")
pub fn index_get_keys(
index: Index,
query: KeyRange,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil
/// Retrieves all keys within the range
/// from an index inside a new transaction.
///
/// The last argument is executed with the index keys or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// This is an utility function that combines
/// [`start_index_transaction`](#start_index_transaction) with [`index_get_keys`](#index_get_keys).
///
pub fn quick_index_get_keys(
db: Connection,
store_index_name: #(String, String),
query: KeyRange,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil {
{ index_get_keys(_, query, next) }
|> quick_index_operation(db, store_index_name, _, next)
}
/// Retrieves some keys within the range
/// from an index.
///
/// Limits the retrieved keys to the amount specified on the third argument.
/// If the limit is a negative `Int`, then it will be treated as no limit.
///
/// The last argument is executed with the index keys or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// Similar to the [`IDBIndex.getAllKeys`](https://developer.mozilla.org/docs/Web/API/IDBIndex/getAllKeys)
/// on the IndexedDB API.
///
@external(javascript, "./idb_ffi.ts", "indexGetKeysWithLimit")
pub fn index_get_keys_with_limit(
index: Index,
query: KeyRange,
limit: Int,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil
/// Retrieves some keys within the range
/// from an index inside a new transaction.
///
/// Limits the retrieved keys to the amount specified on the fourth argument.
/// If the limit is a negative `Int`, then it will be treated as no limit.
///
/// The last argument is executed with the index keys or an error
/// when the operation is completed or errored.
/// The returned value is discarded.
///
/// This is an utility function that combines
/// [`start_index_transaction`](#start_index_transaction) with [`index_get_keys_with_limit`](#index_get_keys_with_limit).
///
pub fn quick_index_get_keys_with_limit(
db: Connection,
store_index_name: #(String, String),
query: KeyRange,
limit: Int,
next: fn(Result(Dynamic, IdbError)) -> a,
) -> Nil {
{ index_get_keys_with_limit(_, query, limit, next) }
|> quick_index_operation(db, store_index_name, _, next)
}
// ---- Util Functions --------------------------------------------------------
/// Same as the deprecated `result.unwrap`.
///
fn result_unwrap(result: Result(a, a)) -> a {
case result {
Ok(a) | Error(a) -> a
}
}