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.
This commit is contained in:
Brooklyn Nicholson 2026-04-26 20:38:47 -05:00
parent 527ac351b4
commit b1c49d5e73
32 changed files with 259 additions and 547 deletions

View file

@ -12,38 +12,29 @@ describe('wheelAccel — native path', () => {
it('same-direction fast events ramp mult (window-mode)', () => {
const s = initWheelAccel(false, 1)
// First click establishes dir. Subsequent clicks inside the 40ms
// window ramp by +0.3 each (capped at 6).
computeWheelStep(s, 1, 1000)
computeWheelStep(s, 1, 1020)
computeWheelStep(s, 1, 1040)
const fourth = computeWheelStep(s, 1, 1060)
// After 3 window events: mult starts at 1 → stays 1 on first ramp
// (first event just sets baseline), then +0.3 × 3 = 1.9 → floor=1.
// The key property: doesn't shrink below base.
expect(fourth).toBeGreaterThanOrEqual(1)
// Key property: doesn't shrink below base.
expect(computeWheelStep(s, 1, 1060)).toBeGreaterThanOrEqual(1)
})
it('gap beyond window resets mult to base', () => {
const s = initWheelAccel(false, 1)
// Ramp up
for (let t = 1000; t < 1100; t += 20) {
computeWheelStep(s, 1, t)
}
// Long pause, then click
const afterPause = computeWheelStep(s, 1, 2000)
expect(afterPause).toBe(1)
expect(computeWheelStep(s, 1, 2000)).toBe(1)
})
it('direction flip defers one event for bounce detection', () => {
const s = initWheelAccel(false, 1)
computeWheelStep(s, 1, 1000)
// Flip — should defer
expect(computeWheelStep(s, -1, 1050)).toBe(0)
})
@ -51,9 +42,7 @@ describe('wheelAccel — native path', () => {
const s = initWheelAccel(false, 1)
computeWheelStep(s, 1, 1000)
// Flip (deferred)
computeWheelStep(s, -1, 1050)
// Flip BACK within 200ms → bounce confirmed → wheelMode engaged
computeWheelStep(s, 1, 1100)
expect(s.wheelMode).toBe(true)
@ -63,8 +52,7 @@ describe('wheelAccel — native path', () => {
const s = initWheelAccel(false, 1)
computeWheelStep(s, 1, 1000)
computeWheelStep(s, -1, 1050) // defer
// Flip-back arrives 300ms later → too late → real reversal
computeWheelStep(s, -1, 1050)
computeWheelStep(s, 1, 1400)
expect(s.wheelMode).toBe(false)
@ -76,12 +64,9 @@ describe('wheelAccel — native path', () => {
s.dir = 1
s.time = 1000
// 5 bursts <5ms apart (trackpad flick)
computeWheelStep(s, 1, 1002)
computeWheelStep(s, 1, 1004)
computeWheelStep(s, 1, 1006)
computeWheelStep(s, 1, 1008)
computeWheelStep(s, 1, 1010)
for (let t = 1002; t <= 1010; t += 2) {
computeWheelStep(s, 1, t)
}
expect(s.wheelMode).toBe(false)
})
@ -92,7 +77,7 @@ describe('wheelAccel — native path', () => {
s.dir = 1
s.time = 1000
computeWheelStep(s, 1, 3000) // 2 second gap
computeWheelStep(s, 1, 3000)
expect(s.wheelMode).toBe(false)
})
@ -102,34 +87,23 @@ describe('wheelAccel — xterm.js path', () => {
it('first click returns 2 after long idle', () => {
const s = initWheelAccel(true, 1)
// First event — "sameDir && gap > WHEEL_DECAY_IDLE_MS" triggers
// reset-to-2 branch since dir starts at 0 and 0 !== 1.
const n = computeWheelStep(s, 1, 1000)
expect(n).toBeGreaterThanOrEqual(1)
expect(computeWheelStep(s, 1, 1000)).toBeGreaterThanOrEqual(1)
})
it('sub-5ms burst returns 1 (same-direction, same-batch)', () => {
const s = initWheelAccel(true, 1)
computeWheelStep(s, 1, 1000)
const burst = computeWheelStep(s, 1, 1002)
expect(burst).toBe(1)
expect(computeWheelStep(s, 1, 1002)).toBe(1)
})
it('slow steady scroll stays in precision range', () => {
const s = initWheelAccel(true, 1)
// Simulated 30Hz sustained scroll: 33ms gap
const results: number[] = []
for (let t = 1000; t < 2000; t += 33) {
results.push(computeWheelStep(s, 1, t))
}
const r = computeWheelStep(s, 1, t)
// Every event should produce 1-6 rows. No runaway.
for (const r of results) {
expect(r).toBeGreaterThanOrEqual(1)
expect(r).toBeLessThanOrEqual(6)
}
@ -138,27 +112,22 @@ describe('wheelAccel — xterm.js path', () => {
it('direction reversal resets mult', () => {
const s = initWheelAccel(true, 1)
// Ramp up
for (let t = 1000; t < 1100; t += 20) {
computeWheelStep(s, 1, t)
}
const beforeFlip = s.mult
// Flip
computeWheelStep(s, -1, 1200)
expect(s.mult).toBeLessThanOrEqual(beforeFlip)
// Reset branch sets mult=2
expect(s.mult).toBe(2)
})
it('frac stays in [0,1) across events', () => {
const s = initWheelAccel(true, 1)
// frac must never go negative or reach 1.0 — that's the correctness
// invariant of the fractional carry. Whether a specific series of
// inputs produces a nonzero frac depends on tuning constants; just
// check the bound is maintained across a realistic scroll pattern.
// Correctness invariant of fractional carry: never negative, never reaches 1.
for (let t = 1000; t < 1200; t += 30) {
computeWheelStep(s, 1, t)