File size: 1,615 Bytes
63f6453
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/**
 * Küçük olay yayıcı — arayüz (sözleşme) testleri için örnek.
 * Genel API:
 *   on(event, fn) -> unsubscribe fonksiyonu
 *   once(event, fn) -> unsubscribe fonksiyonu
 *   off(event, fn) -> boolean
 *   emit(event, ...args) -> çağrılan dinleyici sayısı
 *   listenerCount(event) -> number
 */
class EventEmitter {
  constructor() {
    this._listeners = new Map();
  }

  on(event, fn) {
    if (typeof fn !== 'function') throw new TypeError('listener bir fonksiyon olmalı');
    if (!this._listeners.has(event)) this._listeners.set(event, []);
    this._listeners.get(event).push({ fn, once: false });
    return () => this.off(event, fn);
  }

  once(event, fn) {
    if (typeof fn !== 'function') throw new TypeError('listener bir fonksiyon olmalı');
    if (!this._listeners.has(event)) this._listeners.set(event, []);
    this._listeners.get(event).push({ fn, once: true });
    return () => this.off(event, fn);
  }

  off(event, fn) {
    const list = this._listeners.get(event);
    if (!list) return false;
    const idx = list.findIndex((l) => l.fn === fn);
    if (idx === -1) return false;
    list.splice(idx, 1);
    if (list.length === 0) this._listeners.delete(event);
    return true;
  }

  emit(event, ...args) {
    const list = this._listeners.get(event);
    if (!list) return 0;
    const snapshot = list.slice();
    for (const l of snapshot) {
      if (l.once) this.off(event, l.fn);
      l.fn(...args);
    }
    return snapshot.length;
  }

  listenerCount(event) {
    return (this._listeners.get(event) || []).length;
  }
}

module.exports = { EventEmitter };