import { IDocumentStorageService } from "@fluidframework/driver-definitions" ; import { ISnapshotTree } from "@fluidframework/protocol-definitions" ; import { IChannelStorageService } from "@fluidframework/datastore-definitions" ; import { getNormalizedObjectStoragePathParts } from "@fluidframework/runtime-utils" ; export class ChannelStorageService implements IChannelStorageService { private static flattenTree ( base , tree , results ) { for ( const path in tree . trees ) { ChannelStorageService . flattenTree ( `${ base }${ path }/` , tree . trees [ path ] , results ) ; } for ( const blob in tree . blobs ) { results [ `${ base }${ blob }` ] = tree . blobs [ blob ] ; } } private readonly flattenedTree : { [ path ] : string ; } ; constructor ( private readonly tree , private readonly storage , private readonly extraBlobs ? ) { this . flattenedTree = { } ; if ( tree !== undefined ) { ChannelStorageService . flattenTree ( "" , tree , this . flattenedTree ) ; } } public async contains ( path ) { return this . flattenedTree [ path ] !== undefined ; } public async readBlob ( path ) { const id = await this . getIdForPath ( path ) ; const blob = this . extraBlobs !== undefined ? this . extraBlobs . get ( id ) : undefined ; if ( blob !== undefined ) { return blob ; } return this . storage . readBlob ( id ) ; } public async list ( path ) { let tree = this . tree ; const pathParts = getNormalizedObjectStoragePathParts ( path ) ; while ( tree !== undefined && pathParts . length > 0 ) { const part = pathParts . shift ( ) ! ; tree = tree . trees [ part ] ; } if ( tree === undefined || pathParts . length !== 0 ) { throw new Error ( "path does not exist" ) ; } return Object . keys ( tree ?. blobs ?? { } ) ; } private async getIdForPath ( path ) { return this . flattenedTree [ path ] ; } }