tech-debt batch 5b: decompose IntervalHistory.tsx into hooks (#156)#169
Merged
Conversation
) Extract the three impure shells out of the 1424-LOC IntervalHistory widget into colocated custom hooks under lib/hooks/, leaving a presentational shell (-525 LOC): - useIntervalFetch(key, url): the WS2 SWR fetch lifecycle — warm-cache hydrate, no-cold-blank revalidate, alive-guard, stale-beats-blank on error. Owns the IntervalApiRow/Loaded/LoadState types + toLoaded. Keeps the justified exhaustive-deps disable (reads state only for the shimmer flag at fetch start). - useOverscanLoad(bounds): the WS8 reconcile trio (loadWindowForView / reconcileLoad / scheduleReconcile) + the load state, loadRef mirror, debounce timer, and a resetLoad() for the context-change effect. - useChartNavigation(bodyRef, curWindowRef, applyNavWindow, bounds, dataLength): the two native non-passive listeners (wheel zoom/shift-pan + Ctrl+drag pan) and focus/modifier tracking; returns the focus state, chart cursor, and the refs the Recharts drag-select handlers read. Behaviour-preserving: the pure window math stays in lib/intervalZoom + lib/intervalOverscan. Preserves the fresh-curWindowRef read (no stale zoom closure), horizontal-wheel pan gate, the wheel stopPropagation, and the loading guards (the populated chart subtree stays behind the loading/empty/errored ternary; no payload deref runs with null state). Hooks satisfy no-floating-promises via void + .catch. Docker test 983/983; production build (lint+typecheck) green.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Tech-debt batch 5b (epic #161). Behavior-preserving structural decomposition of the biggest component.
Closes #156.
What
IntervalHistory.tsx1424 → 899 LOC; extracted three colocated impure-shell hooks (pure window math stays inlib/intervalZoom.ts):lib/hooks/useIntervalFetch.ts— SWR lifecycle (warm-cache hydrate, no-cold-blank revalidate, alive-guard).lib/hooks/useOverscanLoad.ts— the WS8 reconcile trio + load state + debounce/cleanup.lib/hooks/useChartNavigation.ts— the two native non-passive listeners (wheel zoom/shift-pan, ctrl+drag) + focus/modifier tracking.Regression-safety (this is the sibling of the widget that crashed prod in v0.40.2)
Explicitly guarded every payload deref against the loading/null state — the #150 crash class.
datais[]until a payload exists (if (!state || 'error' in state) return []), sostate.rowsis never read eagerly; the chart subtree is only built in the final non-loading render branch; all payload reads guard withstate && !('error' in state). Nostate!/payload!in JSX. Preserved invariants: freshcurWindowRefreads (no stale-zoom closure), horizontal-wheel pan +stopPropagation, and the one justifiedexhaustive-depsdisable (kept, not broadened).Verification