import { Logger } from '../../utils/logger'; import { CommunicationCoordinator } from '../../integrations/gcp/communication-coordinator'; /** * @interface EventBusConfig * @description Configuration for the Event Bus System. */ export interface EventBusConfig { projectID: string; defaultTopic: string; // Default Pub/Sub topic for the event bus // Add configuration for dead letter queues, event replay, etc. } /** * @interface EventBusOperations * @description Defines operations for the Event Bus System. */ export interface EventBusOperations { publish(eventType: string, payload: any, topic?: string): Promise; subscribe(eventType: string, handler: (payload: any) => void, topic?: string): Promise; // Add methods for event filtering, transformation, replay, etc. } /** * @class EventBus * @description Implements a high-performance event routing system with Google Cloud Pub/Sub integration. */ export class EventBus implements EventBusOperations { private config: EventBusConfig; private logger: Logger; private communicationCoordinator: CommunicationCoordinator; private subscriptions: Map void)[]> = new Map(); // eventType -> handlers constructor(config: EventBusConfig, communicationCoordinator: CommunicationCoordinator) { this.config = config; this.logger = new Logger('EventBus'); this.communicationCoordinator = communicationCoordinator; this.logger.info('Event Bus System initialized.'); // Initialize Pub/Sub subscription for the default topic this.communicationCoordinator.subscribeToTopic(this.config.defaultTopic, (message: any) => { try { const event = JSON.parse(message.data.toString()); this.logger.debug(`Received event from Pub/Sub: ${event.type}`); this.distributeLocally(event.type, event.payload); } catch (error: any) { this.logger.error(`Failed to parse Pub/Sub message or distribute event: ${error.message}`); } }); } /** * Publishes an event to the Event Bus, which then routes it to Pub/Sub. * @param {string} eventType The type of event to publish. * @param {any} payload The payload associated with the event. * @param {string} [topic] Optional Pub/Sub topic to publish to. Defaults to defaultTopic. * @returns {Promise} */ public async publish(eventType: string, payload: any, topic?: string): Promise { const targetTopic = topic || this.config.defaultTopic; const event = { type: eventType, payload: payload, timestamp: Date.now() }; this.logger.info(`Publishing event '${eventType}' to topic '${targetTopic}'.`); await this.communicationCoordinator.publishMessage(targetTopic, JSON.stringify(event)); // Also distribute locally for immediate processing this.distributeLocally(eventType, payload); } /** * Subscribes a handler function to a specific event type. * @param {string} eventType The type of event to subscribe to. * @param {(payload: any) => void} handler The function to call when the event occurs. * @param {string} [topic] Optional Pub/Sub topic to subscribe to. Defaults to defaultTopic. * @returns {Promise} */ public async subscribe(eventType: string, handler: (payload: any) => void, topic?: string): Promise { this.logger.info(`Subscribing to event type '${eventType}'.`); if (!this.subscriptions.has(eventType)) { this.subscriptions.set(eventType, []); } this.subscriptions.get(eventType)?.push(handler); // If a specific topic is provided, also subscribe to it via Pub/Sub (conceptual, as Pub/Sub subscriptions are usually per-service) if (topic && topic !== this.config.defaultTopic) { this.logger.warn(`Specific topic subscriptions via Pub/Sub are conceptual for this layer: ${topic}`); // await this.communicationCoordinator.subscribeToTopic(topic, (message: any) => { /* ... */ }); } } /** * Distributes an event to locally subscribed handlers. * @param {string} eventType The type of event. * @param {any} payload The event payload. * @private */ private distributeLocally(eventType: string, payload: any): void { const handlers = this.subscriptions.get(eventType); if (handlers) { this.logger.debug(`Distributing event '${eventType}' to ${handlers.length} local handlers.`); handlers.forEach(handler => { try { handler(payload); } catch (error: any) { this.logger.error(`Error executing local event handler for '${eventType}': ${error.message}`); } }); } } // Conceptual methods for event filtering, transformation, replay, etc. public async filterEvents(eventType: string, criteria: any): Promise { this.logger.info(`Filtering events for ${eventType} with criteria (conceptual)... `); return []; } public async transformEvent(eventType: string, payload: any, transformationRules: any): Promise { this.logger.info(`Transforming event for ${eventType} (conceptual)... `); return payload; } public async replayEvents(eventType: string, startTime: number, endTime: number): Promise { this.logger.info(`Replaying events for ${eventType} from ${startTime} to ${endTime} (conceptual)... `); } }