From ee2ab5623a234e9382876a356270e505fafdd699 Mon Sep 17 00:00:00 2001 From: Zeraphim Date: Mon, 27 Jul 2026 11:50:49 +0800 Subject: [PATCH] fix(tui): prevent overlapping frames in update preflight animation The update preflight footer's frame callback was returning an immediately-resolved promise after batch() and tick() signal updates, allowing the renderer to proceed to the next frame before SolidJS had flushed its reactive microtasks. This caused the renderer to write terminal escape sequences for frame N+1 while SolidJS was still applying frame N's updates, resulting in overlapping, corrupted output during long service startups. The fix makes the frame callback async and yields to the microtask queue after batched signal updates, ensuring SolidJS flushes all reactive effects before the renderer begins the next paint cycle. --- packages/cli/src/services/update-preflight.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/cli/src/services/update-preflight.tsx b/packages/cli/src/services/update-preflight.tsx index 9deb28bae87c..342cfa4be044 100644 --- a/packages/cli/src/services/update-preflight.tsx +++ b/packages/cli/src/services/update-preflight.tsx @@ -329,7 +329,6 @@ const createFade = () => }) const smoothstep = (value: number) => value * value * (3 - 2 * value) -const frameDone = Promise.resolve() function UpdateFooter(props: { from?: string @@ -427,8 +426,8 @@ function UpdateFooter(props: { let value = 0 let velocity = 0 let phase = 0 - const frame = (deltaTime: number) => { - if (!props.animating()) return frameDone + const frame = async (deltaTime: number) => { + if (!props.animating()) return const elapsed = Math.min(0.032, deltaTime / 1_000) const stiffness = 110 const damping = 2 * Math.sqrt(stiffness) @@ -442,7 +441,7 @@ function UpdateFooter(props: { }) headerFade.tick(deltaTime) statusSweep.tick(deltaTime) - return frameDone + await new Promise(resolve => queueMicrotask(resolve)) } props.renderer.setFrameCallback(frame) onCleanup(() => props.renderer.removeFrameCallback(frame))