diff --git a/src/renderer/src/lib/hook-command-delayed-delivery-perf.test.ts b/src/renderer/src/lib/hook-command-delayed-delivery-perf.test.ts new file mode 100644 index 00000000000..f0b28c30887 --- /dev/null +++ b/src/renderer/src/lib/hook-command-delayed-delivery-perf.test.ts @@ -0,0 +1,40 @@ +import { afterEach, describe, expect, it, vi } from 'vitest' +import { useAppStore } from '@/store' +import { + queueHookCommandsForFirstWorktreeTab, + resetHookCommandDelayedDeliveryForTests +} from './hook-command-delayed-delivery' + +const initialState = useAppStore.getState() + +afterEach(() => { + resetHookCommandDelayedDeliveryForTests() + useAppStore.setState(initialState, true) +}) + +describe('delayed hook-command subscription', () => { + it('does not rescan pending worktrees for unrelated store updates', () => { + const reads = { value: 0 } + useAppStore.setState({ + tabsByWorktree: {}, + getKnownWorktreeById: ((worktreeId: string) => { + reads.value += 1 + return { id: worktreeId } + }) as never + } as never) + + for (let index = 0; index < 500; index += 1) { + queueHookCommandsForFirstWorktreeTab({ + worktreeId: `runtime-worktree-${index}`, + deliver: vi.fn() + }) + } + + reads.value = 0 + for (let update = 0; update < 100; update += 1) { + useAppStore.setState({ activeView: update % 2 === 0 ? 'terminal' : 'settings' } as never) + } + + expect(reads.value).toBe(0) + }) +}) diff --git a/src/renderer/src/lib/hook-command-delayed-delivery.ts b/src/renderer/src/lib/hook-command-delayed-delivery.ts index 234126f73ad..5f2db5d0cd2 100644 --- a/src/renderer/src/lib/hook-command-delayed-delivery.ts +++ b/src/renderer/src/lib/hook-command-delayed-delivery.ts @@ -33,7 +33,31 @@ function ensurePendingHookCommandSubscription(): void { if (unsubscribePendingHookCommandDeliveries) { return } - unsubscribePendingHookCommandDeliveries = useAppStore.subscribe(() => { + const initial = useAppStore.getState() + // Capture references so unrelated PTY/status updates do not rescan every + // runtime worktree waiting for its first mirrored terminal tab. + let previousTabsByWorktree = initial.tabsByWorktree + let previousWorktreesByRepo = initial.worktreesByRepo + let previousDetectedWorktreesByRepo = initial.detectedWorktreesByRepo + let previousFolderWorkspaces = initial.folderWorkspaces + let previousWorktreeLookup = initial.getKnownWorktreeById + unsubscribePendingHookCommandDeliveries = useAppStore.subscribe((state) => { + // Why: only these slices (or the test-adapter lookup itself) can change + // whether a pending worktree exists or has received its first tab. + if ( + state.tabsByWorktree === previousTabsByWorktree && + state.worktreesByRepo === previousWorktreesByRepo && + state.detectedWorktreesByRepo === previousDetectedWorktreesByRepo && + state.folderWorkspaces === previousFolderWorkspaces && + state.getKnownWorktreeById === previousWorktreeLookup + ) { + return + } + previousTabsByWorktree = state.tabsByWorktree + previousWorktreesByRepo = state.worktreesByRepo + previousDetectedWorktreesByRepo = state.detectedWorktreesByRepo + previousFolderWorkspaces = state.folderWorkspaces + previousWorktreeLookup = state.getKnownWorktreeById flushPendingHookCommandDeliveries() }) }