mirror of
https://github.com/stablyai/orca.git
synced 2026-09-28 16:02:45 +00:00
fix(diff): drop deferred reload records when the entry set is rebuilt
A refusal recorded against the old entry set outlived a tree/commit mode switch, charging the next save of that path a git diff the freshly loaded row did not need. Also mark the load registry live during render rather than in its effect: child effects run first, so StrictMode's replayed mount briefly read the flag as false while the viewer was live.
This commit is contained in:
+3
-1
@@ -59,13 +59,15 @@ export function useCombinedDiffSectionLoadRegistry(
|
||||
loadSchedulerRef.current ??= createCombinedDiffLoadScheduler({
|
||||
loadSection: (index) => loadSectionRef.current(index)
|
||||
})
|
||||
// Why here and not in the effect below: child effects run before this parent's, so StrictMode's
|
||||
// replayed mount would leave a window where the ref reads false while the viewer is live.
|
||||
registryLiveRef.current = true
|
||||
|
||||
useEffect(() => {
|
||||
// Why: React StrictMode replays effect cleanup in dev; reset revives the scheduler for the replayed mount.
|
||||
const scheduler = loadSchedulerRef.current
|
||||
const reloadTimers = reloadTimersRef.current
|
||||
scheduler.reset()
|
||||
registryLiveRef.current = true
|
||||
return () => {
|
||||
registryLiveRef.current = false
|
||||
clearPendingSectionReloadTimers(reloadTimers)
|
||||
|
||||
+30
@@ -37,6 +37,10 @@ function buildAllModeEntrySet(
|
||||
}
|
||||
}
|
||||
|
||||
function statusEntry(path: string): GitStatusEntry {
|
||||
return { path, status: 'modified', area: 'unstaged', added: 1 }
|
||||
}
|
||||
|
||||
function restoreSections(entrySet: CombinedDiffEntrySet, viewStateKey: string): DiffSection[] {
|
||||
let sections: DiffSection[] = []
|
||||
renderHook(() => {
|
||||
@@ -148,3 +152,29 @@ describe('useCombinedDiffViewRestore deferral', () => {
|
||||
expect(sections.map((section) => section.loadOnDemand)).toEqual([false, false])
|
||||
})
|
||||
})
|
||||
|
||||
it('clears deferred reload records when the entry set is rebuilt', () => {
|
||||
// Why: the rebuilt rows load fresh, so a refusal recorded against the old set would charge the
|
||||
// next save of that path a git diff it no longer needs.
|
||||
let keys: Set<string> | undefined
|
||||
const view = renderHook(
|
||||
({ entrySet }: { entrySet: CombinedDiffEntrySet }) => {
|
||||
const registry = useCombinedDiffSectionLoadRegistry(useRef([]))
|
||||
keys = registry.deferredReloadKeysRef.current
|
||||
useCombinedDiffViewRestore({
|
||||
entrySet,
|
||||
gitStatusEntries: [],
|
||||
registry,
|
||||
setGeneration: () => {},
|
||||
setSectionHeights: () => {},
|
||||
setSections: () => {},
|
||||
setSideBySide: () => {},
|
||||
viewStateKey: 'rebuild'
|
||||
})
|
||||
},
|
||||
{ initialProps: { entrySet: buildAllModeEntrySet([statusEntry('a.ts')], []) } }
|
||||
)
|
||||
keys?.add('a.ts')
|
||||
view.rerender({ entrySet: buildAllModeEntrySet([statusEntry('a.ts'), statusEntry('b.ts')], []) })
|
||||
expect([...(keys ?? [])]).toEqual([])
|
||||
})
|
||||
|
||||
+5
@@ -57,6 +57,7 @@ export function useCombinedDiffViewRestore({
|
||||
} = entrySet
|
||||
const {
|
||||
generationRef,
|
||||
deferredReloadKeysRef,
|
||||
deferredLoadRequestsRef,
|
||||
loadSchedulerRef,
|
||||
loadedIndicesRef,
|
||||
@@ -180,6 +181,9 @@ export function useCombinedDiffViewRestore({
|
||||
loadedIndicesRef.current.clear()
|
||||
loadingIndicesRef.current.clear()
|
||||
sectionLoadTokensRef.current.clear()
|
||||
// Why: the rebuilt rows load fresh, so a refusal recorded against the old set would charge the
|
||||
// next save of that path a git diff it no longer needs.
|
||||
deferredReloadKeysRef.current.clear()
|
||||
clearPendingSectionReloadTimers(reloadTimersRef.current)
|
||||
loadSchedulerRef.current.reset()
|
||||
generationRef.current += 1
|
||||
@@ -188,6 +192,7 @@ export function useCombinedDiffViewRestore({
|
||||
entries,
|
||||
entrySignature,
|
||||
generationRef,
|
||||
deferredReloadKeysRef,
|
||||
deferredLoadRequestsRef,
|
||||
gitStatusEntries,
|
||||
hasUncommittedEntriesSnapshot,
|
||||
|
||||
Reference in New Issue
Block a user