Adds core calendar package components including: - Base services for events, resources, and settings - Calendar app and orchestrator - Build and bundling configuration - IndexedDB storage setup Prepares foundational architecture for calendar functionality
84 lines
2.8 KiB
TypeScript
84 lines
2.8 KiB
TypeScript
import { ICalendarEvent, EntityType, IEventBus } from '../../types/CalendarTypes';
|
|
import { EventStore } from './EventStore';
|
|
import { EventSerialization } from './EventSerialization';
|
|
import { BaseEntityService } from '../BaseEntityService';
|
|
import { IndexedDBContext } from '../IndexedDBContext';
|
|
|
|
/**
|
|
* EventService - CRUD operations for calendar events in IndexedDB
|
|
*
|
|
* Extends BaseEntityService for shared CRUD and sync logic.
|
|
* Provides event-specific query methods.
|
|
*/
|
|
export class EventService extends BaseEntityService<ICalendarEvent> {
|
|
readonly storeName = EventStore.STORE_NAME;
|
|
readonly entityType: EntityType = 'Event';
|
|
|
|
constructor(context: IndexedDBContext, eventBus: IEventBus) {
|
|
super(context, eventBus);
|
|
}
|
|
|
|
protected serialize(event: ICalendarEvent): unknown {
|
|
return EventSerialization.serialize(event);
|
|
}
|
|
|
|
protected deserialize(data: unknown): ICalendarEvent {
|
|
return EventSerialization.deserialize(data as Record<string, unknown>);
|
|
}
|
|
|
|
/**
|
|
* Get events within a date range
|
|
*/
|
|
async getByDateRange(start: Date, end: Date): Promise<ICalendarEvent[]> {
|
|
return new Promise((resolve, reject) => {
|
|
const transaction = this.db.transaction([this.storeName], 'readonly');
|
|
const store = transaction.objectStore(this.storeName);
|
|
const index = store.index('start');
|
|
|
|
const range = IDBKeyRange.lowerBound(start.toISOString());
|
|
const request = index.getAll(range);
|
|
|
|
request.onsuccess = () => {
|
|
const data = request.result as unknown[];
|
|
const events = data
|
|
.map(item => this.deserialize(item))
|
|
.filter(event => event.start <= end);
|
|
resolve(events);
|
|
};
|
|
|
|
request.onerror = () => {
|
|
reject(new Error(`Failed to get events by date range: ${request.error}`));
|
|
};
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get events for a specific resource
|
|
*/
|
|
async getByResource(resourceId: string): Promise<ICalendarEvent[]> {
|
|
return new Promise((resolve, reject) => {
|
|
const transaction = this.db.transaction([this.storeName], 'readonly');
|
|
const store = transaction.objectStore(this.storeName);
|
|
const index = store.index('resourceId');
|
|
const request = index.getAll(resourceId);
|
|
|
|
request.onsuccess = () => {
|
|
const data = request.result as unknown[];
|
|
const events = data.map(item => this.deserialize(item));
|
|
resolve(events);
|
|
};
|
|
|
|
request.onerror = () => {
|
|
reject(new Error(`Failed to get events for resource ${resourceId}: ${request.error}`));
|
|
};
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get events for a resource within a date range
|
|
*/
|
|
async getByResourceAndDateRange(resourceId: string, start: Date, end: Date): Promise<ICalendarEvent[]> {
|
|
const resourceEvents = await this.getByResource(resourceId);
|
|
return resourceEvents.filter(event => event.start >= start && event.start <= end);
|
|
}
|
|
}
|