import { ITelemetryLogger } from "@fluidframework/common-definitions" ; import { IDocumentStorageService , IDocumentStorageServicePolicies , ISummaryContext , } from "@fluidframework/driver-definitions" ; import { ICreateBlobResponse , ISnapshotTree , ISummaryHandle , ISummaryTree , ITree , IVersion , } from "@fluidframework/protocol-definitions" ; import { IDetachedBlobStorage } from "./loader" ; import { ISnapshotTreeWithBlobContents } from "./utils" ; /**
 * This class wraps the actual storage and make sure no wrong apis are called according to
 * container attach state.
 */ export class ContainerStorageAdapter implements IDocumentStorageService { private readonly blobContents : { [ id ] : ArrayBufferLike ; } = { } ; constructor ( private readonly storageGetter ) { } public loadSnapshotForRehydratingContainer ( snapshotTree ) { this . getBlobContents ( snapshotTree ) ; } private getBlobContents ( snapshotTree ) { for ( const [ id , value ] of Object . entries ( snapshotTree . blobsContents ) ) { this . blobContents [ id ] = value ; } for ( const [ _ , tree ] of Object . entries ( snapshotTree . trees ) ) { this . getBlobContents ( tree ) ; } } public get policies ( ) : IDocumentStorageServicePolicies | undefined { try { return this . storageGetter ( ) . policies ; } catch ( e ) { } return undefined ; } public get repositoryUrl ( ) : string { return this . storageGetter ( ) . repositoryUrl ; } public async getSnapshotTree ( version ? ) { return this . storageGetter ( ) . getSnapshotTree ( version ) ; } public async readBlob ( id ) { const blob = this . blobContents [ id ] ; if ( blob !== undefined ) { return blob ; } return this . storageGetter ( ) . readBlob ( id ) ; } public async getVersions ( versionId , count ) { return this . storageGetter ( ) . getVersions ( versionId , count ) ; } public async write ( tree , parents , message , ref ) { return this . storageGetter ( ) . write ( tree , parents , message , ref ) ; } public async uploadSummaryWithContext ( summary , context ) { return this . storageGetter ( ) . uploadSummaryWithContext ( summary , context ) ; } public async downloadSummary ( handle ) { return this . storageGetter ( ) . downloadSummary ( handle ) ; } public async createBlob ( file ) { return this . storageGetter ( ) . createBlob ( file ) ; } } /**
 * Storage which only supports createBlob() and readBlob(). This is used with IDetachedBlobStorage to support
 * blobs in detached containers.
 */ export class BlobOnlyStorage implements IDocumentStorageService { constructor ( private readonly blobStorage , private readonly logger ) { } public async createBlob ( content ) { return this . blobStorage . createBlob ( content ) ; } public async readBlob ( blobId ) { return this . blobStorage . readBlob ( blobId ) ; } public get policies ( ) : IDocumentStorageServicePolicies | undefined { return this . notCalled ( ) ; } public get repositoryUrl ( ) : string { return this . notCalled ( ) ; } public getSnapshotTree : ( ) => Promise < ISnapshotTree | null > = this . notCalled ; public getVersions : ( ) => Promise < IVersion [ ] > = this . notCalled ; public write : ( ) => Promise < IVersion > = this . notCalled ; public uploadSummaryWithContext : ( ) => Promise < string > = this . notCalled ; public downloadSummary : ( ) => Promise < ISummaryTree > = this . notCalled ; private notCalled ( ) { try { throw new Error ( "BlobOnlyStorage not implemented method used" ) ; } catch ( err ) { this . logger . sendErrorEvent ( { eventName : "BlobOnlyStorageWrongCall" } , err ) ; throw err ; } } }