This commit is contained in:
2026-02-17 20:43:23 +03:00
commit 55d819f935
22 changed files with 5874 additions and 0 deletions

View File

@@ -0,0 +1,129 @@
import { ref, onUnmounted, onMounted } from 'vue'
export interface Message {
id: number
text: string
userId: string
createdAt: string
}
export interface Chat {
id: string
type_id: number
users: User[]
}
export interface User {
id: number
email: string
}
export interface WsData {
type: WsDataType
// data: Chat | Message | User | User[] | Message[] | Chat[]
data: {text: string}
}
export enum WsDataType {
CHAT = 'CHAT',
USER = 'USER',
MESSAGE = 'MESSAGE',
STATUS = 'STATUS',
ERROR = 'ERROR',
}
export enum COMMAND {
CONNECT = 'CONNECT',
SEND = 'SEND',
CLOSE = 'CLOSE',
}
export function useSharedWebSocket(options?: { url?: string; autoConnect?: true }) {
const url = options?.url || 'ws://localhost:3000/ws'
const autoConnect = options?.autoConnect ?? true
console.log('useSharedWebSocket', url, autoConnect)
const messages = ref<Message[]>([])
const chats = ref<Chat[]>([])
const users = ref<unknown[]>([])
const isConnected = ref(false)
const error = ref<string>()
const worker = ref<SharedWorker>()
const initWorker = () => {
if (!window.SharedWorker) {
console.warn('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
console.log(event.data)
switch (type) {
case WsDataType.USER:
console.log('USER')
break
case WsDataType.CHAT:
console.log('chat')
chats.value = data
break
case WsDataType.MESSAGE:
messages.value.push(data)
// if (options.onMessage) {
// options.onMessage(data)
// }
break
case WsDataType.STATUS:
isConnected.value = connected
break
case WsDataType.ERROR:
error.value = message
break
}
}
worker.value.port.postMessage({
command: COMMAND.CONNECT,
data: { url },
})
}
const send = (data: WsData) => {
if (worker.value) {
worker.value.port.postMessage({
command: COMMAND.SEND,
data: data,
})
}
}
const close = () => {
if (worker.value) {
worker.value.port.postMessage({ command: COMMAND.CLOSE })
}
}
onMounted(() => {
if (autoConnect) initWorker()
})
onUnmounted(() => {
if (worker.value) close()
})
return {
messages,
chats,
isConnected,
error,
send,
close,
initWorker,
}
}