Files
microchat-app/src/stores/sockets.ts
2026-03-20 09:56:14 +03:00

137 lines
3.5 KiB
TypeScript

import { defineStore } from 'pinia'
import { onMounted, onUnmounted, ref } from 'vue'
import { type Chat, useChatsStore } from '@/stores/chats.ts'
import { useAuthStore } from '@/stores/auth.ts'
import { type Message, useMessagesStore } from '@/stores/messages.ts'
import { useUsersStore } from '@/stores/users.ts'
import { useMenuStore } from '@/stores/menu.ts'
export enum SocketDataReq {
GET_CHATS = 'GET_CHATS',
CREATE_CHAT = 'CREATE_CHAT',
GET_USERS = 'GET_USERS',
GET_USER = 'GET_USER',
GET_MESSAGES = 'GET_MESSAGES',
CREATE_MESSAGE = 'CREATE_MESSAGE',
}
export enum SocketDataRes {
USERS = 'USERS',
CHATS = 'CHATS',
MESSAGES = 'MESSAGES',
MESSAGE = 'MESSAGE',
USER = 'USER',
STATUS = 'STATUS',
ERROR = 'ERROR',
}
export enum COMMAND {
CONNECT = 'CONNECT',
SEND = 'SEND',
CLOSE = 'CLOSE',
}
export const useSocketsStore = defineStore('sockets', () => {
const url = 'ws://localhost:3000/ws'
const authStore = useAuthStore()
const chatsStore = useChatsStore()
const messagesStore = useMessagesStore()
const usersStore = useUsersStore()
const menuStore = useMenuStore()
const isConnected = ref(false)
const error = ref<string>()
const worker = ref<SharedWorker>()
function init() {
console.log('INIT SHARED WORKER')
if (!window.SharedWorker) {
console.log('SharedWorker not supported')
error.value = 'SharedWorker not supported'
}
worker.value = new SharedWorker(new URL('@/workers/worker.js', import.meta.url), {
type: 'module',
})
worker.value.port.onmessage = (event) => {
const { type, data, connected, message } = event.data
switch (type) {
case SocketDataRes.USERS:
console.log('Received from back: USERS', data)
usersStore.users = data
break
case SocketDataRes.USER:
console.log('Received from back: USER', data)
authStore.me = data
break
case SocketDataRes.CHATS:
console.log('Received from back: CHATS', data)
if (Array.isArray(data)) {
chatsStore.chats = data
} else {
const idx = chatsStore.chats.findIndex((chat) => chat.id === data.id)
if (idx < 0) chatsStore.chats.push(data)
menuStore.selected = ['chats']
chatsStore.selected = [data.id]
}
break
case SocketDataRes.MESSAGES:
console.log('Received from back: MESSAGES', data)
messagesStore.messages = data
// if (options.onMessage) {
// options.onMessage(data)
// }
break
case SocketDataRes.MESSAGE:
console.log('Received from back: MESSAGE', data)
messagesStore.messages.unshift(data)
break
case SocketDataRes.STATUS:
isConnected.value = connected
break
case SocketDataRes.ERROR:
error.value = message
authStore.logout()
break
}
}
connect()
}
function postMessage(command: COMMAND, data?: unknown) {
if (worker.value) worker.value.port.postMessage({ command, data })
}
function connect() {
postMessage(COMMAND.CONNECT, { url: url, token: authStore.getToken() })
}
const send = (data: unknown) => {
console.log(COMMAND.SEND, data)
postMessage(COMMAND.SEND, data)
}
const close = () => {
postMessage(COMMAND.CLOSE)
}
onUnmounted(() => {
if (worker.value) close()
})
return {
isConnected,
error,
send,
close,
init,
}
})