Replace ICodeLoader with ICodeDetailsLoader (#9697)
The usage of ICodeLoader is replaced with ICodeDetailsLoader in the entire repo. The old interface is not yet removed.
This commit is contained in:
Родитель
6783a8ecc5
Коммит
64afd91ad2
26
BREAKING.md
26
BREAKING.md
|
@ -17,12 +17,17 @@ There are a few steps you can take to write a good change note and avoid needing
|
|||
# 0.59
|
||||
|
||||
## 0.59 Upcoming changes
|
||||
- [Remove ICodeLoader interface](#Remove-ICodeLoader-interface)
|
||||
|
||||
### Remove ICodeLoader interface
|
||||
ICodeLoader interface was deprecated a while ago and will be removed in the next release. Please refer to [replace ICodeLoader with ICodeDetailsLoader interface](#Replace-ICodeLoader-with-ICodeDetailsLoader-interface) for more details.
|
||||
|
||||
## 0.59 Breaking changes
|
||||
- [Removing Commit from TreeEntry and commits from SnapShotTree](#Removing-Commit-from-TreeEntry-and-commits-from-SnapShotTree)
|
||||
- [raiseContainerWarning removed from IContainerContext](#raiseContainerWarning-removed-from-IContainerContext)
|
||||
- [Remove `@fluidframework/core-interface#fluidPackage.ts`](#Remove-fluidframeworkcore-interfacefluidPackagets)
|
||||
- [getAbsoluteUrl() argument type changed](#getAbsoluteUrl-argument-type-changed)
|
||||
- [Replace ICodeLoader with ICodeDetailsLoader interface](#Replace-ICodeLoader-with-ICodeDetailsLoader-interface)
|
||||
|
||||
### Removing Commit from TreeEntry and commits from SnapShotTree
|
||||
Cleaning up properties that are not being used in the codebase: `TreeEntry.Commit` and `ISnapshotTree.commits`.
|
||||
|
@ -67,6 +72,27 @@ The `packageInfoSource` argument in `getAbsoluteUrl()` on `@fluidframework/odsp-
|
|||
+ ): Promise<string>;
|
||||
```
|
||||
|
||||
### Replace ICodeLoader with ICodeDetailsLoader interface
|
||||
The interface `ICodeLoader` was deprecated a while ago in previous releases. The alternative for `ICodeLoader` interface is the `ICodeDetailsLoader` interface which can be imported from `@fluidframework/container-definitions`. `ICodeLoader` interface will be removed in the next release.
|
||||
|
||||
In particular, note the `ILoaderService` and `ILoaderProps` interfaces used with the `Loader` class now only support `ICodeDetailsLoader`. If you were using an `ICodeLoader` with these previously, you'll need to update to an `ICodeDetailsLoader`.
|
||||
|
||||
```ts
|
||||
export interface ICodeDetailsLoader
|
||||
extends Partial<IProvideFluidCodeDetailsComparer> {
|
||||
/**
|
||||
* Load the code module (package) that is capable to interact with the document.
|
||||
*
|
||||
* @param source - Code proposal that articulates the current schema the document is written in.
|
||||
* @returns - Code module entry point along with the code details associated with it.
|
||||
*/
|
||||
load(source: IFluidCodeDetails): Promise<IFluidModuleWithDetails>;
|
||||
}
|
||||
```
|
||||
All codeloaders are now expected to return the object including both the runtime factory and code details of the package that was actually loaded. These code details may be used later then to check whether the currently loaded package `.satisfies()` a constraint.
|
||||
|
||||
You can start by returning default code details that were passed into the code loader which used to be our implementation on your behalf if code details were not passed in. Later on, this gives an opportunity to implement more sophisticated code loading where the code loader now can inform about the actual loaded module via the returned details.
|
||||
|
||||
# 0.58
|
||||
|
||||
## 0.58 Upcoming changes
|
||||
|
|
|
@ -10,7 +10,6 @@ import { FluidObject } from '@fluidframework/core-interfaces';
|
|||
import { IAudience } from '@fluidframework/container-definitions';
|
||||
import { IClientConfiguration } from '@fluidframework/protocol-definitions';
|
||||
import { IClientDetails } from '@fluidframework/protocol-definitions';
|
||||
import { ICodeLoader } from '@fluidframework/container-definitions';
|
||||
import { IConfigProviderBase } from '@fluidframework/telemetry-utils';
|
||||
import { IContainer } from '@fluidframework/container-definitions';
|
||||
import { IContainerEvents } from '@fluidframework/container-definitions';
|
||||
|
@ -155,7 +154,7 @@ export interface ILoaderOptions extends ILoaderOptions_2 {
|
|||
|
||||
// @public
|
||||
export interface ILoaderProps {
|
||||
readonly codeLoader: ICodeDetailsLoader | ICodeLoader;
|
||||
readonly codeLoader: ICodeDetailsLoader;
|
||||
readonly configProvider?: IConfigProviderBase;
|
||||
readonly detachedBlobStorage?: IDetachedBlobStorage;
|
||||
readonly documentServiceFactory: IDocumentServiceFactory;
|
||||
|
@ -168,7 +167,7 @@ export interface ILoaderProps {
|
|||
|
||||
// @public
|
||||
export interface ILoaderServices {
|
||||
readonly codeLoader: ICodeDetailsLoader | ICodeLoader;
|
||||
readonly codeLoader: ICodeDetailsLoader;
|
||||
readonly detachedBlobStorage?: IDetachedBlobStorage;
|
||||
readonly documentServiceFactory: IDocumentServiceFactory;
|
||||
readonly options: ILoaderOptions;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
import { ContainerRuntime } from '@fluidframework/container-runtime';
|
||||
import { FluidDataStoreRuntime } from '@fluidframework/datastore';
|
||||
import { IChannelFactory } from '@fluidframework/datastore-definitions';
|
||||
import { ICodeLoader } from '@fluidframework/container-definitions';
|
||||
import { ICodeDetailsLoader } from '@fluidframework/container-definitions';
|
||||
import { IContainer } from '@fluidframework/container-definitions';
|
||||
import { IContainerContext } from '@fluidframework/container-definitions';
|
||||
import { IContainerRuntime } from '@fluidframework/container-runtime-definitions';
|
||||
|
@ -21,6 +21,7 @@ import { IFluidDataStoreRuntime } from '@fluidframework/datastore-definitions';
|
|||
import { IFluidHandle } from '@fluidframework/core-interfaces';
|
||||
import { IFluidLoadable } from '@fluidframework/core-interfaces';
|
||||
import { IFluidModule } from '@fluidframework/container-definitions';
|
||||
import { IFluidModuleWithDetails } from '@fluidframework/container-definitions';
|
||||
import { IHostLoader } from '@fluidframework/container-definitions';
|
||||
import { ILoaderOptions } from '@fluidframework/container-definitions';
|
||||
import { ILoaderProps } from '@fluidframework/container-loader';
|
||||
|
@ -194,9 +195,9 @@ export class LoaderContainerTracker implements IOpProcessingController {
|
|||
}
|
||||
|
||||
// @public
|
||||
export class LocalCodeLoader implements ICodeLoader {
|
||||
export class LocalCodeLoader implements ICodeDetailsLoader {
|
||||
constructor(packageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>, runtimeOptions?: IContainerRuntimeOptions);
|
||||
load(source: IFluidCodeDetails): Promise<IFluidModule>;
|
||||
load(source: IFluidCodeDetails): Promise<IFluidModuleWithDetails>;
|
||||
}
|
||||
|
||||
// @public
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
```ts
|
||||
|
||||
import { ICodeAllowList } from '@fluidframework/container-definitions';
|
||||
import { ICodeLoader } from '@fluidframework/container-definitions';
|
||||
import { ICodeDetailsLoader } from '@fluidframework/container-definitions';
|
||||
import { IFluidCodeDetails } from '@fluidframework/container-definitions';
|
||||
import { IFluidCodeResolver } from '@fluidframework/container-definitions';
|
||||
import { IFluidModule } from '@fluidframework/container-definitions';
|
||||
import { IFluidModuleWithDetails } from '@fluidframework/container-definitions';
|
||||
import { IFluidPackage } from '@fluidframework/container-definitions';
|
||||
import { IFluidPackageEnvironment } from '@fluidframework/container-definitions';
|
||||
import { IResolvedFluidCodeDetails } from '@fluidframework/container-definitions';
|
||||
|
@ -47,14 +47,14 @@ export class SemVerCdnCodeResolver implements IFluidCodeResolver {
|
|||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export class WebCodeLoader implements ICodeLoader {
|
||||
export class WebCodeLoader implements ICodeDetailsLoader {
|
||||
constructor(codeResolver: IFluidCodeResolver, allowList?: ICodeAllowList | undefined);
|
||||
// (undocumented)
|
||||
load(source: IFluidCodeDetails): Promise<IFluidModule>;
|
||||
load(source: IFluidCodeDetails): Promise<IFluidModuleWithDetails>;
|
||||
// (undocumented)
|
||||
preCache(source: IFluidCodeDetails): Promise<void>;
|
||||
// (undocumented)
|
||||
seedModule(source: IFluidCodeDetails, maybeFluidModule?: Promise<IFluidModule> | IFluidModule): Promise<void>;
|
||||
seedModule(source: IFluidCodeDetails, maybeFluidModule?: Promise<IFluidModuleWithDetails> | IFluidModuleWithDetails): Promise<void>;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -6,12 +6,13 @@
|
|||
import * as Comlink from "comlink";
|
||||
import {
|
||||
AttachState,
|
||||
ICodeLoader,
|
||||
IContainerContext,
|
||||
IRuntime,
|
||||
IProxyLoaderFactory,
|
||||
ILoaderOptions,
|
||||
IContainer,
|
||||
ICodeDetailsLoader,
|
||||
IFluidCodeDetails,
|
||||
} from "@fluidframework/container-definitions";
|
||||
import { Loader } from "@fluidframework/container-loader";
|
||||
import { IRequest, IResponse, FluidObject } from "@fluidframework/core-interfaces";
|
||||
|
@ -104,9 +105,14 @@ class ProxyChaincode extends RuntimeFactoryHelper {
|
|||
}
|
||||
}
|
||||
|
||||
class ProxyCodeLoader implements ICodeLoader {
|
||||
async load() {
|
||||
return Promise.resolve({ fluidExport: new ProxyChaincode() });
|
||||
class ProxyCodeLoader implements ICodeDetailsLoader {
|
||||
async load(source: IFluidCodeDetails) {
|
||||
return {
|
||||
module: {
|
||||
fluidExport: new ProxyChaincode(),
|
||||
},
|
||||
details: source,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import * as Comlink from "comlink";
|
||||
import { fluidExport as TodoContainer } from "@fluid-example/todo";
|
||||
import { IContainer } from "@fluidframework/container-definitions";
|
||||
import { IContainer, IFluidModuleWithDetails } from "@fluidframework/container-definitions";
|
||||
import { Loader } from "@fluidframework/container-loader";
|
||||
import { IFluidResolvedUrl } from "@fluidframework/driver-definitions";
|
||||
import { FluidObject, IRequest } from "@fluidframework/core-interfaces";
|
||||
|
@ -51,8 +51,14 @@ async function loadContainer(
|
|||
const documentServiceFactory = await InnerDocumentServiceFactory.create(innerPort);
|
||||
const urlResolver = await InnerUrlResolver.create(innerPort);
|
||||
|
||||
const module = { fluidExport: TodoContainer };
|
||||
const codeLoader = { load: async () => module };
|
||||
const load = async (): Promise<IFluidModuleWithDetails> => {
|
||||
return {
|
||||
module: { fluidExport: TodoContainer },
|
||||
details: { package: "no-dynamic-package", config: {} },
|
||||
};
|
||||
};
|
||||
|
||||
const codeLoader = { load };
|
||||
|
||||
const loader = new Loader({
|
||||
urlResolver,
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
import {
|
||||
IContainer,
|
||||
IFluidModuleWithDetails,
|
||||
IRuntimeFactory,
|
||||
} from "@fluidframework/container-definitions";
|
||||
import { Loader } from "@fluidframework/container-loader";
|
||||
|
@ -24,9 +25,14 @@ export interface IGetContainerParams {
|
|||
export async function createContainer(
|
||||
params: IGetContainerParams,
|
||||
): Promise<IContainer> {
|
||||
const module = { fluidExport: params.containerRuntimeFactory };
|
||||
const codeLoader = { load: async () => module };
|
||||
const load = async (): Promise<IFluidModuleWithDetails> => {
|
||||
return {
|
||||
module: { fluidExport: params.containerRuntimeFactory },
|
||||
details: { package: "no-dynamic-package", config: {} },
|
||||
};
|
||||
};
|
||||
|
||||
const codeLoader = { load };
|
||||
const loader = new Loader({
|
||||
urlResolver: params.urlResolver,
|
||||
documentServiceFactory: params.documentServiceFactory,
|
||||
|
@ -45,9 +51,14 @@ export async function createContainer(
|
|||
export async function getContainer(
|
||||
params: IGetContainerParams,
|
||||
): Promise<IContainer> {
|
||||
const module = { fluidExport: params.containerRuntimeFactory };
|
||||
const codeLoader = { load: async () => module };
|
||||
const load = async (): Promise<IFluidModuleWithDetails> => {
|
||||
return {
|
||||
module: { fluidExport: params.containerRuntimeFactory },
|
||||
details: { package: "no-dynamic-package", config: {} },
|
||||
};
|
||||
};
|
||||
|
||||
const codeLoader = { load };
|
||||
const loader = new Loader({
|
||||
urlResolver: params.urlResolver,
|
||||
documentServiceFactory: params.documentServiceFactory,
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
import {
|
||||
IContainer,
|
||||
IFluidModuleWithDetails,
|
||||
IRuntimeFactory,
|
||||
} from "@fluidframework/container-definitions";
|
||||
import { Loader } from "@fluidframework/container-loader";
|
||||
|
@ -37,8 +38,14 @@ export async function getSessionStorageContainer(
|
|||
|
||||
// To bypass proposal-based loading, we need a codeLoader that will return our already-in-memory container factory.
|
||||
// The expected format of that response is an IFluidModule with a fluidExport.
|
||||
const module = { fluidExport: containerRuntimeFactory };
|
||||
const codeLoader = { load: async () => module };
|
||||
const load = async (): Promise<IFluidModuleWithDetails> => {
|
||||
return {
|
||||
module: { fluidExport: containerRuntimeFactory },
|
||||
details: { package: "no-dynamic-package", config: {} },
|
||||
};
|
||||
};
|
||||
|
||||
const codeLoader = { load };
|
||||
|
||||
const loader = new Loader({
|
||||
urlResolver,
|
||||
|
|
|
@ -7,7 +7,11 @@ import {
|
|||
IDocumentServiceFactory,
|
||||
IUrlResolver,
|
||||
} from "@fluidframework/driver-definitions";
|
||||
import { AttachState, IContainer } from "@fluidframework/container-definitions";
|
||||
import {
|
||||
AttachState,
|
||||
IContainer,
|
||||
IFluidModuleWithDetails,
|
||||
} from "@fluidframework/container-definitions";
|
||||
import { RouterliciousDocumentServiceFactory } from "@fluidframework/routerlicious-driver";
|
||||
import { requestFluidObject } from "@fluidframework/runtime-utils";
|
||||
import { ensureFluidResolvedUrl } from "@fluidframework/driver-utils";
|
||||
|
@ -138,8 +142,14 @@ export class AzureClient {
|
|||
const runtimeFactory = new DOProviderContainerRuntimeFactory(
|
||||
containerSchema,
|
||||
);
|
||||
const module = { fluidExport: runtimeFactory };
|
||||
const codeLoader = { load: async () => module };
|
||||
const load = async (): Promise<IFluidModuleWithDetails> => {
|
||||
return {
|
||||
module: { fluidExport: runtimeFactory },
|
||||
details: { package: "no-dynamic-package", config: {} },
|
||||
};
|
||||
};
|
||||
|
||||
const codeLoader = { load };
|
||||
return new Loader({
|
||||
urlResolver: this.urlResolver,
|
||||
documentServiceFactory: this.documentServiceFactory,
|
||||
|
|
|
@ -7,7 +7,11 @@ import {
|
|||
IDocumentServiceFactory,
|
||||
IUrlResolver,
|
||||
} from "@fluidframework/driver-definitions";
|
||||
import { AttachState, IContainer } from "@fluidframework/container-definitions";
|
||||
import {
|
||||
AttachState,
|
||||
IContainer,
|
||||
IFluidModuleWithDetails,
|
||||
} from "@fluidframework/container-definitions";
|
||||
import { RouterliciousDocumentServiceFactory } from "@fluidframework/routerlicious-driver";
|
||||
import {
|
||||
createTinyliciousCreateNewRequest,
|
||||
|
@ -119,8 +123,14 @@ export class TinyliciousClient {
|
|||
const containerRuntimeFactory = new DOProviderContainerRuntimeFactory(
|
||||
containerSchema,
|
||||
);
|
||||
const module = { fluidExport: containerRuntimeFactory };
|
||||
const codeLoader = { load: async () => module };
|
||||
const load = async (): Promise<IFluidModuleWithDetails> => {
|
||||
return {
|
||||
module: { fluidExport: containerRuntimeFactory },
|
||||
details: { package: "no-dynamic-package", config: {} },
|
||||
};
|
||||
};
|
||||
|
||||
const codeLoader = { load };
|
||||
const loader = new Loader({
|
||||
urlResolver: this.urlResolver,
|
||||
documentServiceFactory: this.documentServiceFactory,
|
||||
|
|
|
@ -15,11 +15,12 @@ import {
|
|||
AttachState,
|
||||
ILoaderOptions,
|
||||
IRuntimeFactory,
|
||||
ICodeLoader,
|
||||
IProvideRuntimeFactory,
|
||||
IFluidCodeDetails,
|
||||
IFluidCodeDetailsComparer,
|
||||
IProvideFluidCodeDetailsComparer,
|
||||
ICodeDetailsLoader,
|
||||
IFluidModuleWithDetails,
|
||||
} from "@fluidframework/container-definitions";
|
||||
import {
|
||||
IFluidObject,
|
||||
|
@ -44,7 +45,6 @@ import {
|
|||
} from "@fluidframework/protocol-definitions";
|
||||
import { PerformanceEvent } from "@fluidframework/telemetry-utils";
|
||||
import { Container } from "./container";
|
||||
import { ICodeDetailsLoader, IFluidModuleWithDetails } from "./loader";
|
||||
|
||||
const PackageNotFactoryError = "Code package does not implement IRuntimeFactory";
|
||||
|
||||
|
@ -52,7 +52,7 @@ export class ContainerContext implements IContainerContext {
|
|||
public static async createOrLoad(
|
||||
container: Container,
|
||||
scope: FluidObject,
|
||||
codeLoader: ICodeDetailsLoader | ICodeLoader,
|
||||
codeLoader: ICodeDetailsLoader,
|
||||
codeDetails: IFluidCodeDetails,
|
||||
baseSnapshot: ISnapshotTree | undefined,
|
||||
deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,
|
||||
|
@ -157,7 +157,7 @@ export class ContainerContext implements IContainerContext {
|
|||
constructor(
|
||||
private readonly container: Container,
|
||||
public readonly scope: IFluidObject & FluidObject,
|
||||
private readonly codeLoader: ICodeDetailsLoader | ICodeLoader,
|
||||
private readonly codeLoader: ICodeDetailsLoader,
|
||||
private readonly _codeDetails: IFluidCodeDetails,
|
||||
private readonly _baseSnapshot: ISnapshotTree | undefined,
|
||||
public readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,
|
||||
|
@ -329,6 +329,9 @@ export class ContainerContext implements IContainerContext {
|
|||
details: details ?? codeDetails,
|
||||
};
|
||||
} else {
|
||||
// If "module" is not in the result, we are using a legacy ICodeLoader. Fix the result up with details.
|
||||
// Once usage drops to 0 we can remove this compat path.
|
||||
this.taggedLogger.sendTelemetryEvent({ eventName: "LegacyCodeLoader" });
|
||||
return { module: loadCodeResult, details: codeDetails };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ import {
|
|||
IResponse,
|
||||
} from "@fluidframework/core-interfaces";
|
||||
import {
|
||||
ICodeLoader,
|
||||
IContainer,
|
||||
IFluidModule,
|
||||
IHostLoader,
|
||||
|
@ -187,7 +186,7 @@ export interface ILoaderProps {
|
|||
* The code loader handles loading the necessary code
|
||||
* for running a container once it is loaded.
|
||||
*/
|
||||
readonly codeLoader: ICodeDetailsLoader | ICodeLoader;
|
||||
readonly codeLoader: ICodeDetailsLoader;
|
||||
|
||||
/**
|
||||
* A property bag of options used by various layers
|
||||
|
@ -243,7 +242,7 @@ export interface ILoaderServices {
|
|||
* The code loader handles loading the necessary code
|
||||
* for running a container once it is loaded.
|
||||
*/
|
||||
readonly codeLoader: ICodeDetailsLoader | ICodeLoader;
|
||||
readonly codeLoader: ICodeDetailsLoader;
|
||||
|
||||
/**
|
||||
* A property bag of options used by various layers
|
||||
|
|
|
@ -9,6 +9,8 @@ import {
|
|||
ILoader,
|
||||
IRuntime,
|
||||
IRuntimeFactory,
|
||||
ICodeDetailsLoader,
|
||||
IFluidModuleWithDetails,
|
||||
IFluidCodeDetails,
|
||||
} from "@fluidframework/container-definitions";
|
||||
import {
|
||||
|
@ -23,7 +25,6 @@ import {
|
|||
} from "@fluidframework/telemetry-utils";
|
||||
import { Container } from "../container";
|
||||
import { ContainerContext } from "../containerContext";
|
||||
import { ICodeDetailsLoader } from "../loader";
|
||||
|
||||
describe("ContainerContext Tests", () => {
|
||||
let sandbox: Sinon.SinonSandbox;
|
||||
|
@ -57,13 +58,13 @@ describe("ContainerContext Tests", () => {
|
|||
})(defaultErrorHandler);
|
||||
|
||||
const createTestContext = async (
|
||||
codeLoader: unknown, /* ICodeDetailsLoader */
|
||||
codeLoader: ICodeDetailsLoader,
|
||||
existing: boolean = true,
|
||||
) => {
|
||||
return ContainerContext.createOrLoad(
|
||||
(mockContainer as unknown) as Container,
|
||||
(sandbox.stub() as unknown) as FluidObject,
|
||||
codeLoader as ICodeDetailsLoader,
|
||||
codeLoader,
|
||||
quorumCodeDetails,
|
||||
undefined,
|
||||
sandbox.stub() as any,
|
||||
|
@ -89,14 +90,20 @@ describe("ContainerContext Tests", () => {
|
|||
it("Should load code using legacy loader", async () => {
|
||||
// Arrange
|
||||
const proposedCodeDetails = codeDetailsForVersion("2.0.0");
|
||||
const load = async (): Promise<IFluidModuleWithDetails> => {
|
||||
return {
|
||||
module: { fluidExport: { } },
|
||||
details: proposedCodeDetails,
|
||||
};
|
||||
};
|
||||
|
||||
const simpleCodeLoader = { load: async () => {} };
|
||||
const simpleCodeLoader = { load };
|
||||
const mockCodeLoader = sandbox.mock(simpleCodeLoader);
|
||||
// emulate legacy ICodeLoader
|
||||
mockCodeLoader
|
||||
.expects("load")
|
||||
.once()
|
||||
.resolves({ fluidExport: mockRuntimeFactory });
|
||||
.resolves({ module: { fluidExport: mockRuntimeFactory }, details: proposedCodeDetails });
|
||||
|
||||
// Act
|
||||
const testContext = await createTestContext(simpleCodeLoader);
|
||||
|
@ -117,16 +124,23 @@ describe("ContainerContext Tests", () => {
|
|||
it("Should load code without details", async () => {
|
||||
// Arrange
|
||||
const proposedCodeDetails = codeDetailsForVersion("2.0.0");
|
||||
const load = async (): Promise<IFluidModuleWithDetails> => {
|
||||
return {
|
||||
module: { fluidExport: { } },
|
||||
details: { package: "no-dynamic-package", config: {} },
|
||||
};
|
||||
};
|
||||
|
||||
const codeDetailsLoader = {
|
||||
load: async () => {},
|
||||
load,
|
||||
get IFluidCodeDetailsComparer() {
|
||||
return this;
|
||||
},
|
||||
satisfies: async (
|
||||
candidate: IFluidCodeDetails,
|
||||
constraint: IFluidCodeDetails,
|
||||
) => {},
|
||||
) => { return true; },
|
||||
compare: async () => { return 0; },
|
||||
};
|
||||
const mockCodeLoader = sandbox.mock(codeDetailsLoader);
|
||||
mockCodeLoader
|
||||
|
@ -157,16 +171,23 @@ describe("ContainerContext Tests", () => {
|
|||
// Arrange
|
||||
const proposedCodeDetails = codeDetailsForVersion("2.0.0");
|
||||
const moduleCodeDetails = codeDetailsForVersion("3.0.0");
|
||||
const load = async (): Promise<IFluidModuleWithDetails> => {
|
||||
return {
|
||||
module: { fluidExport: { } },
|
||||
details: proposedCodeDetails,
|
||||
};
|
||||
};
|
||||
|
||||
const codeDetailsLoader = {
|
||||
load: async () => {},
|
||||
load,
|
||||
get IFluidCodeDetailsComparer() {
|
||||
return this;
|
||||
},
|
||||
satisfies: async (
|
||||
candidate: IFluidCodeDetails,
|
||||
constraint: IFluidCodeDetails,
|
||||
) => {},
|
||||
) => { return true; },
|
||||
compare: async () => { return 0; },
|
||||
};
|
||||
const mockCodeLoader = sandbox.mock(codeDetailsLoader);
|
||||
mockCodeLoader
|
||||
|
|
|
@ -4,18 +4,19 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
ICodeLoader,
|
||||
ICodeAllowList,
|
||||
IFluidModule,
|
||||
IFluidCodeResolver,
|
||||
IResolvedFluidCodeDetails,
|
||||
isFluidBrowserPackage,
|
||||
IFluidCodeDetails,
|
||||
ICodeDetailsLoader,
|
||||
IFluidModuleWithDetails,
|
||||
} from "@fluidframework/container-definitions";
|
||||
import { ScriptManager } from "./scriptManager";
|
||||
|
||||
export class WebCodeLoader implements ICodeLoader {
|
||||
private readonly loadedModules = new Map<string, Promise<IFluidModule> | IFluidModule>();
|
||||
export class WebCodeLoader implements ICodeDetailsLoader {
|
||||
private readonly loadedModules = new Map<string, Promise<IFluidModuleWithDetails> | IFluidModuleWithDetails>();
|
||||
private readonly scriptManager = new ScriptManager();
|
||||
|
||||
constructor(
|
||||
|
@ -24,7 +25,7 @@ export class WebCodeLoader implements ICodeLoader {
|
|||
|
||||
public async seedModule(
|
||||
source: IFluidCodeDetails,
|
||||
maybeFluidModule?: Promise<IFluidModule> | IFluidModule,
|
||||
maybeFluidModule?: Promise<IFluidModuleWithDetails> | IFluidModuleWithDetails,
|
||||
): Promise<void> {
|
||||
const resolved = await this.codeResolver.resolveCodeDetails(source);
|
||||
if (resolved.resolvedPackageCacheId !== undefined
|
||||
|
@ -50,7 +51,7 @@ export class WebCodeLoader implements ICodeLoader {
|
|||
*/
|
||||
public async load(
|
||||
source: IFluidCodeDetails,
|
||||
): Promise<IFluidModule> {
|
||||
): Promise<IFluidModuleWithDetails> {
|
||||
const resolved = await this.codeResolver.resolveCodeDetails(source);
|
||||
if (resolved.resolvedPackageCacheId !== undefined) {
|
||||
const maybePkg = this.loadedModules.get(resolved.resolvedPackageCacheId);
|
||||
|
@ -60,6 +61,7 @@ export class WebCodeLoader implements ICodeLoader {
|
|||
}
|
||||
|
||||
const fluidModuleP = this.loadModuleFromResolvedCodeDetails(resolved);
|
||||
|
||||
if (resolved.resolvedPackageCacheId !== undefined) {
|
||||
this.loadedModules.set(resolved.resolvedPackageCacheId, fluidModuleP);
|
||||
}
|
||||
|
@ -91,6 +93,6 @@ export class WebCodeLoader implements ICodeLoader {
|
|||
if (fluidModule?.fluidExport === undefined) {
|
||||
throw new Error("Entry point of loaded code package not a Fluid module");
|
||||
}
|
||||
return fluidModule;
|
||||
return { module: fluidModule, details: resolved };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,11 +6,12 @@
|
|||
import assert from "assert";
|
||||
import { ContainerRuntimeFactoryWithDefaultDataStore } from "@fluidframework/aqueduct";
|
||||
import {
|
||||
ICodeLoader,
|
||||
IProvideRuntimeFactory,
|
||||
IFluidModule,
|
||||
IProvideFluidCodeDetailsComparer,
|
||||
IFluidCodeDetails,
|
||||
ICodeDetailsLoader,
|
||||
IFluidModuleWithDetails,
|
||||
} from "@fluidframework/container-definitions";
|
||||
import { IRequest } from "@fluidframework/core-interfaces";
|
||||
import { IContainerRuntimeBase, IProvideFluidDataStoreFactory,
|
||||
|
@ -31,8 +32,8 @@ 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 ICodeLoader {
|
||||
private readonly fluidPackageCache = new Map<string, IFluidModule>();
|
||||
export class LocalCodeLoader implements ICodeDetailsLoader {
|
||||
private readonly fluidPackageCache = new Map<string, IFluidModuleWithDetails>();
|
||||
|
||||
constructor(
|
||||
packageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>,
|
||||
|
@ -77,7 +78,12 @@ export class LocalCodeLoader implements ICodeLoader {
|
|||
}
|
||||
}
|
||||
|
||||
this.fluidPackageCache.set(pkgId, fluidModule);
|
||||
const runtimeFactory = {
|
||||
module: fluidModule,
|
||||
details: source,
|
||||
};
|
||||
|
||||
this.fluidPackageCache.set(pkgId, runtimeFactory);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,7 +94,7 @@ export class LocalCodeLoader implements ICodeLoader {
|
|||
*/
|
||||
public async load(
|
||||
source: IFluidCodeDetails,
|
||||
): Promise<IFluidModule> {
|
||||
): 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.
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
ICodeLoader,
|
||||
ICodeDetailsLoader,
|
||||
IContainer,
|
||||
IHostLoader,
|
||||
ILoaderOptions,
|
||||
|
@ -30,7 +30,7 @@ export function createLoader(
|
|||
logger?: ITelemetryBaseLogger,
|
||||
options?: ILoaderOptions,
|
||||
): IHostLoader {
|
||||
const codeLoader: ICodeLoader = new LocalCodeLoader(packageEntries);
|
||||
const codeLoader: ICodeDetailsLoader = new LocalCodeLoader(packageEntries);
|
||||
|
||||
return new Loader({
|
||||
urlResolver,
|
||||
|
|
|
@ -4,11 +4,12 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
ICodeLoader,
|
||||
ICodeDetailsLoader,
|
||||
IFluidModule,
|
||||
IProvideRuntimeFactory,
|
||||
IFluidCodeDetails,
|
||||
IFluidCodeDetailsComparer,
|
||||
IFluidModuleWithDetails,
|
||||
} from "@fluidframework/container-definitions";
|
||||
import { IRequest } from "@fluidframework/core-interfaces";
|
||||
import { IResolvedUrl, IUrlResolver } from "@fluidframework/driver-definitions";
|
||||
|
@ -36,7 +37,7 @@ import { IResolvedUrl, IUrlResolver } from "@fluidframework/driver-definitions";
|
|||
}
|
||||
|
||||
/** Simple code loader that loads the runtime factory provided during creation. */
|
||||
export class ReplayCodeLoader implements ICodeLoader, IFluidCodeDetailsComparer {
|
||||
export class ReplayCodeLoader implements ICodeDetailsLoader, IFluidCodeDetailsComparer {
|
||||
private readonly fluidModule: IFluidModule;
|
||||
|
||||
constructor(runtimeFactory: IProvideRuntimeFactory) {
|
||||
|
@ -47,8 +48,11 @@ export class ReplayCodeLoader implements ICodeLoader, IFluidCodeDetailsComparer
|
|||
return this;
|
||||
}
|
||||
|
||||
public async load(source: IFluidCodeDetails): Promise<IFluidModule> {
|
||||
return Promise.resolve(this.fluidModule);
|
||||
public async load(source: IFluidCodeDetails): Promise<IFluidModuleWithDetails> {
|
||||
return {
|
||||
module: this.fluidModule,
|
||||
details: source,
|
||||
};
|
||||
}
|
||||
|
||||
public async satisfies(candidate: IFluidCodeDetails, constraint: IFluidCodeDetails): Promise<boolean> {
|
||||
|
|
|
@ -9,7 +9,6 @@ import { ContainerRuntimeFactoryWithDefaultDataStore } from "@fluidframework/aqu
|
|||
import { assert, BaseTelemetryNullLogger, Deferred } from "@fluidframework/common-utils";
|
||||
import {
|
||||
AttachState,
|
||||
IFluidModule,
|
||||
IFluidCodeResolver,
|
||||
IResolvedFluidCodeDetails,
|
||||
isFluidBrowserPackage,
|
||||
|
@ -17,6 +16,8 @@ import {
|
|||
IContainer,
|
||||
IFluidPackage,
|
||||
IFluidCodeDetails,
|
||||
IFluidModuleWithDetails,
|
||||
IFluidModule,
|
||||
} from "@fluidframework/container-definitions";
|
||||
import { Loader } from "@fluidframework/container-loader";
|
||||
import { prefetchLatestSnapshot } from "@fluidframework/odsp-driver";
|
||||
|
@ -92,7 +93,8 @@ export type RouteOptions =
|
|||
| ITinyliciousRouteOptions
|
||||
| IOdspRouteOptions;
|
||||
|
||||
function wrapWithRuntimeFactoryIfNeeded(packageJson: IFluidPackage, fluidModule: IFluidModule): IFluidModule {
|
||||
function wrapWithRuntimeFactoryIfNeeded(packageJson: IFluidPackage, fluidModule: IFluidModule):
|
||||
IFluidModuleWithDetails {
|
||||
const fluidModuleExport: FluidObject<IProvideRuntimeFactory & IFluidDataStoreFactory> =
|
||||
fluidModule.fluidExport;
|
||||
if (fluidModuleExport.IRuntimeFactory === undefined) {
|
||||
|
@ -107,12 +109,19 @@ function wrapWithRuntimeFactoryIfNeeded(packageJson: IFluidPackage, fluidModule:
|
|||
]),
|
||||
);
|
||||
return {
|
||||
fluidExport: {
|
||||
IRuntimeFactory: runtimeFactory,
|
||||
module: {
|
||||
fluidExport: {
|
||||
IRuntimeFactory: runtimeFactory,
|
||||
},
|
||||
},
|
||||
details: { package: packageJson.name, config: { } },
|
||||
};
|
||||
}
|
||||
return fluidModule;
|
||||
|
||||
return {
|
||||
module: fluidModule,
|
||||
details: { package: packageJson.name, config: { } },
|
||||
};
|
||||
}
|
||||
|
||||
// Invoked by `start()` when the 'double' option is enabled to create the side-by-side panes.
|
||||
|
|
Загрузка…
Ссылка в новой задаче