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() const worker = ref() 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, } })