Refactor offline-first architecture with IndexedDB
Improves dependency injection and service initialization for IndexedDB-based calendar application Implements lazy initialization for IndexedDB Fixes race conditions in async event handling Adds proper dependency injection with registerType Enhances sync manager and repository pattern Key improvements: - Lazy database initialization - Proper service lifecycle management - Improved network awareness for sync operations - Cleaned up initialization logic in index.ts
This commit is contained in:
parent
e7011526e3
commit
a1bee99d8e
6 changed files with 226 additions and 34 deletions
41
src/index.ts
41
src/index.ts
|
|
@ -80,22 +80,6 @@ async function initializeCalendar(): Promise<void> {
|
|||
// Load configuration from JSON
|
||||
const config = await ConfigManager.load();
|
||||
|
||||
// ========================================
|
||||
// Initialize IndexedDB and seed if needed
|
||||
// ========================================
|
||||
const indexedDB = new IndexedDBService();
|
||||
await indexedDB.initialize();
|
||||
await indexedDB.seedIfEmpty();
|
||||
|
||||
// Create operation queue
|
||||
const queue = new OperationQueue(indexedDB);
|
||||
|
||||
// Create API repository (placeholder for now)
|
||||
const apiRepository = new ApiEventRepository(config.apiEndpoint || '/api');
|
||||
|
||||
// Create IndexedDB repository
|
||||
const repository = new IndexedDBEventRepository(indexedDB, queue);
|
||||
|
||||
// Create NovaDI container
|
||||
const container = new Container();
|
||||
const builder = container.builder();
|
||||
|
|
@ -109,13 +93,14 @@ async function initializeCalendar(): Promise<void> {
|
|||
// Register configuration instance
|
||||
builder.registerInstance(config).as<Configuration>();
|
||||
|
||||
// Register IndexedDB and storage instances
|
||||
builder.registerInstance(indexedDB).as<IndexedDBService>();
|
||||
builder.registerInstance(queue).as<OperationQueue>();
|
||||
builder.registerInstance(apiRepository).as<ApiEventRepository>();
|
||||
// Register storage and repository services
|
||||
builder.registerType(IndexedDBService).as<IndexedDBService>();
|
||||
builder.registerType(OperationQueue).as<OperationQueue>();
|
||||
builder.registerType(ApiEventRepository).as<ApiEventRepository>();
|
||||
builder.registerType(IndexedDBEventRepository).as<IEventRepository>();
|
||||
|
||||
// Register repository
|
||||
builder.registerInstance(repository).as<IEventRepository>();
|
||||
// Register workers
|
||||
builder.registerType(SyncManager).as<SyncManager>();
|
||||
|
||||
// Register renderers
|
||||
builder.registerType(DateHeaderRenderer).as<IHeaderRenderer>();
|
||||
|
|
@ -171,12 +156,8 @@ async function initializeCalendar(): Promise<void> {
|
|||
await calendarManager.initialize?.();
|
||||
await resizeHandleManager.initialize?.();
|
||||
|
||||
// ========================================
|
||||
// Initialize and start SyncManager
|
||||
// ========================================
|
||||
const syncManager = new SyncManager(eventBus, queue, indexedDB, apiRepository);
|
||||
syncManager.startSync();
|
||||
console.log('SyncManager initialized and started');
|
||||
// Resolve SyncManager (starts automatically in constructor)
|
||||
const syncManager = app.resolveType<SyncManager>();
|
||||
|
||||
// Handle deep linking after managers are initialized
|
||||
await handleDeepLinking(eventManager, urlManager);
|
||||
|
|
@ -189,8 +170,6 @@ async function initializeCalendar(): Promise<void> {
|
|||
calendarManager: typeof calendarManager;
|
||||
eventManager: typeof eventManager;
|
||||
syncManager: typeof syncManager;
|
||||
indexedDB: typeof indexedDB;
|
||||
queue: typeof queue;
|
||||
};
|
||||
}).calendarDebug = {
|
||||
eventBus,
|
||||
|
|
@ -198,8 +177,6 @@ async function initializeCalendar(): Promise<void> {
|
|||
calendarManager,
|
||||
eventManager,
|
||||
syncManager,
|
||||
indexedDB,
|
||||
queue,
|
||||
};
|
||||
|
||||
} catch (error) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { ICalendarEvent } from '../types/CalendarTypes';
|
||||
import { Configuration } from '../configurations/CalendarConfig';
|
||||
|
||||
/**
|
||||
* ApiEventRepository
|
||||
|
|
@ -15,8 +16,8 @@ import { ICalendarEvent } from '../types/CalendarTypes';
|
|||
export class ApiEventRepository {
|
||||
private apiEndpoint: string;
|
||||
|
||||
constructor(apiEndpoint: string) {
|
||||
this.apiEndpoint = apiEndpoint;
|
||||
constructor(config: Configuration) {
|
||||
this.apiEndpoint = config.apiEndpoint || '/api';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -23,8 +23,15 @@ export class IndexedDBEventRepository implements IEventRepository {
|
|||
|
||||
/**
|
||||
* Load all events from IndexedDB
|
||||
* Ensures IndexedDB is initialized and seeded on first call
|
||||
*/
|
||||
async loadEvents(): Promise<ICalendarEvent[]> {
|
||||
// Lazy initialization on first data load
|
||||
if (!this.indexedDB.isInitialized()) {
|
||||
await this.indexedDB.initialize();
|
||||
await this.indexedDB.seedIfEmpty();
|
||||
}
|
||||
|
||||
return await this.indexedDB.getAllEvents();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ export class IndexedDBService {
|
|||
private static readonly SYNC_STATE_STORE = 'syncState';
|
||||
|
||||
private db: IDBDatabase | null = null;
|
||||
private initialized: boolean = false;
|
||||
|
||||
/**
|
||||
* Initialize and open the database
|
||||
|
|
@ -38,6 +39,7 @@ export class IndexedDBService {
|
|||
|
||||
request.onsuccess = () => {
|
||||
this.db = request.result;
|
||||
this.initialized = true;
|
||||
resolve();
|
||||
};
|
||||
|
||||
|
|
@ -66,6 +68,13 @@ export class IndexedDBService {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if database is initialized
|
||||
*/
|
||||
public isInitialized(): boolean {
|
||||
return this.initialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure database is initialized
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ export class SyncManager {
|
|||
this.apiRepository = apiRepository;
|
||||
|
||||
this.setupNetworkListeners();
|
||||
this.startSync();
|
||||
console.log('SyncManager initialized and started');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue