97 lines
2.6 KiB
TypeScript
97 lines
2.6 KiB
TypeScript
import { isConnected, socketData } from '$lib/stores';
|
|
import { Result, Ok } from '$lib/utilities';
|
|
import { resultService } from '$lib/services';
|
|
import { type WebSocketJsonMsg } from '$lib/models';
|
|
import type { Writable } from 'svelte/store';
|
|
|
|
type WebsocketOutData = string | ArrayBufferLike | Blob | ArrayBufferView;
|
|
|
|
// TODO
|
|
/**
|
|
* MOVE THE store to a store.ts file
|
|
*
|
|
* Make an object on the class that encapsulate all the stores
|
|
*
|
|
* Make the handle message function look up the type and set the value, to simplify the code
|
|
*/
|
|
|
|
class SocketService {
|
|
private socket!: WebSocket;
|
|
private url?:string
|
|
|
|
constructor() {}
|
|
|
|
public connect(url: string): void {
|
|
this.url = url
|
|
this.socket = new WebSocket(url);
|
|
this.socket.binaryType = 'arraybuffer';
|
|
this.socket.onopen = () => this.handleConnected();
|
|
this.socket.onclose = () => this.handleDisconnected();
|
|
this.socket.onmessage = (event: MessageEvent) =>
|
|
resultService.handleResult(this.handleMessage(event), 'SocketService');
|
|
this.socket.onerror = (error: Event) => console.log(error);
|
|
}
|
|
|
|
public send(data: WebsocketOutData): Result<void, string> {
|
|
if (this.socket.readyState === WebSocket.OPEN) {
|
|
this.socket.send(data);
|
|
return Ok.void();
|
|
}
|
|
return Result.err('The connection is not open');
|
|
}
|
|
|
|
public addPublisher(store: Writable<WebsocketOutData>, type?: string) {
|
|
const publish = (data: WebsocketOutData) =>
|
|
this.send(type ? JSON.stringify({ type, data }) : data);
|
|
store.subscribe(publish);
|
|
}
|
|
|
|
private handleConnected(): void {
|
|
isConnected.set(true);
|
|
}
|
|
|
|
private handleDisconnected(): void {
|
|
isConnected.set(false);
|
|
setTimeout(() => this.connect(this.url as string), 500)
|
|
}
|
|
|
|
private getJsonFromMessage(msg: string): Result<WebSocketJsonMsg, string> {
|
|
try {
|
|
return Result.ok(JSON.parse(msg) as WebSocketJsonMsg);
|
|
} catch (error) {
|
|
return Result.err('Failed to parse socket message', error);
|
|
}
|
|
}
|
|
|
|
private handleBufferMessage(buffer: ArrayBuffer): Result<void, string> {
|
|
console.log(buffer);
|
|
return Ok.void();
|
|
}
|
|
|
|
private handleMessage(event: MessageEvent): Result<void, string> {
|
|
if (event.data instanceof ArrayBuffer) {
|
|
return this.handleBufferMessage(event.data);
|
|
}
|
|
let msgRes = this.getJsonFromMessage(event.data);
|
|
if (msgRes.isErr()) {
|
|
return msgRes;
|
|
}
|
|
const msg = msgRes.inner;
|
|
|
|
if (msg.type === 'log') {
|
|
socketData.logs.update((entries) => {
|
|
entries.push(msg.data);
|
|
return entries;
|
|
});
|
|
return Ok.void();
|
|
} else if (msg.data && msg.type in socketData) {
|
|
socketData[msg.type].set(msg.data);
|
|
return Ok.void();
|
|
}
|
|
|
|
return Result.err(`Got invalid msg: ${JSON.stringify(msg)}`);
|
|
}
|
|
}
|
|
|
|
export default new SocketService();
|