Skip to content

Instantly share code, notes, and snippets.

@sillvva
Created September 21, 2023 15:04
Show Gist options
  • Save sillvva/aaeafe94890eb4746ee05a3deb10244c to your computer and use it in GitHub Desktop.
Save sillvva/aaeafe94890eb4746ee05a3deb10244c to your computer and use it in GitHub Desktop.
Websocket Wrapper with Svelte 5 Runes
export default function createSocket<T>(
url: string | URL,
options?: {
name?: string;
protocols?: string | string[];
onOpen?: (event: Event) => void;
onError?: (error: Event) => void;
onMessage?: (data: T, requests: T[], event: Event) => void;
}
) {
let requests = $state<T[]>([]);
let latest = $derived(requests.at(requests.length - 1));
let websocket: WebSocket | null = null;
$effect(() => {
websocket = new WebSocket(url, options?.protocols)
websocket.onopen = (event) => {
console.log(`${options?.name || "Websocket"} connected!`);
if (options?.onOpen) options.onOpen(event);
};
websocket.onerror = (error) => {
console.log(`${options?.name || "Websocket"} error:`, error);
if (options?.onError) options.onError(error);
};
websocket.onmessage = (event) => {
const data = JSON.parse(event.data) as T;
requests = requests.concat(data);
if (options?.afterMessage) options.onMessage(data, requests, event);
};
return () => {
if (websocket) websocket.close();
}
});
return {
get requests() { return requests },
get latest() { return latest },
close() {
if (websocket) websocket.close();
},
send(data: T) {
if (!websocket) throw new Error("No websocket connection");
if (websocket.readyState !== websocket.OPEN) throw new Error("No websocket connection");
websocket.send(JSON.stringify(data));
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment