import { ReconnectionHandler , ReconnectionOptions } from './BlazorOptions' ; import { ReconnectDisplay } from './ReconnectDisplay' ; import { DefaultReconnectDisplay } from './DefaultReconnectDisplay' ; import { UserSpecifiedDisplay } from './UserSpecifiedDisplay' ; import { Logger , LogLevel } from '../Logging/Logger' ; export class DefaultReconnectionHandler implements ReconnectionHandler { private readonly _logger : Logger ; private readonly _reconnectCallback : ( ) => Promise < boolean > ; private _currentReconnectionProcess : ReconnectionProcess | null = null ; private _reconnectionDisplay ? : ReconnectDisplay ; constructor ( logger , overrideDisplay ? , reconnectCallback ? ) { this . _logger = logger ; this . _reconnectionDisplay = overrideDisplay ; this . _reconnectCallback = reconnectCallback || ( ( ) => window [ 'Blazor' ] . reconnect ( ) ) ; } onConnectionDown ( options , error ? ) { if ( ! this . _reconnectionDisplay ) { const modal = document . getElementById ( options . dialogId ) ; this . _reconnectionDisplay = modal ? new UserSpecifiedDisplay ( modal ) : new DefaultReconnectDisplay ( options . dialogId , document , this . _logger ) ; } if ( ! this . _currentReconnectionProcess ) { this . _currentReconnectionProcess = new ReconnectionProcess ( options , this . _logger , this . _reconnectCallback , this . _reconnectionDisplay ! ) ; } } onConnectionUp ( ) { if ( this . _currentReconnectionProcess ) { this . _currentReconnectionProcess . dispose ( ) ; this . _currentReconnectionProcess = null ; } } } ; class ReconnectionProcess { readonly reconnectDisplay : ReconnectDisplay ; isDisposed = false ; constructor ( options , private logger , private reconnectCallback , display ) { this . reconnectDisplay = display ; this . reconnectDisplay . show ( ) ; this . attemptPeriodicReconnection ( options ) ; } public dispose ( ) { this . isDisposed = true ; this . reconnectDisplay . hide ( ) ; } async attemptPeriodicReconnection ( options ) { for ( let i = 0 ; i < options . maxRetries ; i ++ ) { await this . delay ( options . retryIntervalMilliseconds ) ; if ( this . isDisposed ) { break ; } try { const result = await this . reconnectCallback ( ) ; if ( ! result ) { this . reconnectDisplay . rejected ( ) ; return ; } return ; } catch ( err ) { this . logger . log ( LogLevel . Error , err ) ; } } this . reconnectDisplay . failed ( ) ; } delay ( durationMilliseconds ) { return new Promise ( resolve => setTimeout ( resolve , durationMilliseconds ) ) ; } }