MCPcopy Index your code
hub / github.com/codeaashu/claude-code / QueryGuard

Class QueryGuard

src/utils/QueryGuard.ts:29–121  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

27import { createSignal } from './signal.js'
28
29export class QueryGuard {
30 private _status: 'idle' | 'dispatching' | 'running' = 'idle'
31 private _generation = 0
32 private _changed = createSignal()
33
34 /**
35 * Reserve the guard for queue processing. Transitions idle → dispatching.
36 * Returns false if not idle (another query or dispatch in progress).
37 */
38 reserve(): boolean {
39 if (this._status !== 'idle') return false
40 this._status = 'dispatching'
41 this._notify()
42 return true
43 }
44
45 /**
46 * Cancel a reservation when processQueueIfReady had nothing to process.
47 * Transitions dispatching → idle.
48 */
49 cancelReservation(): void {
50 if (this._status !== 'dispatching') return
51 this._status = 'idle'
52 this._notify()
53 }
54
55 /**
56 * Start a query. Returns the generation number on success,
57 * or null if a query is already running (concurrent guard).
58 * Accepts transitions from both idle (direct user submit)
59 * and dispatching (queue processor path).
60 */
61 tryStart(): number | null {
62 if (this._status === 'running') return null
63 this._status = 'running'
64 ++this._generation
65 this._notify()
66 return this._generation
67 }
68
69 /**
70 * End a query. Returns true if this generation is still current
71 * (meaning the caller should perform cleanup). Returns false if a
72 * newer query has started (stale finally block from a cancelled query).
73 */
74 end(generation: number): boolean {
75 if (this._generation !== generation) return false
76 if (this._status !== 'running') return false
77 this._status = 'idle'
78 this._notify()
79 return true
80 }
81
82 /**
83 * Force-end the current query regardless of generation.
84 * Used by onCancel where any running query should be terminated.
85 * Increments generation so stale finally blocks from the cancelled
86 * query's promise rejection will see a mismatch and skip cleanup.

Callers

nothing calls this directly

Calls 1

createSignalFunction · 0.85

Tested by

no test coverage detected