import { IConnection , NotificationHandler , NotificationType , } from 'vscode-languageserver' ; /**
 * Defines a type of notification for which subscriptions in the queue can be raised.
 */ interface Notification < P > { method : string ; params : P ; documentVersion : number | undefined ; } /**
 * An object that provides a document version.
 */ interface VersionProvider < P > { ( params ) : number | undefined ; } /**
 * Message queue for processing requests to lint a document. Ensures that a
 * given request is acting against the current version of the document to avoid
 * using up resources to run lint operations against a stale document version
 * where the results will no longer apply.
 */ export class BufferedMessageQueue { private queue : Notification < any > [ ] ; private notificationHandlers : Map < string , { handler : NotificationHandler < any > ; versionProvider ? : VersionProvider < any > ; } > ; private timer : NodeJS . Immediate | undefined ; param { IConnection } connection constructor ( private connection ) { this . queue = [ ] ; this . notificationHandlers = new Map ( ) ; } callback queue param { P } params return { number } param { NotificationType < P , RO > } type param { NotificationHandler < P > } handler param { queue public registerNotification < P , RO > ( type , handler , versionProvider ? ) { this . connection . onNotification ( type , ( params ) => { this . queue . push ( { method : type . method , params : params , documentVersion : versionProvider ? versionProvider ( params ) : undefined , } ) ; this . trigger ( ) ; } ) ; this . notificationHandlers . set ( type . method , { handler , versionProvider } ) ; } param { NotificationType < P , RO > } type param { P } params param { number } version public addNotificationMessage < P , RO > ( type , params , version ) { this . queue . push ( { method : type . method , params , documentVersion : version , } ) ; this . trigger ( ) ; } param { NotificationType < P , RO > } type param { NotificationHandler < P > } handler param { queue public onNotification < P , RO > ( type , handler , versionProvider ? ) { this . notificationHandlers . set ( type . method , { handler , versionProvider } ) ; } /**
     * Kicks off the queue for processing.
     */ private trigger ( ) { if ( this . timer || this . queue . length === 0 ) { return ; } this . timer = setImmediate ( ( ) => { this . timer = undefined ; this . processQueue ( ) ; this . trigger ( ) ; } ) ; } /**
     * Runs through queued messages and processes them with the associated
     * handler. Discards stale messages if needed.
     */ private processQueue ( ) { const message = this . queue . shift ( ) as Notification < any > ; if ( ! message ) { return ; } const elem = this . notificationHandlers . get ( message . method ) ; if ( elem === undefined ) { throw new Error ( `No handler registered` ) ; } if ( elem . versionProvider && message . documentVersion !== undefined && message . documentVersion !== elem . versionProvider ( message . params ) ) { return ; } elem . handler ( message . params ) ; } }