-
-
Notifications
You must be signed in to change notification settings - Fork 496
/
AsyncEventEmitter.js
84 lines (74 loc) · 1.93 KB
/
AsyncEventEmitter.js
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
73
74
75
76
77
78
79
80
81
82
83
84
import { EventEmitter } from "node:events";
/**
* This class emits events asynchronously.
* It can be used for time measurements during a build.
*/
class AsyncEventEmitter extends EventEmitter {
#handlerMode = "parallel";
// TypeScript slop
constructor(...args) {
super(...args);
}
reset() {
// `eleventy#` event type listeners are removed at the start of each build (singletons)
for (let type of this.eventNames()) {
if (typeof type === "string" && type.startsWith("eleventy#")) {
this.removeAllListeners(type);
}
}
}
/**
* @param {string} type - The event name to emit.
* @param {...*} args - Additional arguments that get passed to listeners.
* @returns {Promise} - Promise resolves once all listeners were invoked
*/
/** @ts-expect-error */
async emit(type, ...args) {
let listeners = this.listeners(type);
if (listeners.length === 0) {
return [];
}
if (this.#handlerMode == "sequential") {
const result = [];
for (const listener of listeners) {
const returnValue = await listener.apply(this, args);
result.push(returnValue);
}
return result;
} else {
return Promise.all(
listeners.map((listener) => {
return listener.apply(this, args);
}),
);
}
}
/**
* @param {string} type - The event name to emit.
* @param {...*} args - Additional lazy-executed function arguments that get passed to listeners.
* @returns {Promise} - Promise resolves once all listeners were invoked
*/
async emitLazy(type, ...args) {
let listeners = this.listeners(type);
if (listeners.length === 0) {
return [];
}
let argsMap = [];
for (let arg of args) {
if (typeof arg === "function") {
let r = arg();
if (r instanceof Promise) {
r = await r;
}
argsMap.push(r);
} else {
argsMap.push(arg);
}
}
return this.emit.call(this, type, ...argsMap);
}
setHandlerMode(mode) {
this.#handlerMode = mode;
}
}
export default AsyncEventEmitter;