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
|
import { getChannel } from "../connection";
import type { AnyMessage } from "./messages";
export type Handlers = {
[event: string]: EventHandler<unknown>;
};
type EventHandler<Message extends AnyMessage> = {
tokenHandler: TokenHandler<Message>;
directHandlers: Handler<Message>[];
};
export type TokenHandler<Message extends AnyMessage> = {
[token: string]: Handler<Message>;
};
export type Handler<Message extends AnyMessage> = (message?: Message) => void;
export type UnregisterHandler = () => void;
export function registerTokenHandler<Message extends AnyMessage>(
handlers: Handlers,
channel: Channel,
event: string,
token: string | null,
handler: Handler<Message>
): UnregisterHandler {
let eventHandler = handlers[event];
// If this event did not yet have any handlers registered we have to register it
if (eventHandler === undefined) {
eventHandler = {
tokenHandler: {},
directHandlers: [],
};
handlers[event] = eventHandler;
registerNewEvent<Message>(channel, eventHandler, event);
}
let unregister: UnregisterHandler;
if (token === null) {
const directHandlers = eventHandler.directHandlers;
directHandlers.push(handler);
unregister = () => {
const index = directHandlers.findIndex(h => h === handler);
directHandlers.splice(index, 1);
};
} else {
const tokenHandler = eventHandler.tokenHandler;
tokenHandler[token] = handler;
unregister = () => {
delete tokenHandler[token];
};
}
return unregister;
}
function registerNewEvent<Message extends AnyMessage>(
channel: Channel,
eventHandler: EventHandler<Message>,
event: string
) {
const callback = (data: Message) => {
handleEvent<Message>(eventHandler, data);
};
channel.on(event, callback);
}
function handleEvent<Message extends AnyMessage>(
eventHandler: EventHandler<Message>,
message: Message
) {
if (message["token"] !== undefined) {
const token = message["token"];
const handler: Handler<Message> = eventHandler.tokenHandler[token];
if (handler === undefined) {
throw new Error("Received message for an unknown token.");
}
handler(message);
}
for (const handler of eventHandler.directHandlers) {
handler(message);
}
}
|