ブラウザ標準の IndexedDB を使う

Recipe ID: db-007

localStorage よりも大容量かつ構造化されたデータをブラウザ標準機能で保存したい場合は IndexedDB が適しています。
Tauri 環境でもそのまま使用でき、idb などのラッパーライブラリを使うと便利です。

実装例 (idb ライブラリ使用)

IndexedDB はネイティブのまま扱うとコールバック地獄になりがちですが、idb ライブラリを使うことで Promise ベースのモダンな記述が可能になります。

npm install idb
import { openDB } from 'idb';

// データベースの初期化
async function initDB() {
  // 'my-db' という名前のデータベースをバージョン 1 で開く
  const db = await openDB('my-db', 1, {
    // バージョンが上がった場合や初回作成時に実行される
    upgrade(db) {
      // 'keyval' という名前のオブジェクトストア(RDBでいうテーブル)を作成
      if (!db.objectStoreNames.contains('keyval')) {
        db.createObjectStore('keyval');
      }
    },
  });
  return db;
}

async function demo() {
  const db = await initDB();
  
  // データの保存 (put)
  // 第1引数: ストア名, 第2引数: 保存する値, 第3引数: キー (省略時はストア設定に従う)
  await db.put('keyval', 'Hello World', 'greeting');
  
  // データの取得 (get)
  const val = await db.get('keyval', 'greeting');
  console.log(val); // "Hello World"
  
  // トランザクションも自動的に処理されますが、明示的に行うことも可能です
  const tx = db.transaction('keyval', 'readwrite');
  await tx.store.put('Another Value', 'foo');
  await tx.done;
}

Tauri での使い所

SQLite プラグインなどを導入するほどではないが、複雑な検索や大量のデータを扱いたい場合に、追加の Rust 依存関係・権限設定なしで使える点がメリットです。
ただし、Local Storage と同様に OS/WebView の仕様によるデータ削除のリスクは考慮する必要があります。