@vivtel/web-storage
v1.0.4
Published
Full-featured browser storage solution supporting localStorage, sessionStorage, and IndexedDB with React integration
Downloads
409
Maintainers
Readme
@vivtel/web-storage
A comprehensive, type-safe browser storage solution for modern web applications. Supports localStorage, sessionStorage, and IndexedDB with React integration, TypeScript support, TTL, and cross-tab synchronization.
Features
- 🗄️ Multiple Storage Types: localStorage, sessionStorage, and IndexedDB
- ⚛️ React Integration: Hooks and context provider for seamless React integration
- 🔒 Type-Safe: Full TypeScript support with generic types
- ⏱️ TTL Support: Automatic expiration for stored data
- 🔄 Cross-Tab Sync: Automatic synchronization across browser tabs (localStorage)
- 🎯 Simple API: Intuitive and consistent API across all storage types
- 🔌 SSR-Safe: Server-side rendering compatible
- 🎨 Flexible: Use with or without React
Installation
pnpm add @vivtel/web-storageQuick Start
Vanilla JavaScript/TypeScript
import { StorageManager } from '@vivtel/web-storage';
// Create a storage manager
const storage = new StorageManager({
driver: 'local_storage',
prefix: 'myapp_',
ttl: 3600, // Default 1 hour TTL
});
// Store data
await storage.set('user', { id: 1, name: 'John Doe' });
// Retrieve data
const user = await storage.get<User>('user');
// Remove data
await storage.remove('user');React
import { StorageProvider, useLocalStorage } from '@vivtel/web-storage/react';
// 1. Wrap your app with StorageProvider
function App() {
return (
<StorageProvider
config={{
driver: 'local_storage',
prefix: 'myapp_',
ttl: 3600,
}}
>
<YourApp />
</StorageProvider>
);
}
// 2. Use storage hooks in your components
function ThemeSelector() {
const [theme, setTheme] = useLocalStorage('theme', 'light');
return (
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Current theme: {theme}
</button>
);
}Storage Types
LocalStorage
Best for: User preferences, settings, and persistent data across sessions.
const storage = new StorageManager({
driver: 'local_storage',
prefix: 'myapp_',
});React Hook:
const [value, setValue, removeValue, loading, error] = useLocalStorage(
'key',
defaultValue
);Features:
- Persists across browser sessions
- Cross-tab synchronization (React hook)
- ~5-10MB storage limit
SessionStorage
Best for: Temporary session data, wizard forms, shopping carts.
const storage = new StorageManager({
driver: 'session_storage',
prefix: 'session_',
});React Hook:
const [value, setValue, removeValue, loading, error] = useSessionStorage(
'key',
defaultValue
);Features:
- Clears when tab/window closes
- Isolated per tab
- ~5-10MB storage limit
IndexedDB
Best for: Large datasets, files, blobs, offline-first applications.
const storage = new StorageManager({
driver: 'indexed_db',
dbName: 'MyAppDB',
storeName: 'cache',
});React Hook:
const [value, setValue, removeValue, loading, error] = useIndexedDB(
'key',
defaultValue
);Features:
- Persists across browser sessions
- High storage limits (hundreds of MB to GB)
- Asynchronous API
- Can store complex data types
API Reference
StorageManager
Main class for interacting with storage.
Constructor
new StorageManager(config: IStorageConfig)Config Options:
interface IStorageConfig {
driver: 'local_storage' | 'session_storage' | 'indexed_db';
prefix?: string; // Key prefix (default: '')
ttl?: number; // Default TTL in seconds
// IndexedDB-specific options
dbName?: string; // Database name (default: 'WebStorage')
storeName?: string; // Object store name (default: 'storage')
version?: number; // Database version (default: 1)
// Custom serialization (optional)
serializer?: (value: any) => string;
deserializer?: (value: string) => any;
}Methods
// Get value
async get<T>(key: string): Promise<T | null>
// Set value (with optional TTL)
async set<T>(key: string, value: T, ttl?: number): Promise<void>
// Remove value
async remove(key: string): Promise<void>
// Clear all values
async clear(): Promise<void>
// Check if key exists
async has(key: string): Promise<boolean>
// Get all keys
async keys(): Promise<string[]>
// Get storage size
async size(): Promise<number>
// Get or set (cache pattern)
async getOrSet<T>(
key: string,
defaultValue: () => T | Promise<T>,
ttl?: number
): Promise<T>
// Batch operations
async setMany<T>(items: Record<string, T>, ttl?: number): Promise<void>
async getMany<T>(keys: string[]): Promise<Record<string, T | null>>
async removeMany(keys: string[]): Promise<void>React Hooks
useLocalStorage
const [value, setValue, removeValue, loading, error] = useLocalStorage<T>(
key: string,
defaultValue: T
);Features:
- Automatic cross-tab synchronization
- Component re-renders on storage changes
useSessionStorage
const [value, setValue, removeValue, loading, error] = useSessionStorage<T>(
key: string,
defaultValue: T
);Features:
- Session-scoped storage
- Isolated per browser tab
useIndexedDB
const [value, setValue, removeValue, loading, error] = useIndexedDB<T>(
key: string,
defaultValue: T
);Features:
- High storage capacity
- Efficient for large data
useStorage (Generic)
const [value, setValue, removeValue, loading, error] = useStorage<T>(
key: string,
defaultValue: T,
storageManager?: StorageManager
);Use case: When you need to dynamically choose storage type or use custom storage configuration.
StorageProvider
Provides storage context to React components.
<StorageProvider
config={{
driver: 'local_storage',
prefix: 'app_',
}}
localStorageConfig={{ ttl: 86400 }}
sessionStorageConfig={{ prefix: 'session_' }}
indexedDBConfig={{ dbName: 'MyDB' }}
>
{children}
</StorageProvider>Examples
TTL (Time To Live)
// Set data with 1 hour TTL
await storage.set('session_token', token, 3600);
// Data expires automatically after 1 hour
const token = await storage.get('session_token'); // null after expirationCache Pattern
// Fetch from storage or compute if missing
const userData = await storage.getOrSet(
'user_profile',
async () => {
const response = await fetch('/api/user');
return response.json();
},
3600
); // Cache for 1 hourBatch Operations
// Store multiple values at once
await storage.setMany({
user_id: 123,
username: 'john',
email: '[email protected]',
});
// Get multiple values at once
const data = await storage.getMany(['user_id', 'username', 'email']);
console.log(data.username); // 'john'Cross-Tab Synchronization (React)
// Component A in Tab 1
function ComponentA() {
const [count, setCount] = useLocalStorage('counter', 0);
return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}
// Component B in Tab 2 - automatically syncs!
function ComponentB() {
const [count] = useLocalStorage('counter', 0);
return <div>Current count: {count}</div>; // Updates when Tab 1 changes
}Custom Storage Manager with React
function DataTable() {
const { indexedDB } = useStorageContext();
const [data, setData] = useStorage('api_cache', null, indexedDB);
useEffect(() => {
async function loadData() {
if (!data) {
const response = await fetch('/api/data');
const result = await response.json();
await setData(result, 3600); // Cache in IndexedDB for 1 hour
}
}
loadData();
}, []);
return data ? <Table data={data} /> : 'Loading...';
}Fallback Strategy
import { StorageFactory } from '@vivtel/web-storage';
// Try IndexedDB, fallback to localStorage if unavailable
const storage = StorageFactory.createWithFallback(
{ driver: 'indexed_db', dbName: 'MyDB' },
{ driver: 'local_storage', prefix: 'fallback_' }
);SSR-Safe Usage
// Automatically handles server-side rendering
const storage = new StorageManager({
driver: 'local_storage',
prefix: 'app_',
});
// Safe to call on server - returns null gracefully
const value = await storage.get('key'); // null on serverTypeScript Support
Full TypeScript support with generic types:
interface User {
id: number;
name: string;
email: string;
}
// Type-safe storage
const storage = new StorageManager({ driver: 'local_storage' });
await storage.set<User>('user', {
id: 1,
name: 'John',
email: '[email protected]',
});
const user = await storage.get<User>('user'); // user is User | null
// Type-safe React hook
const [user, setUser] = useLocalStorage<User>('user', null);Browser Support
- localStorage/sessionStorage: All modern browsers
- IndexedDB: Chrome 24+, Firefox 16+, Safari 10+, Edge 12+
The package automatically detects browser support and gracefully handles unsupported environments.
License
MIT
Contributing
Contributions are welcome! Please see the main repository for contribution guidelines.
