feat: StorageProvider abstraction for CLI/Node compatibility#3
Draft
feat: StorageProvider abstraction for CLI/Node compatibility#3
Conversation
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).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
StorageProviderinterface that abstractslocalStorage/sessionStorageaccessstoragefield onconfigure()— omitted = browser default (zero breaking changes)window.localStorage/sessionStoragecalls across 7 files withgetStorage().persistent.*/getStorage().session.*window.crypto.randomUUID()→globalThis.crypto.randomUUID()for Node/Bun compatibilityMotivation
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
src/lib/storage.ts—StorageProvidertype,getStorage(),setStorageProvider(),resetStorage()config.ts— accepts optionalstorageinconfigure()api.ts,encryptedApi.ts,getAttestation.ts,platformApi.ts,ai.ts— usegetStorage()main.tsx,developer.tsx— usegetStorage()for consistencytest/preload.ts— usessetStorageProvider()instead of patching globalstest/storage.test.ts— 7 testsTest plan
bun test— 20/20 non-integration tests passtsc --noEmit— zero errorsstoragefield = browser default)configure({ storage: sqliteProvider })for non-browser usage🤖 Generated with Claude Code