Integration Guide
Ecosistema completo para organización y gestión de contenido con interfaces espaciales
🔧 Complete Integration Guide
Step-by-step guide to integrating the storage system into your Angular application.
Step 1: Basic Setup
Install (Already Available)
The storage system is part of your NX monorepo - no installation needed!
Add Provider
// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideGgStorage } from '@storage-system';
export const appConfig: ApplicationConfig = {
providers: [
provideGgStorage({
namespace: 'my-app', // Unique identifier for your app
cache: {
maxItems: 1000, // Cache up to 1000 items
ttlMs: 300000 // 5 minutes TTL
}
})
]
};
Step 2: Service Integration
Inject StorageService
import { Component, inject } from '@angular/core';
import { StorageService } from '@storage-system';
@Component({
selector: 'app-example',
template: `...`
})
export class ExampleComponent {
private storage = inject(StorageService);
async ngOnInit() {
// Use storage here
}
}
Basic Operations
// Save data
await this.storage.put('user-profile', {
name: 'John Doe',
email: '[email protected]'
});
// Load data
const profile = await this.storage.get<UserProfile>('user-profile');
// Check existence
if (await this.storage.has('user-profile')) {
console.log('Profile exists');
}
// Remove data
await this.storage.remove('temp-data');
// List keys
const keys = await this.storage.list({ prefix: 'user/' });
// Clear data
await this.storage.clear('cache/');
Step 3: Flash Persistence (Recommended)
Auto-Persistent Signals
Use Flash Persistence for automatic state management:
import { Component } from '@angular/core';
import { autoFlashState } from '@storage-system';
@Component({
selector: 'app-settings',
template: `
<div>
<label>
Theme:
<select [value]="settings().theme"
(change)="updateTheme($any($event.target).value)">
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</label>
<label>
<input type="checkbox"
[checked]="settings().notifications"
(change)="toggleNotifications()">
Enable Notifications
</label>
</div>
`
})
export class SettingsComponent {
// ✨ Automatically persisted across sessions!
settings = autoFlashState('app-settings', {
theme: 'light',
notifications: true,
language: 'en'
});
updateTheme(theme: string) {
this.settings.update(s => ({ ...s, theme }));
// 💾 Automatically saved!
}
toggleNotifications() {
this.settings.update(s => ({ ...s, notifications: !s.notifications }));
// 💾 Automatically saved!
}
}
With MongoDB Sync
Add optional database and collection for cloud sync:
const userPreferences = autoFlashState('preferences', {
theme: 'dark',
language: 'en'
}, {
database: 'app-data', // MongoDB database
collection: 'user-prefs', // MongoDB collection
priority: 'high' // Sync every 5 minutes
});
Step 4: Reactive Patterns
Storage Signals
Create reactive signals from storage:
@Component({
template: `
<div class="profile">
@if (userProfile(); as profile) {
<h1>{{ profile.name }}</h1>
<p>{{ profile.email }}</p>
} @else {
<p>Loading...</p>
}
</div>
`
})
export class ProfileComponent {
private storage = inject(StorageService);
// Reactive signal - automatically updates UI when storage changes
readonly userProfile = this.storage.asSignal<UserProfile>(
'user/profile',
null
).value;
async ngOnInit() {
// Load profile
await this.loadProfile();
}
async loadProfile() {
const profile = await this.fetchProfileFromAPI();
await this.storage.put('user/profile', profile);
// UI automatically updates!
}
}
Computed Values
Derive state from storage signals:
@Component({
template: `
<div [attr.data-theme]="currentTheme()">
<h1>{{ welcomeMessage() }}</h1>
</div>
`
})
export class DashboardComponent {
private storage = inject(StorageService);
// Base storage signals
userProfile = this.storage.asSignal<UserProfile>('user/profile', null).value;
settings = this.storage.asSignal<Settings>('user/settings', {
theme: 'light'
}).value;
// Computed signals
currentTheme = computed(() => this.settings().theme);
welcomeMessage = computed(() => {
const profile = this.userProfile();
return profile ? `Welcome, ${profile.name}!` : 'Welcome!';
});
}
Step 5: Advanced Configuration
Performance Optimization
provideGgStorage({
namespace: 'my-app',
cache: { maxItems: 2000, ttlMs: 600000 },
strategy: 'balanced', // or 'speed' | 'durable'
performance: {
monitoring: true, // Enable performance tracking
redundancy: true, // Enable smart data mirroring
adaptiveStrategy: true, // Enable intelligent adapter selection
batchProcessing: true, // Enable operation batching
microCacheBudget: 150 * 1024 // 150KB micro-cache
}
})
Custom Adapter Preference
provideGgStorage({
namespace: 'my-app',
cache: { maxItems: 1000, ttlMs: 300000 },
adapterPreference: 'opfs', // Prefer OPFS when available
strategy: 'speed' // Maximum performance
})
Step 6: Cloud Sync (Optional)
MongoDB Integration
Add MongoDB sync for cloud persistence:
// app.config.ts
import { provideMongoDBSync } from '@storage-system';
providers: [
provideGgStorage({ namespace: 'my-app' }),
provideMongoDBSync({
connectionString: environment.mongoDbUri,
database: 'my-app',
defaultStrategy: {
mode: 'offline-first', // Local first, sync in background
priority: 'normal', // Sync every 30 minutes
conflictResolution: 'last-write-wins'
},
enableRealtime: true, // Enable Change Streams
autoInit: true // Initialize on app start
})
]
Firebase Integration
Add Firebase/Firestore sync:
import { FirestoreSyncAdapter } from '@storage-system';
@Component({})
export class MyComponent {
private storage = inject(StorageService);
async ngOnInit() {
const adapter = new FirestoreSyncAdapter({
databaseId: 'g-space-db-standard',
collection: 'app-data'
});
await adapter.waitForReady();
this.storage.setSyncAdapter(adapter);
console.log('✅ Firebase sync enabled');
}
}
Step 7: Pre-Loading & Hydration
APP_INITIALIZER Setup
Pre-load critical data for instant access:
// app.config.ts
import { APP_INITIALIZER } from '@angular/core';
import { FlashStateHydratorService } from '@storage-system';
export const appConfig: ApplicationConfig = {
providers: [
provideGgStorage({ namespace: 'my-app' }),
{
provide: APP_INITIALIZER,
useFactory: (hydrator: FlashStateHydratorService) => {
return async () => {
// Pre-load critical states
await hydrator.preloadStates([
'user-profile',
'user-settings',
'app-config'
]);
console.log('✅ States pre-loaded');
};
},
deps: [FlashStateHydratorService],
multi: true
}
]
};
Instant State Access
Access pre-loaded state without await:
@Component({})
export class AppComponent {
private hydrator = inject(FlashStateHydratorService);
constructor() {
// Instant access (no await needed - already pre-loaded)
const profile = this.hydrator.getInstantState<UserProfile>('user-profile');
if (profile) {
console.log('Profile loaded instantly:', profile.name);
}
}
}
Step 8: Monitoring & Debugging
Performance Monitoring
@Component({})
export class AdminComponent {
private storage = inject(StorageService);
checkPerformance() {
const stats = this.storage.getPerformanceStats();
if (stats) {
console.log('Cache hit rate:', stats.cacheHitRate);
console.log('Avg operation time:', stats.avgDuration, 'ms');
console.log('Total operations:', stats.totalOperations);
}
const cacheStats = this.storage.getMicroCacheStats();
console.log('Cache usage:', cacheStats.size, '/', cacheStats.budget);
console.log('Cache hit rate:', cacheStats.hitRate);
}
}
Storage Inspector
Add the Storage Inspector component for visual debugging:
import { StorageInspectorComponent } from '@storage-system';
@Component({
template: `
<router-outlet />
@if (environment.development) {
<ux-storage-inspector />
}
`,
imports: [RouterOutlet, StorageInspectorComponent]
})
export class AppComponent {}
Common Integration Patterns
Pattern 1: User Profile Management
@Injectable({ providedIn: 'root' })
export class UserService {
private storage = inject(StorageService);
private profileSignal = this.storage.asSignal<UserProfile>('user/profile', null).value;
// Expose as readonly
readonly profile = this.profileSignal.asReadonly();
async updateProfile(updates: Partial<UserProfile>) {
const current = this.profileSignal();
if (current) {
const updated = { ...current, ...updates };
await this.storage.put('user/profile', updated);
// Signal automatically updates!
}
}
async logout() {
await this.storage.clear('user/');
}
}
Pattern 2: Application Settings
@Injectable({ providedIn: 'root' })
export class SettingsService {
// Auto-persistent settings
readonly settings = autoFlashState('app-settings', {
theme: 'light' as 'light' | 'dark',
language: 'en',
notifications: true,
autoSave: true
});
// Computed values
readonly isDarkMode = computed(() => this.settings().theme === 'dark');
toggleTheme() {
const current = this.settings().theme;
this.settings.update(s => ({
...s,
theme: current === 'light' ? 'dark' : 'light'
}));
}
}
Pattern 3: Cache Management
@Injectable({ providedIn: 'root' })
export class ApiCacheService {
private storage = inject(StorageService);
async cacheResponse<T>(endpoint: string, data: T, ttlMs = 300000) {
await this.storage.put(`cache/api/${endpoint}`, {
data,
timestamp: Date.now(),
ttl: ttlMs
});
}
async getCached<T>(endpoint: string): Promise<T | null> {
const cached = await this.storage.get<{
data: T;
timestamp: number;
ttl: number;
}>(`cache/api/${endpoint}`);
if (!cached) return null;
// Check if expired
if (Date.now() - cached.timestamp > cached.ttl) {
await this.storage.remove(`cache/api/${endpoint}`);
return null;
}
return cached.data;
}
async clearCache() {
await this.storage.clear('cache/api/');
}
}
Testing Integration
Unit Testing
import { TestBed } from '@angular/core/testing';
import { provideGgStorage, StorageService } from '@storage-system';
describe('MyComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
provideGgStorage({
namespace: 'test',
cache: { maxItems: 100, ttlMs: 60000 }
})
]
});
});
it('should save and load data', async () => {
const storage = TestBed.inject(StorageService);
await storage.put('test-key', { value: 'test' });
const result = await storage.get('test-key');
expect(result).toEqual({ value: 'test' });
});
});
Troubleshooting
Issue: Data Not Persisting
Check adapter availability:
const caps = storage.getCapabilities();
console.log('Available adapters:', caps);
Issue: Slow Performance
Enable monitoring:
const stats = storage.getPerformanceStats();
console.log('Performance:', stats);
Check micro-cache:
const cacheStats = storage.getMicroCacheStats();
console.log('Cache efficiency:', cacheStats.hitRate);
Issue: Quota Exceeded
The system automatically migrates to OPFS. If issues persist:
// Clear old cache data
await storage.clear('cache/');
// Check current usage
const keys = await storage.list();
console.log('Total keys:', keys.length);
Next Steps
- API Reference - Complete API documentation
- Flash Persistence - Deep dive
- MongoDB Integration - Cloud sync
- Performance Guide - Optimization
You're now ready to integrate the storage system into any Angular application! 🚀