/**
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */ import * as util from '../Utils/util' ; export interface Deferred { resolve : Function ; reject : Function ; pollConfig : IPollConfig < any > ; } export interface ActivePoll { id : string ; end : number ; deferred : Deferred [ ] ; } export interface IPollConfig < T > { id : string ; maxDuration : number ; request : ( ) => Promise < T > ; isResolved : ( t : T ) => boolean ; onExpired : ( ) => void ; onUpdate : ( t : T ) => void ; } export interface IPollerOptions { interval : number ; } const global = window ; export class Poller { private polls : ActivePoll [ ] = [ ] ; constructor ( options ) { global . setInterval ( async ( ) => this . poll ( ) , options . interval ) ; } addPoll < T > ( pollConfig ) { const { id , maxDuration } = pollConfig ; const start = new Date ( ) . getTime ( ) ; const end = start + maxDuration ; const activeApp = this . polls . find ( p => p ?. id === id ) ; if ( activeApp ) { activeApp . end = end ; return new Promise ( ( resolve , reject ) => { activeApp . deferred . push ( { resolve , reject , pollConfig } ) ; } ) ; } return new Promise ( ( resolve , reject ) => { this . polls . push ( { id , end , deferred : [ { resolve , reject , pollConfig } ] } ) ; } ) ; } removePoll ( pollId ) { this . polls = this . polls . filter ( p => p . id !== pollId ) ; } private async poll ( ) { const now = ( new Date ( ) ) . getTime ( ) ; this . polls = ( await Promise . all ( this . polls . map ( async ( poll ) => { const { end } = poll ; if ( now >= end ) { poll . deferred . forEach ( deferred => { deferred . pollConfig . onExpired ( ) ; deferred . resolve ( ) ; } ) ; return undefined ; } const firstConfig = poll . deferred [ 0 ] . pollConfig ; const result = await firstConfig . request ( ) ; firstConfig . onUpdate ( result ) ; if ( firstConfig . isResolved ( result ) ) { poll . deferred . forEach ( deferred => deferred . resolve ( ) ) ; return undefined ; } return poll ; } ) ) ) . filter ( util . notNullOrUndefined ) ; } }