/
WatchEmitter.ts
72 lines (61 loc) · 2.3 KB
/
WatchEmitter.ts
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import { AwaitedEventListener, AwaitingEventEmitter } from '../rollup/types';
export class WatchEmitter<T extends { [event: string]: (...args: any) => any }>
implements AwaitingEventEmitter<T>
{
private currentHandlers: {
[K in keyof T]?: AwaitedEventListener<T, K>[];
} = Object.create(null);
private persistentHandlers: {
[K in keyof T]?: AwaitedEventListener<T, K>[];
} = Object.create(null);
// Will be overwritten by Rollup
async close(): Promise<void> {}
emit<K extends keyof T>(event: K, ...args: Parameters<T[K]>): Promise<unknown> {
return Promise.all(
this.getCurrentHandlers(event)
.concat(this.getPersistentHandlers(event))
.map(handler => handler(...args))
);
}
off<K extends keyof T>(event: K, listener: AwaitedEventListener<T, K>): this {
const listeners = this.persistentHandlers[event];
if (listeners) {
// A hack stolen from "mitt": ">>> 0" does not change numbers >= 0, but -1
// (which would remove the last array element if used unchanged) is turned
// into max_int, which is outside the array and does not change anything.
listeners.splice(listeners.indexOf(listener) >>> 0, 1);
}
return this;
}
on<K extends keyof T>(event: K, listener: AwaitedEventListener<T, K>): this {
this.getPersistentHandlers(event).push(listener);
return this;
}
onCurrentRun<K extends keyof T>(event: K, listener: AwaitedEventListener<T, K>): this {
this.getCurrentHandlers(event).push(listener);
return this;
}
once<K extends keyof T>(event: K, listener: AwaitedEventListener<T, K>): this {
const selfRemovingListener: AwaitedEventListener<T, K> = (...args) => {
this.off(event, selfRemovingListener);
return listener(...args);
};
this.on(event, selfRemovingListener);
return this;
}
removeAllListeners(): this {
this.removeListenersForCurrentRun();
this.persistentHandlers = Object.create(null);
return this;
}
removeListenersForCurrentRun(): this {
this.currentHandlers = Object.create(null);
return this;
}
private getCurrentHandlers<K extends keyof T>(event: K): AwaitedEventListener<T, K>[] {
return this.currentHandlers[event] || (this.currentHandlers[event] = []);
}
private getPersistentHandlers<K extends keyof T>(event: K): AwaitedEventListener<T, K>[] {
return this.persistentHandlers[event] || (this.persistentHandlers[event] = []);
}
}