/** * useWebSocket Hook * * Main WebSocket connection hook for React components. * Manages connection lifecycle and provides socket instance. * * Usage: * const { socket, connected, connecting, error } = useWebSocket({ * url: 'ws://localhost:4001', * token: userToken, * }); */ import { useEffect, useState, useRef } from 'react' import { Socket } from 'socket.io-client' import { WebSocketClient } from '../client' import type { WebSocketClientConfig, WebSocketConnectionState } from '../types' export interface UseWebSocketReturn extends WebSocketConnectionState { socket: Socket | null; client: WebSocketClient | null; } export function useWebSocket(config: WebSocketClientConfig): UseWebSocketReturn { const [state, setState] = useState({ connected: false, connecting: false, error: null, }) const clientRef = useRef(null) const [socket, setSocket] = useState(null) useEffect(() => { // Create client instance const client = new WebSocketClient({ url: config.url, token: config.token, reconnection: config.reconnection, reconnectionAttempts: config.reconnectionAttempts, reconnectionDelay: config.reconnectionDelay, reconnectionDelayMax: config.reconnectionDelayMax, autoConnect: false, // We control connection in useEffect }) clientRef.current = client // Connect setState({ connected: false, connecting: true, error: null }) const socketInstance = client.connect() setSocket(socketInstance) // Setup event handlers const handleConnect = () => { setState({ connected: true, connecting: false, error: null }) } const handleDisconnect = () => { setState({ connected: false, connecting: false, error: null }) } const handleConnectError = (error: Error) => { setState({ connected: false, connecting: false, error }) } socketInstance.on('connect', handleConnect) socketInstance.on('disconnect', handleDisconnect) socketInstance.on('connect_error', handleConnectError) // Cleanup on unmount return () => { client.disconnect() clientRef.current = null setSocket(null) } }, [ config.url, config.token, config.reconnection, config.reconnectionAttempts, config.reconnectionDelay, config.reconnectionDelayMax, ]) // Reconnect if config changes return { socket, client: clientRef.current, ...state, } }