import cron from "node-cron"; import {Class} from "../types/Class"; import {randomUUID} from "node:crypto"; import {Container} from "../Container/Container"; import {Logger} from "log4js"; import {BaseEvent, EventEntry, EventType, HandlerEvents, TimedEvent} from "./EventHandler.types"; export class EventHandler { private static DEFAULT_EVENT_ENTRY: Omit = { persistent: false } private eventHandlers: Map> = new Map(); public get EventHandlers() { return this.eventHandlers; } constructor() { } public addHandler(eventName: string, entry: EventEntry): string { if (!this.eventHandlers.has(eventName)) { this.eventHandlers.set(eventName, new Map()); } const id = randomUUID(); this.eventHandlers.get(eventName)?.set(id, { ...EventHandler.DEFAULT_EVENT_ENTRY, ...entry }); return id; } public removeHandler(eventName: string, id: string) { if (!this.eventHandlers.has(eventName)) { return; } const localEventHandlers = this.eventHandlers.get(eventName); if (!localEventHandlers || !localEventHandlers.has(id)) { return; } localEventHandlers.delete(id); } public dispatch(event: T) { const eventName = event.constructor.name; if (!this.eventHandlers.has(eventName)) { return; } this.eventHandlers.get(eventName)?.forEach((handler) => { try { handler.method(event); } catch (e: any) { Container.get("logger").error(e); } }) if (event.type !== EventType.Acknowledge) { return; } if (event.isAcknowledged()) { return; } event.handleUnacknowledgement(); } public addTimed(event: TimedEvent) { if (!cron.validate(event.cronExpression)) { throw new Error(`Can't create event with name '${event.configuration.name}': Invalid cron expression.`) } cron.schedule(event.cronExpression, event.execute.bind(event), event.configuration); } }