import chalk from 'chalk' ; function indentString ( indentLevel ) { let str = "" ; for ( let i = 0 ; i < indentLevel ; i ++ ) { str += chalk . blackBright ( "⎸ " ) ; } return str ; } /**
 * A facility to log messages for debugging.
 *
 * A `DebugLogger` maintains an indentation level that is used before logged messages. That indentation level gets
 * increased by calling `group()` and decreased by `groupEnd()`. This is meant to help representing the nestedness
 * of the code being debugged.
 */ export class DebugLogger { private currentIndentLevel : number = 0 ; param enabled constructor ( private readonly enabled ) { } param message param prefix public log ( message , prefix = chalk . yellow ( '• ' ) ) { if ( ! this . enabled ) return this ; if ( typeof message !== 'string' ) { message = message ( ) ; } const indentStr = indentString ( this . currentIndentLevel ) ; console . log ( indentStr + prefix + message ) ; return this ; } param values param printFn public groupedValues < T > ( values , printFn ) { if ( ! this . enabled ) return this ; this . group ( ) ; const indentStr = indentString ( this . currentIndentLevel ) ; for ( const value of values ) { console . log ( indentStr + '- ' + printFn ( value ) ) ; } return this . groupEnd ( ) ; } param map param keyPrintFn param valuePrintFn public groupedEntries < K , V > ( map , keyPrintFn , valuePrintFn ) { if ( ! this . enabled ) return this ; this . group ( ) ; const indentStr = indentString ( this . currentIndentLevel ) ; for ( const [ k , v ] of map . entries ( ) ) { console . log ( indentStr + '- ' + keyPrintFn ( k ) + ': ' + valuePrintFn ( v ) ) ; } return this . groupEnd ( ) ; } param openingMessage public group ( openingMessage ? ) { if ( this . enabled ) { if ( openingMessage ) { this . log ( openingMessage , chalk . blue ( '‣ ' ) ) ; } this . currentIndentLevel ++ ; } return this ; } param closingMessage public groupEnd ( closingMessage ? ) { if ( ! this . enabled || this . currentIndentLevel == 0 ) { return this ; } this . currentIndentLevel -- ; if ( closingMessage ) { this . log ( closingMessage , chalk . green ( '⇒ ' ) ) ; } return this ; } }