import { useEffect, useState } from 'react' import { getSession, type CollabSession } from './store' import type { CollabUser } from './user' export type ConnStatus = 'connecting' | 'connected' | 'disconnected' export interface CollabState { session: CollabSession status: ConnStatus peers: CollabUser[] synced: boolean } export function useCollab(deckId: string, user: CollabUser, token?: string): CollabState { const session = getSession(deckId, token) const [status, setStatus] = useState('connecting') const [peers, setPeers] = useState([]) const [synced, setSynced] = useState(Boolean(session.provider.isSynced)) useEffect(() => { const { provider } = session const aw = provider.awareness aw?.setLocalStateField('user', user) const onStatus = (e: { status: ConnStatus }) => setStatus(e.status) provider.on('status', onStatus) setStatus((provider.status as ConnStatus) ?? 'connecting') const onSynced = () => setSynced(true) provider.on('synced', onSynced) if (provider.isSynced) setSynced(true) const updatePeers = () => { if (!aw) return const users: CollabUser[] = [] aw.getStates().forEach((st) => { const u = (st as { user?: CollabUser }).user if (u) users.push(u) }) setPeers(users) } aw?.on('change', updatePeers) updatePeers() return () => { provider.off('status', onStatus) provider.off('synced', onSynced) aw?.off('change', updatePeers) } }, [session, user]) return { session, status, peers, synced } }