import indent = require ( "indent-string" ) ; import typeName = require ( "type-name" ) ; import { inspect } from "util" ; const writeStream = require ( "flush-write-stream" ) ; const argsTruncLen = 80 ; const returnTruncLen = 20 ; function trunc ( s , max ) { if ( s && s . length > max ) { return s . slice ( 0 , max ) + "..." ; } return s ; } let nesting = 0 ; function isBuffer ( _data , encoding ) { return encoding === "buffer" ; } const traceWritable = writeStream ( ( data , encoding , cb ) => { if ( ! isBuffer ( data , encoding ) ) { throw new Error ( `Unhandled encoding type in trace.log` ) ; } process . stdout . write ( indent ( data . toString ( ) , 2 * nesting ) ) ; cb ( ) ; } ) ; const _console = new console . Console ( traceWritable ) ; function log ( ... args ) { _console . log ( ... args ) ; } function simpleStringify ( obj ) { return inspect ( obj , { depth : 1 , maxArrayLength : 1 , breakLength : Infinity } ) ; } export function tracef ( enable ) { if ( enable ) { return function logMethod ( _target , propKey , propDesc ) { return { value ( ... args ) { let objname ; if ( this ) { objname = typeName ( this ) ; const id = ( this as any ) . _id ; if ( id ) objname += id ; } else { objname = "null" ; } const fname = `${ objname }.${ propKey }` ; const a = args . map ( ( arg ) => { return trunc ( simpleStringify ( arg ) , argsTruncLen ) ; } ) . join ( ) ; log ( `${ fname }(${ a })` ) ; nesting ++ ; const result = propDesc . value . apply ( this , args ) ; nesting -- ; const r = trunc ( simpleStringify ( result ) , returnTruncLen ) ; log ( `${ fname } => ${ r }` ) ; return result ; } } ; } ; } else { return function noLog ( target , _key , _val ) { } ; } } export function trace ( enable , ... args ) { if ( ! enable ) return ; log ( ... args ) ; } export function traceLazy ( enable , argFunc ) { if ( ! enable ) return ; const args = argFunc ( ) ; log ( ... args ) ; }