Skip to content

[SUB-FEATURE] Implement BrowserStorage WASM backend #87

@takasaki404

Description

@takasaki404

[SUB-FEATURE] Implement BrowserStorage WASM backend

📋 Summary

Provide a concrete Storage implementation that runs under wasm32-unknown-unknown, using the browser’s IndexedDB (with a LocalStorage fallback) to persist key/value blobs.

💡 Proposal

  1. Module & Struct

    • Create amico-core/src/browser_storage.rs

    • Define

      pub struct BrowserStorage {
          db_name: String,
          // optionally hold a handle to `web_sys::IdbDatabase`
      }
  2. Initialization

    • Feature-gate on cfg(target_arch = "wasm32")

    • In constructor, open (or create) an IndexedDB database named e.g. "amico-storage".

    • Expose an async constructor:

      impl BrowserStorage {
          pub async fn new(db_name: &str) -> Result<Self, StorageError> {}
      }
  3. Namespace & Key Mapping

    • Treat each namespace as an object store in IndexedDB.
    • Use key as the primary key in that store.
    • Store values as Uint8Array or base64-encoded strings for LocalStorage.
  4. Trait Implementation

    • All methods become async fn returning Future<Output = Result<…, StorageError>>.
    • get: open transaction, fetch key, return None if missing.
    • put: open readwrite transaction, put or add the blob.
    • delete: open readwrite, call delete.
    • list_keys: open readonly, use a cursor to collect all keys.
    #[async_trait::async_trait]
    impl Storage for BrowserStorage {
        async fn get(&self, namespace: &str, key: &str) -> Result<Option<Vec<u8>>, StorageError> {}
        async fn put(&mut self, namespace: &str, key: &str, value: Vec<u8>) -> Result<(), StorageError> {}
        async fn delete(&mut self, namespace: &str, key: &str) -> Result<(), StorageError> {}
        async fn list_keys(&self, namespace: &str) -> Result<Vec<String>, StorageError> {}
    }
  5. LocalStorage Fallback

    • If IndexedDB isn’t available (e.g. insecure contexts), fallback to window.localStorage.
    • Serialize the entire namespace map as a JSON object under a single LS key (e.g. "amico:<namespace>").
  6. Testing

    • Write wasm-bindgen integration tests (e.g. with wasm-pack test --headless).
    • Cover all operations in a browser-like environment (headless Chrome or wasm-bindgen test runner).
    • Fallback LS behavior should be tested in a simulated environment where IDB isn’t present.

✅ Acceptance Criteria

  • browser_storage.rs module with BrowserStorage struct and async new() constructor.
  • Implements Storage trait (async) with correct namespace ↔ object store mapping.
  • IndexedDB operations using web_sys APIs, with appropriate error conversions to StorageError.
  • LocalStorage fallback path that preserves semantics.
  • Integration tests exercising all four methods under both IDB and LS modes.
  • Docs/comments explaining feature flag, async behavior, and fallbacks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions