forked from microsoft/FluidFramework
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlocalCodeLoader.ts
107 lines (97 loc) · 4.57 KB
/
localCodeLoader.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*!
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
* Licensed under the MIT License.
*/
import assert from "assert";
import { ContainerRuntimeFactoryWithDefaultDataStore } from "@fluidframework/aqueduct";
import {
IProvideRuntimeFactory,
IFluidModule,
IProvideFluidCodeDetailsComparer,
IFluidCodeDetails,
ICodeDetailsLoader,
IFluidModuleWithDetails,
} from "@fluidframework/container-definitions";
import { IRequest } from "@fluidframework/core-interfaces";
import { IContainerRuntimeBase, IProvideFluidDataStoreFactory,
IProvideFluidDataStoreRegistry } from "@fluidframework/runtime-definitions";
import { createDataStoreFactory } from "@fluidframework/runtime-utils";
import { IContainerRuntimeOptions } from "@fluidframework/container-runtime";
export type SupportedExportInterfaces = Partial<
IProvideRuntimeFactory &
IProvideFluidDataStoreFactory &
IProvideFluidDataStoreRegistry &
IProvideFluidCodeDetailsComparer>;
// Represents the entry point for a Fluid container.
export type fluidEntryPoint = SupportedExportInterfaces | IFluidModule;
/**
* A simple code loader that caches a mapping of package name to a Fluid entry point.
* On load, it retrieves the entry point matching the package name in the given code details.
*/
export class LocalCodeLoader implements ICodeDetailsLoader {
private readonly fluidPackageCache = new Map<string, IFluidModuleWithDetails>();
constructor(
packageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>,
runtimeOptions?: IContainerRuntimeOptions,
) {
for (const entry of packageEntries) {
// Store the entry point against a unique id in the fluidPackageCache.
// For code details containing a package name, use the package name as the id.
// For code details containing a Fluid package, create a unique id from the package name and version.
const source = entry[0];
const pkgId = typeof source.package === "string"
? source.package
: `${source.package.name}@${source.package.version}`;
let fluidModule = entry[1] as IFluidModule;
if (fluidModule?.fluidExport === undefined) {
const maybeExport = fluidModule as SupportedExportInterfaces;
if (maybeExport.IRuntimeFactory !== undefined) {
fluidModule = { fluidExport: maybeExport };
} else {
assert(maybeExport.IFluidDataStoreFactory !== undefined);
const defaultFactory = createDataStoreFactory("default", maybeExport.IFluidDataStoreFactory);
const innerRequestHandler = async (request: IRequest, runtime: IContainerRuntimeBase) =>
runtime.IFluidHandleContext.resolveHandle(request);
fluidModule = {
fluidExport: {
... maybeExport,
IRuntimeFactory:
new ContainerRuntimeFactoryWithDefaultDataStore(
defaultFactory,
[[defaultFactory.type, Promise.resolve(defaultFactory)]],
undefined,
[innerRequestHandler],
runtimeOptions,
),
},
};
}
}
const runtimeFactory = {
module: fluidModule,
details: source,
};
this.fluidPackageCache.set(pkgId, runtimeFactory);
}
}
/**
* It finds the entry point for the package name in the given source and return it
* as a Fluid module.
* @param source - Details of where to find chaincode
*/
public async load(
source: IFluidCodeDetails,
): Promise<IFluidModuleWithDetails> {
// Get the entry point for from the fluidPackageCache for the given code details.
// For code details containing a package name, use the package name as the id.
// For code details containing a Fluid package, create a unique id from the package name and version.
const pkdId = typeof source.package === "string"
? source.package
: `${source.package.name}@${source.package.version}`;
const entryPoint = this.fluidPackageCache.get(pkdId);
if (entryPoint === undefined) {
throw new Error(`Cannot find package ${pkdId}`);
}
return entryPoint;
}
}