@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.
Files changed (41) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/api-report/runtime-utils.legacy.alpha.api.md +6 -0
  3. package/dist/index.d.ts +4 -0
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +11 -1
  6. package/dist/index.js.map +1 -1
  7. package/dist/legacyAlpha.d.ts +5 -0
  8. package/dist/packageVersion.d.ts +1 -1
  9. package/dist/packageVersion.d.ts.map +1 -1
  10. package/dist/packageVersion.js +1 -1
  11. package/dist/packageVersion.js.map +1 -1
  12. package/dist/serviceClientBase.d.ts +96 -0
  13. package/dist/serviceClientBase.d.ts.map +1 -0
  14. package/dist/serviceClientBase.js +165 -0
  15. package/dist/serviceClientBase.js.map +1 -0
  16. package/dist/serviceClientUtils.d.ts +90 -0
  17. package/dist/serviceClientUtils.d.ts.map +1 -0
  18. package/dist/serviceClientUtils.js +128 -0
  19. package/dist/serviceClientUtils.js.map +1 -0
  20. package/lib/index.d.ts +4 -0
  21. package/lib/index.d.ts.map +1 -1
  22. package/lib/index.js +2 -0
  23. package/lib/index.js.map +1 -1
  24. package/lib/legacyAlpha.d.ts +5 -0
  25. package/lib/packageVersion.d.ts +1 -1
  26. package/lib/packageVersion.d.ts.map +1 -1
  27. package/lib/packageVersion.js +1 -1
  28. package/lib/packageVersion.js.map +1 -1
  29. package/lib/serviceClientBase.d.ts +96 -0
  30. package/lib/serviceClientBase.d.ts.map +1 -0
  31. package/lib/serviceClientBase.js +159 -0
  32. package/lib/serviceClientBase.js.map +1 -0
  33. package/lib/serviceClientUtils.d.ts +90 -0
  34. package/lib/serviceClientUtils.d.ts.map +1 -0
  35. package/lib/serviceClientUtils.js +121 -0
  36. package/lib/serviceClientUtils.js.map +1 -0
  37. package/package.json +17 -17
  38. package/src/index.ts +18 -0
  39. package/src/packageVersion.ts +1 -1
  40. package/src/serviceClientBase.ts +261 -0
  41. package/src/serviceClientUtils.ts +236 -0
