@@ -165,6 +165,7 @@ export class FancyConsoleWriter extends Writer {
165165 private formattedEntries : string [ ]
166166 private logUpdate : any
167167 private intervalID : number | null
168+ public persistedAtIdx : number
168169
169170 public level : LogLevel
170171
@@ -173,6 +174,7 @@ export class FancyConsoleWriter extends Writer {
173174 this . intervalID = null
174175 this . formattedEntries = [ ] // Entries are cached on format
175176 this . spinners = [ ] // Each entry has it's own spinner
177+ this . persistedAtIdx = 0
176178 }
177179
178180 private initLogUpdate ( rootLogNode : RootLogNode ) : any {
@@ -182,18 +184,17 @@ export class FancyConsoleWriter extends Writer {
182184 write : ( str , enc , cb ) => ( < any > process . stdout . write ) ( str , enc , cb , { noIntercept : true } ) ,
183185 }
184186 const makeOpts = msg => ( {
185- // Remove trailing new line from console writes since Logger already handles it
186- msg : typeof msg === "string" ? msg . replace ( / \n $ / , "" ) : msg ,
187+ msg,
187188 notOriginatedFromLogger : true ,
188189 } )
189- /*
190- NOTE: On every write, log-update library calls the cli-cursor library to hide the cursor
191- which the cli-cursor library does via stderr write. This causes an infinite loop as
192- the stderr writes are intercepted and funneled back to the Logger.
193- Therefore we manually toggle the cursor using the custom stream from above.
194-
195- log-update types are missing the `opts?: {showCursor?: boolean}` parameter
196- */
190+ /**
191+ * NOTE: On every write, log-update library calls the cli-cursor library to hide the cursor
192+ * which the cli-cursor library does via stderr write. This causes an infinite loop as
193+ * the stderr writes are intercepted and funneled back to the Logger.
194+ * Therefore we manually toggle the cursor using the custom stream from above.
195+ *
196+ * log-update types are missing the `opts?: {showCursor?: boolean}` parameter
197+ */
197198 const customLogUpdate = ( < any > logUpdate . create ) ( < any > stream , { showCursor : true } )
198199 cliCursor . hide ( stream )
199200
@@ -241,7 +242,7 @@ export class FancyConsoleWriter extends Writer {
241242 private updateStream ( rootLogNode : RootLogNode ) : void {
242243 const out = this . render ( rootLogNode )
243244 if ( out ) {
244- this . logUpdate ( out . join ( "\n " ) )
245+ this . logUpdate ( out . join ( "" ) )
245246 }
246247 }
247248
@@ -254,13 +255,19 @@ export class FancyConsoleWriter extends Writer {
254255 const level = this . level || rootLogNode . level
255256 const entries = < any > getChildNodes ( rootLogNode )
256257
257- /*
258- This is a bit ugly for performance sake.
259- Rather than just creating a new string with an updated spinner frame in each render cycle
260- we instead cache the formatted string and splice the updated frame into it.
261- */
262- const out = entries . reduce ( ( acc : string [ ] , entry : LogEntry , idx : number ) : string [ ] => {
258+ /**
259+ * This is a bit ugly for performance sake.
260+ * Rather than just creating a new string with an updated spinner frame in each render cycle
261+ * we instead cache the formatted string and splice the updated frame into it.
262+ */
263+ const out = entries . slice ( this . persistedAtIdx ) . reduce ( ( acc : string [ ] , entry : LogEntry , idx : number ) : string [ ] => {
263264 let spinnerFrame = ""
265+
266+ if ( entry . notOriginatedFromLogger ( ) ) {
267+ acc . push ( renderMsg ( entry ) )
268+ return acc
269+ }
270+
264271 if ( entry . status === EntryStatus . ACTIVE ) {
265272 hasActiveEntries = true
266273 spinnerFrame = this . readOrSetSpinner ( idx )
@@ -271,7 +278,7 @@ export class FancyConsoleWriter extends Writer {
271278 const withSpinner = spinnerFrame
272279 ? `${ formatted . slice ( 0 , startPos ) } ${ spinnerStyle ( spinnerFrame ) } ${ formatted . slice ( startPos ) } `
273280 : formatted
274- acc . push ( withSpinner )
281+ acc . push ( withSpinner + "\n" )
275282 }
276283 return acc
277284 } , [ ] )
@@ -300,6 +307,16 @@ export class FancyConsoleWriter extends Writer {
300307 public stop ( ) : void {
301308 this . stopLoop ( )
302309 this . logUpdate && this . logUpdate . cleanUp ( )
310+ this . logUpdate = null
311+ }
312+
313+ /**
314+ * Escape hatch for reclaiming the stream, e.g. when reading stdin.
315+ * Logger will then continue afterwards but won't be able to update the previous content
316+ */
317+ public stopAndPersist ( rootLogNode : RootLogNode ) : void {
318+ this . stop ( )
319+ this . persistedAtIdx = rootLogNode . children . length
303320 }
304321
305322}
0 commit comments