From 81c41388ac5da1e5d546b8116c42d3a5318e3ea4 Mon Sep 17 00:00:00 2001 From: Bohdan Triapitsyn Date: Wed, 1 Apr 2026 12:25:58 +0300 Subject: [PATCH] refactor: simplify file reference interactions by removing unused validation logic --- .../src/components/chat/MarkdownRenderer.tsx | 185 +++--------------- 1 file changed, 30 insertions(+), 155 deletions(-) diff --git a/packages/ui/src/components/chat/MarkdownRenderer.tsx b/packages/ui/src/components/chat/MarkdownRenderer.tsx index 01380763..97bb6ab5 100644 --- a/packages/ui/src/components/chat/MarkdownRenderer.tsx +++ b/packages/ui/src/components/chat/MarkdownRenderer.tsx @@ -1022,23 +1022,15 @@ const getContextDirectory = (effectiveDirectory: string, resolvedPath: string): const useFileReferenceInteractions = ({ containerRef, effectiveDirectory, - statFile, editor, preferRuntimeEditor, - deferValidationUntilIdle = false, }: { containerRef: React.RefObject; effectiveDirectory: string; - statFile?: (path: string) => Promise<{ path: string; isFile: boolean; size: number }>; editor?: EditorAPI; preferRuntimeEditor?: boolean; - deferValidationUntilIdle?: boolean; }) => { - const validationCacheRef = React.useRef>(new Map()); - const inFlightValidationsRef = React.useRef>>(new Map()); - const annotationPassRef = React.useRef(0); const annotationDebounceRef = React.useRef(null); - const isValidationSweepRunningRef = React.useRef(false); React.useEffect(() => { const container = containerRef.current; @@ -1046,158 +1038,47 @@ const useFileReferenceInteractions = ({ return; } - let disposed = false; - - const isPathResolvable = async (resolvedPath: string): Promise => { - const cache = validationCacheRef.current; - if (cache.has(resolvedPath)) { - return cache.get(resolvedPath) === true; - } - - const inFlight = inFlightValidationsRef.current.get(resolvedPath); - if (inFlight) { - return inFlight; - } - - const checkPromise = (async () => { - try { - if (!statFile) { - return false; - } - const stat = await statFile(resolvedPath); - if (!stat.isFile) { - cache.set(resolvedPath, false); - return false; - } - cache.set(resolvedPath, true); - return true; - } catch { - cache.set(resolvedPath, false); - return false; - } finally { - inFlightValidationsRef.current.delete(resolvedPath); - } - })(); - - inFlightValidationsRef.current.set(resolvedPath, checkPromise); - return checkPromise; - }; - - const clearCandidateLinkAttrs = (candidate: HTMLElement) => { - candidate.removeAttribute('data-openchamber-file-link'); - candidate.removeAttribute('data-openchamber-file-ref'); - candidate.removeAttribute('data-openchamber-file-path'); - if (candidate.getAttribute('title') === 'Open file') { - candidate.removeAttribute('title'); - } - if (candidate.tagName.toLowerCase() !== 'a') { - candidate.removeAttribute('role'); - candidate.removeAttribute('tabindex'); - } - }; - - const applyCandidateLinkAttrs = (candidate: HTMLElement, rawCandidate: string, resolvedPath: string) => { - candidate.setAttribute('data-openchamber-file-link', 'true'); - candidate.setAttribute('data-openchamber-file-ref', rawCandidate); - candidate.setAttribute('data-openchamber-file-path', resolvedPath); - candidate.setAttribute('title', 'Open file'); - if (candidate.tagName.toLowerCase() !== 'a') { - candidate.setAttribute('role', 'button'); - candidate.setAttribute('tabindex', '0'); - } - }; - - const runValidationSweep = async (paths: string[], expectedPassID: number) => { - if (deferValidationUntilIdle) { - return; - } - if (isValidationSweepRunningRef.current || paths.length === 0) { - return; - } - - isValidationSweepRunningRef.current = true; - const maxConcurrent = 3; - let cursor = 0; - - const worker = async () => { - while (!disposed && cursor < paths.length) { - const index = cursor; - cursor += 1; - const pathToCheck = paths[index]; - if (!pathToCheck) { - continue; - } - await isPathResolvable(pathToCheck); - } - }; - - try { - await Promise.all(Array.from({ length: Math.min(maxConcurrent, paths.length) }, () => worker())); - } finally { - isValidationSweepRunningRef.current = false; - } - - if (!disposed && annotationPassRef.current === expectedPassID) { - void annotateFileLinks(); - } - }; - - const annotateFileLinks = async () => { - const passID = annotationPassRef.current + 1; - annotationPassRef.current = passID; + const annotateFileLinks = () => { const candidates = container.querySelectorAll('[data-streamdown="inline-code"], a'); - const unresolvedPaths = new Set(); for (const candidate of Array.from(candidates)) { const rawCandidate = extractPathCandidateFromElement(candidate); const resolved = getResolvedReference(rawCandidate, effectiveDirectory); if (!resolved) { - clearCandidateLinkAttrs(candidate); + candidate.removeAttribute('data-openchamber-file-link'); + candidate.removeAttribute('data-openchamber-file-ref'); + candidate.removeAttribute('data-openchamber-file-path'); + if (candidate.getAttribute('title') === 'Open file') { + candidate.removeAttribute('title'); + } + if (candidate.tagName.toLowerCase() !== 'a') { + candidate.removeAttribute('role'); + candidate.removeAttribute('tabindex'); + } continue; } - if (annotationPassRef.current !== passID) { - return; + candidate.setAttribute('data-openchamber-file-link', 'true'); + candidate.setAttribute('data-openchamber-file-ref', rawCandidate); + candidate.setAttribute('data-openchamber-file-path', resolved.resolvedPath); + candidate.setAttribute('title', 'Open file'); + if (candidate.tagName.toLowerCase() !== 'a') { + candidate.setAttribute('role', 'button'); + candidate.setAttribute('tabindex', '0'); } - - const cachedResult = validationCacheRef.current.get(resolved.resolvedPath); - if (cachedResult === true) { - applyCandidateLinkAttrs(candidate, rawCandidate, resolved.resolvedPath); - continue; - } - - clearCandidateLinkAttrs(candidate); - if (cachedResult !== false) { - unresolvedPaths.add(resolved.resolvedPath); - } - } - - if (unresolvedPaths.size > 0) { - void runValidationSweep(Array.from(unresolvedPaths), passID); } }; - const openFileReference = async (sourceElement: HTMLElement): Promise => { + const openFileReference = (sourceElement: HTMLElement) => { const raw = sourceElement.getAttribute('data-openchamber-file-ref') || extractPathCandidateFromElement(sourceElement); const resolved = getResolvedReference(raw, effectiveDirectory); if (!resolved) { - return false; - } - - const isResolvable = await isPathResolvable(resolved.resolvedPath); - if (!isResolvable) { - sourceElement.removeAttribute('data-openchamber-file-link'); - sourceElement.removeAttribute('data-openchamber-file-ref'); - sourceElement.removeAttribute('data-openchamber-file-path'); - if (sourceElement.getAttribute('title') === 'Open file') { - sourceElement.removeAttribute('title'); - } - return false; + return; } const contextDirectory = getContextDirectory(effectiveDirectory, resolved.resolvedPath); if (preferRuntimeEditor && editor) { - await editor.openFile( + void editor.openFile( resolved.resolvedPath, Number.isFinite(resolved.line ?? Number.NaN) ? Math.max(1, Math.trunc(resolved.line as number)) @@ -1206,7 +1087,7 @@ const useFileReferenceInteractions = ({ ? Math.max(1, Math.trunc(resolved.column as number)) : undefined, ); - return true; + return; } const uiStore = useUIStore.getState(); @@ -1222,7 +1103,6 @@ const useFileReferenceInteractions = ({ } else { uiStore.openContextFile(contextDirectory, resolved.resolvedPath); } - return true; }; const handleClick = (event: MouseEvent) => { @@ -1239,7 +1119,7 @@ const useFileReferenceInteractions = ({ event.preventDefault(); event.stopPropagation(); - void openFileReference(fileRefElement); + openFileReference(fileRefElement); }; const handleKeyDown = (event: KeyboardEvent) => { @@ -1255,36 +1135,34 @@ const useFileReferenceInteractions = ({ event.preventDefault(); event.stopPropagation(); - void openFileReference(target); + openFileReference(target); }; - void annotateFileLinks(); + annotateFileLinks(); const observer = new MutationObserver(() => { if (annotationDebounceRef.current !== null && typeof window !== 'undefined') { window.clearTimeout(annotationDebounceRef.current); } if (typeof window === 'undefined') { - void annotateFileLinks(); + annotateFileLinks(); return; } annotationDebounceRef.current = window.setTimeout(() => { annotationDebounceRef.current = null; - void annotateFileLinks(); - }, deferValidationUntilIdle ? 280 : 120); + annotateFileLinks(); + }, 120); }); observer.observe(container, { childList: true, subtree: true, - ...(deferValidationUntilIdle ? {} : { characterData: true }), + characterData: true, }); container.addEventListener('click', handleClick); container.addEventListener('keydown', handleKeyDown); return () => { - disposed = true; - annotationPassRef.current += 1; if (annotationDebounceRef.current !== null && typeof window !== 'undefined') { window.clearTimeout(annotationDebounceRef.current); } @@ -1293,7 +1171,7 @@ const useFileReferenceInteractions = ({ container.removeEventListener('click', handleClick); container.removeEventListener('keydown', handleKeyDown); }; - }, [containerRef, deferValidationUntilIdle, editor, effectiveDirectory, preferRuntimeEditor, statFile]); + }, [containerRef, editor, effectiveDirectory, preferRuntimeEditor]); }; const useMermaidInlineInteractions = ({ @@ -1409,10 +1287,8 @@ export const MarkdownRenderer: React.FC = ({ useFileReferenceInteractions({ containerRef: streamdownContainerRef, effectiveDirectory, - statFile: files.statFile, editor, preferRuntimeEditor: runtime.isVSCode, - deferValidationUntilIdle: isStreaming, }); useExternalLinkInteractions({ containerRef: streamdownContainerRef }); @@ -1495,7 +1371,6 @@ export const SimpleMarkdownRenderer: React.FC<{ useFileReferenceInteractions({ containerRef: streamdownContainerRef, effectiveDirectory, - statFile: files.statFile, editor, preferRuntimeEditor: runtime.isVSCode, });