import { EventEmitter } from 'events' ; import { BalmError } from '@balm-core/index' ; const PLUGIN_NAME = 'plumber' ; const emitter = new EventEmitter ( ) ; function removeDefaultHandler ( stream , event ) { let found = false ; stream . listeners ( event ) . forEach ( function ( this , item ) { if ( item . name === `on${ event }` ) { found = item ; this . removeListener ( event , item ) ; } } , stream ) ; return found ; } function wrapPanicOnErrorHandler ( stream ) { const oldHandler = removeDefaultHandler ( stream , 'error' ) ; if ( oldHandler ) { stream . on ( 'error' , function onerror2 ( this , error ) { if ( emitter . listenerCount ( 'error' ) === 1 ) { this . removeListener ( 'error' , onerror2 ) ; ( oldHandler as Function ) . call ( stream , error ) ; } } ) ; } } function defaultErrorHandler ( this , error ) { if ( emitter . listenerCount ( 'error' ) < 3 ) { BalmJS . logger . error ( `${ PLUGIN_NAME } - found unhandled error` , error . toString ( ) ) ; } } function gulpPlumber ( opts = { } ) { if ( BalmJS . utils . isFunction ( opts ) ) { opts = { errorHandler : opts } ; } const through = through2 . obj ( ) ; through . _plumber = true ; if ( opts . errorHandler !== false ) { through . errorHandler = BalmJS . utils . isFunction ( opts . errorHandler ) ? opts . errorHandler : defaultErrorHandler ; } function patchPipe ( stream ) { if ( stream . pipe2 ) { wrapPanicOnErrorHandler ( stream ) ; stream . _pipe = stream . _pipe || stream . pipe ; stream . pipe = stream . pipe2 ; stream . _plumbed = true ; } } through . pipe2 = function pipe2 ( this , dest ) : any { if ( ! dest ) { throw new PluginError ( PLUGIN_NAME , "Can't pipe to undefined" ) ; } this . _pipe ( dest ) ; if ( dest . _unplumbed ) { return dest ; } removeDefaultHandler ( this , 'error' ) ; if ( dest . _plumber ) { return dest ; } dest . pipe2 = pipe2 ; if ( opts . inherit !== false ) { patchPipe ( dest ) ; } if ( this . errorHandler ) { dest . errorHandler = this . errorHandler ; dest . on ( 'error' , this . errorHandler . bind ( dest ) ) ; } dest . _plumbed = true ; return dest ; } ; patchPipe ( through ) ; return through ; } function stop ( ) { const through = through2 . obj ( ) ; through . _unplumbed = true ; return through ; } export default gulpPlumber ; export { stop } ;