Refactors calendar data management and sync infrastructure
Introduces comprehensive data management system for calendar V2 - Adds IndexedDB storage with pluggable entity services - Implements EventBus for decoupled event communication - Creates data seeding mechanism for initial application setup - Establishes sync and repository abstractions for flexible data handling
This commit is contained in:
parent
dee977d4df
commit
e581039b62
17 changed files with 1076 additions and 4 deletions
73
src/v2/workers/DataSeeder.ts
Normal file
73
src/v2/workers/DataSeeder.ts
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
import { IApiRepository } from '../repositories/IApiRepository';
|
||||
import { IEntityService } from '../storage/IEntityService';
|
||||
import { ISync } from '../types/CalendarTypes';
|
||||
|
||||
/**
|
||||
* DataSeeder - Orchestrates initial data loading from repositories into IndexedDB
|
||||
*
|
||||
* ARCHITECTURE:
|
||||
* - Repository (Mock/Api): Fetches data from source (JSON file or backend API)
|
||||
* - DataSeeder (this class): Orchestrates fetch + save operations
|
||||
* - Service (EventService, etc.): Saves data to IndexedDB
|
||||
*
|
||||
* POLYMORPHIC DESIGN:
|
||||
* - Uses arrays of IEntityService[] and IApiRepository[]
|
||||
* - Matches services with repositories using entityType property
|
||||
* - Open/Closed Principle: Adding new entity requires no code changes here
|
||||
*/
|
||||
export class DataSeeder {
|
||||
constructor(
|
||||
private services: IEntityService<ISync>[],
|
||||
private repositories: IApiRepository<ISync>[]
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Seed all entity stores if they are empty
|
||||
*/
|
||||
async seedIfEmpty(): Promise<void> {
|
||||
console.log('[DataSeeder] Checking if database needs seeding...');
|
||||
|
||||
try {
|
||||
for (const service of this.services) {
|
||||
const repository = this.repositories.find(repo => repo.entityType === service.entityType);
|
||||
|
||||
if (!repository) {
|
||||
console.warn(`[DataSeeder] No repository found for entity type: ${service.entityType}, skipping`);
|
||||
continue;
|
||||
}
|
||||
|
||||
await this.seedEntity(service.entityType, service, repository);
|
||||
}
|
||||
|
||||
console.log('[DataSeeder] Seeding complete');
|
||||
} catch (error) {
|
||||
console.error('[DataSeeder] Seeding failed:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
private async seedEntity<T extends ISync>(
|
||||
entityType: string,
|
||||
service: IEntityService<T>,
|
||||
repository: IApiRepository<T>
|
||||
): Promise<void> {
|
||||
const existing = await service.getAll();
|
||||
|
||||
if (existing.length > 0) {
|
||||
console.log(`[DataSeeder] ${entityType} store already has ${existing.length} items, skipping seed`);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`[DataSeeder] ${entityType} store is empty, fetching from repository...`);
|
||||
|
||||
const data = await repository.fetchAll();
|
||||
|
||||
console.log(`[DataSeeder] Fetched ${data.length} ${entityType} items, saving to IndexedDB...`);
|
||||
|
||||
for (const entity of data) {
|
||||
await service.save(entity);
|
||||
}
|
||||
|
||||
console.log(`[DataSeeder] ${entityType} seeding complete (${data.length} items saved)`);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue