5cf077fc3ec9packages/react-server/lib/build/output-filter.mjs+22 -75cf077fc3ec9packages/react-server/lib/build/output-filter.mjs+22 -7| 81 | 81 | spinnerStream.write(`\r\x1b[K${text}`); | |
| 82 | 82 | } | |
| 83 | 83 | | |
| 84 | + | /** | |
| 85 | + | * Truncate a string to fit within `maxLen` columns, inserting an ellipsis | |
| 86 | + | * in the middle so both the prefix and suffix remain visible. Used to keep | |
| 87 | + | * spinner lines on a single terminal row — without this, lines longer than | |
| 88 | + | * the terminal width wrap, and the next `\r\x1b[K` only clears the wrapped | |
| 89 | + | * row, leaving previous content on screen. | |
| 90 | + | */ | |
| 91 | + | function truncateMiddle(str, maxLen) { | |
| 92 | + | if (str.length <= maxLen) return str; | |
| 93 | + | if (maxLen < 4) return str.slice(0, Math.max(0, maxLen)); | |
| 94 | + | const halfLen = Math.floor((maxLen - 3) / 2); | |
| 95 | + | return str.slice(0, maxLen - 3 - halfLen) + "..." + str.slice(-halfLen); | |
| 96 | + | } | |
| 97 | + | | |
| 84 | 98 | function getGroupColor(group) { | |
| 85 | 99 | const groupDef = FILE_GROUPS.find((g) => g.name === group); | |
| 86 | 100 | return groupDef ? groupDef.color : colors.dim; |
| 96 | 110 | const sizeStr = sharedCurrentSize.padStart(10); | |
| 97 | 111 | const maxFileLen = termWidth - 4 - sizeStr.length - 2; // spinner + spaces | |
| 98 | 112 | | |
| 99 | - | let displayName = sharedCurrentFile; | |
| 100 | - | if (displayName.length > maxFileLen && maxFileLen > 10) { | |
| 101 | - | const halfLen = Math.floor((maxFileLen - 3) / 2); | |
| 102 | - | displayName = | |
| 103 | - | displayName.slice(0, halfLen) + "..." + displayName.slice(-halfLen); | |
| 104 | - | } | |
| 113 | + | const displayName = truncateMiddle(sharedCurrentFile, maxFileLen); | |
| 105 | 114 | | |
| 106 | 115 | writeLine( | |
| 107 | 116 | `${colors.cyan(frame)} ${groupColor(displayName.padEnd(maxFileLen))} ${colors.bold(colors.dim(sizeStr))}` |
| 480 | 489 | | |
| 481 | 490 | const render = () => { | |
| 482 | 491 | const spinner = spinnerFrames[frame]; | |
| 483 | - | stream.write(`\r\x1b[K${colorFn(spinner)} ${colors.dim(currentMessage)}`); | |
| 492 | + | // 2 cols reserved for the spinner glyph + space. | |
| 493 | + | const termWidth = stream.columns || process.stdout.columns || 80; | |
| 494 | + | const displayMessage = truncateMiddle( | |
| 495 | + | currentMessage, | |
| 496 | + | Math.max(0, termWidth - 2) | |
| 497 | + | ); | |
| 498 | + | stream.write(`\r\x1b[K${colorFn(spinner)} ${colors.dim(displayMessage)}`); | |
| 484 | 499 | }; | |
| 485 | 500 | | |
| 486 | 501 | // Hide cursor |