@@ -0,0 +1,236 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import type {
7
+ ICodeDetailsLoader,
8
+ IContainerContext,
9
+ IFluidCodeDetails,
10
+ IFluidCodeDetailsComparer,
11
+ IFluidModuleWithDetails,
12
+ IRuntime,
13
+ IRuntimeFactory,
14
+ } from "@fluidframework/container-definitions/internal";
15
+ import type { FluidObject } from "@fluidframework/core-interfaces";
16
+ import { assert } from "@fluidframework/core-utils/internal";
17
+ import {
18
+ createBasicRegistryKey,
19
+ type DataStoreKey,
20
+ type DataStoreKind,
21
+ type DataStoreRegistry,
22
+ type FluidContainerAttached,
23
+ type FluidContainerWithService,
24
+ type Registry,
25
+ lookupInRegistry,
26
+ type ServiceClient,
27
+ } from "@fluidframework/driver-definitions/internal";
28
+ import type {
29
+ FluidDataStoreRegistryEntry,
30
+ IContainerRuntimeBase,
31
+ IFluidDataStoreRegistry,
32
+ MinimumVersionForCollab,
33
+ } from "@fluidframework/runtime-definitions/internal";
34
+
35
+ import { DataStoreKindImplementation } from "./serviceClientBase.js";
36
+
37
+ /**
38
+ * The constant ID used for the root data store alias in service containers.
39
+ * @internal
40
+ */
41
+ export const rootDataStoreId = "root";
42
+
43
+ /**
44
+ * Converts a `DataStoreRegistry` to the `IFluidDataStoreRegistry` interface expected by the container runtime.
45
+ * @remarks
46
+ * This does not leverage the ability for `IFluidDataStoreRegistry.get` to return undefined.
47
+ * Note that all use-cases of `IFluidDataStoreRegistry.get` returning undefined currently end up as a fatal error.
48
+ * Therefore it should be fine for the error to instead be thrown by the registry function, which is what this function does.
49
+ * @internal
50
+ */
51
+ export function convertRegistry<T>(registry: DataStoreRegistry<T>): IFluidDataStoreRegistry {
52
+ return {
53
+ async get(name: string): Promise<FluidDataStoreRegistryEntry | undefined> {
54
+ const dataStoreKind = await lookupInRegistry(registry, createBasicRegistryKey(name));
55
+ DataStoreKindImplementation.narrowGeneric(dataStoreKind);
56
+ return dataStoreKind;
57
+ },
58
+ get IFluidDataStoreRegistry(): IFluidDataStoreRegistry {
59
+ return this;
60
+ },
61
+ };
62
+ }
63
+
64
+ /**
65
+ * Normalizes a `DataStoreKind` or registry function into a registry function.
66
+ * @internal
67
+ */
68
+ export function normalizeRegistry<T>(
69
+ input: DataStoreKind<T> | Registry<Promise<DataStoreKind<T>>>,
70
+ ): Registry<Promise<DataStoreKind<T>>> {
71
+ if (DataStoreKindImplementation.guard(input)) {
72
+ return async () => input;
73
+ }
74
+ assert(typeof input === "function", 0xd17 /* Registry must be a function */);
75
+ return input;
76
+ }
77
+
78
+ /**
79
+ * Parameters passed to a {@link ContainerRuntimeLoader}.
80
+ * @internal
81
+ */
82
+ export interface ContainerRuntimeLoaderParams {
83
+ context: IContainerContext;
84
+ registry: IFluidDataStoreRegistry;
85
+ provideEntryPoint: (runtime: IContainerRuntimeBase) => Promise<FluidObject>;
86
+ existing: boolean;
87
+ minVersionForCollab: MinimumVersionForCollab;
88
+ /**
89
+ * The type string of the root data store to create. Only set when `existing` is false.
90
+ */
91
+ newContainerRootType: string | undefined;
92
+ }
93
+
94
+ /**
95
+ * A service-specific callback that creates or loads the container runtime.
96
+ *
97
+ * @remarks
98
+ * Receives the runtime parameters assembled by {@link makeCodeLoader} and is responsible for
99
+ * calling the concrete runtime factory (e.g. `ContainerRuntime.loadRuntime2`) and, when
100
+ * `existing` is `false`, initializing the root data store before returning.
101
+ *
102
+ * @internal
103
+ */
104
+ export type ContainerRuntimeLoader = (
105
+ parameters: ContainerRuntimeLoaderParams,
106
+ ) => Promise<IRuntime>;
107
+
108
+ /**
109
+ * Creates an `ICodeDetailsLoader` that wires up the container runtime via the supplied
110
+ * `loadRuntime` callback.
111
+ *
112
+ * @remarks
113
+ * The `loadRuntime` callback is responsible for invoking the concrete runtime factory and,
114
+ * when `parameters.existing` is `false` and `parameters.newContainerRootType` is set, creating and
115
+ * aliasing the root data store.
116
+ *
117
+ * This loader never does any code loading, and always assumes it is compatible.
118
+ * TODO: We should reevaluate this before promoting ServiceClient APIs to beta.
119
+ *
120
+ * @internal
121
+ */
122
+ export function makeCodeLoader<T>(
123
+ registry: DataStoreRegistry<T>,
124
+ minVersionForCollab: MinimumVersionForCollab,
125
+ loadRuntime: ContainerRuntimeLoader,
126
+ root?: DataStoreKind<T>,
127
+ ): ICodeDetailsLoader {
128
+ const fluidExport: IRuntimeFactory & IFluidCodeDetailsComparer = {
129
+ async instantiateRuntime(
130
+ context: IContainerContext,
131
+ existing: boolean,
132
+ ): Promise<IRuntime> {
133
+ const provideEntryPoint = async (
134
+ entryPointRuntime: IContainerRuntimeBase,
135
+ ): Promise<T & FluidObject> => {
136
+ const data = await entryPointRuntime.getAliasedDataStoreEntryPoint(rootDataStoreId);
137
+ if (data === undefined) {
138
+ throw new Error("Root data store missing!");
139
+ }
140
+ const rootDataStore = await data.get();
141
+ return rootDataStore as T & FluidObject;
142
+ };
143
+
144
+ return loadRuntime({
145
+ context,
146
+ registry: convertRegistry(registry),
147
+ provideEntryPoint,
148
+ existing,
149
+ minVersionForCollab,
150
+ newContainerRootType: root?.type,
151
+ });
152
+ },
153
+
154
+ async satisfies(
155
+ candidate: IFluidCodeDetails,
156
+ constraint: IFluidCodeDetails,
157
+ ): Promise<boolean> {
158
+ return true;
159
+ },
160
+
161
+ async compare(a: IFluidCodeDetails, b: IFluidCodeDetails): Promise<number | undefined> {
162
+ return 0;
163
+ },
164
+
165
+ get IRuntimeFactory(): IRuntimeFactory {
166
+ return fluidExport;
167
+ },
168
+
169
+ get IFluidCodeDetailsComparer(): IFluidCodeDetailsComparer {
170
+ return fluidExport;
171
+ },
172
+ };
173
+
174
+ return {
175
+ load: async (details: IFluidCodeDetails): Promise<IFluidModuleWithDetails> => {
176
+ return { module: { fluidExport }, details };
177
+ },
178
+ };
179
+ }
180
+
181
+ /**
182
+ * Minimal interface for the static container factory methods used by {@link ServiceClientImplementation}.
183
+ * @internal
184
+ */
185
+ export interface ServiceContainerStatics<TOptions> {
186
+ createDetached<T>(
187
+ registry: DataStoreRegistry<T>,
188
+ options: TOptions,
189
+ root: DataStoreKind<T>,
190
+ ): Promise<FluidContainerWithService<T>>;
191
+
192
+ load<T>(
193
+ registry: DataStoreRegistry<T>,
194
+ options: TOptions,
195
+ id: string,
196
+ ): Promise<FluidContainerAttached<T>>;
197
+ }
198
+
199
+ /**
200
+ * Creates a {@link @fluidframework/driver-definitions#ServiceClient} that delegates container
201
+ * creation and loading to the supplied container class statics.
202
+ * @internal
203
+ */
204
+ export class ServiceClientImplementation<TOptions> implements ServiceClient {
205
+ public constructor(
206
+ private readonly options: TOptions,
207
+ private readonly statics: ServiceContainerStatics<TOptions>,
208
+ ) {}
209
+
210
+ public createContainer<T>(root: DataStoreKind<T>): Promise<FluidContainerWithService<T>>;
211
+
212
+ public createContainer<T>(
213
+ root: DataStoreKey<T>,
214
+ registry: Registry<Promise<DataStoreKind>>,
215
+ ): Promise<FluidContainerWithService<T>>;
216
+
217
+ public async createContainer<T>(
218
+ root: DataStoreKey<T> | DataStoreKind<T>,
219
+ registry?: Registry<Promise<DataStoreKind<T>>>,
220
+ ): Promise<FluidContainerWithService<T>> {
221
+ if (registry === undefined) {
222
+ DataStoreKindImplementation.narrowGeneric(root);
223
+ return this.statics.createDetached(normalizeRegistry(root), this.options, root);
224
+ } else {
225
+ const result = await lookupInRegistry(registry, root);
226
+ return this.statics.createDetached(registry, this.options, result);
227
+ }
228
+ }
229
+
230
+ public async loadContainer<T>(
231
+ id: string,
232
+ root: DataStoreKind<T> | Registry<Promise<DataStoreKind<T>>>,
233
+ ): Promise<FluidContainerAttached<T>> {
234
+ return this.statics.load(normalizeRegistry(root), this.options, id);
235
+ }
236
+ }