import { FluidObject , IFluidObject , IRequest } from "@fluidframework/core-interfaces" ; import { FluidDataStoreRuntime , ISharedObjectRegistry , mixinRequestHandler } from "@fluidframework/datastore" ; import { FluidDataStoreRegistry } from "@fluidframework/container-runtime" ; import { IFluidDataStoreContext , IFluidDataStoreFactory , IFluidDataStoreRegistry , NamedFluidDataStoreRegistryEntries , } from "@fluidframework/runtime-definitions" ; import { IFluidDataStoreRuntime , IChannelFactory , } from "@fluidframework/datastore-definitions" ; import { ISharedObject } from "@fluidframework/shared-object-base" ; import { LazyPromise } from "@fluidframework/common-utils" ; import { requestFluidObject } from "@fluidframework/runtime-utils" ; import { LazyLoadedDataObject } from "./lazyLoadedDataObject" ; export class LazyLoadedDataObjectFactory < T extends LazyLoadedDataObject > implements IFluidDataStoreFactory { public readonly ISharedObjectRegistry : ISharedObjectRegistry ; public readonly IFluidDataStoreRegistry : IFluidDataStoreRegistry | undefined ; constructor ( public readonly type , private readonly ctor , public readonly root , sharedObjects = [ ] , storeFactories ? ) { if ( storeFactories !== undefined ) { this . IFluidDataStoreRegistry = new FluidDataStoreRegistry ( storeFactories . map ( ( factory ) => [ factory . type , factory ] ) as NamedFluidDataStoreRegistryEntries ) ; } this . ISharedObjectRegistry = new Map ( sharedObjects . concat ( this . root ) . map ( ( ext ) => [ ext . type , ext ] ) ) ; } public get IFluidDataStoreFactory ( ) { return this ; } public async instantiateDataStore ( context , existing ) { const runtimeClass = mixinRequestHandler ( async ( request ) => { const router = await instance ; return router . request ( request ) ; } ) ; const runtime = new runtimeClass ( context , this . ISharedObjectRegistry , existing ) ; const instance = this . instantiate ( context , runtime , existing ) ; return runtime ; } public async create ( parentContext , props ? ) { const { containerRuntime , packagePath } = parentContext ; const router = await containerRuntime . createDataStore ( packagePath . concat ( this . type ) ) ; return requestFluidObject ( router , "/" ) ; } private instantiate ( context , runtime , existing ) { return existing ? new LazyPromise ( async ( ) => this . load ( context , runtime , existing ) ) : this . createCore ( context , runtime , existing ) ; } private createCore ( context , runtime , props ? ) { const root = runtime . createChannel ( "root" , this . root . type ) as ISharedObject ; const instance = new this . ctor ( context , runtime , root ) ; instance . create ( props ) ; root . bindToContext ( ) ; return instance ; } private async load ( context , runtime , existing ) { const instance = new this . ctor ( context , runtime , await runtime . getChannel ( "root" ) as ISharedObject ) ; await instance . load ( context , runtime , existing ) ; return instance ; } }