import { assert } from "@fluidframework/common-utils" ; import { FluidObject , IFluidObject , IFluidRouter , IRequest , IResponse , } from "@fluidframework/core-interfaces" ; import { IFluidDataStoreFactory , IFluidDataStoreRegistry , IProvideFluidDataStoreRegistry , } from "@fluidframework/runtime-definitions" ; import { generateErrorWithStack } from "@fluidframework/telemetry-utils" ; interface IResponseException extends Error { errorFromRequestFluidObject : true ; message : string ; code : number ; stack ? : string ; } export function exceptionToResponse ( err ) { const status = 500 ; if ( err !== null && typeof err === "object" && err . errorFromRequestFluidObject === true ) { const responseErr = err ; return { mimeType : "text/plain" , status : responseErr . code , value : responseErr . message , get stack ( ) { return responseErr . stack ; } } ; } const errWithStack = generateErrorWithStack ( ) ; return { mimeType : "text/plain" , status , value : `${ err }` , get stack ( ) { return ( ( err ?. stack ) as ( string | undefined ) ) ?? errWithStack . stack ; } } ; } export function responseToException ( response , request ) { const message = response . value ; const errWithStack = generateErrorWithStack ( ) ; const responseErr = { errorFromRequestFluidObject : true , message , name : "Error" , code : response . status , get stack ( ) { return response . stack ?? errWithStack . stack ; } } ; return responseErr ; } export async function requestFluidObject < T = IFluidObject & FluidObject > ( router , url ) { const request = typeof url === "string" ? { url } : url ; const response = await router . request ( request ) ; if ( response . status !== 200 || response . mimeType !== "fluid/object" ) { throw responseToException ( response , request ) ; } assert ( response . value , 0x19a ) ; return response . value as T ; } export const create404Response = ( request ) => createResponseError ( 404 , "not found" , request ) ; export function createResponseError ( status , value , request ) { assert ( status !== 200 , 0x19b ) ; const urlNoQuery = request . url ?. split ( "?" ) [ 0 ] ; const errWithStack = generateErrorWithStack ( ) ; return { mimeType : "text/plain" , status , value : urlNoQuery === undefined ? value : `${ value }: ${ urlNoQuery }` , get stack ( ) { return errWithStack . stack ; } } ; } export type Factory = IFluidDataStoreFactory & Partial < IProvideFluidDataStoreRegistry > ; export function createDataStoreFactory ( type , factory ) { return { type , get IFluidDataStoreFactory ( ) { return this ; } , get IFluidDataStoreRegistry ( ) { return this ; } , instantiateDataStore : async ( context , existing ) => ( await factory ) . instantiateDataStore ( context , existing ) , get : async ( name ) => ( await factory ) . IFluidDataStoreRegistry ?. get ( name ) } ; }