hermes-agent/apps/desktop/src/store/tool-diffs.test.ts
Brooklyn Nicholson e30174fa17 perf(desktop): scope tool-diff subscriptions + narrow profile query invalidation
Two structural fixes from the Desktop performance audit (P2 tier):

1. Scope live tool-diff subscriptions. `ToolEntry` subscribed to the whole
   `$toolDiffs` map via `useStore`, so one `recordToolDiff` re-rendered every
   mounted tool row. Add a cached per-toolCallId derived atom
   (`$toolInlineDiff(id)`, mirroring the existing `$toolDisclosureOpen` pattern);
   computed() only notifies when that id's diff string changes, so a live patch
   re-renders one row.

2. Narrow profile / gateway-switch query invalidation. Both the active-profile
   subscription and `wipeSessionListsForGatewaySwitch` called keyless
   `queryClient.invalidateQueries()`, refetching account/marketplace/onboarding
   caches on every switch. Add `invalidateProfileScopedQueries()` with a
   denylist of profile-independent roots (billing, marketplace-themes,
   onboarding-model-options, contrib-logs-tail). A denylist is correctness-safe:
   a root we forget just refetches (cheap), whereas an allowlist that misses a
   profile-scoped key would paint the previous profile's data.

Tests: per-tool notify isolation, and real-QueryClient invalidation partition
(profile-scoped invalidated, global left intact, unknown keys invalidated).
2026-07-18 19:15:57 -04:00

47 lines
1.5 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { $toolInlineDiff, getToolDiff, recordToolDiff } from './tool-diffs'
describe('tool-diffs per-tool subscriptions', () => {
it('returns a stable cached atom per toolCallId', () => {
expect($toolInlineDiff('a')).toBe($toolInlineDiff('a'))
expect($toolInlineDiff('a')).not.toBe($toolInlineDiff('b'))
})
it('notifies only the tool whose diff changed', () => {
const aCalls: string[] = []
const bCalls: string[] = []
const unsubA = $toolInlineDiff('notify-a').listen(v => aCalls.push(v))
const unsubB = $toolInlineDiff('notify-b').listen(v => bCalls.push(v))
recordToolDiff('notify-a', 'diffA')
expect(aCalls).toEqual(['diffA'])
expect(bCalls).toEqual([]) // the unrelated tool row is never notified
recordToolDiff('notify-b', 'diffB')
expect(aCalls).toEqual(['diffA']) // still not re-notified
expect(bCalls).toEqual(['diffB'])
unsubA()
unsubB()
})
it('does not re-notify when the same diff is recorded again', () => {
const calls: string[] = []
const unsub = $toolInlineDiff('same').listen(v => calls.push(v))
recordToolDiff('same', 'x')
recordToolDiff('same', 'x')
expect(calls).toEqual(['x'])
unsub()
})
it('reads the current diff for a tool and empty for unknown/blank ids', () => {
recordToolDiff('read-me', 'value')
expect(getToolDiff('read-me')).toBe('value')
expect(getToolDiff('missing')).toBe('')
expect(getToolDiff('')).toBe('')
expect($toolInlineDiff('').get()).toBe('')
})
})