import assert from "assert" ; import { EventEmitter } from "events" ; import { IContext , IQueuedMessage , ILogger , IContextErrorData , IRoutingKey , } from "@fluidframework/server-services-core" ; export class DocumentContext extends EventEmitter implements IContext { private headInternal : IQueuedMessage ; private tailInternal : IQueuedMessage ; private closed = false ; private contextError = undefined ; constructor ( private readonly routingKey , head , public readonly log , private readonly getLatestTail ) { super ( ) ; this . headInternal = head ; this . tailInternal = this . getLatestTail ( ) ; } public get head ( ) : IQueuedMessage { return this . headInternal ; } public get tail ( ) : IQueuedMessage { return this . tailInternal ; } /**
     * Returns whether or not there is pending work in flight - i.e. the head and tail are not equal
     */ public hasPendingWork ( ) { return this . headInternal !== this . tailInternal ; } /**
     * Updates the head offset for the context.
     */ public setHead ( head ) { assert ( head . offset > this . head . offset , `${ head . offset } > ${ this . head . offset } ` + `(${ head . topic }, ${ head . partition }, ${ this . routingKey . tenantId }/${ this . routingKey . documentId })` ) ; if ( ! this . hasPendingWork ( ) ) { this . tailInternal = this . getLatestTail ( ) ; } this . headInternal = head ; } public checkpoint ( message ) { if ( this . closed ) { return ; } const offset = message . offset ; assert ( offset > this . tail . offset && offset <= this . head . offset , `${ offset } > ${ this . tail . offset } && ${ offset } <= ${ this . head . offset } ` + `(${ message . topic }, ${ message . partition }, ${ this . routingKey . tenantId }/${ this . routingKey . documentId })` ) ; this . tailInternal = message ; this . emit ( "checkpoint" , this ) ; } public error ( error , errorData ) { this . contextError = error ; this . emit ( "error" , error , errorData ) ; } public close ( ) { this . closed = true ; this . removeAllListeners ( ) ; } public getContextError ( ) { return this . contextError ; } }