import _ from 'lodash' ; interface PollerOptions { functionToPoll : ( ) => Promise < void > ; pollFrequencyInMillis : number ; trailing ? : boolean ; continuePollingOnError ? : boolean ; pollFrequencyErrorMultiplier ? : number ; successFunction ? : ( ... args : unknown [ ] ) => void ; errorFunction ? : ( error : Error ) => void ; } export class Poller { private readonly functionToPoll : ( ) => Promise < void > ; private readonly successFunction : ( ... args : unknown [ ] ) => void ; private readonly errorFunction : ( error : Error ) => void ; private _isRunning : boolean ; private _timeoutId : NodeJS . Timeout | null ; private pollFrequencyInMillis : number ; private trailing : boolean ; private continuePollingOnError : boolean ; private pollFrequencyErrorMultiplier : number ; constructor ( options ) { this . functionToPoll = options . functionToPoll ; this . successFunction = options . successFunction || _ . noop ; this . errorFunction = options . errorFunction || _ . noop ; this . pollFrequencyInMillis = options . pollFrequencyInMillis ; this . trailing = options . trailing || false ; this . continuePollingOnError = options . continuePollingOnError || false ; this . pollFrequencyErrorMultiplier = options . pollFrequencyErrorMultiplier || 1 ; this . _timeoutId = null ; this . _isRunning = false ; } getPollFrequency ( ) { return this . pollFrequencyInMillis ; } _poll ( ) { return this . functionToPoll ( ) . then ( this . successFunction ) . then ( ( ) => { if ( ! this . _isRunning ) { return ; } this . _timeoutId = setTimeout ( this . _poll . bind ( this ) , this . pollFrequencyInMillis ) ; } ) . catch ( ( e ) => { this . errorFunction ( e ) ; if ( ! this . _isRunning ) { return ; } if ( this . continuePollingOnError ) { this . _timeoutId = setTimeout ( this . _poll . bind ( this ) , this . pollFrequencyInMillis * this . pollFrequencyErrorMultiplier ) ; } else { this . stop ( ) ; } } ) ; } start ( ) { if ( this . _isRunning ) { return ; } this . _isRunning = true ; if ( this . trailing ) { this . _timeoutId = setTimeout ( this . _poll . bind ( this ) , this . pollFrequencyInMillis ) ; } else { this . _poll ( ) ; } } stop ( ) { if ( ! this . _isRunning ) { return ; } this . _isRunning = false ; if ( this . _timeoutId ) { clearTimeout ( this . _timeoutId ) ; } this . _timeoutId = null ; } isRunning ( ) { return this . _isRunning ; } }