diff options
| author | Adam Soltys <[email protected]> | 2024-08-30 18:52:00 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2024-08-30 18:52:00 -0700 |
| commit | 8346eb9e052d10abf4fb65b66838aaab47152e2a (patch) | |
| tree | 0f5efabd144b720598441d9a638fd27d849628ff /src/lib/socket.ts | |
| parent | cb2edf24e48a49417ed6ec4a386e566470ff046c (diff) | |
| download | coinos-ui-8346eb9e052d10abf4fb65b66838aaab47152e2a.tar.gz coinos-ui-8346eb9e052d10abf4fb65b66838aaab47152e2a.zip | |
typescript
Diffstat (limited to 'src/lib/socket.ts')
| -rw-r--r-- | src/lib/socket.ts | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/src/lib/socket.ts b/src/lib/socket.ts new file mode 100644 index 00000000..98d42ead --- /dev/null +++ b/src/lib/socket.ts @@ -0,0 +1,92 @@ +import { navigating } from "$app/stores"; +import { get } from "svelte/store"; +import { event, invoice, request, newPayment, last } from "$lib/store"; +import { success, sat, sleep } from "$lib/utils"; +import { PUBLIC_SOCKET } from "$env/static/public"; +import { invalidate } from "$app/navigation"; +import { browser } from "$app/environment"; + +let socket, token; + +export const auth = () => token && send("login", token); + +export const send = (type, data) => { + socket?.readyState === 1 && socket.send(JSON.stringify({ type, data })); + return true; +}; + +export const messages = (data) => ({ + id() { + last.set(Date.now()); + }, + invoice() { + invoice.set(data); + }, + event() { + event.set(data); + }, + + request() { + request.set(data); + invalidate("app:invoice"); + }, + + async payment() { + let { amount, confirmed } = data; + + invalidate("app:user"); + invalidate("app:invoice"); + invalidate("app:payments"); + + if (amount > 0) { + success(`${confirmed ? "Received" : "Detected"} ${sat(amount)}!`); + } + }, + + connected: auth, +}); + +const initialReconnectDelay = 1000; +const maxReconnectDelay = 16000; + +let currentReconnectDelay = initialReconnectDelay; + +export function connect(t) { + token = t; + + if (socket) return auth(); + + socket = new WebSocket(PUBLIC_SOCKET); + socket.addEventListener("open", onWebsocketOpen); + socket.addEventListener("close", onWebsocketClose); + socket.addEventListener("message", onWebsocketMessage); +} + +export function close() { + if (socket) socket.close(); +} + +async function onWebsocketMessage(msg) { + let { type, data } = JSON.parse(msg.data); + if (get(navigating)) await sleep(2000); + + messages(data)[type] && messages(data)[type](); +} + +function onWebsocketOpen() { + currentReconnectDelay = initialReconnectDelay; +} + +function onWebsocketClose() { + socket = null; + setTimeout(() => { + reconnectToWebsocket(); + }, currentReconnectDelay + Math.floor(Math.random() * 3000)); +} + +function reconnectToWebsocket() { + if (currentReconnectDelay < maxReconnectDelay) { + currentReconnectDelay *= 2; + } + connect(token); +} |
