hermes-agent/apps/desktop/electron/event-dedupe.ts
Brooklyn Nicholson a41346f8ae refactor(desktop): tidy the cross-window deduper
Drop the unused DEDUPE_WINDOW_MS export and rename its interval so
"window" isn't overloaded against BrowserWindow in a multi-window
feature (windowMs → intervalMs). DRY the completion-sound play path.
No behavior change.
2026-07-20 18:36:05 -05:00

32 lines
1.1 KiB
TypeScript

// Cross-window de-dupe for one-shot side-effects (OS notifications, the turn-end
// sound, spoken replies). Every desktop window is its own renderer process, so N
// open windows each independently react to the same backend event. The main
// process is the one place they all share and it handles IPC serially, so it's
// the race-free owner: the first window to claim a key within the interval wins;
// peers see it's taken and stay quiet. Pure + injectable clock, so it's
// unit-testable without Electron.
const DEDUPE_INTERVAL_MS = 1000
// Returns true when `key` was already claimed within the interval (caller drops
// this one). Self-evicting: stale keys are pruned on every call, so the map
// can't grow unbounded.
export function createEventDeduper(intervalMs = DEDUPE_INTERVAL_MS) {
const lastSeenAt = new Map<string, number>()
return function isDuplicate(key: string, now = Date.now()): boolean {
for (const [k, at] of lastSeenAt) {
if (now - at >= intervalMs) {
lastSeenAt.delete(k)
}
}
if (lastSeenAt.has(key)) {
return true
}
lastSeenAt.set(key, now)
return false
}
}