🎯 Use case
This file lives under “hooks/”, which covers reusable UI or integration hooks. On the API surface it exposes useQueueProcessor — mainly functions, hooks, or classes. Dependencies touch React UI. It composes internal code from types and utils (relative imports).
Generated from folder role, exports, dependency roots, and inline comments — not hand-reviewed for every path.
🧠 Inline summary
import { useEffect, useSyncExternalStore } from 'react' import type { QueuedCommand } from '../types/textInputTypes.js' import { getCommandQueueSnapshot, subscribeToCommandQueue,
📤 Exports (heuristic)
useQueueProcessor
📚 External import roots
Package roots from from "…" (relative paths omitted).
react
🖥️ Source preview
import { useEffect, useSyncExternalStore } from 'react'
import type { QueuedCommand } from '../types/textInputTypes.js'
import {
getCommandQueueSnapshot,
subscribeToCommandQueue,
} from '../utils/messageQueueManager.js'
import type { QueryGuard } from '../utils/QueryGuard.js'
import { processQueueIfReady } from '../utils/queueProcessor.js'
type UseQueueProcessorParams = {
executeQueuedInput: (commands: QueuedCommand[]) => Promise<void>
hasActiveLocalJsxUI: boolean
queryGuard: QueryGuard
}
/**
* Hook that processes queued commands when conditions are met.
*
* Uses a single unified command queue (module-level store). Priority determines
* processing order: 'now' > 'next' (user input) > 'later' (task notifications).
* The dequeue() function handles priority ordering automatically.
*
* Processing triggers when:
* - No query active (queryGuard — reactive via useSyncExternalStore)
* - Queue has items
* - No active local JSX UI blocking input
*/
export function useQueueProcessor({
executeQueuedInput,
hasActiveLocalJsxUI,
queryGuard,
}: UseQueueProcessorParams): void {
// Subscribe to the query guard. Re-renders when a query starts or ends
// (or when reserve/cancelReservation transitions dispatching state).
const isQueryActive = useSyncExternalStore(
queryGuard.subscribe,
queryGuard.getSnapshot,
)
// Subscribe to the unified command queue via useSyncExternalStore.
// This guarantees re-render when the store changes, bypassing
// React context propagation delays that cause missed notifications in Ink.
const queueSnapshot = useSyncExternalStore(
subscribeToCommandQueue,
getCommandQueueSnapshot,
)
useEffect(() => {
if (isQueryActive) return
if (hasActiveLocalJsxUI) return
if (queueSnapshot.length === 0) return
// Reservation is now owned by handlePromptSubmit (inside executeUserInput's
// try block). The sync chain executeQueuedInput → handlePromptSubmit →
// executeUserInput → queryGuard.reserve() runs before the first real await,
// so by the time React re-runs this effect (due to the dequeue-triggered
// snapshot change), isQueryActive is already true (dispatching) and the
// guard above returns early. handlePromptSubmit's finally releases the
// reservation via cancelReservation() (no-op if onQuery already ran end()).
processQueueIfReady({ executeInput: executeQueuedInput })
}, [
queueSnapshot,
isQueryActive,
executeQueuedInput,
hasActiveLocalJsxUI,
queryGuard,
])
}