(
text: string,
labelPrefix: string,
{ maxChars, maxLines }: { maxChars: number; maxLines: number }
)
| 131 | ) => boundedRenderText(text, 'showing live tail', { maxChars, maxLines }) |
| 132 | |
| 133 | const boundedRenderText = ( |
| 134 | text: string, |
| 135 | labelPrefix: string, |
| 136 | { maxChars, maxLines }: { maxChars: number; maxLines: number } |
| 137 | ) => { |
| 138 | if (text.length <= maxChars && text.split('\n', maxLines + 1).length <= maxLines) { |
| 139 | return text |
| 140 | } |
| 141 | |
| 142 | let start = 0 |
| 143 | let idx = text.length |
| 144 | |
| 145 | for (let seen = 0; seen < maxLines && idx > 0; seen++) { |
| 146 | idx = text.lastIndexOf('\n', idx - 1) |
| 147 | start = idx < 0 ? 0 : idx + 1 |
| 148 | |
| 149 | if (idx < 0) { |
| 150 | break |
| 151 | } |
| 152 | } |
| 153 | |
| 154 | const lineStart = start |
| 155 | start = Math.max(lineStart, text.length - maxChars) |
| 156 | |
| 157 | if (start > lineStart) { |
| 158 | const nextBreak = text.indexOf('\n', start) |
| 159 | |
| 160 | if (nextBreak >= 0 && nextBreak < text.length - 1) { |
| 161 | start = nextBreak + 1 |
| 162 | } |
| 163 | } |
| 164 | |
| 165 | const tail = text.slice(start).trimStart() |
| 166 | const omittedLines = countNewlines(text, start) |
| 167 | const omittedChars = Math.max(0, text.length - tail.length) |
| 168 | |
| 169 | const label = |
| 170 | omittedLines > 0 |
| 171 | ? `[${labelPrefix}; omitted ${fmtK(omittedLines)} lines / ${fmtK(omittedChars)} chars]\n` |
| 172 | : `[${labelPrefix}; omitted ${fmtK(omittedChars)} chars]\n` |
| 173 | |
| 174 | return `${label}${tail}` |
| 175 | } |
| 176 | |
| 177 | const countNewlines = (text: string, end: number) => { |
| 178 | let count = 0 |
no test coverage detected