| import { writable } from 'svelte/store'; |
| import { playSound } from '$utils/helpers.js'; |
|
|
| function createWebSocketStore() { |
| const { subscribe, set, update } = writable({ |
| connected: false, |
| ws: null |
| }); |
|
|
| let ws = null; |
| let reconnectTimer = null; |
| let listeners = {}; |
|
|
| function connect(token) { |
| if (ws && ws.readyState === WebSocket.OPEN) return; |
|
|
| const protocol = window.location.protocol === 'https:' ? 'wss' : 'ws'; |
| const host = window.location.host; |
| const url = `${protocol}://${host}/ws?token=${token}`; |
|
|
| ws = new WebSocket(url); |
|
|
| ws.onopen = () => { |
| console.log('[WS] Connected'); |
| update((s) => ({ ...s, connected: true, ws })); |
| clearTimeout(reconnectTimer); |
| }; |
|
|
| ws.onmessage = (event) => { |
| try { |
| const msg = JSON.parse(event.data); |
| const { channel, event: evt, data } = msg; |
|
|
| |
| const key = `${channel}:${evt}`; |
| if (listeners[key]) { |
| listeners[key].forEach((fn) => fn(data)); |
| } |
|
|
| |
| if (listeners[`*:${evt}`]) { |
| listeners[`*:${evt}`].forEach((fn) => fn(data, channel)); |
| } |
|
|
| |
| if (evt === 'new_order' || evt === 'new_kot') { |
| playSound('order'); |
| } |
| } catch { |
| |
| } |
| }; |
|
|
| ws.onclose = () => { |
| console.log('[WS] Disconnected, reconnecting in 3s...'); |
| update((s) => ({ ...s, connected: false, ws: null })); |
| reconnectTimer = setTimeout(() => connect(token), 3000); |
| }; |
|
|
| ws.onerror = () => { |
| ws.close(); |
| }; |
| } |
|
|
| function disconnect() { |
| clearTimeout(reconnectTimer); |
| if (ws) { |
| ws.close(); |
| ws = null; |
| } |
| set({ connected: false, ws: null }); |
| listeners = {}; |
| } |
|
|
| function on(channel, event, callback) { |
| const key = `${channel}:${event}`; |
| if (!listeners[key]) listeners[key] = []; |
| listeners[key].push(callback); |
|
|
| |
| return () => { |
| listeners[key] = listeners[key].filter((fn) => fn !== callback); |
| }; |
| } |
|
|
| function send(channel, event, data) { |
| if (ws && ws.readyState === WebSocket.OPEN) { |
| ws.send(JSON.stringify({ channel, event, data })); |
| } |
| } |
|
|
| return { |
| subscribe, |
| connect, |
| disconnect, |
| on, |
| send |
| }; |
| } |
|
|
| export const wsStore = createWebSocketStore(); |
|
|