1
0
Files
nir-frontend/src/lib/stores/websocket.ts
2024-05-20 12:20:22 +03:00

99 lines
2.6 KiB
TypeScript

import { BASE_API_URL } from '$lib/constants';
import { EventEmitter } from '$lib/event';
import { derived, get } from 'svelte/store';
import { token as tokenStore } from './user';
import type { Channel, Message } from '$lib/types';
import { messagesCache, channelsCache } from './cache';
export type WebSocketMessageType =
| 'createMessage'
| 'updateChannel'
| 'createChannel'
| 'deleteChannel'
| 'connect'
| 'disconnect'
| 'any';
export type WebSocketMessageData =
| Message
| Channel
| { id: number }
| null
| {
type: WebSocketMessageType;
};
export type WebsoketMessage = {
type: WebSocketMessageType;
data: WebSocketMessageData;
};
export const appWebsocket = new EventEmitter<WebSocketMessageType, WebSocketMessageData>();
appWebsocket.on('any', (data) => {
console.log(`[WS] Recieved message: `, data);
});
function updateCache(type: WebSocketMessageType, data: WebSocketMessageData) {
switch (type) {
case 'createMessage':
messagesCache.set((data as Message).id, data as Message);
break;
case 'updateChannel':
channelsCache.set((data as Channel).id, data as Channel);
break;
case 'createChannel':
channelsCache.set((data as Channel).id, data as Channel);
break;
case 'deleteChannel':
channelsCache.remove((data as { id: number }).id);
break;
default:
break;
}
}
const connect = (token: string) => {
const websocket = new WebSocket(`ws://${BASE_API_URL}/ws/${token}`);
websocket.onopen = () => {
appWebsocket.emit('connect', null);
appWebsocket.emit('any', { type: 'connect' });
};
websocket.onmessage = (event) => {
const message: WebsoketMessage = JSON.parse(event.data);
updateCache(message.type, message.data);
appWebsocket.emit(message.type, message.data as WebSocketMessageData);
appWebsocket.emit('any', message);
};
websocket.onclose = () => {
appWebsocket.emit('disconnect', null);
appWebsocket.emit('any', { type: 'disconnect' });
setTimeout(() => {
const token = get(tokenStore);
if (token) connect(token);
}, 500);
};
return websocket;
};
const socket = derived<typeof tokenStore, WebSocket | null>(
tokenStore,
($token, set) => {
if ($token) {
set(connect($token));
} else {
set(null);
}
},
null
);
socket.subscribe((socket) => {
console.log(`[WS] Connected: `, socket);
});