Skip to content

feat: StorageProvider abstraction for CLI/Node compatibility#3

Draft
gudnuf wants to merge 6 commits intomasterfrom
feat/storage-provider
Draft

feat: StorageProvider abstraction for CLI/Node compatibility#3
gudnuf wants to merge 6 commits intomasterfrom
feat/storage-provider

Conversation

@gudnuf
Copy link
Copy Markdown

@gudnuf gudnuf commented Apr 1, 2026

Summary

  • Adds a StorageProvider interface that abstracts localStorage/sessionStorage access
  • Injects via optional storage field on configure() — omitted = browser default (zero breaking changes)
  • Replaces all 31 direct window.localStorage/sessionStorage calls across 7 files with getStorage().persistent.* / getStorage().session.*
  • Fixes window.crypto.randomUUID()globalThis.crypto.randomUUID() for Node/Bun compatibility
  • Adds 7 unit tests covering browser fallback, custom provider, reset, CRUD, and isolation

Motivation

The agicash CLI needs to use the OpenSecret SDK without a browser environment. This abstraction lets CLI consumers provide a file-backed or SQLite-backed storage implementation while keeping the browser experience unchanged.

Changes

  • New: src/lib/storage.tsStorageProvider type, getStorage(), setStorageProvider(), resetStorage()
  • Modified: config.ts — accepts optional storage in configure()
  • Modified: api.ts, encryptedApi.ts, getAttestation.ts, platformApi.ts, ai.ts — use getStorage()
  • Modified: main.tsx, developer.tsx — use getStorage() for consistency
  • Modified: test/preload.ts — uses setStorageProvider() instead of patching globals
  • New: test/storage.test.ts — 7 tests

Test plan

  • bun test — 20/20 non-integration tests pass
  • tsc --noEmit — zero errors
  • Verify existing agicash wallet app works unchanged (no storage field = browser default)
  • Verify CLI can use configure({ storage: sqliteProvider }) for non-browser usage

🤖 Generated with Claude Code

gudnuf added 6 commits March 31, 2026 17:47
Create src/lib/storage.ts with StorageProvider type, getStorage(),
setStorageProvider(), and resetStorage(). Wire into configure() so
consumers in non-browser environments can pass a custom storage
provider. Export StorageProvider type and getStorage from the public
barrel.
Replace all window.localStorage, localStorage, and sessionStorage
calls in api.ts (13), encryptedApi.ts (1), getAttestation.ts (4),
platformApi.ts (3), and ai.ts (1) with getStorage().persistent/session.
Also replace window.crypto.randomUUID with globalThis.crypto.randomUUID
in getAttestation.ts for non-browser compatibility.
Replace all window.localStorage and localStorage calls in main.tsx (2)
and developer.tsx (7) with getStorage().persistent.
Replace the old storageMock + global.localStorage/sessionStorage
patching with setStorageProvider() using a lightweight mock that
satisfies the StorageProvider interface.
Add 7 tests covering browser fallback, custom provider via
setStorageProvider and configure(), resetConfig/resetStorage,
persistent/session CRUD, and storage isolation.

Make preload.ts gracefully skip setup.ts when env vars are missing so
unit tests can run without a server.
Replace window.crypto.randomUUID() with globalThis.crypto.randomUUID()
in main.tsx and developer.tsx, matching the fix already applied in
getAttestation.ts. globalThis.crypto is available in all modern runtimes
(Node 19+, Bun, browsers).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant