@onlyfrontend/remote-storage
v0.1.1
Published
A localStorage-compatible library that syncs with OnlyFrontend backend
Maintainers
Readme
OnlyFrontend Remote Storage
A TypeScript library that provides a localStorage-compatible interface to automatically sync data with a remote backend. Perfect for building frontend applications that need persistent state without managing complex backend infrastructure.
Features
- localStorage-compatible API - Drop-in replacement for localStorage
- Automatic sync - Changes are automatically synced to the remote backend
- Offline support - Works offline and syncs when connection is restored
- TypeScript support - Full type safety and IntelliSense support
- Zero backend setup - Uses OnlyFrontend's managed backend service
- Client-side encryption - Built-in encryption using client-side generated userId to keep data private
Installation
npm install @onlyfrontend/remote-storageQuick Start
import { createRemoteStorage } from '@onlyfrontend/remote-storage';
// Create a remote storage instance
const remoteStorage = createRemoteStorage({
apiKey: 'your-api-key'
});
// Create user (do this once)
const userId = await remoteStorage.createUser();
// Use it like localStorage!
remoteStorage.setItem('username', 'john_doe');
remoteStorage.setItem('preferences', JSON.stringify({
theme: 'dark',
language: 'en'
}));
console.log(remoteStorage.getItem('username')); // 'john_doe'
console.log(remoteStorage.length); // 2
// Data is automatically synced to the backend!API Reference
Class: RemoteStorage
The main class that implements the Storage interface with remote synchronization.
Constructor
new RemoteStorage(config: Partial<RemoteStorageConfig>)config.baseUrl- The base URL of your backend (optional, uses DEFAULT_BASE_URL if not provided)config.apiKey- (optional) API key for clientconfig.userId- (optional) User ID for the current user
Authentication Methods
createUser(): Promise<string>
Create a new user for the current client. Requires API key to be set.
const userId = await remoteStorage.createUser();initialize(apiKey: string, userId?: string): Promise<void>
Initialize with API key and optionally a user ID. If user ID is provided, it will load remote state.
await remoteStorage.initialize('your-api-key', 'user-id');setUserId(userId: string): void
Set the current user ID.
remoteStorage.setUserId('user-id');Storage Methods (localStorage-compatible)
setItem(key: string, value: string): void
Store a key-value pair. Automatically syncs to remote.
remoteStorage.setItem('theme', 'dark');getItem(key: string): string | null
Retrieve a value by key.
const theme = remoteStorage.getItem('theme'); // 'dark' or nullremoveItem(key: string): void
Remove a key-value pair. Automatically syncs to remote.
remoteStorage.removeItem('theme');clear(): void
Remove all stored data. Automatically syncs to remote.
remoteStorage.clear();key(index: number): string | null
Get the key at the specified index.
const firstKey = remoteStorage.key(0);length: number
Get the number of stored items.
console.log(remoteStorage.length); // 5Sync Methods
syncFromRemote(): Promise<void>
Manually sync remote data to local cache. Requires API key and user ID to be set.
await remoteStorage.syncFromRemote();syncToRemote(): Promise<void>
Manually sync local data to the remote backend. Requires API key and user ID to be set.
await remoteStorage.syncToRemote();save(): Promise<void>
Alias for syncToRemote().
await remoteStorage.save();load(): Promise<void>
Alias for syncFromRemote().
await remoteStorage.load();Additional Methods
getAll(): Record<string, string>
Get all stored data as an object.
const allData = remoteStorage.getAll();
// Returns: { key1: 'value1', key2: 'value2' }setMultiple(items: Record<string, string>): void
Set multiple key-value pairs at once. Automatically syncs to remote if initialized.
remoteStorage.setMultiple({
'username': 'john',
'email': '[email protected]',
'preferences': JSON.stringify({ theme: 'dark' })
});Usage Examples
Basic Usage
import { createRemoteStorage } from '@onlyfrontend/remote-storage';
const remoteStorage = createRemoteStorage({
apiKey: 'your-api-key'
});
// One-time setup - create a user
const userId = await remoteStorage.createUser();
// Store credentials for future sessions
localStorage.setItem('app_user_id', userId);
// Use as localStorage
remoteStorage.setItem('user_settings', JSON.stringify({
theme: 'dark',
notifications: true
}));With Existing Credentials
const remoteStorage = createRemoteStorage({
apiKey: 'your-api-key'
});
// Initialize with stored credentials
await remoteStorage.initialize(
localStorage.getItem('app_user_id')!
);
// Load existing data
await remoteStorage.load();
// Now use normally
const settings = remoteStorage.getItem('user_settings');User Preferences Class
import { RemoteStorage } from '@onlyfrontend/remote-storage';
class UserPreferences {
constructor(private storage: RemoteStorage) {}
getTheme(): 'light' | 'dark' {
return this.storage.getItem('theme') as 'light' | 'dark' || 'light';
}
setTheme(theme: 'light' | 'dark'): void {
this.storage.setItem('theme', theme);
}
getLanguage(): string {
return this.storage.getItem('language') || 'en';
}
setLanguage(language: string): void {
this.storage.setItem('language', language);
}
}
// Usage
const prefs = new UserPreferences(remoteStorage);
prefs.setTheme('dark');
console.log(prefs.getTheme()); // 'dark'Error Handling
try {
await remoteStorage.initialize('your-api-key');
await remoteStorage.createUser();
} catch (error) {
console.error('Failed to initialize:', error);
// Fall back to localStorage
const fallbackStorage = window.localStorage;
}Backend Integration
This library is designed to work with the OnlyFrontend backend service. The backend provides these endpoints:
POST /users- Create a new userPOST /users/{user_id}- Save user stateGET /users/{user_id}- Load user state
Authentication
The library automatically handles authentication using an API key:
X-API-Keyheader with the API key
TypeScript Support
The library is written in TypeScript and provides full type definitions:
interface RemoteStorageConfig {
baseUrl: string;
apiKey?: string;
userId?: string;
}
interface SaveStateRequest {
state: Record<string, any>;
}
interface StateResponse {
state: Record<string, any>;
updated_at: string;
}Development
# Install dependencies
npm install
# Build the library
npm run build
# Watch for changes
npm run dev
# Run linting
npm run lintLicense
MIT License - see LICENSE file for details.
