Skip to content

Alorel/rust-indexed-db

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

44 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Indexed DB Futures

Wraps the web_sys Indexed DB API in a Future-based API and removes the pain of dealing with Javascript callbacks in Rust.

master CI badge crates.io badge docs.rs badge dependencies badge

Overall API design

In most cases API methods will return a Result containing a wrapped IdbRequest that implements IntoFuture, such as VoidRequest, or, when more appropriate, the Future directly, e.g. CountFuture.

The key difference between a wrapped Request and Future is that Requests don't have any event listeners attached, which aims to make quickfire operations such as inserting several records into an IdbObjectStore a little bit more efficient.

Features

The library can ship without cursor or index support for apps that just need a simple key-value store akin to localStorage.

  • cursors - Enable cursor support
  • indices - Enable index support
  • nightly - Use unsafe nightly features where appropriate, such as unwrap_unchecked.
  • default:
    • cursors
    • indices

Examples

Connecting to a DB and doing basic CRUD

Variable types included for clarity.

use indexed_db_futures::prelude::*;

pub async fn example() -> Result<(), DomException> {
    // Open my_db v1
    let mut db_req: OpenDbRequest = IdbDatabase::open_u32("my_db", 1)?;
    db_req.set_on_upgrade_needed(Some(|evt: &IdbVersionChangeEvent| -> Result<(), JsValue> {
        // Check if the object store exists; create it if it doesn't
        if let None = evt.db().object_store_names().find(|n| n == "my_store") {
            evt.db().create_object_store("my_store")?;
        }
        Ok(())
    }));

    let db: IdbDatabase = db_req.await?;

    // Insert/overwrite a record
    let tx: IdbTransaction = db
      .transaction_on_one_with_mode("my_store", IdbTransactionMode::Readwrite)?;
    let store: IdbObjectStore = tx.object_store("my_store")?;

    let value_to_put: JsValue = get_some_js_value();
    store.put_key_val_owned("my_key", &value_to_put)?;

    // IDBTransactions can have an Error or an Abort event; into_result() turns both into a
    // DOMException
    tx.await.into_result()?;

    // Delete a record
    let tx = db.transaction_on_one_with_mode("my_store", IdbTransactionMode::Readwrite)?;
    let store = tx.object_store("my_store")?;
    store.delete_owned("my_key")?;
    tx.await.into_result()?;

    // Get a record
    let tx = db.transaction_on_one("my_store")?;
    let store = tx.object_store("my_store")?;

    let value: Option<JsValue> = store.get_owned("my_key")?.await?;
    use_value(value);

    Ok(())
}