import { useCallback, useRef, useState } from 'react' // Mutates `arr` in place; returned reference is the same input array, kept // so callers can chain. Use `Array.prototype.toSpliced` if you need a copy. export function removeAtInPlace(arr: T[], i: number): T[] { if (i < 0 || i >= arr.length) { return arr } arr.splice(i, 1) return arr } export function useQueue() { const queueRef = useRef([]) const [queuedDisplay, setQueuedDisplay] = useState([]) const queueEditRef = useRef(null) const [queueEditIdx, setQueueEditIdx] = useState(null) const syncQueue = useCallback(() => setQueuedDisplay([...queueRef.current]), []) const setQueueEdit = useCallback((idx: number | null) => { queueEditRef.current = idx setQueueEditIdx(idx) }, []) const enqueue = useCallback( (text: string) => { queueRef.current.push(text) syncQueue() }, [syncQueue] ) const dequeue = useCallback(() => { const head = queueRef.current.shift() syncQueue() return head }, [syncQueue]) const replaceQ = useCallback( (i: number, text: string) => { queueRef.current[i] = text syncQueue() }, [syncQueue] ) const removeQ = useCallback( (i: number) => { const before = queueRef.current.length removeAtInPlace(queueRef.current, i) if (queueRef.current.length !== before) { syncQueue() } }, [syncQueue] ) return { dequeue, enqueue, queueEditIdx, queueEditRef, queueRef, queuedDisplay, removeQ, replaceQ, setQueueEdit, syncQueue } }