import fs from 'fs' ; type DataHandler = ( data : string , byteRead : number ) => void ; type ErrorHandler = ( err : any , byteRead : number ) => void ; type EndHandler = ( byteRead : number ) => void ; interface SimpleReadStream { onData ( handler ) : void ; onError ( handler ) : void ; onEnd ( handler ) : void ; close ( ) : void ; } export function createChunkReader ( path , start ) { const stream = fs . createReadStream ( path , { encoding : 'utf8' , autoClose : true , start , } ) ; let dataHandler ; let errorHandler ; let endHandler ; let byteRead = 0 ; let buffer = '' ; stream . on ( 'data' , ( chunk ) => { let lastLineBreak = chunk . lastIndexOf ( '\n' ) ; if ( lastLineBreak > 0 && ( chunk . length <= lastLineBreak + 1 || chunk [ lastLineBreak + 1 ] === '{' ) ) { lastLineBreak = chunk . lastIndexOf ( '\n' , lastLineBreak - 1 ) ; } if ( lastLineBreak === - 1 ) { byteRead += chunk . length ; buffer += chunk ; return ; } if ( dataHandler ) { dataHandler ( buffer + chunk . slice ( 0 , lastLineBreak + 1 ) , byteRead ) ; } byteRead += lastLineBreak + 1 ; buffer = chunk . slice ( lastLineBreak + 1 ) ; } ) ; stream . on ( 'error' , ( err ) => { if ( errorHandler ) { errorHandler ( err , byteRead ) ; } } ) ; stream . on ( 'end' , ( ) => { if ( buffer . length > 0 ) { if ( dataHandler ) { dataHandler ( buffer , byteRead ) ; } byteRead += buffer . length ; } if ( endHandler ) { endHandler ( byteRead ) ; } } ) ; return { onData : ( handler ) => ( dataHandler = handler ) , onError : ( handler ) => ( errorHandler = handler ) , onEnd : ( handler ) => ( endHandler = handler ) , close : ( ) => stream . close ( ) , } ; }