fix: stabilize streaming footer and status layout (#882)

This commit is contained in:
Charles Packer
2026-02-09 19:49:44 -08:00
committed by GitHub
parent fe8a4042d2
commit baa28ede88
5 changed files with 476 additions and 213 deletions

63
vendor/ink/build/log-update.js vendored Normal file
View File

@@ -0,0 +1,63 @@
import ansiEscapes from 'ansi-escapes';
import cliCursor from 'cli-cursor';
const create = (stream, { showCursor = false } = {}) => {
let previousLineCount = 0;
let previousOutput = '';
let hasHiddenCursor = false;
const renderWithClearedLineEnds = (output) => {
const lines = output.split('\n');
return lines.map((line) => line + ansiEscapes.eraseEndLine).join('\n');
};
const render = (str) => {
if (!showCursor && !hasHiddenCursor) {
cliCursor.hide();
hasHiddenCursor = true;
}
const output = str + '\n';
if (output === previousOutput) {
return;
}
// Keep existing line-count semantics used by Ink's bundled log-update.
const nextLineCount = output.split('\n').length;
// Avoid eraseLines() pre-clear flashes by repainting in place:
// move to start of previous frame, rewrite each line while erasing EOL,
// then clear any trailing old lines if the frame got shorter.
if (previousLineCount > 1) {
stream.write(ansiEscapes.cursorUp(previousLineCount - 1));
}
stream.write(renderWithClearedLineEnds(output));
if (nextLineCount < previousLineCount) {
stream.write(ansiEscapes.eraseDown);
}
previousOutput = output;
previousLineCount = nextLineCount;
};
render.clear = () => {
stream.write(ansiEscapes.eraseLines(previousLineCount));
previousOutput = '';
previousLineCount = 0;
};
render.done = () => {
previousOutput = '';
previousLineCount = 0;
if (!showCursor) {
cliCursor.show();
hasHiddenCursor = false;
}
};
return render;
};
const logUpdate = { create };
export default logUpdate;