UNPKG

@underpostnet/underpost

Version:

Underpost Platform — end-to-end CI/CD and application-delivery toolchain CLI. Covers bare metal, Kubernetes, K3s, kubeadm, LXD, container/image orchestration, secrets, databases, cron jobs, monitoring, SSH, runners, PWA + Workbox delivery, and release orc

97 lines (75 loc) 2.15 kB
class EventBus { constructor() { this.target = new EventTarget(); this.listeners = new Map(); this.typeKeys = new Map(); this.bridges = new Map(); } ensureBridge(type) { if (this.bridges.has(type)) return; const bridge = async (event) => { const deferred = event._deferred; try { const keys = [...(this.typeKeys.get(type) ?? [])]; for (const key of keys) { const entry = this.listeners.get(key); if (!entry) continue; await entry.listener(event.detail, event); if (entry.once) this.off(key); } deferred?.resolve(); } catch (error) { deferred?.reject(error); } }; this.bridges.set(type, bridge); this.target.addEventListener(type, bridge); } on(type, listener, options = {}) { const key = options.key ?? Symbol(type); this.off(key); this.ensureBridge(type); const keys = this.typeKeys.get(type) ?? new Set(); keys.add(key); this.typeKeys.set(type, keys); this.listeners.set(key, { type, listener, once: Boolean(options.once), }); return () => this.off(key); } off(key) { const entry = this.listeners.get(key); if (!entry) return false; this.listeners.delete(key); const keys = this.typeKeys.get(entry.type); if (keys) { keys.delete(key); if (keys.size === 0) this.typeKeys.delete(entry.type); } return true; } has(key) { return this.listeners.has(key); } keysOf(type) { return [...(this.typeKeys.get(type) ?? [])]; } async emit(type, detail) { if (!(this.typeKeys.get(type)?.size > 0)) return; const event = new CustomEvent(type, { detail }); return await new Promise((resolve, reject) => { event._deferred = { resolve, reject }; this.target.dispatchEvent(event); }); } async emitKey(key, detail) { const entry = this.listeners.get(key); if (!entry) return; const event = new CustomEvent(entry.type, { detail }); await entry.listener(detail, event); if (entry.once) this.off(key); } } export { EventBus };