Api Reference
Ecosistema completo para organización y gestión de contenido con interfaces espaciales
Flash Persistence - API Reference
Complete API documentation for Flash Persistence.
Table of Contents
- autoFlashState()
- Flash State Builders
- FlashStateService
- FlashStateHydratorService
- Provider Functions
- Types & Interfaces
autoFlashState()
Create an auto-persistent signal.
Signature
function autoFlashState<T>(
options: AutoFlashStateOptions<T>
): WritableSignal<T>
Parameters
AutoFlashStateOptions
interface AutoFlashStateOptions<T> {
key: string; // Required: Unique storage key
initialValue: T; // Required: Default value
database?: string; // Optional: Database name
collection?: string; // Optional: Collection name
namespace?: string; // Optional: Namespace
ttl?: number; // Optional: Time-to-live (ms)
priority?: SyncPriority; // Optional: Sync priority
equal?: (a: T, b: T) => boolean; // Optional: Custom equality
}
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
key |
string |
✅ | - | Unique identifier for this state |
initialValue |
T |
✅ | - | Initial/default value |
database |
string |
❌ | 'default' |
Database name for organization |
collection |
string |
❌ | 'general' |
Collection name for grouping |
namespace |
string |
❌ | '' |
Additional namespace for isolation |
ttl |
number |
❌ | undefined |
Expiration time in milliseconds |
priority |
SyncPriority |
❌ | undefined |
MongoDB sync priority |
equal |
function |
❌ | === |
Custom equality function |
Returns
WritableSignal<T> - A writable Angular signal with automatic persistence
Usage Examples
Basic Usage
const theme = autoFlashState({
key: 'theme',
initialValue: 'dark'
});
// Read
console.log(theme()); // 'dark'
// Write
theme.set('light'); // ✅ Persisted automatically
With Database Organization
const userProfile = autoFlashState({
key: 'profile',
database: 'user-data',
collection: 'profiles',
namespace: 'current-user',
initialValue: { name: '', email: '' }
});
// Full key: user-data:current-user:profiles:profile
With TTL (Temporary Data)
const sessionData = autoFlashState({
key: 'session',
initialValue: null,
ttl: 30 * 60 * 1000 // 30 minutes
});
// Automatically deleted after 30 minutes
With MongoDB Sync Priority
const sharedDocument = autoFlashState({
key: 'doc-123',
database: 'collaboration',
collection: 'documents',
initialValue: { content: '' },
priority: 'high' // Sync every 5 minutes
});
With Custom Equality
interface ComplexObject {
id: string;
data: any[];
timestamp: number;
}
const complexState = autoFlashState<ComplexObject>({
key: 'complex',
initialValue: { id: '', data: [], timestamp: 0 },
equal: (a, b) => {
// Only consider 'id' for equality
return a.id === b.id;
}
});
Flash State Builders
Convenience helpers for common patterns.
appFlashState()
Create state in the 'app-data' database.
function appFlashState<T>(options: {
key: string;
initialValue: T;
collection?: string;
ttl?: number;
priority?: SyncPriority;
}): WritableSignal<T>
Example:
const appState = appFlashState({
key: 'state',
initialValue: { sidebarOpen: true },
collection: 'ui-state'
});
// Stored in: app-data:ui-state:state
userFlashState()
Create state in the 'user-data' database.
function userFlashState<T>(options: {
key: string;
initialValue: T;
collection?: string;
ttl?: number;
priority?: SyncPriority;
}): WritableSignal<T>
Example:
const preferences = userFlashState({
key: 'preferences',
initialValue: { theme: 'dark' },
collection: 'settings',
priority: 'high' // Sync to MongoDB
});
// Stored in: user-data:settings:preferences
cacheFlashState()
Create temporary cached state with TTL.
function cacheFlashState<T>(options: {
key: string;
initialValue: T;
ttl?: number;
}): WritableSignal<T>
Example:
const apiCache = cacheFlashState({
key: 'users-list',
initialValue: [],
ttl: 5 * 60 * 1000 // 5 minutes
});
// Automatically expires after 5 minutes
criticalFlashState()
Create critical state with immediate sync.
function criticalFlashState<T>(options: {
key: string;
initialValue: T;
database?: string;
collection?: string;
}): WritableSignal<T>
Example:
const authToken = criticalFlashState({
key: 'auth-token',
database: 'security',
initialValue: null
});
// Syncs immediately to MongoDB (if configured)
FlashStateService
Injectable service for component-scoped state.
Constructor
@Injectable()
export class FlashStateService {
createState<T>(options: AutoFlashStateOptions<T>): WritableSignal<T>
createAppState<T>(options: {...}): WritableSignal<T>
createUserState<T>(options: {...}): WritableSignal<T>
createCacheState<T>(options: {...}): WritableSignal<T>
}
Usage
import { Component, inject } from '@angular/core';
import { FlashStateService } from '@storage-system';
@Component({
selector: 'app-settings',
standalone: true,
providers: [FlashStateService]
})
export class SettingsComponent {
private flashState = inject(FlashStateService);
// Component-scoped persistent state
localSettings = this.flashState.createState({
key: 'component-settings',
initialValue: { expanded: false }
});
toggleExpanded() {
this.localSettings.update(s => ({ expanded: !s.expanded }));
}
}
FlashStateHydratorService
Core service managing state hydration and persistence.
Methods
updateState()
Manually trigger state persistence.
updateState(key: string, value: any): void
Example:
import { inject } from '@angular/core';
import { FlashStateHydratorService } from '@storage-system';
const hydrator = inject(FlashStateHydratorService);
hydrator.updateState('my-key', { data: 'value' });
getInstantState()
Get cached state without async.
getInstantState<T>(key: string): T | undefined
Example:
const cachedValue = hydrator.getInstantState('theme');
console.log(cachedValue); // Instant access
clearState()
Clear a specific state.
clearState(key: string): Promise<void>
Example:
await hydrator.clearState('draft');
clearAllStates()
Clear all persisted states.
clearAllStates(): Promise<void>
Example:
await hydrator.clearAllStates();
flush()
Force immediate persistence of pending changes.
flush(): Promise<void>
Example:
// Before navigation
await hydrator.flush();
router.navigate(['/next-page']);
Provider Functions
provideFlashPersistence()
Setup Flash Persistence in your app.
function provideFlashPersistence(
config?: FlashPersistenceConfig
): EnvironmentProviders
FlashPersistenceConfig
interface FlashPersistenceConfig {
debounceMs?: number; // Debounce time (default: 300ms)
enableMongoDBSync?: boolean; // Enable MongoDB sync
preloadKeys?: string[]; // Keys to pre-load
flushBeforeNavigation?: boolean; // Flush on route change
storageConfig?: {
namespace?: string;
cache?: { maxItems: number; ttlMs: number };
};
}
Example:
import { ApplicationConfig } from '@angular/core';
import { provideFlashPersistence } from '@storage-system';
export const appConfig: ApplicationConfig = {
providers: [
provideFlashPersistence({
debounceMs: 500, // Wait 500ms before saving
enableMongoDBSync: true, // Enable cloud sync
preloadKeys: ['theme', 'preferences'],
flushBeforeNavigation: true, // Auto-flush on navigation
storageConfig: {
namespace: 'my-app',
cache: { maxItems: 1000, ttlMs: 600_000 }
}
})
]
};
Types & Interfaces
SyncPriority
type SyncPriority = 'critical' | 'high' | 'normal' | 'low';
Usage:
critical: Immediate sync (auth, payments)high: Sync every 5 minutes (user actions)normal: Sync every 30 minutes (preferences)low: Manual or idle sync (analytics)
FlashPerformanceMetrics
interface FlashPerformanceMetrics {
totalStates: number;
cacheHitRate: number;
avgReadTime: number;
avgWriteTime: number;
totalReads: number;
totalWrites: number;
}
Access:
const hydrator = inject(FlashStateHydratorService);
const metrics = hydrator.getPerformanceMetrics();
console.log(`Cache hit rate: ${metrics.cacheHitRate}%`);
AutoDiscoveredState
interface AutoDiscoveredState {
fullKey: string;
database: string;
collection: string;
namespace: string;
key: string;
priority?: SyncPriority;
ttl?: number;
}
Access:
import { AUTO_DISCOVERED_STATES } from '@storage-system';
console.log('All Flash states:', AUTO_DISCOVERED_STATES);
Advanced Usage
Computed Signals with Flash Persistence
const cart = autoFlashState<CartItem[]>({
key: 'cart',
initialValue: []
});
// Computed from persistent state
const itemCount = computed(() =>
cart().reduce((sum, item) => sum + item.quantity, 0)
);
const total = computed(() =>
cart().reduce((sum, item) => sum + (item.price * item.quantity), 0)
);
Effects with Flash Persistence
const theme = autoFlashState({
key: 'theme',
initialValue: 'dark'
});
// React to theme changes
effect(() => {
const currentTheme = theme();
document.body.classList.toggle('dark-theme', currentTheme === 'dark');
}, { allowSignalWrites: true });
Migration from NGXS
// Before (NGXS)
@Select(PreferencesState.theme) theme$!: Observable<string>;
constructor(private store: Store) {}
setTheme(theme: string) {
this.store.dispatch(new SetTheme(theme));
}
// After (Flash Persistence)
theme = autoFlashState({
key: 'theme',
initialValue: 'dark'
});
setTheme(newTheme: string) {
this.theme.set(newTheme); // That's it!
}
Custom Serialization
For complex types that need special serialization:
class CustomDate {
constructor(public value: Date) {}
toJSON() {
return this.value.toISOString();
}
static fromJSON(json: string) {
return new CustomDate(new Date(json));
}
}
const dateState = autoFlashState({
key: 'date',
initialValue: new CustomDate(new Date())
});
// Serialization/deserialization handled automatically via toJSON
Performance Tips
1. Use Computed for Derived Values
// ❌ Bad - Recomputes every time
function getTotal() {
return cart().reduce((sum, item) => sum + item.price, 0);
}
// ✅ Good - Computed once
const total = computed(() =>
cart().reduce((sum, item) => sum + item.price, 0)
);
2. Batch Updates
// ❌ Bad - Multiple writes
items.forEach(item => cart.update(c => [...c, item]));
// ✅ Good - Single write
cart.update(c => [...c, ...items]);
3. Use TTL for Temporary Data
// ✅ Automatic cleanup
const tempCache = autoFlashState({
key: 'temp-data',
initialValue: null,
ttl: 60 * 1000 // 1 minute
});
4. Optimize Large Objects
// ❌ Bad - Stores entire object
const largeState = autoFlashState({
key: 'large',
initialValue: { ...hugeObject }
});
// ✅ Good - Store only needed fields
const essentialState = autoFlashState({
key: 'essential',
initialValue: { id: hugeObject.id, name: hugeObject.name }
});
Error Handling
Flash Persistence handles errors gracefully:
const state = autoFlashState({
key: 'data',
initialValue: { value: 0 }
});
try {
state.set({ value: 1 });
} catch (error) {
// Errors are logged but don't throw
// State update succeeds, persistence may be queued for retry
console.error('Persistence error:', error);
}
Storage Quota Exceeded
When storage quota is exceeded:
- Least recently used items are evicted
- Write is retried
- If still fails, error is logged
- In-memory state is maintained
Debugging
Enable Debug Logging
// In development
if (!environment.production) {
localStorage.setItem('DEBUG_FLASH_PERSISTENCE', 'true');
}
View Auto-Discovered States
import { AUTO_DISCOVERED_STATES } from '@storage-system';
console.table(AUTO_DISCOVERED_STATES);
Check Performance Metrics
const hydrator = inject(FlashStateHydratorService);
console.log(hydrator.getPerformanceMetrics());
Next Steps
- 🎓 Best Practices - Recommended patterns
- 🔧 Advanced Usage - Complex scenarios
- 📖 Overview - Architecture and concepts
- 🚀 Quick Start - Get started guide
Questions? Check GitHub Discussions or open an issue.