()
| 58 | } |
| 59 | |
| 60 | export function useConsoleMessages(): UseConsoleMessagesReturn { |
| 61 | const [consoleMessages, dispatch] = useReducer(consoleMessagesReducer, []); |
| 62 | const messageQueueRef = useRef<ConsoleMessageItem[]>([]); |
| 63 | const timeoutRef = useRef<NodeJS.Timeout | null>(null); |
| 64 | const [, startTransition] = useTransition(); |
| 65 | |
| 66 | const processQueue = useCallback(() => { |
| 67 | if (messageQueueRef.current.length > 0) { |
| 68 | const messagesToProcess = messageQueueRef.current; |
| 69 | messageQueueRef.current = []; |
| 70 | startTransition(() => { |
| 71 | dispatch({ type: 'ADD_MESSAGES', payload: messagesToProcess }); |
| 72 | }); |
| 73 | } |
| 74 | timeoutRef.current = null; |
| 75 | }, []); |
| 76 | |
| 77 | const handleNewMessage = useCallback( |
| 78 | (message: ConsoleMessageItem) => { |
| 79 | messageQueueRef.current.push(message); |
| 80 | if (!timeoutRef.current) { |
| 81 | // Batch updates using a timeout. 16ms is a reasonable delay to batch |
| 82 | // rapid-fire messages without noticeable lag. |
| 83 | timeoutRef.current = setTimeout(processQueue, 16); |
| 84 | } |
| 85 | }, |
| 86 | [processQueue], |
| 87 | ); |
| 88 | |
| 89 | const clearConsoleMessages = useCallback(() => { |
| 90 | if (timeoutRef.current) { |
| 91 | clearTimeout(timeoutRef.current); |
| 92 | timeoutRef.current = null; |
| 93 | } |
| 94 | messageQueueRef.current = []; |
| 95 | startTransition(() => { |
| 96 | dispatch({ type: 'CLEAR' }); |
| 97 | }); |
| 98 | }, []); |
| 99 | |
| 100 | // Cleanup on unmount |
| 101 | useEffect( |
| 102 | () => () => { |
| 103 | if (timeoutRef.current) { |
| 104 | clearTimeout(timeoutRef.current); |
| 105 | } |
| 106 | }, |
| 107 | [], |
| 108 | ); |
| 109 | |
| 110 | return { consoleMessages, handleNewMessage, clearConsoleMessages }; |
| 111 | } |
no outgoing calls