Something went wrong. Try again.
source dump of claude code forked from oppi.li/claude-code
Something went wrong. Try again.
2.5 kB · 68 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869import { 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, ])}