hermes-agent-features/ui-tui/src/components/fpsOverlay.tsx
Brooklyn Nicholson b1c49d5e73 chore(tui): /clean recent perf work — KISS/DRY pass
24 files, -319 LoC. Behaviour preserved, 369/369 tests green.

- hermes-ink caches: shared lruEvict helper for the four parallel LRU
  caches (stringWidth, wrapText, sliceAnsi, lineWidth); touch-on-read
  stays inlined per cache; tightened output.ts skip-slice fast path.
- wheelAccel: trimmed provenance header, collapsed env parsing, ternary
  dispatch in computeWheelStep.
- perfPane: folded ensureLogDir into once-flag, spread-with-overrides
  for fastPath/phases instead of full rebuilds.
- env: extracted truthy() (used 4×).
- virtualHeights: collapsed user/diff/slash height bumps; trail+todos
  estimate.
- useInputHandlers: scrollIdleTimer cleanup on unmount, ?? undefined
  shorthand.
- useMainApp: dropped dead liveTailVisible IIFE and liveProgress
  indirection.
- appLayout, markdown, messageLine, entry: vertical rhythm, dropped
  narration comments, inlined one-shot vars.
- fix: empty catch blocks → /* best-effort */ for no-empty lint.
2026-04-26 20:38:47 -05:00

29 lines
756 B
TypeScript

// FPS counter overlay (HERMES_TUI_FPS=1). Zero-cost when disabled.
import { Text } from '@hermes/ink'
import { useStore } from '@nanostores/react'
import { SHOW_FPS } from '../config/env.js'
import { $fpsState } from '../lib/fpsStore.js'
const fpsColor = (fps: number) => (fps >= 50 ? 'green' : fps >= 30 ? 'yellow' : 'red')
export function FpsOverlay() {
if (!SHOW_FPS) {
return null
}
return <FpsOverlayInner />
}
function FpsOverlayInner() {
const { fps, lastDurationMs, totalFrames } = useStore($fpsState)
// Zero-pad widths so digit churn doesn't jitter the corner.
return (
<Text color={fpsColor(fps)}>
{fps.toFixed(1).padStart(5)}fps · {lastDurationMs.toFixed(1).padStart(5)}ms · #{totalFrames}
</Text>
)
}