-
-
Notifications
You must be signed in to change notification settings - Fork 122
/
Copy pathuse-server-events.ts
87 lines (69 loc) · 1.94 KB
/
use-server-events.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
export enum ServerEvent {
LocationMutation = "location.mutation",
ItemMutation = "item.mutation",
LabelMutation = "label.mutation",
}
export type EventMessage = {
event: ServerEvent;
};
let socket: WebSocket | null = null;
const listeners = new Map<ServerEvent, (() => void)[]>();
function connect(onmessage: (m: EventMessage) => void) {
let protocol = "ws";
if (window.location.protocol === "https:") {
protocol = "wss";
}
const dev = import.meta.dev;
const host = dev ? window.location.host.replace("3000", "7745") : window.location.host;
const ws = new WebSocket(`${protocol}://${host}/api/v1/ws/events`);
ws.onopen = () => {
console.debug("connected to server");
};
ws.onclose = () => {
console.debug("disconnected from server");
setTimeout(() => {
connect(onmessage);
}, 3000);
};
ws.onerror = err => {
console.error("websocket error", err);
};
const thorttled = new Map<ServerEvent, any>();
thorttled.set(ServerEvent.LocationMutation, useThrottleFn(onmessage, 1000));
thorttled.set(ServerEvent.ItemMutation, useThrottleFn(onmessage, 1000));
thorttled.set(ServerEvent.LabelMutation, useThrottleFn(onmessage, 1000));
ws.onmessage = msg => {
const pm = JSON.parse(msg.data);
const fn = thorttled.get(pm.event);
if (fn) {
fn(pm);
}
};
socket = ws;
}
export function onServerEvent(event: ServerEvent, callback: () => void) {
if (socket === null) {
connect(e => {
console.debug("received event", e);
listeners.get(e.event)?.forEach(c => c());
});
}
onMounted(() => {
if (!listeners.has(event)) {
listeners.set(event, []);
}
listeners.get(event)?.push(callback);
});
onUnmounted(() => {
const got = listeners.get(event);
if (got) {
listeners.set(
event,
got.filter(c => c !== callback)
);
}
if (listeners.get(event)?.length === 0) {
listeners.delete(event);
}
});
}