Calendar/src/storage/SyncPlugin.ts

65 lines
1.8 KiB
TypeScript
Raw Normal View History

import { ISync, SyncStatus } from '../types/CalendarTypes';
/**
* SyncPlugin<T extends ISync> - Pluggable sync functionality for entity services
*
* COMPOSITION PATTERN:
* - Encapsulates all sync-related logic in separate class
* - Composed into BaseEntityService (not inheritance)
*/
export class SyncPlugin<T extends ISync> {
constructor(private service: any) {}
/**
* Mark entity as successfully synced
*/
async markAsSynced(id: string): Promise<void> {
const entity = await this.service.get(id);
if (entity) {
entity.syncStatus = 'synced';
await this.service.save(entity);
}
}
/**
* Mark entity as sync error
*/
async markAsError(id: string): Promise<void> {
const entity = await this.service.get(id);
if (entity) {
entity.syncStatus = 'error';
await this.service.save(entity);
}
}
/**
* Get current sync status for an entity
*/
async getSyncStatus(id: string): Promise<SyncStatus | null> {
const entity = await this.service.get(id);
return entity ? entity.syncStatus : null;
}
/**
* Get entities by sync status using IndexedDB index
*/
async getBySyncStatus(syncStatus: string): Promise<T[]> {
return new Promise((resolve, reject) => {
const transaction = this.service.db.transaction([this.service.storeName], 'readonly');
const store = transaction.objectStore(this.service.storeName);
const index = store.index('syncStatus');
const request = index.getAll(syncStatus);
request.onsuccess = () => {
const data = request.result as unknown[];
const entities = data.map(item => this.service.deserialize(item));
resolve(entities);
};
request.onerror = () => {
reject(new Error(`Failed to get by sync status ${syncStatus}: ${request.error}`));
};
});
}
}