import { useState, useEffect, useCallback, useRef } from 'react'; import { audit } from '../services/audit.service'; import { AuditEvent, StreamConfig, StreamFilter } from '../types'; interface UseAuditStreamOptions { filter?: StreamFilter; limit?: number; autoConnect?: boolean; } export function useAuditStream(options: UseAuditStreamOptions = {}) { const { filter, limit = 50, autoConnect = true } = options; const [events, setEvents] = useState([]); const [loading, setLoading] = useState(false); const [connected, setConnected] = useState(false); const [error, setError] = useState(null); const subscriptionRef = useRef(null); const connect = useCallback(() => { if (subscriptionRef.current) { return; // Already connected } setLoading(true); setError(null); try { const config: StreamConfig = { filter, onEvent: (event) => { setEvents(prev => { const newEvents = [event, ...prev]; return newEvents.slice(0, limit); }); }, onError: (streamError) => { setError(new Error(streamError.message)); }, onConnect: () => { setConnected(true); setLoading(false); }, onDisconnect: () => { setConnected(false); }, }; subscriptionRef.current = audit.stream(config); } catch (err: any) { setError(err); setLoading(false); } }, [filter, limit]); const disconnect = useCallback(() => { if (subscriptionRef.current) { subscriptionRef.current.unsubscribe(); subscriptionRef.current = null; setConnected(false); } }, []); const pause = useCallback(() => { if (subscriptionRef.current) { subscriptionRef.current.pause(); } }, []); const resume = useCallback(() => { if (subscriptionRef.current) { subscriptionRef.current.resume(); } }, []); const updateFilter = useCallback((newFilter: StreamFilter) => { if (subscriptionRef.current) { subscriptionRef.current.updateFilter(newFilter); } }, []); const clear = useCallback(() => { setEvents([]); }, []); // Auto-connect on mount if enabled useEffect(() => { if (autoConnect) { connect(); } return () => { disconnect(); }; }, [autoConnect, connect, disconnect]); return { events, loading, connected, error, connect, disconnect, pause, resume, updateFilter, clear, }; }