import * as Y from 'yjs'; import { WebsocketProvider } from 'y-websocket'; import { WebrtcProvider } from 'y-webrtc'; import { Poll, PollOption } from '../types/poll.types'; const WS_URL = import.meta.env.VITE_WS_URL || 'ws://localhost:3000'; const ROOM_NAME = 'default-poll'; export const ydoc = new Y.Doc(); export const yPolls = ydoc.getArray('polls'); export let wsProvider: WebsocketProvider | null = null; export let webrtcProvider: WebrtcProvider | null = null; export function initializeProviders() { wsProvider = new WebsocketProvider( WS_URL + '/yjs', ROOM_NAME, ydoc, { connect: true } ); webrtcProvider = new WebrtcProvider( ROOM_NAME, ydoc, { signaling: [WS_URL.replace('ws://', 'wss://').replace('http://', 'https://') + '/signal'], password: null, awareness: wsProvider.awareness, maxConns: 20, filterBcConns: true, peerOpts: {} } ); wsProvider.on('status', (event: { status: string }) => { console.log('WebSocket status:', event.status); }); webrtcProvider.on('synced', (synced: boolean) => { console.log('WebRTC synced:', synced); }); return { wsProvider, webrtcProvider }; } export function destroyProviders() { wsProvider?.destroy(); webrtcProvider?.destroy(); } export function createPoll(question: string, createdBy: string): string { const pollId = Math.random().toString(36).substr(2, 9); const poll: Poll = { id: pollId, question, createdBy, timestamp: Date.now(), options: [] }; yPolls.push([poll]); return pollId; } export function addOption(pollId: string, text: string, createdBy: string): void { const polls = yPolls.toArray(); const pollIndex = polls.findIndex(p => p.id === pollId); if (pollIndex !== -1) { const poll = polls[pollIndex]; const option: PollOption = { id: Math.random().toString(36).substr(2, 9), text, votes: 0, votedBy: [], createdBy, timestamp: Date.now() }; const updatedPoll = { ...poll, options: [...poll.options, option] }; yPolls.delete(pollIndex, 1); yPolls.insert(pollIndex, [updatedPoll]); } } export function voteForOption(pollId: string, optionId: string, userId: string): void { const polls = yPolls.toArray(); const pollIndex = polls.findIndex(p => p.id === pollId); if (pollIndex !== -1) { const poll = polls[pollIndex]; const optionIndex = poll.options.findIndex(opt => opt.id === optionId); if (optionIndex !== -1) { const option = poll.options[optionIndex]; if (option.votedBy.includes(userId)) { return; } const updatedOption = { ...option, votes: option.votes + 1, votedBy: [...option.votedBy, userId] }; const updatedOptions = [...poll.options]; updatedOptions[optionIndex] = updatedOption; const updatedPoll = { ...poll, options: updatedOptions }; yPolls.delete(pollIndex, 1); yPolls.insert(pollIndex, [updatedPoll]); } } } export function getPolls(): Poll[] { return yPolls.toArray(); } export function getPoll(pollId: string): Poll | undefined { return yPolls.toArray().find(p => p.id === pollId); }