UNPKG

@ideal-photography/shared

Version:

Shared MongoDB and utility logic for Ideal Photography PWAs: users, products, services, bookings, orders/cart, galleries, reviews, notifications, campaigns, settings, audit logs, minimart items/orders, and push notification subscriptions.

62 lines (57 loc) 2.13 kB
import EventEmitter from 'events'; /** * Central AlertBus for emitting and listening to system alert events. * * Internally maintains a micro-queue so that heavy alert handlers * never block the caller thread. All alert payloads are processed * asynchronously in FIFO order. */ class AlertBus extends EventEmitter { constructor() { super(); // Simple in-memory queue (FIFO) this.queue = []; this.isProcessing = false; } /** * Emit an alert trigger. Consumers should subscribe to the * `alert` event or listen for specific triggers via * `bus.on(triggerName, handler)`. * * @param {string} trigger Canonical event name e.g. `user.registered` * @param {any} payload Arbitrary payload data for handlers * @param {object} opts Optional meta e.g. channel overrides */ enqueue(trigger, payload = {}, opts = {}) { this.queue.push({ trigger, payload, opts }); this._schedule(); } /** * Schedule queue processing on next tick if not already scheduled. * Ensures only one processing loop runs at a time. * @private */ _schedule() { if (this.isProcessing) return; this.isProcessing = true; // Process asynchronously so caller returns immediately setImmediate(async () => { try { while (this.queue.length) { const job = this.queue.shift(); // Wildcard event for global listeners this.emit('alert', job); // Specific trigger event e.g. `user.registered` this.emit(job.trigger, job.payload, job.opts); } } finally { this.isProcessing = false; // If new jobs were enqueued while processing, schedule again if (this.queue.length) this._schedule(); } }); } } // Export a singleton instance so the bus is shared process-wide const bus = new AlertBus(); export default bus;