import { bufferToString } from "@fluidframework/common-utils" ; import { IChannelAttributes , IFluidDataStoreRuntime , IChannelStorageService , IChannelServices , IChannelFactory , } from "@fluidframework/datastore-definitions" ; import { ISequencedDocumentMessage , MessageType } from "@fluidframework/protocol-definitions" ; import { ISummaryTreeWithStats } from "@fluidframework/runtime-definitions" ; import { createSingleBlobSummary , IFluidSerializer , SharedObject , } from "@fluidframework/shared-object-base" ; import { Interval , IntervalCollection , IntervalCollectionValueType , ISerializableInterval , } from "./intervalCollection" ; import { MapKernel } from "./mapKernel" ; import { pkgVersion } from "./packageVersion" ; const snapshotFileName = "header" ; /**
 * The factory that defines the SharedIntervalCollection
 */ export class SharedIntervalCollectionFactory implements IChannelFactory { public static readonly Type = "https://graph.microsoft.com/types/sharedIntervalCollection" ; public static readonly Attributes : IChannelAttributes = { type : SharedIntervalCollectionFactory . Type , snapshotFormatVersion : "0.1" , packageVersion : pkgVersion } ; public get type ( ) { return SharedIntervalCollectionFactory . Type ; } public get attributes ( ) { return SharedIntervalCollectionFactory . Attributes ; } /**
     * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.load}
     */ public async load ( runtime , id , services , attributes ) { const map = new SharedIntervalCollection ( id , runtime , attributes ) ; await map . load ( services ) ; return map ; } public create ( runtime , id ) { const map = new SharedIntervalCollection ( id , runtime , this . attributes ) ; map . initializeLocal ( ) ; return map ; } } export interface ISharedIntervalCollection < TInterval extends ISerializableInterval > { waitIntervalCollection ( label ) : Promise < IntervalCollection < TInterval > > ; getIntervalCollection ( label ) : IntervalCollection < TInterval > ; } export class SharedIntervalCollection < TInterval extends ISerializableInterval = Interval > extends SharedObject implements ISharedIntervalCollection < TInterval > { param runtime param id returns public static create ( runtime , id ? ) { return runtime . createChannel ( id , SharedIntervalCollectionFactory . Type ) as SharedIntervalCollection ; } returns public static getFactory ( ) { return new SharedIntervalCollectionFactory ( ) ; } public readonly [ Symbol . toStringTag ] : string = "SharedIntervalCollection" ; private readonly intervalMapKernel : MapKernel ; /**
     * Constructs a new shared SharedIntervalCollection. If the object is non-local an id and service interfaces will
     * be provided
     */ constructor ( id , runtime , attributes ) { super ( id , runtime , attributes ) ; this . intervalMapKernel = new MapKernel ( this . serializer , this . handle , ( op , localOpMetadata ) => this . submitLocalMessage ( op , localOpMetadata ) , ( ) => this . isAttached ( ) , [ new IntervalCollectionValueType ( ) ] ) ; } public async waitIntervalCollection ( label ) { return this . intervalMapKernel . wait < IntervalCollection < TInterval > > ( this . getIntervalCollectionPath ( label ) ) ; } public getIntervalCollection ( label ) { const realLabel = this . getIntervalCollectionPath ( label ) ; if ( ! this . intervalMapKernel . has ( realLabel ) ) { this . intervalMapKernel . createValueType ( label , IntervalCollectionValueType . Name , undefined ) ; } const sharedCollection = this . intervalMapKernel . get < IntervalCollection < TInterval > > ( realLabel ) ; return sharedCollection ; } protected summarizeCore ( serializer ) { return createSingleBlobSummary ( snapshotFileName , this . intervalMapKernel . serialize ( serializer ) ) ; } protected reSubmitCore ( content , localOpMetadata ) { this . intervalMapKernel . trySubmitMessage ( content , localOpMetadata ) ; } protected onDisconnect ( ) { } /**
     * {@inheritDoc @fluidframework/shared-object-base#SharedObject.loadCore}
     */ protected async loadCore ( storage ) { const blob = await storage . readBlob ( snapshotFileName ) ; const header = bufferToString ( blob , "utf8" ) ; this . intervalMapKernel . populate ( header ) ; } protected processCore ( message , local , localOpMetadata ) { if ( message . type === MessageType . Operation ) { this . intervalMapKernel . tryProcessMessage ( message . contents , local , message , localOpMetadata ) ; } } protected registerCore ( ) { for ( const value of this . intervalMapKernel . values ( ) ) { if ( SharedObject . is ( value ) ) { value . bindToContext ( ) ; } } } param label protected getIntervalCollectionPath ( label ) { return label ; } protected applyStashedOp ( ) { throw new Error ( "not implemented" ) ; } }