@fluidframework/runtime-utils 2.113.0-411909 → 2.114.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +73 -0
- package/api-report/runtime-utils.legacy.alpha.api.md +6 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -1
- package/dist/index.js.map +1 -1
- package/dist/legacyAlpha.d.ts +5 -0
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/serviceClientBase.d.ts +96 -0
- package/dist/serviceClientBase.d.ts.map +1 -0
- package/dist/serviceClientBase.js +165 -0
- package/dist/serviceClientBase.js.map +1 -0
- package/dist/serviceClientUtils.d.ts +90 -0
- package/dist/serviceClientUtils.d.ts.map +1 -0
- package/dist/serviceClientUtils.js +128 -0
- package/dist/serviceClientUtils.js.map +1 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -1
- package/lib/legacyAlpha.d.ts +5 -0
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/serviceClientBase.d.ts +96 -0
- package/lib/serviceClientBase.d.ts.map +1 -0
- package/lib/serviceClientBase.js +159 -0
- package/lib/serviceClientBase.js.map +1 -0
- package/lib/serviceClientUtils.d.ts +90 -0
- package/lib/serviceClientUtils.d.ts.map +1 -0
- package/lib/serviceClientUtils.js +121 -0
- package/lib/serviceClientUtils.js.map +1 -0
- package/package.json +17 -17
- package/src/index.ts +18 -0
- package/src/packageVersion.ts +1 -1
- package/src/serviceClientBase.ts +261 -0
- package/src/serviceClientUtils.ts +236 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serviceClientUtils.d.ts","sourceRoot":"","sources":["../src/serviceClientUtils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
import { assert } from "@fluidframework/core-utils/internal";
|
|
6
|
+
import { createBasicRegistryKey, lookupInRegistry, } from "@fluidframework/driver-definitions/internal";
|
|
7
|
+
import { DataStoreKindImplementation } from "./serviceClientBase.js";
|
|
8
|
+
/**
|
|
9
|
+
* The constant ID used for the root data store alias in service containers.
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export const rootDataStoreId = "root";
|
|
13
|
+
/**
|
|
14
|
+
* Converts a `DataStoreRegistry` to the `IFluidDataStoreRegistry` interface expected by the container runtime.
|
|
15
|
+
* @remarks
|
|
16
|
+
* This does not leverage the ability for `IFluidDataStoreRegistry.get` to return undefined.
|
|
17
|
+
* Note that all use-cases of `IFluidDataStoreRegistry.get` returning undefined currently end up as a fatal error.
|
|
18
|
+
* Therefore it should be fine for the error to instead be thrown by the registry function, which is what this function does.
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
21
|
+
export function convertRegistry(registry) {
|
|
22
|
+
return {
|
|
23
|
+
async get(name) {
|
|
24
|
+
const dataStoreKind = await lookupInRegistry(registry, createBasicRegistryKey(name));
|
|
25
|
+
DataStoreKindImplementation.narrowGeneric(dataStoreKind);
|
|
26
|
+
return dataStoreKind;
|
|
27
|
+
},
|
|
28
|
+
get IFluidDataStoreRegistry() {
|
|
29
|
+
return this;
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Normalizes a `DataStoreKind` or registry function into a registry function.
|
|
35
|
+
* @internal
|
|
36
|
+
*/
|
|
37
|
+
export function normalizeRegistry(input) {
|
|
38
|
+
if (DataStoreKindImplementation.guard(input)) {
|
|
39
|
+
return async () => input;
|
|
40
|
+
}
|
|
41
|
+
assert(typeof input === "function", 0xd17 /* Registry must be a function */);
|
|
42
|
+
return input;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Creates an `ICodeDetailsLoader` that wires up the container runtime via the supplied
|
|
46
|
+
* `loadRuntime` callback.
|
|
47
|
+
*
|
|
48
|
+
* @remarks
|
|
49
|
+
* The `loadRuntime` callback is responsible for invoking the concrete runtime factory and,
|
|
50
|
+
* when `parameters.existing` is `false` and `parameters.newContainerRootType` is set, creating and
|
|
51
|
+
* aliasing the root data store.
|
|
52
|
+
*
|
|
53
|
+
* This loader never does any code loading, and always assumes it is compatible.
|
|
54
|
+
* TODO: We should reevaluate this before promoting ServiceClient APIs to beta.
|
|
55
|
+
*
|
|
56
|
+
* @internal
|
|
57
|
+
*/
|
|
58
|
+
export function makeCodeLoader(registry, minVersionForCollab, loadRuntime, root) {
|
|
59
|
+
const fluidExport = {
|
|
60
|
+
async instantiateRuntime(context, existing) {
|
|
61
|
+
const provideEntryPoint = async (entryPointRuntime) => {
|
|
62
|
+
const data = await entryPointRuntime.getAliasedDataStoreEntryPoint(rootDataStoreId);
|
|
63
|
+
if (data === undefined) {
|
|
64
|
+
throw new Error("Root data store missing!");
|
|
65
|
+
}
|
|
66
|
+
const rootDataStore = await data.get();
|
|
67
|
+
return rootDataStore;
|
|
68
|
+
};
|
|
69
|
+
return loadRuntime({
|
|
70
|
+
context,
|
|
71
|
+
registry: convertRegistry(registry),
|
|
72
|
+
provideEntryPoint,
|
|
73
|
+
existing,
|
|
74
|
+
minVersionForCollab,
|
|
75
|
+
newContainerRootType: root?.type,
|
|
76
|
+
});
|
|
77
|
+
},
|
|
78
|
+
async satisfies(candidate, constraint) {
|
|
79
|
+
return true;
|
|
80
|
+
},
|
|
81
|
+
async compare(a, b) {
|
|
82
|
+
return 0;
|
|
83
|
+
},
|
|
84
|
+
get IRuntimeFactory() {
|
|
85
|
+
return fluidExport;
|
|
86
|
+
},
|
|
87
|
+
get IFluidCodeDetailsComparer() {
|
|
88
|
+
return fluidExport;
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
return {
|
|
92
|
+
load: async (details) => {
|
|
93
|
+
return { module: { fluidExport }, details };
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Creates a {@link @fluidframework/driver-definitions#ServiceClient} that delegates container
|
|
99
|
+
* creation and loading to the supplied container class statics.
|
|
100
|
+
* @internal
|
|
101
|
+
*/
|
|
102
|
+
export class ServiceClientImplementation {
|
|
103
|
+
constructor(options, statics) {
|
|
104
|
+
this.options = options;
|
|
105
|
+
this.statics = statics;
|
|
106
|
+
}
|
|
107
|
+
async createContainer(root, registry) {
|
|
108
|
+
if (registry === undefined) {
|
|
109
|
+
DataStoreKindImplementation.narrowGeneric(root);
|
|
110
|
+
return this.statics.createDetached(normalizeRegistry(root), this.options, root);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
const result = await lookupInRegistry(registry, root);
|
|
114
|
+
return this.statics.createDetached(registry, this.options, result);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
async loadContainer(id, root) {
|
|
118
|
+
return this.statics.load(normalizeRegistry(root), this.options, id);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=serviceClientUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serviceClientUtils.js","sourceRoot":"","sources":["../src/serviceClientUtils.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type {\n\tICodeDetailsLoader,\n\tIContainerContext,\n\tIFluidCodeDetails,\n\tIFluidCodeDetailsComparer,\n\tIFluidModuleWithDetails,\n\tIRuntime,\n\tIRuntimeFactory,\n} from \"@fluidframework/container-definitions/internal\";\nimport type { FluidObject } from \"@fluidframework/core-interfaces\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport {\n\tcreateBasicRegistryKey,\n\ttype DataStoreKey,\n\ttype DataStoreKind,\n\ttype DataStoreRegistry,\n\ttype FluidContainerAttached,\n\ttype FluidContainerWithService,\n\ttype Registry,\n\tlookupInRegistry,\n\ttype ServiceClient,\n} from \"@fluidframework/driver-definitions/internal\";\nimport type {\n\tFluidDataStoreRegistryEntry,\n\tIContainerRuntimeBase,\n\tIFluidDataStoreRegistry,\n\tMinimumVersionForCollab,\n} from \"@fluidframework/runtime-definitions/internal\";\n\nimport { DataStoreKindImplementation } from \"./serviceClientBase.js\";\n\n/**\n * The constant ID used for the root data store alias in service containers.\n * @internal\n */\nexport const rootDataStoreId = \"root\";\n\n/**\n * Converts a `DataStoreRegistry` to the `IFluidDataStoreRegistry` interface expected by the container runtime.\n * @remarks\n * This does not leverage the ability for `IFluidDataStoreRegistry.get` to return undefined.\n * Note that all use-cases of `IFluidDataStoreRegistry.get` returning undefined currently end up as a fatal error.\n * Therefore it should be fine for the error to instead be thrown by the registry function, which is what this function does.\n * @internal\n */\nexport function convertRegistry<T>(registry: DataStoreRegistry<T>): IFluidDataStoreRegistry {\n\treturn {\n\t\tasync get(name: string): Promise<FluidDataStoreRegistryEntry | undefined> {\n\t\t\tconst dataStoreKind = await lookupInRegistry(registry, createBasicRegistryKey(name));\n\t\t\tDataStoreKindImplementation.narrowGeneric(dataStoreKind);\n\t\t\treturn dataStoreKind;\n\t\t},\n\t\tget IFluidDataStoreRegistry(): IFluidDataStoreRegistry {\n\t\t\treturn this;\n\t\t},\n\t};\n}\n\n/**\n * Normalizes a `DataStoreKind` or registry function into a registry function.\n * @internal\n */\nexport function normalizeRegistry<T>(\n\tinput: DataStoreKind<T> | Registry<Promise<DataStoreKind<T>>>,\n): Registry<Promise<DataStoreKind<T>>> {\n\tif (DataStoreKindImplementation.guard(input)) {\n\t\treturn async () => input;\n\t}\n\tassert(typeof input === \"function\", 0xd17 /* Registry must be a function */);\n\treturn input;\n}\n\n/**\n * Parameters passed to a {@link ContainerRuntimeLoader}.\n * @internal\n */\nexport interface ContainerRuntimeLoaderParams {\n\tcontext: IContainerContext;\n\tregistry: IFluidDataStoreRegistry;\n\tprovideEntryPoint: (runtime: IContainerRuntimeBase) => Promise<FluidObject>;\n\texisting: boolean;\n\tminVersionForCollab: MinimumVersionForCollab;\n\t/**\n\t * The type string of the root data store to create. Only set when `existing` is false.\n\t */\n\tnewContainerRootType: string | undefined;\n}\n\n/**\n * A service-specific callback that creates or loads the container runtime.\n *\n * @remarks\n * Receives the runtime parameters assembled by {@link makeCodeLoader} and is responsible for\n * calling the concrete runtime factory (e.g. `ContainerRuntime.loadRuntime2`) and, when\n * `existing` is `false`, initializing the root data store before returning.\n *\n * @internal\n */\nexport type ContainerRuntimeLoader = (\n\tparameters: ContainerRuntimeLoaderParams,\n) => Promise<IRuntime>;\n\n/**\n * Creates an `ICodeDetailsLoader` that wires up the container runtime via the supplied\n * `loadRuntime` callback.\n *\n * @remarks\n * The `loadRuntime` callback is responsible for invoking the concrete runtime factory and,\n * when `parameters.existing` is `false` and `parameters.newContainerRootType` is set, creating and\n * aliasing the root data store.\n *\n * This loader never does any code loading, and always assumes it is compatible.\n * TODO: We should reevaluate this before promoting ServiceClient APIs to beta.\n *\n * @internal\n */\nexport function makeCodeLoader<T>(\n\tregistry: DataStoreRegistry<T>,\n\tminVersionForCollab: MinimumVersionForCollab,\n\tloadRuntime: ContainerRuntimeLoader,\n\troot?: DataStoreKind<T>,\n): ICodeDetailsLoader {\n\tconst fluidExport: IRuntimeFactory & IFluidCodeDetailsComparer = {\n\t\tasync instantiateRuntime(\n\t\t\tcontext: IContainerContext,\n\t\t\texisting: boolean,\n\t\t): Promise<IRuntime> {\n\t\t\tconst provideEntryPoint = async (\n\t\t\t\tentryPointRuntime: IContainerRuntimeBase,\n\t\t\t): Promise<T & FluidObject> => {\n\t\t\t\tconst data = await entryPointRuntime.getAliasedDataStoreEntryPoint(rootDataStoreId);\n\t\t\t\tif (data === undefined) {\n\t\t\t\t\tthrow new Error(\"Root data store missing!\");\n\t\t\t\t}\n\t\t\t\tconst rootDataStore = await data.get();\n\t\t\t\treturn rootDataStore as T & FluidObject;\n\t\t\t};\n\n\t\t\treturn loadRuntime({\n\t\t\t\tcontext,\n\t\t\t\tregistry: convertRegistry(registry),\n\t\t\t\tprovideEntryPoint,\n\t\t\t\texisting,\n\t\t\t\tminVersionForCollab,\n\t\t\t\tnewContainerRootType: root?.type,\n\t\t\t});\n\t\t},\n\n\t\tasync satisfies(\n\t\t\tcandidate: IFluidCodeDetails,\n\t\t\tconstraint: IFluidCodeDetails,\n\t\t): Promise<boolean> {\n\t\t\treturn true;\n\t\t},\n\n\t\tasync compare(a: IFluidCodeDetails, b: IFluidCodeDetails): Promise<number | undefined> {\n\t\t\treturn 0;\n\t\t},\n\n\t\tget IRuntimeFactory(): IRuntimeFactory {\n\t\t\treturn fluidExport;\n\t\t},\n\n\t\tget IFluidCodeDetailsComparer(): IFluidCodeDetailsComparer {\n\t\t\treturn fluidExport;\n\t\t},\n\t};\n\n\treturn {\n\t\tload: async (details: IFluidCodeDetails): Promise<IFluidModuleWithDetails> => {\n\t\t\treturn { module: { fluidExport }, details };\n\t\t},\n\t};\n}\n\n/**\n * Minimal interface for the static container factory methods used by {@link ServiceClientImplementation}.\n * @internal\n */\nexport interface ServiceContainerStatics<TOptions> {\n\tcreateDetached<T>(\n\t\tregistry: DataStoreRegistry<T>,\n\t\toptions: TOptions,\n\t\troot: DataStoreKind<T>,\n\t): Promise<FluidContainerWithService<T>>;\n\n\tload<T>(\n\t\tregistry: DataStoreRegistry<T>,\n\t\toptions: TOptions,\n\t\tid: string,\n\t): Promise<FluidContainerAttached<T>>;\n}\n\n/**\n * Creates a {@link @fluidframework/driver-definitions#ServiceClient} that delegates container\n * creation and loading to the supplied container class statics.\n * @internal\n */\nexport class ServiceClientImplementation<TOptions> implements ServiceClient {\n\tpublic constructor(\n\t\tprivate readonly options: TOptions,\n\t\tprivate readonly statics: ServiceContainerStatics<TOptions>,\n\t) {}\n\n\tpublic createContainer<T>(root: DataStoreKind<T>): Promise<FluidContainerWithService<T>>;\n\n\tpublic createContainer<T>(\n\t\troot: DataStoreKey<T>,\n\t\tregistry: Registry<Promise<DataStoreKind>>,\n\t): Promise<FluidContainerWithService<T>>;\n\n\tpublic async createContainer<T>(\n\t\troot: DataStoreKey<T> | DataStoreKind<T>,\n\t\tregistry?: Registry<Promise<DataStoreKind<T>>>,\n\t): Promise<FluidContainerWithService<T>> {\n\t\tif (registry === undefined) {\n\t\t\tDataStoreKindImplementation.narrowGeneric(root);\n\t\t\treturn this.statics.createDetached(normalizeRegistry(root), this.options, root);\n\t\t} else {\n\t\t\tconst result = await lookupInRegistry(registry, root);\n\t\t\treturn this.statics.createDetached(registry, this.options, result);\n\t\t}\n\t}\n\n\tpublic async loadContainer<T>(\n\t\tid: string,\n\t\troot: DataStoreKind<T> | Registry<Promise<DataStoreKind<T>>>,\n\t): Promise<FluidContainerAttached<T>> {\n\t\treturn this.statics.load(normalizeRegistry(root), this.options, id);\n\t}\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/runtime-utils",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.114.0",
|
|
4
4
|
"description": "Collection of utility functions for Fluid Runtime",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -79,27 +79,27 @@
|
|
|
79
79
|
"temp-directory": "nyc/.nyc_output"
|
|
80
80
|
},
|
|
81
81
|
"dependencies": {
|
|
82
|
-
"@fluid-internal/client-utils": "2.
|
|
83
|
-
"@fluidframework/container-definitions": "2.
|
|
84
|
-
"@fluidframework/container-runtime-definitions": "2.
|
|
85
|
-
"@fluidframework/core-interfaces": "2.
|
|
86
|
-
"@fluidframework/core-utils": "2.
|
|
87
|
-
"@fluidframework/datastore-definitions": "2.
|
|
88
|
-
"@fluidframework/driver-definitions": "2.
|
|
89
|
-
"@fluidframework/driver-utils": "2.
|
|
90
|
-
"@fluidframework/runtime-definitions": "2.
|
|
91
|
-
"@fluidframework/telemetry-utils": "2.
|
|
82
|
+
"@fluid-internal/client-utils": "~2.114.0",
|
|
83
|
+
"@fluidframework/container-definitions": "~2.114.0",
|
|
84
|
+
"@fluidframework/container-runtime-definitions": "~2.114.0",
|
|
85
|
+
"@fluidframework/core-interfaces": "~2.114.0",
|
|
86
|
+
"@fluidframework/core-utils": "~2.114.0",
|
|
87
|
+
"@fluidframework/datastore-definitions": "~2.114.0",
|
|
88
|
+
"@fluidframework/driver-definitions": "~2.114.0",
|
|
89
|
+
"@fluidframework/driver-utils": "~2.114.0",
|
|
90
|
+
"@fluidframework/runtime-definitions": "~2.114.0",
|
|
91
|
+
"@fluidframework/telemetry-utils": "~2.114.0",
|
|
92
92
|
"semver-ts": "^1.0.3"
|
|
93
93
|
},
|
|
94
94
|
"devDependencies": {
|
|
95
95
|
"@arethetypeswrong/cli": "^0.18.2",
|
|
96
96
|
"@biomejs/biome": "~2.4.5",
|
|
97
|
-
"@fluid-internal/mocha-test-setup": "2.
|
|
97
|
+
"@fluid-internal/mocha-test-setup": "~2.114.0",
|
|
98
98
|
"@fluid-tools/build-cli": "^0.65.0",
|
|
99
99
|
"@fluidframework/build-common": "^2.0.3",
|
|
100
100
|
"@fluidframework/build-tools": "^0.65.0",
|
|
101
101
|
"@fluidframework/eslint-config-fluid": "^13.0.0",
|
|
102
|
-
"@fluidframework/runtime-utils-previous": "npm:@fluidframework/runtime-utils@2.
|
|
102
|
+
"@fluidframework/runtime-utils-previous": "npm:@fluidframework/runtime-utils@2.112.0",
|
|
103
103
|
"@microsoft/api-extractor": "7.58.1",
|
|
104
104
|
"@types/mocha": "^10.0.10",
|
|
105
105
|
"@types/node": "~22.19.17",
|
|
@@ -122,9 +122,6 @@
|
|
|
122
122
|
"entrypoint": "legacy"
|
|
123
123
|
},
|
|
124
124
|
"scripts": {
|
|
125
|
-
"api": "fluid-build . --task api",
|
|
126
|
-
"api-extractor:commonjs": "flub generate entrypoints --resolutionConditions require --outFileLegacyBeta legacy --outFileLegacyAlpha legacyAlpha --outDir ./dist",
|
|
127
|
-
"api-extractor:esnext": "flub generate entrypoints --outFileLegacyBeta legacy --outFileLegacyAlpha legacyAlpha --outDir ./lib --node10TypeCompat",
|
|
128
125
|
"build": "fluid-build . --task build",
|
|
129
126
|
"build:api-reports": "concurrently \"npm:build:api-reports:*\"",
|
|
130
127
|
"build:api-reports:current": "api-extractor run --local --config api-extractor/api-extractor.current.json",
|
|
@@ -132,9 +129,12 @@
|
|
|
132
129
|
"build:commonjs": "fluid-build . --task commonjs",
|
|
133
130
|
"build:compile": "fluid-build . --task compile",
|
|
134
131
|
"build:docs": "api-extractor run --local",
|
|
132
|
+
"build:entrypoints": "fluid-build . --task build:entrypoints",
|
|
133
|
+
"build:entrypoints:cjs": "flub generate entrypoints --resolutionConditions require --outFileLegacyBeta legacy --outFileLegacyAlpha legacyAlpha --outDir ./dist",
|
|
134
|
+
"build:entrypoints:esm": "flub generate entrypoints --outFileLegacyBeta legacy --outFileLegacyAlpha legacyAlpha --outDir ./lib --node10TypeCompat",
|
|
135
135
|
"build:esnext": "tsc --project ./tsconfig.json",
|
|
136
136
|
"build:genver": "gen-version",
|
|
137
|
-
"build:test": "npm
|
|
137
|
+
"build:test": "concurrently npm:build:test:esm npm:build:test:cjs",
|
|
138
138
|
"build:test:cjs": "fluid-tsc commonjs --project ./src/test/tsconfig.cjs.json",
|
|
139
139
|
"build:test:esm": "tsc --project ./src/test/tsconfig.json",
|
|
140
140
|
"check:are-the-types-wrong": "attw --pack .",
|
package/src/index.ts
CHANGED
|
@@ -82,3 +82,21 @@ export type {
|
|
|
82
82
|
MinimumMinorSemanticVersion,
|
|
83
83
|
SemanticVersion,
|
|
84
84
|
} from "./compatibilityBase.js";
|
|
85
|
+
export type { Audience } from "./serviceClientBase.js";
|
|
86
|
+
export {
|
|
87
|
+
DataStoreKindImplementation,
|
|
88
|
+
ServiceContainerBase,
|
|
89
|
+
getContainerAudience,
|
|
90
|
+
} from "./serviceClientBase.js";
|
|
91
|
+
export {
|
|
92
|
+
convertRegistry,
|
|
93
|
+
makeCodeLoader,
|
|
94
|
+
normalizeRegistry,
|
|
95
|
+
rootDataStoreId,
|
|
96
|
+
ServiceClientImplementation,
|
|
97
|
+
} from "./serviceClientUtils.js";
|
|
98
|
+
export type {
|
|
99
|
+
ContainerRuntimeLoader,
|
|
100
|
+
ContainerRuntimeLoaderParams,
|
|
101
|
+
ServiceContainerStatics,
|
|
102
|
+
} from "./serviceClientUtils.js";
|
package/src/packageVersion.ts
CHANGED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { IAudience } from "@fluidframework/container-definitions";
|
|
7
|
+
import { AttachState, type IContainer } from "@fluidframework/container-definitions/internal";
|
|
8
|
+
import type { IRequest } from "@fluidframework/core-interfaces";
|
|
9
|
+
import { ErasedTypeImplementation } from "@fluidframework/core-interfaces/internal";
|
|
10
|
+
import { assert } from "@fluidframework/core-utils/internal";
|
|
11
|
+
import {
|
|
12
|
+
type DataStoreKey,
|
|
13
|
+
type DataStoreKind,
|
|
14
|
+
type FluidContainerAttached,
|
|
15
|
+
type FluidContainerWithService,
|
|
16
|
+
type Registry,
|
|
17
|
+
lookupInRegistry,
|
|
18
|
+
} from "@fluidframework/driver-definitions/internal";
|
|
19
|
+
import type {
|
|
20
|
+
IContainerRuntimeBase,
|
|
21
|
+
IFluidDataStoreChannel,
|
|
22
|
+
IFluidDataStoreContext,
|
|
23
|
+
IFluidDataStoreFactory,
|
|
24
|
+
} from "@fluidframework/runtime-definitions/internal";
|
|
25
|
+
import { UsageError } from "@fluidframework/telemetry-utils/internal";
|
|
26
|
+
|
|
27
|
+
/*
|
|
28
|
+
* This file provides common implementation logic for ServiceClient implementations.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Implementation of `DataStoreKind`.
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
35
|
+
export class DataStoreKindImplementation<T>
|
|
36
|
+
extends ErasedTypeImplementation<DataStoreKind<T>>
|
|
37
|
+
implements DataStoreKind<T>, IFluidDataStoreFactory
|
|
38
|
+
{
|
|
39
|
+
/**
|
|
40
|
+
* Type guard for narrowing unions which contain DataStoreKind<T> to DataStoreKind<T>.
|
|
41
|
+
*/
|
|
42
|
+
public static guard<T>(
|
|
43
|
+
value: T,
|
|
44
|
+
): value is DataStoreKindImplementation<T extends DataStoreKind<infer T2> ? T2 : never> & T {
|
|
45
|
+
return value instanceof DataStoreKindImplementation;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Type guard for narrowing unions which contain DataStoreKind<T> to DataStoreKind<T>.
|
|
50
|
+
*/
|
|
51
|
+
public static narrowGeneric<T>(
|
|
52
|
+
value: T,
|
|
53
|
+
): asserts value is DataStoreKindImplementation<
|
|
54
|
+
T extends DataStoreKind<infer T2> ? T2 : never
|
|
55
|
+
> &
|
|
56
|
+
T {
|
|
57
|
+
if (!DataStoreKindImplementation.guard(value)) {
|
|
58
|
+
throw new Error("Invalid DataStoreKindImplementation");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
public readonly type: string;
|
|
63
|
+
public readonly createDataStore?: (context: IFluidDataStoreContext) => {
|
|
64
|
+
readonly runtime: IFluidDataStoreChannel;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
public constructor(
|
|
68
|
+
private readonly factory: Pick<
|
|
69
|
+
DataStoreKindImplementation<T>,
|
|
70
|
+
"type" | "instantiateDataStore" | "createDataStore"
|
|
71
|
+
>,
|
|
72
|
+
) {
|
|
73
|
+
super();
|
|
74
|
+
this.type = factory.type;
|
|
75
|
+
if (factory.createDataStore !== undefined) {
|
|
76
|
+
this.createDataStore = factory.createDataStore.bind(factory);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
public async instantiateDataStore(
|
|
81
|
+
context: IFluidDataStoreContext,
|
|
82
|
+
existing: boolean,
|
|
83
|
+
): Promise<IFluidDataStoreChannel> {
|
|
84
|
+
return this.factory.instantiateDataStore(context, existing);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
public get IFluidDataStoreFactory(): IFluidDataStoreFactory {
|
|
88
|
+
return this;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
public async adapt(value: Promise<DataStoreKind>): Promise<DataStoreKind<T>> {
|
|
92
|
+
const input = await value;
|
|
93
|
+
if (input === this) {
|
|
94
|
+
return this;
|
|
95
|
+
}
|
|
96
|
+
if (input.type === this.type) {
|
|
97
|
+
throw new UsageError(`Conflicting DataStoreKinds with same type: ${this.type}`);
|
|
98
|
+
}
|
|
99
|
+
throw new UsageError(
|
|
100
|
+
`Mismatched DataStoreKind type. Expected: ${this.type}, got: ${input.type}`,
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Shared base class for all `ServiceClient` container implementations.
|
|
107
|
+
*
|
|
108
|
+
* @remarks
|
|
109
|
+
* Extends `ErasedTypeImplementation` so that
|
|
110
|
+
* {@link getContainerAudience} can narrow via `ServiceContainerBase.narrow()`.
|
|
111
|
+
*
|
|
112
|
+
* @internal
|
|
113
|
+
*/
|
|
114
|
+
export abstract class ServiceContainerBase<TData, TOptions = unknown>
|
|
115
|
+
extends ErasedTypeImplementation<FluidContainerWithService<TData>>
|
|
116
|
+
implements FluidContainerWithService<TData>
|
|
117
|
+
{
|
|
118
|
+
/**
|
|
119
|
+
* True if an attempt to attach has been started. This is used to prevent multiple concurrent attach attempts.
|
|
120
|
+
*/
|
|
121
|
+
private startedAttach = false;
|
|
122
|
+
|
|
123
|
+
protected constructor(
|
|
124
|
+
public readonly registry: Registry<Promise<DataStoreKind<TData>>>,
|
|
125
|
+
public readonly options: TOptions,
|
|
126
|
+
public readonly container: IContainer,
|
|
127
|
+
public readonly data: TData,
|
|
128
|
+
public id: string | undefined,
|
|
129
|
+
) {
|
|
130
|
+
super();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Creates the service-specific request used to attach this container.
|
|
135
|
+
* @remarks
|
|
136
|
+
* Called by {@link ServiceContainerBase.attach} after validating that no attach is already in progress.
|
|
137
|
+
*/
|
|
138
|
+
protected abstract createAttachRequest(): IRequest;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Extracts the container ID from {@link ServiceContainerBase.container}'s resolved URL after attachment.
|
|
142
|
+
* @remarks
|
|
143
|
+
* Override when the service's resolved URL stores the id in a non-standard field.
|
|
144
|
+
*/
|
|
145
|
+
protected getContainerId(): string {
|
|
146
|
+
if (this.container.resolvedUrl === undefined) {
|
|
147
|
+
throw new Error("Resolved URL unexpectedly missing!");
|
|
148
|
+
}
|
|
149
|
+
return this.container.resolvedUrl.id;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
public async attach(): Promise<FluidContainerAttached<TData>> {
|
|
153
|
+
if (this.id !== undefined) {
|
|
154
|
+
throw new UsageError("Container already attached");
|
|
155
|
+
}
|
|
156
|
+
if (this.startedAttach) {
|
|
157
|
+
throw new UsageError("Container attach already in progress");
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
assert(
|
|
161
|
+
this.container.attachState === AttachState.Detached,
|
|
162
|
+
0xd15 /* Container not detached */,
|
|
163
|
+
);
|
|
164
|
+
this.startedAttach = true;
|
|
165
|
+
|
|
166
|
+
// TODO: support setting where attach can fail, and leave the container in a valid (non-closed) state.
|
|
167
|
+
// Likely the best way to support this is by adding a `tryAttach(request): Promise<FluidContainerAttached<TData> | undefined>`.
|
|
168
|
+
|
|
169
|
+
await this.container.attach(this.createAttachRequest());
|
|
170
|
+
// This type cast is needed to work around the fact that TypeScript assumes the "attach" methods can't modify "attachState".
|
|
171
|
+
assert(
|
|
172
|
+
this.container.attachState === (AttachState.Attached as AttachState),
|
|
173
|
+
0xd16 /* Container failed to attach */,
|
|
174
|
+
);
|
|
175
|
+
this.id = this.getContainerId();
|
|
176
|
+
return this as typeof this & { id: string };
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
public get audience(): IAudience {
|
|
180
|
+
return this.container.audience;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
public getRuntime(): IContainerRuntimeBase {
|
|
184
|
+
// The runtime is not part of the public IContainer surface, so it is reached via a structural cast.
|
|
185
|
+
// This relies on an implementation detail of the containers produced by the loader
|
|
186
|
+
// (createDetachedContainer / loadExistingContainer): they carry a `runtime` property.
|
|
187
|
+
// The undefined guard below turns an incompatible container implementation into a clear error
|
|
188
|
+
// instead of a confusing failure later when the missing runtime is used.
|
|
189
|
+
// This is extra risky since IContainer is not marked sealed.
|
|
190
|
+
// TODO: Replace this with a supported, type-safe accessor once the loader exposes one.
|
|
191
|
+
interface IContainerWithRuntime extends IContainer {
|
|
192
|
+
readonly runtime?: IContainerRuntimeBase;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const container = this.container as IContainerWithRuntime;
|
|
196
|
+
if (container.runtime === undefined) {
|
|
197
|
+
throw new Error(
|
|
198
|
+
"Container does not expose a runtime: incompatible container implementation.",
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
return container.runtime;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
public close(): void {
|
|
205
|
+
// TODO: `container.close()` cancels the container runtime's GC timers, but a couple of
|
|
206
|
+
// container-level timers are only bounded `setTimeout`s that survive close (they are not
|
|
207
|
+
// cancelled here, nor even on `dispose`):
|
|
208
|
+
// - The container-loader `NoopHeuristic` timer (~2s), which has no disposal hook.
|
|
209
|
+
// - The container-runtime `SummaryManager` "delay before creating summarizer" timer, whose
|
|
210
|
+
// pending timeout is not cleared when the SummaryManager is torn down.
|
|
211
|
+
// These self-expire, so they do not cause indefinite hangs, but until they fire they keep the
|
|
212
|
+
// Node.js event loop alive, delaying a clean process exit after close. That is a common reason
|
|
213
|
+
// tests resort to Mocha's `--exit` flag. Ideally close() (via the runtime's close path) would
|
|
214
|
+
// cancel these too so that closing a single container is sufficient to release all its timers.
|
|
215
|
+
this.container.close();
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
public async createDataStore<T>(key: DataStoreKey<T>): Promise<T> {
|
|
219
|
+
const kind = await lookupInRegistry(this.registry, key);
|
|
220
|
+
DataStoreKindImplementation.narrowGeneric(kind);
|
|
221
|
+
const containerRuntime = this.getRuntime();
|
|
222
|
+
|
|
223
|
+
// TODO: There should probably be a higher level more type safe way to do this.
|
|
224
|
+
const context = containerRuntime.createDetachedDataStore([kind.type]);
|
|
225
|
+
const channel = await kind.instantiateDataStore(context, false);
|
|
226
|
+
const dataStore = await context.attachRuntime(kind, channel);
|
|
227
|
+
const entryPoint = await dataStore.entryPoint.get();
|
|
228
|
+
// The data store's entry point type is erased at the registry boundary;
|
|
229
|
+
// the DataStoreKind<T> used to create it guarantees the entry point is a T.
|
|
230
|
+
return entryPoint as T;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* All clients connected to the op stream, both read-only and read/write.
|
|
236
|
+
* @remarks
|
|
237
|
+
* Currently just {@link @fluidframework/container-definitions#IAudience}, but may diverge before stabilizing.
|
|
238
|
+
* @privateRemarks
|
|
239
|
+
* This is currently just an alias for IAudience, but it is defined separately to allow for:
|
|
240
|
+
* 1. Following the no I prefix naming convention.
|
|
241
|
+
* 2. The possibility of diverging from IAudience in the future if desired.
|
|
242
|
+
* 3. Make it easy for the reexport from fluid-framework to be `@alpha` so the name is not locked down prematurely.
|
|
243
|
+
* @sealed @alpha
|
|
244
|
+
*/
|
|
245
|
+
export type Audience = IAudience;
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Gets the {@link Audience} from a Fluid container
|
|
249
|
+
* created by any {@link @fluidframework/driver-definitions#ServiceClient}.
|
|
250
|
+
* @privateRemarks
|
|
251
|
+
* This is exposed via a free function rather than as a property of FluidContainerAttached
|
|
252
|
+
* for a few minor reasons:
|
|
253
|
+
* 1. This allows stabilizing the FluidContainerAttached API independently committing to how we want to expose the audience.
|
|
254
|
+
* 2. This demonstrates the pattern of how we can have possible less stable APIs to expose service specific features without them being part of the core FluidContainer API.
|
|
255
|
+
* This will be important for both new feature stabilization, and also exposing anything needed for legacy interop.
|
|
256
|
+
* @alpha
|
|
257
|
+
*/
|
|
258
|
+
export function getContainerAudience(container: FluidContainerAttached): Audience {
|
|
259
|
+
ServiceContainerBase.narrow(container);
|
|
260
|
+
return container.audience;
|
|
261
|
+
}
|