/
event-bus.class.ts
69 lines (55 loc) · 2.03 KB
/
event-bus.class.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
// Copyright (C) 2020-2022 Acala Foundation.
// SPDX-License-Identifier: Apache-2.0
// Copyright 2022-2023 Webb Technologies Inc.
// SPDX-License-Identifier: Apache-2.0
// This file has been modified by Webb Technologies Inc.
type Event = Record<string, unknown>;
export type Subscription<T extends Event = Event> = {
[Key in keyof T]?: Array<(val: T[Key]) => any>;
};
export abstract class EventBus<T extends Event> {
/**
* Optionally expose the `emit` functionality outside the implementor
**/
sendEvent: undefined | (<E extends keyof T>(event: E, data: T[E]) => void) = undefined;
protected subscriptions: Subscription<T> = {};
/**
* Register an event and pass a callback
* @returns Void|Function , Void if the handler is already registered or Function if the handler is registered
**/
on<E extends keyof T> (event: E, cb: (val: T[E]) => void): () => void {
const listeners = this.subscriptions[event];
if (!listeners || listeners.indexOf(cb) === -1) {
this.subscriptions[event] = [...(this.subscriptions?.[event] ?? []), cb];
}
return () => this.off(event, cb);
}
/**
* emit an event
**/
protected emit<E extends keyof T> (event: E, data: T[E]): void {
this.subscriptions[event]?.forEach((cb) => cb(data));
}
/**
* Unregister the listener for an event
* the reference of the callback function
**/
protected off<E extends keyof T> (event: E, cb: (val: T[E]) => void): void {
const listeners = this.subscriptions[event];
this.subscriptions[event] = listeners?.filter((c) => c !== cb) ?? [];
}
once<E extends keyof T> (event: E, cb: (val: T[E]) => void): () => void {
const hookedCb = (val: T[E]) => {
cb(val);
this.off(event, hookedCb);
};
this.subscriptions[event] = [...(this.subscriptions?.[event] ?? []), hookedCb];
return () => this.off(event, hookedCb);
}
unsubscribeAll () {
this.subscriptions = {} as Subscription<T>;
}
unsubscribeAllForEvent<E extends keyof T> (event: E) {
this.subscriptions[event] = [];
}
}