Files
oxspeak_server/frontend/src/stores/gateway.ts
T
2026-06-21 19:11:23 +02:00

86 lines
2.0 KiB
TypeScript

import {defineStore} from 'pinia';
import {useAppStore} from "@/stores/app.ts";
import {useAuthStore} from "@/stores/auth.ts";
type GatewayStatus = 'disconnected' | 'connecting' | 'connected' | 'error'
export const useGatewayStore = defineStore('gateway', {
state: () => ({
socket: null as WebSocket | null,
status: 'disconnected' as GatewayStatus,
reconnectAttempts: 0,
}),
actions: {
async connect() {
if (this.socket && this.status === 'connected') {
return
}
const appStore = useAppStore()
const authStore = useAuthStore()
this.status = 'connecting'
const token = authStore.token
if (!token) {
this.status = 'error'
return
}
const apiUri = appStore.baseurl ? new URL(appStore.baseurl) : new URL(window.location.href)
const wsProtocol = apiUri.protocol === 'https:' ? 'wss:' : 'ws:'
const wsUrl = `${wsProtocol}//${apiUri.host}/ws/gateway?token=${encodeURIComponent(token)}`
const socket = new WebSocket(wsUrl)
socket.onopen = () => {
this.status = 'connected'
this.reconnectAttempts = 0
}
socket.onclose = () => {
this.status = 'disconnected'
this.socket = null
this.scheduleReconnect()
}
socket.onerror = () => {
this.status = 'error'
}
socket.onmessage = event => {
this.handleMessage(event.data)
}
this.socket = socket
},
async disconnect() {
this.socket?.close()
this.socket = null
this.status = 'disconnected'
},
async send(payload: object) {
if (!this.socket || this.status !== 'connected') {
console.warn('WebSocket is not connected')
return
}
this.socket.send(JSON.stringify(payload))
},
async handleMessage(rawData: string) {
},
async scheduleReconnect() {
const delay = Math.min(1000 * 2 ** this.reconnectAttempts, 30000)
this.reconnectAttempts += 1
window.setTimeout(() => {
this.connect()
}, delay)
},
}
});