UNPKG

2.35 kBJavaScriptView Raw
1function Emitter(object) {
2 if (object) {
3 return mixin(object);
4 }
5
6 this._callbacks = new Map();
7}
8
9function mixin(object) {
10 Object.assign(object, Emitter.prototype);
11 object._callbacks = new Map();
12 return object;
13}
14
15Emitter.prototype.on = function (event, listener) {
16 const callbacks = this._callbacks.get(event) ?? [];
17 callbacks.push(listener);
18 this._callbacks.set(event, callbacks);
19 return this;
20};
21
22Emitter.prototype.once = function (event, listener) {
23 const on = (...arguments_) => {
24 this.off(event, on);
25 listener.apply(this, arguments_);
26 };
27
28 on.fn = listener;
29 this.on(event, on);
30 return this;
31};
32
33Emitter.prototype.off = function (event, listener) {
34 if (event === undefined && listener === undefined) {
35 this._callbacks.clear();
36 return this;
37 }
38
39 if (listener === undefined) {
40 this._callbacks.delete(event);
41 return this;
42 }
43
44 const callbacks = this._callbacks.get(event);
45 if (callbacks) {
46 for (const [index, callback] of callbacks.entries()) {
47 if (callback === listener || callback.fn === listener) {
48 callbacks.splice(index, 1);
49 break;
50 }
51 }
52
53 if (callbacks.length === 0) {
54 this._callbacks.delete(event);
55 } else {
56 this._callbacks.set(event, callbacks);
57 }
58 }
59
60 return this;
61};
62
63Emitter.prototype.emit = function (event, ...arguments_) {
64 const callbacks = this._callbacks.get(event);
65 if (callbacks) {
66 // Create a copy of the callbacks array to avoid issues if it's modified during iteration
67 const callbacksCopy = [...callbacks];
68
69 for (const callback of callbacksCopy) {
70 callback.apply(this, arguments_);
71 }
72 }
73
74 return this;
75};
76
77Emitter.prototype.listeners = function (event) {
78 return this._callbacks.get(event) ?? [];
79};
80
81Emitter.prototype.listenerCount = function (event) {
82 if (event) {
83 return this.listeners(event).length;
84 }
85
86 let totalCount = 0;
87 for (const callbacks of this._callbacks.values()) {
88 totalCount += callbacks.length;
89 }
90
91 return totalCount;
92};
93
94Emitter.prototype.hasListeners = function (event) {
95 return this.listenerCount(event) > 0;
96};
97
98// Aliases
99Emitter.prototype.addEventListener = Emitter.prototype.on;
100Emitter.prototype.removeListener = Emitter.prototype.off;
101Emitter.prototype.removeEventListener = Emitter.prototype.off;
102Emitter.prototype.removeAllListeners = Emitter.prototype.off;
103
104if (typeof module !== 'undefined') {
105 module.exports = Emitter;
106}