-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
125 lines (90 loc) · 2.67 KB
/
index.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// shim to allow node and native browser module path support with the same code
// @ts-expect-error TypeScript can't find this
import Is from "../../@achrinza/strong-type/index.js";
const is = new Is();
type Handler = (...args: unknown[]) => unknown;
class EventPubSub {
constructor() {}
on(type: string, handler: Handler, once = false) {
is.string(type);
is.function(handler);
is.boolean(once);
if (type == "*") {
type = this.#all as unknown as string;
}
if (!this.#events[type]) {
this.#events[type] = [];
}
handler[this.#once] = once;
this.#events[type].push(handler);
return this;
}
once(type: string, handler: (...args: unknown[]) => unknown) {
//sugar for this.on with once set to true
//so let that do the validation
return this.on(type, handler, true);
}
off(type = "*", handler: string | Handler = "*") {
is.string(type);
if (type == this.#all.toString() || type == "*") {
type = this.#all as unknown as string;
}
if (!this.#events[type]) {
return this;
}
if (handler == "*") {
delete this.#events[type];
return this;
}
//If we are not removing all the handlers,
//we need to know which one we are removing.
is.function(handler);
const handlers = this.#events[type];
while (handlers.includes(handler as unknown as Handler)) {
handlers.splice(handlers.indexOf(handler as unknown as Handler), 1);
}
if (handlers.length < 1) {
delete this.#events[type];
}
return this;
}
emit(type: string, ...args: unknown[]) {
is.string(type);
const globalHandlers = this.#events[this.#all as unknown as string] || [];
this.#handleOnce(this.#all.toString(), globalHandlers, type, ...args);
if (!this.#events[type]) {
return this;
}
const handlers = this.#events[type];
this.#handleOnce(type, handlers, ...args);
return this;
}
reset() {
this.off(this.#all.toString());
for (let type in this.#events) {
this.off(type);
}
return this;
}
get list() {
return Object.assign({}, this.#events);
}
#handleOnce = (type: string, handlers: Handler[], ...args: unknown[]) => {
is.string(type);
is.array(handlers);
const deleteOnceHandled = [];
for (let handler of handlers) {
handler(...args);
if (handler[this.#once]) {
deleteOnceHandled.push(handler);
}
}
for (let handler of deleteOnceHandled) {
this.off(type, handler);
}
};
#all = Symbol.for("event-pubsub-all");
#once = Symbol.for("event-pubsub-once");
#events: Record<string, Handler[]> = {};
}
export { EventPubSub as default, EventPubSub };