packages/storage/README.md

Storage

ts
1import * as storage from '@solid-native/storage';
2import * as secure from '@solid-native/storage/secure';
3
4const settings = storage.open('settings');
5await settings.set('theme', 'dark');
6const theme = await settings.get('theme');
7await settings.remove('theme');
8
9await secure.set('token', token, { access: 'biometric' });
10const savedToken = await secure.get('token', { reason: 'Unlock your account' });
11await secure.remove('token');

Ordinary storage persists finite plain JSON through NSUserDefaults / SharedPreferences. Missing keys return undefined; stored JSON null stays null. Values are snapshotted at invocation, and handles opened on the same namespace share ordering within one JS runtime. There are no multi-key transactions, queries, schema validation, or database-size guarantees. This is preferences storage, not a database or secret store. Keys and namespaces use letters, digits, ., _, -.

Secure storage holds strings in iOS Keychain or AES-GCM ciphertext backed by Android Keystore. Encryption keys never enter JS. The access policy belongs to the stored item, not an independent device.verify prompt:

  • unlocked (default): available while the device is unlocked.
  • device: OS device-owner authentication, including PIN/passcode fallback.
  • biometric: current enrolled strong biometrics, without PIN fallback; enrollment changes can invalidate the key.

Unavailable policies reject; they never fall back to weaker protection. Android requires API 28+ for this secure store and API 30+ for device. Android protected writes as well as reads can prompt; overlapping secure operations reject E_BUSY. iOS stores device-only items (not iCloud-synchronized secrets). Passkey provider synchronization is separate from secure storage. Keychain values may survive an app reinstall; neither platform's data should be treated as a portable backup. Biometric invalidation is not always distinguishable from unavailable/missing key material. Handle errors and require fresh account login when necessary.

The sample host registers both native modules and Android adapters. Android needs USE_BIOMETRIC and a foreground FragmentActivity for prompts; iOS needs NSFaceIDUsageDescription. Physical-device locked/unlocked, enrollment-change, and secure-hardware behavior need device verification; simulator persistence tests do not prove those protections.