UNPKG

@sailboat-computer/data-storage

Version:

Shared data storage library for sailboat computer v3

163 lines (136 loc) 3.7 kB
/** * Event Bus for Data Storage * * This module provides a simple event bus implementation for the data storage package. */ import { common } from '@sailboat-computer/sailboat-types'; // Define EventCategory constants export const EventCategory = { DATA: 'category_data' as common.EventCategory, ALERT: 'category_alert' as common.EventCategory, CONFIGURATION: 'category_configuration' as common.EventCategory, SYSTEM: 'category_system' as common.EventCategory, USER_ACTION: 'category_user_action' as common.EventCategory }; export type EventCategoryType = common.EventCategory; /** * Event options */ export interface EventOptions { /** * Event category */ category: EventCategoryType; /** * Event priority */ priority: 'low' | 'normal' | 'high' | 'critical'; } /** * Event handler */ export type EventHandler = (data: any) => void | Promise<void>; /** * Event bus interface */ export interface EventBus { /** * Publish an event * * @param eventType - Event type * @param data - Event data * @param options - Event options */ publish(eventType: string, data: any, options?: EventOptions): Promise<void>; /** * Subscribe to an event * * @param eventType - Event type * @param handler - Event handler * @returns Subscription ID */ subscribe(eventType: string, handler: EventHandler): string; /** * Unsubscribe from an event * * @param subscriptionId - Subscription ID */ unsubscribe(subscriptionId: string): void; } /** * In-memory event bus implementation */ export class InMemoryEventBus implements EventBus { private subscriptions: Map<string, Map<string, EventHandler>> = new Map(); /** * Publish an event * * @param eventType - Event type * @param data - Event data * @param options - Event options */ async publish(eventType: string, data: any, options?: EventOptions): Promise<void> { const handlers = this.subscriptions.get(eventType); if (!handlers) { return; } const promises: Promise<void>[] = []; for (const handler of handlers.values()) { try { const result = handler(data); if (result instanceof Promise) { promises.push(result); } } catch (error) { console.error(`Error handling event ${eventType}:`, error); } } if (promises.length > 0) { await Promise.all(promises); } } /** * Subscribe to an event * * @param eventType - Event type * @param handler - Event handler * @returns Subscription ID */ subscribe(eventType: string, handler: EventHandler): string { if (!this.subscriptions.has(eventType)) { this.subscriptions.set(eventType, new Map()); } const subscriptionId = `${eventType}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`; this.subscriptions.get(eventType)!.set(subscriptionId, handler); return subscriptionId; } /** * Unsubscribe from an event * * @param subscriptionId - Subscription ID */ unsubscribe(subscriptionId: string): void { const [eventType] = subscriptionId.split('-'); if (!eventType) { return; } const handlers = this.subscriptions.get(eventType); if (!handlers) { return; } handlers.delete(subscriptionId); if (handlers.size === 0) { this.subscriptions.delete(eventType); } } } /** * Create a new event bus * * @returns Event bus */ export function createEventBus(): EventBus { return new InMemoryEventBus(); } // Export singleton instance export const eventBus = createEventBus();