import { EventEmitter } from "events" ; import { safelyParseJSON } from "@fluidframework/common-utils" ; import { BoxcarType , IBoxcarMessage , IMessage } from "./messages" ; import { IQueuedMessage } from "./queue" ; /**
 * Reasons why a lambda is closing
 */ export enum LambdaCloseType { Stop = "Stop" , ActivityTimeout = "ActivityTimeout" , Rebalance = "Rebalance" , Error = "Error" } export enum LambdaName { Scribe = "Scribe" } export interface ILogger { info ( message , metaData ? ) : void ; warn ( message , metaData ? ) : void ; error ( message , metaData ? ) : void ; } export interface IContextErrorData { /**
     * Indicates whether the error is recoverable and the lambda should be restarted.
     */ restart : boolean ; tenantId ? : string ; documentId ? : string ; } export interface IContext { /**
     * Updates the checkpoint
     */ checkpoint ( queuedMessage ) : void ; param error param errorData error ( error , errorData ) : void ; /**
     * Used to log events / errors.
     */ readonly log : ILogger | undefined ; } export interface IPartitionLambda { /**
     * Processes an incoming message
     */ handler ( message ) : Promise < void > | undefined ; /**
     * Closes the lambda. After being called handler will no longer be invoked and the lambda is expected to cancel
     * any deferred work.
     */ close ( closeType ) : void ; } /**
 * Factory for creating lambda related objects
 */ export interface IPartitionLambdaFactory < T extends IPartitionConfig = IPartitionLambdaConfig > extends EventEmitter { /**
     * Constructs a new lambda
     */ create ( config , context , updateActivityTime ? ) : Promise < IPartitionLambda > ; /**
     * Disposes of the lambda factory
     */ dispose ( ) : Promise < void > ; } /**
 * Partition config
 */ export interface IPartitionConfig { leaderEpoch : number ; } /**
 * Lambda config
 */ export interface IPartitionLambdaConfig extends IPartitionConfig { tenantId : string ; documentId : string ; } export function extractBoxcar ( message ) { if ( typeof message . value !== "string" && ! Buffer . isBuffer ( message . value ) ) { return message . value ; } const messageContent = message . value . toString ( ) ; const rawMessage = safelyParseJSON ( messageContent ) ; const parsedMessage = rawMessage as IMessage ; if ( ! parsedMessage ) { return { contents : [ ] , documentId : null , tenantId : null , type : BoxcarType } ; } if ( parsedMessage . type === BoxcarType ) { const boxcarMessage = parsedMessage as IBoxcarMessage ; const contents = boxcarMessage . contents . length > 0 && typeof boxcarMessage . contents [ 0 ] === "string" ? boxcarMessage . contents . map ( ( content ) => JSON . parse ( content ) ) : boxcarMessage . contents ; return { contents , documentId : boxcarMessage . documentId , tenantId : boxcarMessage . tenantId , type : boxcarMessage . type } ; } else { return { contents : [ parsedMessage ] , documentId : rawMessage . documentId , tenantId : rawMessage . tenantId , type : BoxcarType } ; } }