@54vie/storage - Persistent Storage
High-performance persistent storage using MMKV.
Installation
pnpm add @54vie/storage
Quick Start
import { StorageManager } from '@54vie/storage';
const storage = new StorageManager({ namespace: 'myapp' });
// Set value
await storage.set('user', { name: 'John', age: 25 });
// Get value
const user = await storage.get('user');
// Remove
await storage.remove('user');
StorageManager
Constructor
const storage = new StorageManager({
namespace: 'myapp', // Isolated namespace
encryption: true, // Enable encryption (optional)
encryptionKey: 'secret', // Encryption key (if encryption enabled)
});
Methods
// Get value (returns undefined if not exists)
const value = await storage.get<T>('key');
// Get with default
const value = await storage.get('key', defaultValue);
// Set value (supports any serializable value)
await storage.set('key', value);
// Check if key exists
const exists = await storage.has('key');
// Remove key
await storage.remove('key');
// Clear all keys in namespace
await storage.clear();
// Get all keys
const keys = await storage.getAllKeys();
// Get multiple values
const values = await storage.getMultiple(['key1', 'key2']);
// Set multiple values
await storage.setMultiple({
key1: value1,
key2: value2,
});
Hooks
useStorage
import { useStorage } from '@54vie/storage';
function Settings() {
const [theme, setTheme] = useStorage('theme', 'light');
return (
<Switch
value={theme === 'dark'}
onValueChange={(dark) => setTheme(dark ? 'dark' : 'light')}
/>
);
}
useStorageItem
import { useStorageItem } from '@54vie/storage';
function Profile() {
const {
value: user,
setValue: setUser,
removeValue,
isLoading,
} = useStorageItem('user');
if (isLoading) return <Loading />;
return (
<View>
<Text>{user?.name}</Text>
<Button onPress={() => setUser({ ...user, name: 'New Name' })}>
Update
</Button>
<Button onPress={removeValue}>Logout</Button>
</View>
);
}
Typed Storage
interface UserSettings {
theme: 'light' | 'dark';
notifications: boolean;
language: string;
}
const settingsStorage = new StorageManager<UserSettings>({
namespace: 'settings',
});
// Type-safe get/set
const theme = await settingsStorage.get('theme'); // 'light' | 'dark' | undefined
await settingsStorage.set('theme', 'dark'); // Type checked
Encryption
const secureStorage = new StorageManager({
namespace: 'secure',
encryption: true,
});
// Values are encrypted at rest
await secureStorage.set('token', 'sensitive-data');
caution
Encryption adds overhead. Only use for sensitive data.
Migration
import { StorageManager, migrateStorage } from '@54vie/storage';
// Migrate from old storage
await migrateStorage({
from: new StorageManager({ namespace: 'v1' }),
to: new StorageManager({ namespace: 'v2' }),
transform: (key, value) => {
// Transform data if needed
return value;
},
});
Best Practices
1. Use namespaces
// ✅ Good - Separate concerns
const authStorage = new StorageManager({ namespace: 'auth' });
const cacheStorage = new StorageManager({ namespace: 'cache' });
// ❌ Bad - Everything in one place
const storage = new StorageManager({ namespace: 'app' });
2. Type your data
// ✅ Good
interface CartItem {
id: string;
quantity: number;
}
const cart = await storage.get<CartItem[]>('cart');
// ❌ Bad
const cart = await storage.get('cart'); // any