From d1960507c03eb3053dd910395454dc7bf186bbfd Mon Sep 17 00:00:00 2001 From: Neil Date: Sat, 12 Sep 2026 03:16:21 -0700 Subject: [PATCH] docs(diff): describe why the post-render chain is safe, accurately The previous comment claimed this effect is declared before every consumer's effects so each emit sees current values. Both halves are false: it is declared after them, and a child would win regardless -- Pierre renders from its own layout effect and React commits children first, so an emit can read the previous cycle's callbacks. What actually makes it safe is that FileDiff.render early-returns without emitting when the diff, annotations, theme and range are unchanged, so search-only and note-target-only updates never reach a stale chain. Record the one real overlap -- content changing while a search is active -- and that it self-corrects on the next results tick. --- .../editor/pierre-diff/PierreDiffSurface.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/renderer/src/components/editor/pierre-diff/PierreDiffSurface.tsx b/src/renderer/src/components/editor/pierre-diff/PierreDiffSurface.tsx index ffe77953412..fa473e68161 100644 --- a/src/renderer/src/components/editor/pierre-diff/PierreDiffSurface.tsx +++ b/src/renderer/src/components/editor/pierre-diff/PierreDiffSurface.tsx @@ -176,8 +176,15 @@ export function PierreDiffSurface({ }) // Why layout and not render: Pierre treats a new onPostRender identity as forceRender, so the // callback below must stay stable and read its chain from here. Writing during render is impure - // -- React can discard that work. useRef seeds the first render's chain, and this effect is - // declared before every consumer's own effects, so each Pierre post-render sees current values. + // -- React can discard that work. + // + // This does NOT guarantee a fresh chain on every emit, and it cannot: Pierre renders from its + // own layout effect in a child, and children commit before parents, so an emit can read the + // previous cycle's callbacks. useRef seeds the first mount. What keeps that harmless is that + // FileDiff.render early-returns without emitting when the diff, annotations, theme and range are + // all unchanged, so search-only and note-target-only updates never reach a stale chain. The one + // overlap -- content changing while a search is active -- can paint a frame of stale ranges; the + // next results tick corrects it. useLayoutEffect(() => { postRenderRef.current = { onPostRender,