📄 src/web3/events/EventBus.ts
D-OPEN SOVEREIGN

Documentation & Insights

Central EventBus for wallet and session events. Pub/sub pattern for
cross-module communication within the SDK.
1import { type EventName } from './enums';
2
3export type EventListener<T = any> = (data: T) => void;
4
5/**
6 * Central EventBus for wallet and session events. Pub/sub pattern for
7 * cross-module communication within the SDK.
8 */
9export class EventBus {
10  private listeners: Map<EventName, Set<EventListener>> = new Map();
11
12  on<T = any>(eventType: EventName, listener: EventListener<T>): () => void {
13    if (!this.listeners.has(eventType)) {
14      this.listeners.set(eventType, new Set());
15    }
16    this.listeners.get(eventType)!.add(listener);
17    return () => this.off(eventType, listener);
18  }
19
20  off<T = any>(eventType: EventName, listener: EventListener<T>): void {
21    const listenersSet = this.listeners.get(eventType);
22    if (listenersSet) {
23      listenersSet.delete(listener);
24      if (listenersSet.size === 0) {
25        this.listeners.delete(eventType);
26      }
27    }
28  }
29
30  emit<T = any>(eventType: EventName, data: T): void {
31    const listenersSet = this.listeners.get(eventType);
32    if (listenersSet) {
33      listenersSet.forEach((listener) => {
34        try {
35          listener(data);
36        } catch (error) {
37          console.error(`Error in event listener for ${eventType}:`, error);
38        }
39      });
40    }
41  }
42
43  once<T = any>(eventType: EventName, listener: EventListener<T>): () => void {
44    const wrappedListener = (data: T) => {
45      listener(data);
46      this.off(eventType, wrappedListener);
47    };
48    return this.on(eventType, wrappedListener);
49  }
50
51  clear(eventType?: EventName): void {
52    if (eventType) {
53      this.listeners.delete(eventType);
54    } else {
55      this.listeners.clear();
56    }
57  }
58
59  listenerCount(eventType: EventName): number {
60    return this.listeners.get(eventType)?.size || 0;
61  }
62}
63
64let globalEventBus: EventBus | null = null;
65
66export function getEventBus(): EventBus {
67  if (!globalEventBus) {
68    globalEventBus = new EventBus();
69  }
70  return globalEventBus;
71}
72