From 1956f85c7b9cba3afd3e449cca0ce717924837b4 Mon Sep 17 00:00:00 2001 From: waleed Date: Wed, 29 Apr 2026 16:50:31 -0700 Subject: [PATCH 1/4] fix(files): use incremental applyEdits to prevent streaming flicker in Monaco editor --- .../components/file-viewer/text-editor.tsx | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/text-editor.tsx b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/text-editor.tsx index 91a70cebe4e..b9fb2705ef6 100644 --- a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/text-editor.tsx +++ b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/text-editor.tsx @@ -442,11 +442,25 @@ export const TextEditor = memo(function TextEditor({ textareaStuckRef.current = true } } - const viewState = - isStreamInteractionLocked && !textareaStuckRef.current ? editor.saveViewState() : null suppressScrollListenerRef.current = true - model.setValue(content) - if (viewState) editor.restoreViewState(viewState) + const prev = lastSyncedContentRef.current + if (content.startsWith(prev) && prev.length < content.length) { + const lastLine = model.getLineCount() + const lastCol = model.getLineMaxColumn(lastLine) + model.applyEdits([ + { + range: { + startLineNumber: lastLine, + startColumn: lastCol, + endLineNumber: lastLine, + endColumn: lastCol, + }, + text: content.slice(prev.length), + }, + ]) + } else { + model.applyEdits([{ range: model.getFullModelRange(), text: content }]) + } suppressScrollListenerRef.current = false lastSyncedContentRef.current = content } From 8b21a0ca5ccfb3afbabcc131b5d146a401289dec Mon Sep 17 00:00:00 2001 From: waleed Date: Wed, 29 Apr 2026 17:00:49 -0700 Subject: [PATCH 2/4] fix(files): use actual model value for additive applyEdits guard --- .../files/components/file-viewer/text-editor.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/text-editor.tsx b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/text-editor.tsx index b9fb2705ef6..26f9ace4e12 100644 --- a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/text-editor.tsx +++ b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/text-editor.tsx @@ -443,8 +443,7 @@ export const TextEditor = memo(function TextEditor({ } } suppressScrollListenerRef.current = true - const prev = lastSyncedContentRef.current - if (content.startsWith(prev) && prev.length < content.length) { + if (content.startsWith(monacoValue) && monacoValue.length < content.length) { const lastLine = model.getLineCount() const lastCol = model.getLineMaxColumn(lastLine) model.applyEdits([ @@ -455,7 +454,7 @@ export const TextEditor = memo(function TextEditor({ endLineNumber: lastLine, endColumn: lastCol, }, - text: content.slice(prev.length), + text: content.slice(monacoValue.length), }, ]) } else { From 00ef26b9910bf719d3f0e1e9e741c90bb884dde8 Mon Sep 17 00:00:00 2001 From: waleed Date: Wed, 29 Apr 2026 17:06:05 -0700 Subject: [PATCH 3/4] fix(files): use pushEditOperations instead of applyEdits to align with VS Code streaming pattern --- .../components/file-viewer/text-editor.tsx | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/text-editor.tsx b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/text-editor.tsx index 26f9ace4e12..a1cebee8d76 100644 --- a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/text-editor.tsx +++ b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/text-editor.tsx @@ -446,19 +446,27 @@ export const TextEditor = memo(function TextEditor({ if (content.startsWith(monacoValue) && monacoValue.length < content.length) { const lastLine = model.getLineCount() const lastCol = model.getLineMaxColumn(lastLine) - model.applyEdits([ - { - range: { - startLineNumber: lastLine, - startColumn: lastCol, - endLineNumber: lastLine, - endColumn: lastCol, + model.pushEditOperations( + null, + [ + { + range: { + startLineNumber: lastLine, + startColumn: lastCol, + endLineNumber: lastLine, + endColumn: lastCol, + }, + text: content.slice(monacoValue.length), }, - text: content.slice(monacoValue.length), - }, - ]) + ], + () => null + ) } else { - model.applyEdits([{ range: model.getFullModelRange(), text: content }]) + model.pushEditOperations( + null, + [{ range: model.getFullModelRange(), text: content }], + () => null + ) } suppressScrollListenerRef.current = false lastSyncedContentRef.current = content From 1b76937593ad8cb8d04444443ef77e453f7863fe Mon Sep 17 00:00:00 2001 From: waleed Date: Wed, 29 Apr 2026 17:30:37 -0700 Subject: [PATCH 4/4] fix(files): revert to applyEdits to avoid polluting undo stack during streaming --- .../components/file-viewer/text-editor.tsx | 30 +++++++------------ 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/text-editor.tsx b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/text-editor.tsx index a1cebee8d76..26f9ace4e12 100644 --- a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/text-editor.tsx +++ b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/text-editor.tsx @@ -446,27 +446,19 @@ export const TextEditor = memo(function TextEditor({ if (content.startsWith(monacoValue) && monacoValue.length < content.length) { const lastLine = model.getLineCount() const lastCol = model.getLineMaxColumn(lastLine) - model.pushEditOperations( - null, - [ - { - range: { - startLineNumber: lastLine, - startColumn: lastCol, - endLineNumber: lastLine, - endColumn: lastCol, - }, - text: content.slice(monacoValue.length), + model.applyEdits([ + { + range: { + startLineNumber: lastLine, + startColumn: lastCol, + endLineNumber: lastLine, + endColumn: lastCol, }, - ], - () => null - ) + text: content.slice(monacoValue.length), + }, + ]) } else { - model.pushEditOperations( - null, - [{ range: model.getFullModelRange(), text: content }], - () => null - ) + model.applyEdits([{ range: model.getFullModelRange(), text: content }]) } suppressScrollListenerRef.current = false lastSyncedContentRef.current = content