mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-30 01:41:43 +00:00
refactor(tui): /clean pass on memory + resize helpers
KISS/DRY sweep — drops ~90 LOC with no behavior change. - circularBuffer: drop unused pushAll/toArray/size; fold toArray into drain - gracefulExit: inline Cleanup type + failsafe const; signal→code as a record instead of nested ternary; drop dead .catch on Promise.allSettled; drop unused forceExit - memory: inline heapDumpRoot() + writeSnapshot() (single-use); collapse the two fd/smaps try/catch blocks behind one `swallow` helper; build potentialLeaks functionally (array+filter) instead of imperative push-chain; UNITS at file bottom - memoryMonitor: inline DEFAULTS; drop unused onSnapshot; collapse dumpedHigh/dumpedCritical bools to a single Set; single callback dispatch line instead of duplicated if-chains - entry.tsx: factor `dumpNotice` formatter (used twice by onHigh + onCritical) - useMainApp resize debounce: drop redundant `if (timer)` guards (clearTimeout(undefined) is a no-op); init as undefined not null - useVirtualHistory: trim wall-of-text comment to one-line intent; hoist `const n = items.length`; split comma-declared lets; remove the `;[start, end] = frozenRange` destructure in favor of direct Math.min clamps; hoist `hi` init in upperBound for consistency Validation: tsc clean (both configs), eslint clean on touched files, vitest 102/102, build produces shebang-preserved dist/entry.js, performHeapDump smoke-test still writes valid snapshot + diagnostics.
This commit is contained in:
parent
0078f743e6
commit
82b927777c
7 changed files with 89 additions and 182 deletions
|
|
@ -18,11 +18,12 @@ const QUANTUM = OVERSCAN >> 1
|
|||
const FREEZE_RENDERS = 2
|
||||
|
||||
const upperBound = (arr: number[], target: number) => {
|
||||
let lo = 0,
|
||||
hi = arr.length
|
||||
let lo = 0
|
||||
let hi = arr.length
|
||||
|
||||
while (lo < hi) {
|
||||
const mid = (lo + hi) >> 1
|
||||
|
||||
arr[mid]! <= target ? (lo = mid + 1) : (hi = mid)
|
||||
}
|
||||
|
||||
|
|
@ -42,16 +43,11 @@ export function useVirtualHistory(
|
|||
const [hasScrollRef, setHasScrollRef] = useState(false)
|
||||
const metrics = useRef({ sticky: true, top: 0, vp: 0 })
|
||||
|
||||
// Resize handling — scale cached heights by oldCols/newCols so post-resize
|
||||
// offsets stay roughly aligned with (still-unknown) real Yoga heights.
|
||||
// Clearing the cache instead would force a pessimistic back-walk that mounts
|
||||
// ~190 rows at once (viewport+overscan at 1-row estimate), each a fresh
|
||||
// marked.lexer + syntax highlight = ~3ms; ~600ms React commit block. Freeze
|
||||
// the mount range for FREEZE_RENDERS so warm useMemo results survive while
|
||||
// the layout effect writes post-resize real heights back into cache.
|
||||
// skipMeasurement prevents that first post-resize useLayoutEffect from
|
||||
// poisoning the cache with pre-resize Yoga values (Yoga's stored heights
|
||||
// are from the frame BEFORE this render's calculateLayout with new width).
|
||||
// Width change: scale cached heights (not clear — clearing forces a
|
||||
// pessimistic back-walk mounting ~190 rows at once, each a fresh
|
||||
// marked.lexer + syntax highlight ≈ 3ms). Freeze mount range for 2
|
||||
// renders so warm memos survive; skip one measurement so useLayoutEffect
|
||||
// doesn't poison the scaled cache with pre-resize Yoga heights.
|
||||
const prevColumns = useRef(columns)
|
||||
const skipMeasurement = useRef(false)
|
||||
const prevRange = useRef<null | readonly [number, number]>(null)
|
||||
|
|
@ -122,34 +118,32 @@ export function useVirtualHistory(
|
|||
return out
|
||||
}, [estimate, items, ver])
|
||||
|
||||
const total = offsets[items.length] ?? 0
|
||||
const n = items.length
|
||||
const total = offsets[n] ?? 0
|
||||
const top = Math.max(0, scrollRef.current?.getScrollTop() ?? 0)
|
||||
const vp = Math.max(0, scrollRef.current?.getViewportHeight() ?? 0)
|
||||
const sticky = scrollRef.current?.isSticky() ?? true
|
||||
|
||||
const frozenRange = freezeRenders.current > 0 ? prevRange.current : null
|
||||
|
||||
let start = 0,
|
||||
end = items.length
|
||||
let start = 0
|
||||
let end = n
|
||||
|
||||
if (frozenRange) {
|
||||
// Columns just changed. Reuse the pre-resize mount range so already-mounted
|
||||
// MessageRows keep their warm memos (marked.lexer, syntax highlight). Clamp
|
||||
// to n in case messages were removed (/clear, compaction) mid-freeze.
|
||||
;[start, end] = frozenRange
|
||||
start = Math.min(start, items.length)
|
||||
end = Math.min(end, items.length)
|
||||
} else if (items.length > 0) {
|
||||
// Clamp in case items shrank (/clear, compaction) mid-freeze.
|
||||
start = Math.min(frozenRange[0], n)
|
||||
end = Math.min(frozenRange[1], n)
|
||||
} else if (n > 0) {
|
||||
if (vp <= 0) {
|
||||
start = Math.max(0, items.length - coldStartCount)
|
||||
start = Math.max(0, n - coldStartCount)
|
||||
} else {
|
||||
start = Math.max(0, Math.min(items.length - 1, upperBound(offsets, Math.max(0, top - overscan)) - 1))
|
||||
end = Math.max(start + 1, Math.min(items.length, upperBound(offsets, top + vp + overscan)))
|
||||
start = Math.max(0, Math.min(n - 1, upperBound(offsets, Math.max(0, top - overscan)) - 1))
|
||||
end = Math.max(start + 1, Math.min(n, upperBound(offsets, top + vp + overscan)))
|
||||
}
|
||||
}
|
||||
|
||||
if (end - start > maxMounted) {
|
||||
sticky ? (start = Math.max(0, end - maxMounted)) : (end = Math.min(items.length, start + maxMounted))
|
||||
sticky ? (start = Math.max(0, end - maxMounted)) : (end = Math.min(n, start + maxMounted))
|
||||
}
|
||||
|
||||
if (freezeRenders.current > 0) {
|
||||
|
|
@ -173,9 +167,6 @@ export function useVirtualHistory(
|
|||
let dirty = false
|
||||
|
||||
if (skipMeasurement.current) {
|
||||
// First render after a column change — Yoga heights still reflect the
|
||||
// pre-resize layout. Writing them into cache would overwrite the scaled
|
||||
// estimates with stale pre-resize values. Next render's Yoga is correct.
|
||||
skipMeasurement.current = false
|
||||
} else {
|
||||
for (let i = start; i < end; i++) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue